1 /* 2 * Copyright (c) 2015-2016 Quantenna Communications, Inc. 3 * All rights reserved. 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License 7 * as published by the Free Software Foundation; either version 2 8 * of the License, or (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 */ 16 17 #include <linux/kernel.h> 18 #include <linux/module.h> 19 #include <linux/slab.h> 20 21 #include "cfg80211.h" 22 #include "core.h" 23 #include "qlink.h" 24 #include "bus.h" 25 #include "trans.h" 26 #include "util.h" 27 #include "event.h" 28 #include "qlink_util.h" 29 30 static int 31 qtnf_event_handle_sta_assoc(struct qtnf_wmac *mac, struct qtnf_vif *vif, 32 const struct qlink_event_sta_assoc *sta_assoc, 33 u16 len) 34 { 35 const u8 *sta_addr; 36 u16 frame_control; 37 struct station_info *sinfo; 38 size_t payload_len; 39 u16 tlv_type; 40 u16 tlv_value_len; 41 size_t tlv_full_len; 42 const struct qlink_tlv_hdr *tlv; 43 int ret = 0; 44 45 if (unlikely(len < sizeof(*sta_assoc))) { 46 pr_err("VIF%u.%u: payload is too short (%u < %zu)\n", 47 mac->macid, vif->vifid, len, sizeof(*sta_assoc)); 48 return -EINVAL; 49 } 50 51 if (vif->wdev.iftype != NL80211_IFTYPE_AP) { 52 pr_err("VIF%u.%u: STA_ASSOC event when not in AP mode\n", 53 mac->macid, vif->vifid); 54 return -EPROTO; 55 } 56 57 sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL); 58 if (!sinfo) 59 return -ENOMEM; 60 61 sta_addr = sta_assoc->sta_addr; 62 frame_control = le16_to_cpu(sta_assoc->frame_control); 63 64 pr_debug("VIF%u.%u: MAC:%pM FC:%x\n", mac->macid, vif->vifid, sta_addr, 65 frame_control); 66 67 qtnf_sta_list_add(vif, sta_addr); 68 69 sinfo->assoc_req_ies = NULL; 70 sinfo->assoc_req_ies_len = 0; 71 sinfo->generation = vif->generation; 72 73 payload_len = len - sizeof(*sta_assoc); 74 tlv = (const struct qlink_tlv_hdr *)sta_assoc->ies; 75 76 while (payload_len >= sizeof(*tlv)) { 77 tlv_type = le16_to_cpu(tlv->type); 78 tlv_value_len = le16_to_cpu(tlv->len); 79 tlv_full_len = tlv_value_len + sizeof(struct qlink_tlv_hdr); 80 81 if (tlv_full_len > payload_len) { 82 ret = -EINVAL; 83 goto out; 84 } 85 86 if (tlv_type == QTN_TLV_ID_IE_SET) { 87 const struct qlink_tlv_ie_set *ie_set; 88 unsigned int ie_len; 89 90 if (payload_len < sizeof(*ie_set)) { 91 ret = -EINVAL; 92 goto out; 93 } 94 95 ie_set = (const struct qlink_tlv_ie_set *)tlv; 96 ie_len = tlv_value_len - 97 (sizeof(*ie_set) - sizeof(ie_set->hdr)); 98 99 if (ie_set->type == QLINK_IE_SET_ASSOC_REQ && ie_len) { 100 sinfo->assoc_req_ies = ie_set->ie_data; 101 sinfo->assoc_req_ies_len = ie_len; 102 } 103 } 104 105 payload_len -= tlv_full_len; 106 tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len); 107 } 108 109 if (payload_len) { 110 ret = -EINVAL; 111 goto out; 112 } 113 114 cfg80211_new_sta(vif->netdev, sta_assoc->sta_addr, sinfo, 115 GFP_KERNEL); 116 117 out: 118 kfree(sinfo); 119 return ret; 120 } 121 122 static int 123 qtnf_event_handle_sta_deauth(struct qtnf_wmac *mac, struct qtnf_vif *vif, 124 const struct qlink_event_sta_deauth *sta_deauth, 125 u16 len) 126 { 127 const u8 *sta_addr; 128 u16 reason; 129 130 if (unlikely(len < sizeof(*sta_deauth))) { 131 pr_err("VIF%u.%u: payload is too short (%u < %zu)\n", 132 mac->macid, vif->vifid, len, 133 sizeof(struct qlink_event_sta_deauth)); 134 return -EINVAL; 135 } 136 137 if (vif->wdev.iftype != NL80211_IFTYPE_AP) { 138 pr_err("VIF%u.%u: STA_DEAUTH event when not in AP mode\n", 139 mac->macid, vif->vifid); 140 return -EPROTO; 141 } 142 143 sta_addr = sta_deauth->sta_addr; 144 reason = le16_to_cpu(sta_deauth->reason); 145 146 pr_debug("VIF%u.%u: MAC:%pM reason:%x\n", mac->macid, vif->vifid, 147 sta_addr, reason); 148 149 if (qtnf_sta_list_del(vif, sta_addr)) 150 cfg80211_del_sta(vif->netdev, sta_deauth->sta_addr, 151 GFP_KERNEL); 152 153 return 0; 154 } 155 156 static int 157 qtnf_event_handle_bss_join(struct qtnf_vif *vif, 158 const struct qlink_event_bss_join *join_info, 159 u16 len) 160 { 161 if (unlikely(len < sizeof(*join_info))) { 162 pr_err("VIF%u.%u: payload is too short (%u < %zu)\n", 163 vif->mac->macid, vif->vifid, len, 164 sizeof(struct qlink_event_bss_join)); 165 return -EINVAL; 166 } 167 168 if (vif->wdev.iftype != NL80211_IFTYPE_STATION) { 169 pr_err("VIF%u.%u: BSS_JOIN event when not in STA mode\n", 170 vif->mac->macid, vif->vifid); 171 return -EPROTO; 172 } 173 174 if (vif->sta_state != QTNF_STA_CONNECTING) { 175 pr_err("VIF%u.%u: BSS_JOIN event when STA is not connecting\n", 176 vif->mac->macid, vif->vifid); 177 return -EPROTO; 178 } 179 180 pr_debug("VIF%u.%u: BSSID:%pM\n", vif->mac->macid, vif->vifid, 181 join_info->bssid); 182 183 cfg80211_connect_result(vif->netdev, join_info->bssid, NULL, 0, NULL, 184 0, le16_to_cpu(join_info->status), GFP_KERNEL); 185 186 if (le16_to_cpu(join_info->status) == WLAN_STATUS_SUCCESS) { 187 vif->sta_state = QTNF_STA_CONNECTED; 188 netif_carrier_on(vif->netdev); 189 } else { 190 vif->sta_state = QTNF_STA_DISCONNECTED; 191 } 192 193 return 0; 194 } 195 196 static int 197 qtnf_event_handle_bss_leave(struct qtnf_vif *vif, 198 const struct qlink_event_bss_leave *leave_info, 199 u16 len) 200 { 201 if (unlikely(len < sizeof(*leave_info))) { 202 pr_err("VIF%u.%u: payload is too short (%u < %zu)\n", 203 vif->mac->macid, vif->vifid, len, 204 sizeof(struct qlink_event_bss_leave)); 205 return -EINVAL; 206 } 207 208 if (vif->wdev.iftype != NL80211_IFTYPE_STATION) { 209 pr_err("VIF%u.%u: BSS_LEAVE event when not in STA mode\n", 210 vif->mac->macid, vif->vifid); 211 return -EPROTO; 212 } 213 214 if (vif->sta_state != QTNF_STA_CONNECTED) { 215 pr_err("VIF%u.%u: BSS_LEAVE event when STA is not connected\n", 216 vif->mac->macid, vif->vifid); 217 return -EPROTO; 218 } 219 220 pr_debug("VIF%u.%u: disconnected\n", vif->mac->macid, vif->vifid); 221 222 cfg80211_disconnected(vif->netdev, le16_to_cpu(leave_info->reason), 223 NULL, 0, 0, GFP_KERNEL); 224 225 vif->sta_state = QTNF_STA_DISCONNECTED; 226 netif_carrier_off(vif->netdev); 227 228 return 0; 229 } 230 231 static int 232 qtnf_event_handle_mgmt_received(struct qtnf_vif *vif, 233 const struct qlink_event_rxmgmt *rxmgmt, 234 u16 len) 235 { 236 const size_t min_len = sizeof(*rxmgmt) + 237 sizeof(struct ieee80211_hdr_3addr); 238 const struct ieee80211_hdr_3addr *frame = (void *)rxmgmt->frame_data; 239 const u16 frame_len = len - sizeof(*rxmgmt); 240 enum nl80211_rxmgmt_flags flags = 0; 241 242 if (unlikely(len < min_len)) { 243 pr_err("VIF%u.%u: payload is too short (%u < %zu)\n", 244 vif->mac->macid, vif->vifid, len, min_len); 245 return -EINVAL; 246 } 247 248 if (le32_to_cpu(rxmgmt->flags) & QLINK_RXMGMT_FLAG_ANSWERED) 249 flags |= NL80211_RXMGMT_FLAG_ANSWERED; 250 251 pr_debug("%s LEN:%u FC:%.4X SA:%pM\n", vif->netdev->name, frame_len, 252 le16_to_cpu(frame->frame_control), frame->addr2); 253 254 cfg80211_rx_mgmt(&vif->wdev, le32_to_cpu(rxmgmt->freq), rxmgmt->sig_dbm, 255 rxmgmt->frame_data, frame_len, flags); 256 257 return 0; 258 } 259 260 static int 261 qtnf_event_handle_scan_results(struct qtnf_vif *vif, 262 const struct qlink_event_scan_result *sr, 263 u16 len) 264 { 265 struct cfg80211_bss *bss; 266 struct ieee80211_channel *channel; 267 struct wiphy *wiphy = priv_to_wiphy(vif->mac); 268 enum cfg80211_bss_frame_type frame_type = CFG80211_BSS_FTYPE_UNKNOWN; 269 size_t payload_len; 270 u16 tlv_type; 271 u16 tlv_value_len; 272 size_t tlv_full_len; 273 const struct qlink_tlv_hdr *tlv; 274 const u8 *ies = NULL; 275 size_t ies_len = 0; 276 277 if (len < sizeof(*sr)) { 278 pr_err("VIF%u.%u: payload is too short\n", vif->mac->macid, 279 vif->vifid); 280 return -EINVAL; 281 } 282 283 channel = ieee80211_get_channel(wiphy, le16_to_cpu(sr->freq)); 284 if (!channel) { 285 pr_err("VIF%u.%u: channel at %u MHz not found\n", 286 vif->mac->macid, vif->vifid, le16_to_cpu(sr->freq)); 287 return -EINVAL; 288 } 289 290 payload_len = len - sizeof(*sr); 291 tlv = (struct qlink_tlv_hdr *)sr->payload; 292 293 while (payload_len >= sizeof(struct qlink_tlv_hdr)) { 294 tlv_type = le16_to_cpu(tlv->type); 295 tlv_value_len = le16_to_cpu(tlv->len); 296 tlv_full_len = tlv_value_len + sizeof(struct qlink_tlv_hdr); 297 298 if (tlv_full_len > payload_len) 299 return -EINVAL; 300 301 if (tlv_type == QTN_TLV_ID_IE_SET) { 302 const struct qlink_tlv_ie_set *ie_set; 303 unsigned int ie_len; 304 305 if (payload_len < sizeof(*ie_set)) 306 return -EINVAL; 307 308 ie_set = (const struct qlink_tlv_ie_set *)tlv; 309 ie_len = tlv_value_len - 310 (sizeof(*ie_set) - sizeof(ie_set->hdr)); 311 312 switch (ie_set->type) { 313 case QLINK_IE_SET_BEACON_IES: 314 frame_type = CFG80211_BSS_FTYPE_BEACON; 315 break; 316 case QLINK_IE_SET_PROBE_RESP_IES: 317 frame_type = CFG80211_BSS_FTYPE_PRESP; 318 break; 319 default: 320 frame_type = CFG80211_BSS_FTYPE_UNKNOWN; 321 } 322 323 if (ie_len) { 324 ies = ie_set->ie_data; 325 ies_len = ie_len; 326 } 327 } 328 329 payload_len -= tlv_full_len; 330 tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len); 331 } 332 333 if (payload_len) 334 return -EINVAL; 335 336 bss = cfg80211_inform_bss(wiphy, channel, frame_type, 337 sr->bssid, get_unaligned_le64(&sr->tsf), 338 le16_to_cpu(sr->capab), 339 le16_to_cpu(sr->bintval), ies, ies_len, 340 DBM_TO_MBM(sr->sig_dbm), GFP_KERNEL); 341 if (!bss) 342 return -ENOMEM; 343 344 cfg80211_put_bss(wiphy, bss); 345 346 return 0; 347 } 348 349 static int 350 qtnf_event_handle_scan_complete(struct qtnf_wmac *mac, 351 const struct qlink_event_scan_complete *status, 352 u16 len) 353 { 354 if (len < sizeof(*status)) { 355 pr_err("MAC%u: payload is too short\n", mac->macid); 356 return -EINVAL; 357 } 358 359 qtnf_scan_done(mac, le32_to_cpu(status->flags) & QLINK_SCAN_ABORTED); 360 361 return 0; 362 } 363 364 static int 365 qtnf_event_handle_freq_change(struct qtnf_wmac *mac, 366 const struct qlink_event_freq_change *data, 367 u16 len) 368 { 369 struct wiphy *wiphy = priv_to_wiphy(mac); 370 struct cfg80211_chan_def chandef; 371 struct qtnf_vif *vif; 372 int i; 373 374 if (len < sizeof(*data)) { 375 pr_err("MAC%u: payload is too short\n", mac->macid); 376 return -EINVAL; 377 } 378 379 if (!wiphy->registered) 380 return 0; 381 382 qlink_chandef_q2cfg(wiphy, &data->chan, &chandef); 383 384 if (!cfg80211_chandef_valid(&chandef)) { 385 pr_err("MAC%u: bad channel freq=%u cf1=%u cf2=%u bw=%u\n", 386 mac->macid, chandef.chan->center_freq, 387 chandef.center_freq1, chandef.center_freq2, 388 chandef.width); 389 return -EINVAL; 390 } 391 392 pr_debug("MAC%d: new channel ieee=%u freq1=%u freq2=%u bw=%u\n", 393 mac->macid, chandef.chan->hw_value, chandef.center_freq1, 394 chandef.center_freq2, chandef.width); 395 396 for (i = 0; i < QTNF_MAX_INTF; i++) { 397 vif = &mac->iflist[i]; 398 if (vif->wdev.iftype == NL80211_IFTYPE_UNSPECIFIED) 399 continue; 400 401 if (vif->netdev) { 402 mutex_lock(&vif->wdev.mtx); 403 cfg80211_ch_switch_notify(vif->netdev, &chandef); 404 mutex_unlock(&vif->wdev.mtx); 405 } 406 } 407 408 return 0; 409 } 410 411 static int qtnf_event_handle_radar(struct qtnf_vif *vif, 412 const struct qlink_event_radar *ev, 413 u16 len) 414 { 415 struct wiphy *wiphy = priv_to_wiphy(vif->mac); 416 struct cfg80211_chan_def chandef; 417 418 if (len < sizeof(*ev)) { 419 pr_err("MAC%u: payload is too short\n", vif->mac->macid); 420 return -EINVAL; 421 } 422 423 if (!wiphy->registered || !vif->netdev) 424 return 0; 425 426 qlink_chandef_q2cfg(wiphy, &ev->chan, &chandef); 427 428 if (!cfg80211_chandef_valid(&chandef)) { 429 pr_err("MAC%u: bad channel f1=%u f2=%u bw=%u\n", 430 vif->mac->macid, 431 chandef.center_freq1, chandef.center_freq2, 432 chandef.width); 433 return -EINVAL; 434 } 435 436 pr_info("%s: radar event=%u f1=%u f2=%u bw=%u\n", 437 vif->netdev->name, ev->event, 438 chandef.center_freq1, chandef.center_freq2, 439 chandef.width); 440 441 switch (ev->event) { 442 case QLINK_RADAR_DETECTED: 443 cfg80211_radar_event(wiphy, &chandef, GFP_KERNEL); 444 break; 445 case QLINK_RADAR_CAC_FINISHED: 446 if (!vif->wdev.cac_started) 447 break; 448 449 cfg80211_cac_event(vif->netdev, &chandef, 450 NL80211_RADAR_CAC_FINISHED, GFP_KERNEL); 451 break; 452 case QLINK_RADAR_CAC_ABORTED: 453 if (!vif->wdev.cac_started) 454 break; 455 456 cfg80211_cac_event(vif->netdev, &chandef, 457 NL80211_RADAR_CAC_ABORTED, GFP_KERNEL); 458 break; 459 case QLINK_RADAR_CAC_STARTED: 460 if (vif->wdev.cac_started) 461 break; 462 463 if (!wiphy_ext_feature_isset(wiphy, 464 NL80211_EXT_FEATURE_DFS_OFFLOAD)) 465 break; 466 467 cfg80211_cac_event(vif->netdev, &chandef, 468 NL80211_RADAR_CAC_STARTED, GFP_KERNEL); 469 break; 470 default: 471 pr_warn("%s: unhandled radar event %u\n", 472 vif->netdev->name, ev->event); 473 break; 474 } 475 476 return 0; 477 } 478 479 static int qtnf_event_parse(struct qtnf_wmac *mac, 480 const struct sk_buff *event_skb) 481 { 482 const struct qlink_event *event; 483 struct qtnf_vif *vif = NULL; 484 int ret = -1; 485 u16 event_id; 486 u16 event_len; 487 488 event = (const struct qlink_event *)event_skb->data; 489 event_id = le16_to_cpu(event->event_id); 490 event_len = le16_to_cpu(event->mhdr.len); 491 492 if (likely(event->vifid < QTNF_MAX_INTF)) { 493 vif = &mac->iflist[event->vifid]; 494 } else { 495 pr_err("invalid vif(%u)\n", event->vifid); 496 return -EINVAL; 497 } 498 499 switch (event_id) { 500 case QLINK_EVENT_STA_ASSOCIATED: 501 ret = qtnf_event_handle_sta_assoc(mac, vif, (const void *)event, 502 event_len); 503 break; 504 case QLINK_EVENT_STA_DEAUTH: 505 ret = qtnf_event_handle_sta_deauth(mac, vif, 506 (const void *)event, 507 event_len); 508 break; 509 case QLINK_EVENT_MGMT_RECEIVED: 510 ret = qtnf_event_handle_mgmt_received(vif, (const void *)event, 511 event_len); 512 break; 513 case QLINK_EVENT_SCAN_RESULTS: 514 ret = qtnf_event_handle_scan_results(vif, (const void *)event, 515 event_len); 516 break; 517 case QLINK_EVENT_SCAN_COMPLETE: 518 ret = qtnf_event_handle_scan_complete(mac, (const void *)event, 519 event_len); 520 break; 521 case QLINK_EVENT_BSS_JOIN: 522 ret = qtnf_event_handle_bss_join(vif, (const void *)event, 523 event_len); 524 break; 525 case QLINK_EVENT_BSS_LEAVE: 526 ret = qtnf_event_handle_bss_leave(vif, (const void *)event, 527 event_len); 528 break; 529 case QLINK_EVENT_FREQ_CHANGE: 530 ret = qtnf_event_handle_freq_change(mac, (const void *)event, 531 event_len); 532 break; 533 case QLINK_EVENT_RADAR: 534 ret = qtnf_event_handle_radar(vif, (const void *)event, 535 event_len); 536 break; 537 default: 538 pr_warn("unknown event type: %x\n", event_id); 539 break; 540 } 541 542 return ret; 543 } 544 545 static int qtnf_event_process_skb(struct qtnf_bus *bus, 546 const struct sk_buff *skb) 547 { 548 const struct qlink_event *event; 549 struct qtnf_wmac *mac; 550 int res; 551 552 if (unlikely(!skb || skb->len < sizeof(*event))) { 553 pr_err("invalid event buffer\n"); 554 return -EINVAL; 555 } 556 557 event = (struct qlink_event *)skb->data; 558 559 mac = qtnf_core_get_mac(bus, event->macid); 560 561 pr_debug("new event id:%x len:%u mac:%u vif:%u\n", 562 le16_to_cpu(event->event_id), le16_to_cpu(event->mhdr.len), 563 event->macid, event->vifid); 564 565 if (unlikely(!mac)) 566 return -ENXIO; 567 568 rtnl_lock(); 569 res = qtnf_event_parse(mac, skb); 570 rtnl_unlock(); 571 572 return res; 573 } 574 575 void qtnf_event_work_handler(struct work_struct *work) 576 { 577 struct qtnf_bus *bus = container_of(work, struct qtnf_bus, event_work); 578 struct sk_buff_head *event_queue = &bus->trans.event_queue; 579 struct sk_buff *current_event_skb = skb_dequeue(event_queue); 580 581 while (current_event_skb) { 582 qtnf_event_process_skb(bus, current_event_skb); 583 dev_kfree_skb_any(current_event_skb); 584 current_event_skb = skb_dequeue(event_queue); 585 } 586 } 587