1 // SPDX-License-Identifier: GPL-2.0+ 2 /* Copyright (c) 2015-2016 Quantenna Communications. All rights reserved. */ 3 4 #include <linux/kernel.h> 5 #include <linux/module.h> 6 #include <linux/slab.h> 7 #include <linux/nospec.h> 8 9 #include "cfg80211.h" 10 #include "core.h" 11 #include "qlink.h" 12 #include "bus.h" 13 #include "trans.h" 14 #include "util.h" 15 #include "event.h" 16 #include "qlink_util.h" 17 18 static int 19 qtnf_event_handle_sta_assoc(struct qtnf_wmac *mac, struct qtnf_vif *vif, 20 const struct qlink_event_sta_assoc *sta_assoc, 21 u16 len) 22 { 23 const u8 *sta_addr; 24 u16 frame_control; 25 struct station_info *sinfo; 26 size_t payload_len; 27 u16 tlv_type; 28 u16 tlv_value_len; 29 const struct qlink_tlv_hdr *tlv; 30 int ret = 0; 31 32 if (unlikely(len < sizeof(*sta_assoc))) { 33 pr_err("VIF%u.%u: payload is too short (%u < %zu)\n", 34 mac->macid, vif->vifid, len, sizeof(*sta_assoc)); 35 return -EINVAL; 36 } 37 38 if (vif->wdev.iftype != NL80211_IFTYPE_AP) { 39 pr_err("VIF%u.%u: STA_ASSOC event when not in AP mode\n", 40 mac->macid, vif->vifid); 41 return -EPROTO; 42 } 43 44 sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL); 45 if (!sinfo) 46 return -ENOMEM; 47 48 sta_addr = sta_assoc->sta_addr; 49 frame_control = le16_to_cpu(sta_assoc->frame_control); 50 51 pr_debug("VIF%u.%u: MAC:%pM FC:%x\n", mac->macid, vif->vifid, sta_addr, 52 frame_control); 53 54 qtnf_sta_list_add(vif, sta_addr); 55 56 sinfo->assoc_req_ies = NULL; 57 sinfo->assoc_req_ies_len = 0; 58 sinfo->generation = vif->generation; 59 60 payload_len = len - sizeof(*sta_assoc); 61 62 qlink_for_each_tlv(tlv, sta_assoc->ies, payload_len) { 63 tlv_type = le16_to_cpu(tlv->type); 64 tlv_value_len = le16_to_cpu(tlv->len); 65 66 if (tlv_type == QTN_TLV_ID_IE_SET) { 67 const struct qlink_tlv_ie_set *ie_set; 68 unsigned int ie_len; 69 70 if (tlv_value_len < 71 (sizeof(*ie_set) - sizeof(ie_set->hdr))) { 72 ret = -EINVAL; 73 goto out; 74 } 75 76 ie_set = (const struct qlink_tlv_ie_set *)tlv; 77 ie_len = tlv_value_len - 78 (sizeof(*ie_set) - sizeof(ie_set->hdr)); 79 80 if (ie_set->type == QLINK_IE_SET_ASSOC_REQ && ie_len) { 81 sinfo->assoc_req_ies = ie_set->ie_data; 82 sinfo->assoc_req_ies_len = ie_len; 83 } 84 } 85 } 86 87 if (!qlink_tlv_parsing_ok(tlv, sta_assoc->ies, payload_len)) { 88 pr_err("Malformed TLV buffer\n"); 89 ret = -EINVAL; 90 goto out; 91 } 92 93 cfg80211_new_sta(vif->netdev, sta_assoc->sta_addr, sinfo, 94 GFP_KERNEL); 95 96 out: 97 kfree(sinfo); 98 return ret; 99 } 100 101 static int 102 qtnf_event_handle_sta_deauth(struct qtnf_wmac *mac, struct qtnf_vif *vif, 103 const struct qlink_event_sta_deauth *sta_deauth, 104 u16 len) 105 { 106 const u8 *sta_addr; 107 u16 reason; 108 109 if (unlikely(len < sizeof(*sta_deauth))) { 110 pr_err("VIF%u.%u: payload is too short (%u < %zu)\n", 111 mac->macid, vif->vifid, len, 112 sizeof(struct qlink_event_sta_deauth)); 113 return -EINVAL; 114 } 115 116 if (vif->wdev.iftype != NL80211_IFTYPE_AP) { 117 pr_err("VIF%u.%u: STA_DEAUTH event when not in AP mode\n", 118 mac->macid, vif->vifid); 119 return -EPROTO; 120 } 121 122 sta_addr = sta_deauth->sta_addr; 123 reason = le16_to_cpu(sta_deauth->reason); 124 125 pr_debug("VIF%u.%u: MAC:%pM reason:%x\n", mac->macid, vif->vifid, 126 sta_addr, reason); 127 128 if (qtnf_sta_list_del(vif, sta_addr)) 129 cfg80211_del_sta(vif->netdev, sta_deauth->sta_addr, 130 GFP_KERNEL); 131 132 return 0; 133 } 134 135 static int 136 qtnf_event_handle_bss_join(struct qtnf_vif *vif, 137 const struct qlink_event_bss_join *join_info, 138 u16 len) 139 { 140 struct wiphy *wiphy = priv_to_wiphy(vif->mac); 141 enum ieee80211_statuscode status = le16_to_cpu(join_info->status); 142 struct cfg80211_chan_def chandef; 143 struct cfg80211_bss *bss = NULL; 144 u8 *ie = NULL; 145 size_t payload_len; 146 u16 tlv_type; 147 u16 tlv_value_len; 148 const struct qlink_tlv_hdr *tlv; 149 const u8 *rsp_ies = NULL; 150 size_t rsp_ies_len = 0; 151 152 if (unlikely(len < sizeof(*join_info))) { 153 pr_err("VIF%u.%u: payload is too short (%u < %zu)\n", 154 vif->mac->macid, vif->vifid, len, 155 sizeof(struct qlink_event_bss_join)); 156 return -EINVAL; 157 } 158 159 if (vif->wdev.iftype != NL80211_IFTYPE_STATION) { 160 pr_err("VIF%u.%u: BSS_JOIN event when not in STA mode\n", 161 vif->mac->macid, vif->vifid); 162 return -EPROTO; 163 } 164 165 pr_debug("VIF%u.%u: BSSID:%pM chan:%u status:%u\n", 166 vif->mac->macid, vif->vifid, join_info->bssid, 167 le16_to_cpu(join_info->chan.chan.center_freq), status); 168 169 if (status != WLAN_STATUS_SUCCESS) 170 goto done; 171 172 qlink_chandef_q2cfg(wiphy, &join_info->chan, &chandef); 173 if (!cfg80211_chandef_valid(&chandef)) { 174 pr_warn("MAC%u.%u: bad channel freq=%u cf1=%u cf2=%u bw=%u\n", 175 vif->mac->macid, vif->vifid, 176 chandef.chan ? chandef.chan->center_freq : 0, 177 chandef.center_freq1, 178 chandef.center_freq2, 179 chandef.width); 180 status = WLAN_STATUS_UNSPECIFIED_FAILURE; 181 goto done; 182 } 183 184 bss = cfg80211_get_bss(wiphy, chandef.chan, join_info->bssid, 185 NULL, 0, IEEE80211_BSS_TYPE_ESS, 186 IEEE80211_PRIVACY_ANY); 187 if (!bss) { 188 pr_warn("VIF%u.%u: add missing BSS:%pM chan:%u\n", 189 vif->mac->macid, vif->vifid, 190 join_info->bssid, chandef.chan->hw_value); 191 192 if (!vif->wdev.u.client.ssid_len) { 193 pr_warn("VIF%u.%u: SSID unknown for BSS:%pM\n", 194 vif->mac->macid, vif->vifid, 195 join_info->bssid); 196 status = WLAN_STATUS_UNSPECIFIED_FAILURE; 197 goto done; 198 } 199 200 ie = kzalloc(2 + vif->wdev.u.client.ssid_len, GFP_KERNEL); 201 if (!ie) { 202 pr_warn("VIF%u.%u: IE alloc failed for BSS:%pM\n", 203 vif->mac->macid, vif->vifid, 204 join_info->bssid); 205 status = WLAN_STATUS_UNSPECIFIED_FAILURE; 206 goto done; 207 } 208 209 ie[0] = WLAN_EID_SSID; 210 ie[1] = vif->wdev.u.client.ssid_len; 211 memcpy(ie + 2, vif->wdev.u.client.ssid, 212 vif->wdev.u.client.ssid_len); 213 214 bss = cfg80211_inform_bss(wiphy, chandef.chan, 215 CFG80211_BSS_FTYPE_UNKNOWN, 216 join_info->bssid, 0, 217 WLAN_CAPABILITY_ESS, 100, 218 ie, 2 + vif->wdev.u.client.ssid_len, 219 0, GFP_KERNEL); 220 if (!bss) { 221 pr_warn("VIF%u.%u: can't connect to unknown BSS: %pM\n", 222 vif->mac->macid, vif->vifid, 223 join_info->bssid); 224 status = WLAN_STATUS_UNSPECIFIED_FAILURE; 225 goto done; 226 } 227 } 228 229 payload_len = len - sizeof(*join_info); 230 231 qlink_for_each_tlv(tlv, join_info->ies, payload_len) { 232 tlv_type = le16_to_cpu(tlv->type); 233 tlv_value_len = le16_to_cpu(tlv->len); 234 235 if (tlv_type == QTN_TLV_ID_IE_SET) { 236 const struct qlink_tlv_ie_set *ie_set; 237 unsigned int ie_len; 238 239 if (tlv_value_len < 240 (sizeof(*ie_set) - sizeof(ie_set->hdr))) { 241 pr_warn("invalid IE_SET TLV\n"); 242 status = WLAN_STATUS_UNSPECIFIED_FAILURE; 243 goto done; 244 } 245 246 ie_set = (const struct qlink_tlv_ie_set *)tlv; 247 ie_len = tlv_value_len - 248 (sizeof(*ie_set) - sizeof(ie_set->hdr)); 249 250 switch (ie_set->type) { 251 case QLINK_IE_SET_ASSOC_RESP: 252 if (ie_len) { 253 rsp_ies = ie_set->ie_data; 254 rsp_ies_len = ie_len; 255 } 256 break; 257 default: 258 pr_warn("unexpected IE type: %u\n", 259 ie_set->type); 260 break; 261 } 262 } 263 } 264 265 if (!qlink_tlv_parsing_ok(tlv, join_info->ies, payload_len)) 266 pr_warn("Malformed TLV buffer\n"); 267 done: 268 cfg80211_connect_result(vif->netdev, join_info->bssid, NULL, 0, rsp_ies, 269 rsp_ies_len, status, GFP_KERNEL); 270 if (bss) { 271 if (!ether_addr_equal(vif->bssid, join_info->bssid)) 272 ether_addr_copy(vif->bssid, join_info->bssid); 273 cfg80211_put_bss(wiphy, bss); 274 } 275 276 if (status == WLAN_STATUS_SUCCESS) 277 netif_carrier_on(vif->netdev); 278 279 kfree(ie); 280 return 0; 281 } 282 283 static int 284 qtnf_event_handle_bss_leave(struct qtnf_vif *vif, 285 const struct qlink_event_bss_leave *leave_info, 286 u16 len) 287 { 288 if (unlikely(len < sizeof(*leave_info))) { 289 pr_err("VIF%u.%u: payload is too short (%u < %zu)\n", 290 vif->mac->macid, vif->vifid, len, 291 sizeof(struct qlink_event_bss_leave)); 292 return -EINVAL; 293 } 294 295 if (vif->wdev.iftype != NL80211_IFTYPE_STATION) { 296 pr_err("VIF%u.%u: BSS_LEAVE event when not in STA mode\n", 297 vif->mac->macid, vif->vifid); 298 return -EPROTO; 299 } 300 301 pr_debug("VIF%u.%u: disconnected\n", vif->mac->macid, vif->vifid); 302 303 cfg80211_disconnected(vif->netdev, le16_to_cpu(leave_info->reason), 304 NULL, 0, 0, GFP_KERNEL); 305 netif_carrier_off(vif->netdev); 306 307 return 0; 308 } 309 310 static int 311 qtnf_event_handle_mgmt_received(struct qtnf_vif *vif, 312 const struct qlink_event_rxmgmt *rxmgmt, 313 u16 len) 314 { 315 const size_t min_len = sizeof(*rxmgmt) + 316 sizeof(struct ieee80211_hdr_3addr); 317 const struct ieee80211_hdr_3addr *frame = (void *)rxmgmt->frame_data; 318 const u16 frame_len = len - sizeof(*rxmgmt); 319 enum nl80211_rxmgmt_flags flags = 0; 320 321 if (unlikely(len < min_len)) { 322 pr_err("VIF%u.%u: payload is too short (%u < %zu)\n", 323 vif->mac->macid, vif->vifid, len, min_len); 324 return -EINVAL; 325 } 326 327 if (le32_to_cpu(rxmgmt->flags) & QLINK_RXMGMT_FLAG_ANSWERED) 328 flags |= NL80211_RXMGMT_FLAG_ANSWERED; 329 330 pr_debug("%s LEN:%u FC:%.4X SA:%pM\n", vif->netdev->name, frame_len, 331 le16_to_cpu(frame->frame_control), frame->addr2); 332 333 cfg80211_rx_mgmt(&vif->wdev, le32_to_cpu(rxmgmt->freq), rxmgmt->sig_dbm, 334 rxmgmt->frame_data, frame_len, flags); 335 336 return 0; 337 } 338 339 static int 340 qtnf_event_handle_scan_results(struct qtnf_vif *vif, 341 const struct qlink_event_scan_result *sr, 342 u16 len) 343 { 344 struct cfg80211_bss *bss; 345 struct ieee80211_channel *channel; 346 struct wiphy *wiphy = priv_to_wiphy(vif->mac); 347 enum cfg80211_bss_frame_type frame_type = CFG80211_BSS_FTYPE_UNKNOWN; 348 size_t payload_len; 349 u16 tlv_type; 350 u16 tlv_value_len; 351 const struct qlink_tlv_hdr *tlv; 352 const u8 *ies = NULL; 353 size_t ies_len = 0; 354 355 if (len < sizeof(*sr)) { 356 pr_err("VIF%u.%u: payload is too short\n", vif->mac->macid, 357 vif->vifid); 358 return -EINVAL; 359 } 360 361 channel = ieee80211_get_channel(wiphy, le16_to_cpu(sr->freq)); 362 if (!channel) { 363 pr_err("VIF%u.%u: channel at %u MHz not found\n", 364 vif->mac->macid, vif->vifid, le16_to_cpu(sr->freq)); 365 return -EINVAL; 366 } 367 368 payload_len = len - sizeof(*sr); 369 370 qlink_for_each_tlv(tlv, sr->payload, payload_len) { 371 tlv_type = le16_to_cpu(tlv->type); 372 tlv_value_len = le16_to_cpu(tlv->len); 373 374 if (tlv_type == QTN_TLV_ID_IE_SET) { 375 const struct qlink_tlv_ie_set *ie_set; 376 unsigned int ie_len; 377 378 if (tlv_value_len < 379 (sizeof(*ie_set) - sizeof(ie_set->hdr))) 380 return -EINVAL; 381 382 ie_set = (const struct qlink_tlv_ie_set *)tlv; 383 ie_len = tlv_value_len - 384 (sizeof(*ie_set) - sizeof(ie_set->hdr)); 385 386 switch (ie_set->type) { 387 case QLINK_IE_SET_BEACON_IES: 388 frame_type = CFG80211_BSS_FTYPE_BEACON; 389 break; 390 case QLINK_IE_SET_PROBE_RESP_IES: 391 frame_type = CFG80211_BSS_FTYPE_PRESP; 392 break; 393 default: 394 frame_type = CFG80211_BSS_FTYPE_UNKNOWN; 395 } 396 397 if (ie_len) { 398 ies = ie_set->ie_data; 399 ies_len = ie_len; 400 } 401 } 402 } 403 404 if (!qlink_tlv_parsing_ok(tlv, sr->payload, payload_len)) 405 return -EINVAL; 406 407 bss = cfg80211_inform_bss(wiphy, channel, frame_type, 408 sr->bssid, get_unaligned_le64(&sr->tsf), 409 le16_to_cpu(sr->capab), 410 le16_to_cpu(sr->bintval), ies, ies_len, 411 DBM_TO_MBM(sr->sig_dbm), GFP_KERNEL); 412 if (!bss) 413 return -ENOMEM; 414 415 cfg80211_put_bss(wiphy, bss); 416 417 return 0; 418 } 419 420 static int 421 qtnf_event_handle_scan_complete(struct qtnf_wmac *mac, 422 const struct qlink_event_scan_complete *status, 423 u16 len) 424 { 425 if (len < sizeof(*status)) { 426 pr_err("MAC%u: payload is too short\n", mac->macid); 427 return -EINVAL; 428 } 429 430 qtnf_scan_done(mac, le32_to_cpu(status->flags) & QLINK_SCAN_ABORTED); 431 432 return 0; 433 } 434 435 static int 436 qtnf_event_handle_freq_change(struct qtnf_wmac *mac, 437 const struct qlink_event_freq_change *data, 438 u16 len) 439 { 440 struct wiphy *wiphy = priv_to_wiphy(mac); 441 struct cfg80211_chan_def chandef; 442 struct qtnf_vif *vif; 443 int i; 444 445 if (len < sizeof(*data)) { 446 pr_err("MAC%u: payload is too short\n", mac->macid); 447 return -EINVAL; 448 } 449 450 if (!wiphy->registered) 451 return 0; 452 453 qlink_chandef_q2cfg(wiphy, &data->chan, &chandef); 454 455 if (!cfg80211_chandef_valid(&chandef)) { 456 pr_err("MAC%u: bad channel freq=%u cf1=%u cf2=%u bw=%u\n", 457 mac->macid, chandef.chan->center_freq, 458 chandef.center_freq1, chandef.center_freq2, 459 chandef.width); 460 return -EINVAL; 461 } 462 463 pr_debug("MAC%d: new channel ieee=%u freq1=%u freq2=%u bw=%u\n", 464 mac->macid, chandef.chan->hw_value, chandef.center_freq1, 465 chandef.center_freq2, chandef.width); 466 467 for (i = 0; i < QTNF_MAX_INTF; i++) { 468 vif = &mac->iflist[i]; 469 470 if (vif->wdev.iftype == NL80211_IFTYPE_UNSPECIFIED) 471 continue; 472 473 if (vif->wdev.iftype == NL80211_IFTYPE_STATION && 474 !vif->wdev.connected) 475 continue; 476 477 if (!vif->netdev) 478 continue; 479 480 mutex_lock(&vif->wdev.mtx); 481 cfg80211_ch_switch_notify(vif->netdev, &chandef, 0); 482 mutex_unlock(&vif->wdev.mtx); 483 } 484 485 return 0; 486 } 487 488 static int qtnf_event_handle_radar(struct qtnf_vif *vif, 489 const struct qlink_event_radar *ev, 490 u16 len) 491 { 492 struct wiphy *wiphy = priv_to_wiphy(vif->mac); 493 struct cfg80211_chan_def chandef; 494 495 if (len < sizeof(*ev)) { 496 pr_err("MAC%u: payload is too short\n", vif->mac->macid); 497 return -EINVAL; 498 } 499 500 if (!wiphy->registered || !vif->netdev) 501 return 0; 502 503 qlink_chandef_q2cfg(wiphy, &ev->chan, &chandef); 504 505 if (!cfg80211_chandef_valid(&chandef)) { 506 pr_err("MAC%u: bad channel f1=%u f2=%u bw=%u\n", 507 vif->mac->macid, 508 chandef.center_freq1, chandef.center_freq2, 509 chandef.width); 510 return -EINVAL; 511 } 512 513 pr_info("%s: radar event=%u f1=%u f2=%u bw=%u\n", 514 vif->netdev->name, ev->event, 515 chandef.center_freq1, chandef.center_freq2, 516 chandef.width); 517 518 switch (ev->event) { 519 case QLINK_RADAR_DETECTED: 520 cfg80211_radar_event(wiphy, &chandef, GFP_KERNEL); 521 break; 522 case QLINK_RADAR_CAC_FINISHED: 523 if (!vif->wdev.cac_started) 524 break; 525 526 cfg80211_cac_event(vif->netdev, &chandef, 527 NL80211_RADAR_CAC_FINISHED, GFP_KERNEL); 528 break; 529 case QLINK_RADAR_CAC_ABORTED: 530 if (!vif->wdev.cac_started) 531 break; 532 533 cfg80211_cac_event(vif->netdev, &chandef, 534 NL80211_RADAR_CAC_ABORTED, GFP_KERNEL); 535 break; 536 case QLINK_RADAR_CAC_STARTED: 537 if (vif->wdev.cac_started) 538 break; 539 540 if (!wiphy_ext_feature_isset(wiphy, 541 NL80211_EXT_FEATURE_DFS_OFFLOAD)) 542 break; 543 544 cfg80211_cac_event(vif->netdev, &chandef, 545 NL80211_RADAR_CAC_STARTED, GFP_KERNEL); 546 break; 547 default: 548 pr_warn("%s: unhandled radar event %u\n", 549 vif->netdev->name, ev->event); 550 break; 551 } 552 553 return 0; 554 } 555 556 static int 557 qtnf_event_handle_external_auth(struct qtnf_vif *vif, 558 const struct qlink_event_external_auth *ev, 559 u16 len) 560 { 561 struct cfg80211_external_auth_params auth = {0}; 562 struct wiphy *wiphy = priv_to_wiphy(vif->mac); 563 int ret; 564 565 if (len < sizeof(*ev)) { 566 pr_err("MAC%u: payload is too short\n", vif->mac->macid); 567 return -EINVAL; 568 } 569 570 if (!wiphy->registered || !vif->netdev) 571 return 0; 572 573 if (ev->ssid_len) { 574 int len = clamp_val(ev->ssid_len, 0, IEEE80211_MAX_SSID_LEN); 575 576 memcpy(auth.ssid.ssid, ev->ssid, len); 577 auth.ssid.ssid_len = len; 578 } 579 580 auth.key_mgmt_suite = le32_to_cpu(ev->akm_suite); 581 ether_addr_copy(auth.bssid, ev->bssid); 582 auth.action = ev->action; 583 584 pr_debug("%s: external SAE processing: bss=%pM action=%u akm=%u\n", 585 vif->netdev->name, auth.bssid, auth.action, 586 auth.key_mgmt_suite); 587 588 ret = cfg80211_external_auth_request(vif->netdev, &auth, GFP_KERNEL); 589 if (ret) 590 pr_warn("failed to offload external auth request\n"); 591 592 return ret; 593 } 594 595 static int 596 qtnf_event_handle_mic_failure(struct qtnf_vif *vif, 597 const struct qlink_event_mic_failure *mic_ev, 598 u16 len) 599 { 600 struct wiphy *wiphy = priv_to_wiphy(vif->mac); 601 u8 pairwise; 602 603 if (len < sizeof(*mic_ev)) { 604 pr_err("VIF%u.%u: payload is too short (%u < %zu)\n", 605 vif->mac->macid, vif->vifid, len, 606 sizeof(struct qlink_event_mic_failure)); 607 return -EINVAL; 608 } 609 610 if (!wiphy->registered || !vif->netdev) 611 return 0; 612 613 if (vif->wdev.iftype != NL80211_IFTYPE_STATION) { 614 pr_err("VIF%u.%u: MIC_FAILURE event when not in STA mode\n", 615 vif->mac->macid, vif->vifid); 616 return -EPROTO; 617 } 618 619 pairwise = mic_ev->pairwise ? 620 NL80211_KEYTYPE_PAIRWISE : NL80211_KEYTYPE_GROUP; 621 622 pr_info("%s: MIC error: src=%pM key_index=%u pairwise=%u\n", 623 vif->netdev->name, mic_ev->src, mic_ev->key_index, pairwise); 624 625 cfg80211_michael_mic_failure(vif->netdev, mic_ev->src, pairwise, 626 mic_ev->key_index, NULL, GFP_KERNEL); 627 628 return 0; 629 } 630 631 static int 632 qtnf_event_handle_update_owe(struct qtnf_vif *vif, 633 const struct qlink_event_update_owe *owe_ev, 634 u16 len) 635 { 636 struct wiphy *wiphy = priv_to_wiphy(vif->mac); 637 struct cfg80211_update_owe_info owe_info = {}; 638 const u16 ie_len = len - sizeof(*owe_ev); 639 u8 *ie; 640 641 if (len < sizeof(*owe_ev)) { 642 pr_err("VIF%u.%u: payload is too short (%u < %zu)\n", 643 vif->mac->macid, vif->vifid, len, 644 sizeof(struct qlink_event_update_owe)); 645 return -EINVAL; 646 } 647 648 if (!wiphy->registered || !vif->netdev) 649 return 0; 650 651 if (vif->wdev.iftype != NL80211_IFTYPE_AP) { 652 pr_err("VIF%u.%u: UPDATE_OWE event when not in AP mode\n", 653 vif->mac->macid, vif->vifid); 654 return -EPROTO; 655 } 656 657 ie = kzalloc(ie_len, GFP_KERNEL); 658 if (!ie) 659 return -ENOMEM; 660 661 memcpy(owe_info.peer, owe_ev->peer, ETH_ALEN); 662 memcpy(ie, owe_ev->ies, ie_len); 663 owe_info.ie_len = ie_len; 664 owe_info.ie = ie; 665 666 pr_info("%s: external OWE processing: peer=%pM\n", 667 vif->netdev->name, owe_ev->peer); 668 669 cfg80211_update_owe_info_event(vif->netdev, &owe_info, GFP_KERNEL); 670 kfree(ie); 671 672 return 0; 673 } 674 675 static int qtnf_event_parse(struct qtnf_wmac *mac, 676 const struct sk_buff *event_skb) 677 { 678 const struct qlink_event *event; 679 struct qtnf_vif *vif = NULL; 680 int ret = -1; 681 u16 event_id; 682 u16 event_len; 683 u8 vifid; 684 685 event = (const struct qlink_event *)event_skb->data; 686 event_id = le16_to_cpu(event->event_id); 687 event_len = le16_to_cpu(event->mhdr.len); 688 689 if (event->vifid >= QTNF_MAX_INTF) { 690 pr_err("invalid vif(%u)\n", event->vifid); 691 return -EINVAL; 692 } 693 694 vifid = array_index_nospec(event->vifid, QTNF_MAX_INTF); 695 vif = &mac->iflist[vifid]; 696 697 switch (event_id) { 698 case QLINK_EVENT_STA_ASSOCIATED: 699 ret = qtnf_event_handle_sta_assoc(mac, vif, (const void *)event, 700 event_len); 701 break; 702 case QLINK_EVENT_STA_DEAUTH: 703 ret = qtnf_event_handle_sta_deauth(mac, vif, 704 (const void *)event, 705 event_len); 706 break; 707 case QLINK_EVENT_MGMT_RECEIVED: 708 ret = qtnf_event_handle_mgmt_received(vif, (const void *)event, 709 event_len); 710 break; 711 case QLINK_EVENT_SCAN_RESULTS: 712 ret = qtnf_event_handle_scan_results(vif, (const void *)event, 713 event_len); 714 break; 715 case QLINK_EVENT_SCAN_COMPLETE: 716 ret = qtnf_event_handle_scan_complete(mac, (const void *)event, 717 event_len); 718 break; 719 case QLINK_EVENT_BSS_JOIN: 720 ret = qtnf_event_handle_bss_join(vif, (const void *)event, 721 event_len); 722 break; 723 case QLINK_EVENT_BSS_LEAVE: 724 ret = qtnf_event_handle_bss_leave(vif, (const void *)event, 725 event_len); 726 break; 727 case QLINK_EVENT_FREQ_CHANGE: 728 ret = qtnf_event_handle_freq_change(mac, (const void *)event, 729 event_len); 730 break; 731 case QLINK_EVENT_RADAR: 732 ret = qtnf_event_handle_radar(vif, (const void *)event, 733 event_len); 734 break; 735 case QLINK_EVENT_EXTERNAL_AUTH: 736 ret = qtnf_event_handle_external_auth(vif, (const void *)event, 737 event_len); 738 break; 739 case QLINK_EVENT_MIC_FAILURE: 740 ret = qtnf_event_handle_mic_failure(vif, (const void *)event, 741 event_len); 742 break; 743 case QLINK_EVENT_UPDATE_OWE: 744 ret = qtnf_event_handle_update_owe(vif, (const void *)event, 745 event_len); 746 break; 747 default: 748 pr_warn("unknown event type: %x\n", event_id); 749 break; 750 } 751 752 return ret; 753 } 754 755 static int qtnf_event_process_skb(struct qtnf_bus *bus, 756 const struct sk_buff *skb) 757 { 758 const struct qlink_event *event; 759 struct qtnf_wmac *mac; 760 int res; 761 762 if (unlikely(!skb || skb->len < sizeof(*event))) { 763 pr_err("invalid event buffer\n"); 764 return -EINVAL; 765 } 766 767 event = (struct qlink_event *)skb->data; 768 769 mac = qtnf_core_get_mac(bus, event->macid); 770 771 pr_debug("new event id:%x len:%u mac:%u vif:%u\n", 772 le16_to_cpu(event->event_id), le16_to_cpu(event->mhdr.len), 773 event->macid, event->vifid); 774 775 if (unlikely(!mac)) 776 return -ENXIO; 777 778 rtnl_lock(); 779 res = qtnf_event_parse(mac, skb); 780 rtnl_unlock(); 781 782 return res; 783 } 784 785 void qtnf_event_work_handler(struct work_struct *work) 786 { 787 struct qtnf_bus *bus = container_of(work, struct qtnf_bus, event_work); 788 struct sk_buff_head *event_queue = &bus->trans.event_queue; 789 struct sk_buff *current_event_skb = skb_dequeue(event_queue); 790 791 while (current_event_skb) { 792 qtnf_event_process_skb(bus, current_event_skb); 793 dev_kfree_skb_any(current_event_skb); 794 current_event_skb = skb_dequeue(event_queue); 795 } 796 } 797