1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * NXP Wireless LAN device driver: station event handling 4 * 5 * Copyright 2011-2024 NXP 6 */ 7 8 #include "cfg.h" 9 #include "util.h" 10 #include "fw.h" 11 #include "main.h" 12 #include "cmdevt.h" 13 #include "wmm.h" 14 #include "11n.h" 15 16 static int 17 nxpwifi_sta_event_link_lost(struct nxpwifi_private *priv) 18 { 19 struct nxpwifi_adapter *adapter = priv->adapter; 20 21 adapter->dbg.num_event_link_lost++; 22 if (priv->media_connected) { 23 adapter->priv_link_lost = priv; 24 adapter->host_mlme_link_lost = true; 25 nxpwifi_queue_wiphy_work(adapter, 26 &adapter->host_mlme_work); 27 } 28 29 return 0; 30 } 31 32 static int 33 nxpwifi_sta_event_link_sensed(struct nxpwifi_private *priv) 34 { 35 struct nxpwifi_adapter *adapter = priv->adapter; 36 37 netif_carrier_on(priv->netdev); 38 nxpwifi_wake_up_net_dev_queue(priv->netdev, adapter); 39 40 return 0; 41 } 42 43 static int 44 nxpwifi_sta_event_deauthenticated(struct nxpwifi_private *priv) 45 { 46 struct nxpwifi_adapter *adapter = priv->adapter; 47 48 if (priv->wps.session_enable) { 49 nxpwifi_dbg(adapter, INFO, 50 "info: receive deauth event in wps session\n"); 51 } else { 52 adapter->dbg.num_event_deauth++; 53 if (priv->media_connected) { 54 priv->last_deauth_reason = 55 get_unaligned_le16(priv->adapter->event_body); 56 nxpwifi_queue_wiphy_work(priv->adapter, 57 &priv->reset_conn_state_work); 58 } 59 } 60 61 return 0; 62 } 63 64 static int 65 nxpwifi_sta_event_disassociated(struct nxpwifi_private *priv) 66 { 67 struct nxpwifi_adapter *adapter = priv->adapter; 68 69 if (priv->wps.session_enable) { 70 nxpwifi_dbg(adapter, INFO, 71 "info: receive disassoc event in wps session\n"); 72 } else { 73 adapter->dbg.num_event_disassoc++; 74 if (priv->media_connected) { 75 priv->last_deauth_reason = 76 get_unaligned_le16(priv->adapter->event_body); 77 nxpwifi_queue_wiphy_work(priv->adapter, 78 &priv->reset_conn_state_work); 79 } 80 } 81 82 return 0; 83 } 84 85 static int 86 nxpwifi_sta_event_ps_awake(struct nxpwifi_private *priv) 87 { 88 struct nxpwifi_adapter *adapter = priv->adapter; 89 90 if (!adapter->pps_uapsd_mode && 91 priv->port_open && 92 priv->media_connected && adapter->sleep_period.period) { 93 adapter->pps_uapsd_mode = true; 94 nxpwifi_dbg(adapter, EVENT, 95 "event: PPS/UAPSD mode activated\n"); 96 } 97 adapter->tx_lock_flag = false; 98 if (adapter->pps_uapsd_mode && adapter->gen_null_pkt) { 99 if (nxpwifi_check_last_packet_indication(priv)) { 100 if (adapter->data_sent) { 101 adapter->ps_state = PS_STATE_AWAKE; 102 adapter->pm_wakeup_card_req = false; 103 adapter->pm_wakeup_fw_try = false; 104 timer_delete(&adapter->wakeup_timer); 105 } else { 106 if (!nxpwifi_send_null_packet 107 (priv, 108 NXPWIFI_TxPD_POWER_MGMT_NULL_PACKET | 109 NXPWIFI_TxPD_POWER_MGMT_LAST_PACKET)) 110 adapter->ps_state = PS_STATE_SLEEP; 111 } 112 113 return 0; 114 } 115 } 116 117 adapter->ps_state = PS_STATE_AWAKE; 118 adapter->pm_wakeup_card_req = false; 119 adapter->pm_wakeup_fw_try = false; 120 timer_delete(&adapter->wakeup_timer); 121 122 return 0; 123 } 124 125 static int 126 nxpwifi_sta_event_ps_sleep(struct nxpwifi_private *priv) 127 { 128 struct nxpwifi_adapter *adapter = priv->adapter; 129 130 adapter->ps_state = PS_STATE_PRE_SLEEP; 131 nxpwifi_check_ps_cond(adapter); 132 133 return 0; 134 } 135 136 static int 137 nxpwifi_sta_event_mic_err_multicast(struct nxpwifi_private *priv) 138 { 139 cfg80211_michael_mic_failure(priv->netdev, priv->cfg_bssid, 140 NL80211_KEYTYPE_GROUP, 141 -1, NULL, GFP_KERNEL); 142 143 return 0; 144 } 145 146 static int 147 nxpwifi_sta_event_mic_err_unicast(struct nxpwifi_private *priv) 148 { 149 cfg80211_michael_mic_failure(priv->netdev, priv->cfg_bssid, 150 NL80211_KEYTYPE_PAIRWISE, 151 -1, NULL, GFP_KERNEL); 152 153 return 0; 154 } 155 156 static int 157 nxpwifi_sta_event_deep_sleep_awake(struct nxpwifi_private *priv) 158 { 159 struct nxpwifi_adapter *adapter = priv->adapter; 160 161 adapter->if_ops.wakeup_complete(adapter); 162 if (adapter->is_deep_sleep) 163 adapter->is_deep_sleep = false; 164 165 return 0; 166 } 167 168 static int 169 nxpwifi_sta_event_wmm_status_change(struct nxpwifi_private *priv) 170 { 171 return nxpwifi_send_cmd(priv, HOST_CMD_WMM_GET_STATUS, 172 0, 0, NULL, false); 173 } 174 175 static int 176 nxpwifi_sta_event_bs_scan_report(struct nxpwifi_private *priv) 177 { 178 return nxpwifi_send_cmd(priv, HOST_CMD_802_11_BG_SCAN_QUERY, 179 HOST_ACT_GEN_GET, 0, NULL, false); 180 } 181 182 static int 183 nxpwifi_sta_event_rssi_low(struct nxpwifi_private *priv) 184 { 185 cfg80211_cqm_rssi_notify(priv->netdev, 186 NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW, 187 0, GFP_KERNEL); 188 priv->subsc_evt_rssi_state = RSSI_LOW_RECVD; 189 190 return nxpwifi_send_cmd(priv, HOST_CMD_RSSI_INFO, 191 HOST_ACT_GEN_GET, 0, NULL, false); 192 } 193 194 static int 195 nxpwifi_sta_event_rssi_high(struct nxpwifi_private *priv) 196 { 197 cfg80211_cqm_rssi_notify(priv->netdev, 198 NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH, 199 0, GFP_KERNEL); 200 priv->subsc_evt_rssi_state = RSSI_HIGH_RECVD; 201 202 return nxpwifi_send_cmd(priv, HOST_CMD_RSSI_INFO, 203 HOST_ACT_GEN_GET, 0, NULL, false); 204 } 205 206 static int 207 nxpwifi_sta_event_port_release(struct nxpwifi_private *priv) 208 { 209 priv->port_open = true; 210 211 return 0; 212 } 213 214 static int 215 nxpwifi_sta_event_addba(struct nxpwifi_private *priv) 216 { 217 struct nxpwifi_adapter *adapter = priv->adapter; 218 219 return nxpwifi_send_cmd(priv, HOST_CMD_11N_ADDBA_RSP, 220 HOST_ACT_GEN_SET, 0, 221 adapter->event_body, false); 222 } 223 224 static int 225 nxpwifi_sta_event_delba(struct nxpwifi_private *priv) 226 { 227 struct nxpwifi_adapter *adapter = priv->adapter; 228 229 nxpwifi_11n_delete_ba_stream(priv, adapter->event_body); 230 231 return 0; 232 } 233 234 static int 235 nxpwifi_sta_event_bs_stream_timeout(struct nxpwifi_private *priv) 236 { 237 struct nxpwifi_adapter *adapter = priv->adapter; 238 struct host_cmd_ds_11n_batimeout *event = 239 (struct host_cmd_ds_11n_batimeout *)adapter->event_body; 240 241 nxpwifi_11n_ba_stream_timeout(priv, event); 242 243 return 0; 244 } 245 246 static int 247 nxpwifi_sta_event_amsdu_aggr_ctrl(struct nxpwifi_private *priv) 248 { 249 struct nxpwifi_adapter *adapter = priv->adapter; 250 u16 ctrl; 251 252 ctrl = get_unaligned_le16(adapter->event_body); 253 adapter->tx_buf_size = min_t(u16, adapter->curr_tx_buf_size, ctrl); 254 255 return 0; 256 } 257 258 static int 259 nxpwifi_sta_event_hs_act_req(struct nxpwifi_private *priv) 260 { 261 return nxpwifi_send_cmd(priv, HOST_CMD_802_11_HS_CFG_ENH, 262 0, 0, NULL, false); 263 } 264 265 static int 266 nxpwifi_sta_event_channel_switch_ann(struct nxpwifi_private *priv) 267 { 268 struct nxpwifi_bssdescriptor *bss_desc; 269 270 bss_desc = &priv->curr_bss_params.bss_descriptor; 271 priv->csa_expire_time = jiffies + msecs_to_jiffies(DFS_CHAN_MOVE_TIME); 272 priv->csa_chan = bss_desc->channel; 273 return nxpwifi_send_cmd(priv, HOST_CMD_802_11_DEAUTHENTICATE, 274 HOST_ACT_GEN_SET, 0, 275 bss_desc->mac_address, false); 276 } 277 278 static int 279 nxpwifi_sta_event_radar_detected(struct nxpwifi_private *priv) 280 { 281 struct nxpwifi_adapter *adapter = priv->adapter; 282 283 return nxpwifi_11h_handle_radar_detected(priv, adapter->event_skb); 284 } 285 286 static int 287 nxpwifi_sta_event_channel_report_rdy(struct nxpwifi_private *priv) 288 { 289 struct nxpwifi_adapter *adapter = priv->adapter; 290 291 return nxpwifi_11h_handle_chanrpt_ready(priv, adapter->event_skb); 292 } 293 294 static int 295 nxpwifi_sta_event_tx_data_pause(struct nxpwifi_private *priv) 296 { 297 struct nxpwifi_adapter *adapter = priv->adapter; 298 299 nxpwifi_process_tx_pause_event(priv, adapter->event_skb); 300 301 return 0; 302 } 303 304 static int 305 nxpwifi_sta_event_ext_scan_report(struct nxpwifi_private *priv) 306 { 307 struct nxpwifi_adapter *adapter = priv->adapter; 308 void *buf = adapter->event_skb->data; 309 int ret = 0; 310 311 /* 312 * We intend to skip this event during suspend, but handle 313 * it in interface disabled case 314 */ 315 if (adapter->ext_scan && (!priv->scan_aborting || 316 !netif_running(priv->netdev))) 317 ret = nxpwifi_handle_event_ext_scan_report(priv, buf); 318 319 return ret; 320 } 321 322 static int 323 nxpwifi_sta_event_rxba_sync(struct nxpwifi_private *priv) 324 { 325 struct nxpwifi_adapter *adapter = priv->adapter; 326 327 nxpwifi_11n_rxba_sync_event(priv, adapter->event_body, 328 adapter->event_skb->len - 329 sizeof(adapter->event_cause)); 330 331 return 0; 332 } 333 334 static int 335 nxpwifi_sta_event_remain_on_chan_expired(struct nxpwifi_private *priv) 336 { 337 if (priv->auth_flag & HOST_MLME_AUTH_PENDING) { 338 priv->auth_flag = 0; 339 priv->auth_alg = WLAN_AUTH_NONE; 340 } else { 341 cfg80211_remain_on_channel_expired(&priv->wdev, 342 priv->roc_cfg.cookie, 343 &priv->roc_cfg.chan, 344 GFP_ATOMIC); 345 } 346 347 memset(&priv->roc_cfg, 0x00, sizeof(struct nxpwifi_roc_cfg)); 348 349 return 0; 350 } 351 352 static int 353 nxpwifi_sta_event_bg_scan_stopped(struct nxpwifi_private *priv) 354 { 355 cfg80211_sched_scan_stopped(priv->wdev.wiphy, 0); 356 if (priv->sched_scanning) 357 priv->sched_scanning = false; 358 359 return 0; 360 } 361 362 static int 363 nxpwifi_sta_event_multi_chan_info(struct nxpwifi_private *priv) 364 { 365 struct nxpwifi_adapter *adapter = priv->adapter; 366 367 nxpwifi_process_multi_chan_event(priv, adapter->event_skb); 368 369 return 0; 370 } 371 372 static int 373 nxpwifi_sta_event_tx_status_report(struct nxpwifi_private *priv) 374 { 375 struct nxpwifi_adapter *adapter = priv->adapter; 376 377 nxpwifi_parse_tx_status_event(priv, adapter->event_body); 378 379 return 0; 380 } 381 382 static int 383 nxpwifi_sta_event_bt_coex_wlan_para_change(struct nxpwifi_private *priv) 384 { 385 struct nxpwifi_adapter *adapter = priv->adapter; 386 387 if (!adapter->ignore_btcoex_events) 388 nxpwifi_bt_coex_wlan_param_update_event(priv, 389 adapter->event_skb); 390 391 return 0; 392 } 393 394 static int 395 nxpwifi_sta_event_vdll_ind(struct nxpwifi_private *priv) 396 { 397 struct nxpwifi_adapter *adapter = priv->adapter; 398 399 return nxpwifi_process_vdll_event(priv, adapter->event_skb); 400 } 401 402 static const struct nxpwifi_evt_entry evt_table_sta[] = { 403 {.event_cause = EVENT_LINK_LOST, 404 .event_handler = nxpwifi_sta_event_link_lost}, 405 {.event_cause = EVENT_LINK_SENSED, 406 .event_handler = nxpwifi_sta_event_link_sensed}, 407 {.event_cause = EVENT_DEAUTHENTICATED, 408 .event_handler = nxpwifi_sta_event_deauthenticated}, 409 {.event_cause = EVENT_DISASSOCIATED, 410 .event_handler = nxpwifi_sta_event_disassociated}, 411 {.event_cause = EVENT_PS_AWAKE, 412 .event_handler = nxpwifi_sta_event_ps_awake}, 413 {.event_cause = EVENT_PS_SLEEP, 414 .event_handler = nxpwifi_sta_event_ps_sleep}, 415 {.event_cause = EVENT_MIC_ERR_MULTICAST, 416 .event_handler = nxpwifi_sta_event_mic_err_multicast}, 417 {.event_cause = EVENT_MIC_ERR_UNICAST, 418 .event_handler = nxpwifi_sta_event_mic_err_unicast}, 419 {.event_cause = EVENT_DEEP_SLEEP_AWAKE, 420 .event_handler = nxpwifi_sta_event_deep_sleep_awake}, 421 {.event_cause = EVENT_WMM_STATUS_CHANGE, 422 .event_handler = nxpwifi_sta_event_wmm_status_change}, 423 {.event_cause = EVENT_BG_SCAN_REPORT, 424 .event_handler = nxpwifi_sta_event_bs_scan_report}, 425 {.event_cause = EVENT_RSSI_LOW, 426 .event_handler = nxpwifi_sta_event_rssi_low}, 427 {.event_cause = EVENT_RSSI_HIGH, 428 .event_handler = nxpwifi_sta_event_rssi_high}, 429 {.event_cause = EVENT_PORT_RELEASE, 430 .event_handler = nxpwifi_sta_event_port_release}, 431 {.event_cause = EVENT_ADDBA, 432 .event_handler = nxpwifi_sta_event_addba}, 433 {.event_cause = EVENT_DELBA, 434 .event_handler = nxpwifi_sta_event_delba}, 435 {.event_cause = EVENT_BA_STREAM_TIEMOUT, 436 .event_handler = nxpwifi_sta_event_bs_stream_timeout}, 437 {.event_cause = EVENT_AMSDU_AGGR_CTRL, 438 .event_handler = nxpwifi_sta_event_amsdu_aggr_ctrl}, 439 {.event_cause = EVENT_HS_ACT_REQ, 440 .event_handler = nxpwifi_sta_event_hs_act_req}, 441 {.event_cause = EVENT_CHANNEL_SWITCH_ANN, 442 .event_handler = nxpwifi_sta_event_channel_switch_ann}, 443 {.event_cause = EVENT_RADAR_DETECTED, 444 .event_handler = nxpwifi_sta_event_radar_detected}, 445 {.event_cause = EVENT_CHANNEL_REPORT_RDY, 446 .event_handler = nxpwifi_sta_event_channel_report_rdy}, 447 {.event_cause = EVENT_TX_DATA_PAUSE, 448 .event_handler = nxpwifi_sta_event_tx_data_pause}, 449 {.event_cause = EVENT_EXT_SCAN_REPORT, 450 .event_handler = nxpwifi_sta_event_ext_scan_report}, 451 {.event_cause = EVENT_RXBA_SYNC, 452 .event_handler = nxpwifi_sta_event_rxba_sync}, 453 {.event_cause = EVENT_REMAIN_ON_CHAN_EXPIRED, 454 .event_handler = nxpwifi_sta_event_remain_on_chan_expired}, 455 {.event_cause = EVENT_BG_SCAN_STOPPED, 456 .event_handler = nxpwifi_sta_event_bg_scan_stopped}, 457 {.event_cause = EVENT_MULTI_CHAN_INFO, 458 .event_handler = nxpwifi_sta_event_multi_chan_info}, 459 {.event_cause = EVENT_TX_STATUS_REPORT, 460 .event_handler = nxpwifi_sta_event_tx_status_report}, 461 {.event_cause = EVENT_BT_COEX_WLAN_PARA_CHANGE, 462 .event_handler = nxpwifi_sta_event_bt_coex_wlan_para_change}, 463 {.event_cause = EVENT_VDLL_IND, 464 .event_handler = nxpwifi_sta_event_vdll_ind}, 465 {.event_cause = EVENT_DUMMY_HOST_WAKEUP_SIGNAL, 466 .event_handler = NULL}, 467 {.event_cause = EVENT_MIB_CHANGED, 468 .event_handler = NULL}, 469 {.event_cause = EVENT_INIT_DONE, 470 .event_handler = NULL}, 471 {.event_cause = EVENT_SNR_LOW, 472 .event_handler = NULL}, 473 {.event_cause = EVENT_MAX_FAIL, 474 .event_handler = NULL}, 475 {.event_cause = EVENT_SNR_HIGH, 476 .event_handler = NULL}, 477 {.event_cause = EVENT_DATA_RSSI_LOW, 478 .event_handler = NULL}, 479 {.event_cause = EVENT_DATA_SNR_LOW, 480 .event_handler = NULL}, 481 {.event_cause = EVENT_DATA_RSSI_HIGH, 482 .event_handler = NULL}, 483 {.event_cause = EVENT_DATA_SNR_HIGH, 484 .event_handler = NULL}, 485 {.event_cause = EVENT_LINK_QUALITY, 486 .event_handler = NULL}, 487 {.event_cause = EVENT_PRE_BEACON_LOST, 488 .event_handler = NULL}, 489 {.event_cause = EVENT_WEP_ICV_ERR, 490 .event_handler = NULL}, 491 {.event_cause = EVENT_BW_CHANGE, 492 .event_handler = NULL}, 493 {.event_cause = EVENT_HOSTWAKE_STAIE, 494 .event_handler = NULL}, 495 {.event_cause = EVENT_UNKNOWN_DEBUG, 496 .event_handler = NULL}, 497 }; 498 499 static void nxpwifi_process_uap_tx_pause(struct nxpwifi_private *priv, 500 struct nxpwifi_ie_types_header *tlv) 501 { 502 struct nxpwifi_tx_pause_tlv *tp; 503 struct nxpwifi_sta_node *sta_ptr; 504 505 tp = (void *)tlv; 506 nxpwifi_dbg(priv->adapter, EVENT, 507 "uap tx_pause: %pM pause=%d, pkts=%d\n", 508 tp->peermac, tp->tx_pause, 509 tp->pkt_cnt); 510 511 if (ether_addr_equal(tp->peermac, priv->netdev->dev_addr)) { 512 if (tp->tx_pause) 513 priv->port_open = false; 514 else 515 priv->port_open = true; 516 } else if (is_multicast_ether_addr(tp->peermac)) { 517 nxpwifi_update_ralist_tx_pause(priv, tp->peermac, tp->tx_pause); 518 } else { 519 rcu_read_lock(); 520 sta_ptr = nxpwifi_get_sta_entry(priv, tp->peermac); 521 if (sta_ptr && sta_ptr->tx_pause != tp->tx_pause) { 522 sta_ptr->tx_pause = tp->tx_pause; 523 nxpwifi_update_ralist_tx_pause(priv, tp->peermac, 524 tp->tx_pause); 525 } 526 rcu_read_unlock(); 527 } 528 } 529 530 static void nxpwifi_process_sta_tx_pause(struct nxpwifi_private *priv, 531 struct nxpwifi_ie_types_header *tlv) 532 { 533 struct nxpwifi_tx_pause_tlv *tp; 534 535 tp = (void *)tlv; 536 nxpwifi_dbg(priv->adapter, EVENT, 537 "sta tx_pause: %pM pause=%d, pkts=%d\n", 538 tp->peermac, tp->tx_pause, 539 tp->pkt_cnt); 540 541 if (ether_addr_equal(tp->peermac, priv->cfg_bssid)) { 542 if (tp->tx_pause) 543 priv->port_open = false; 544 else 545 priv->port_open = true; 546 } 547 } 548 549 /* 550 * Reset connection state after a firmware-triggered disconnect. 551 * Clears link state, queues, RSSI/SNR and security settings, 552 * saves previous SSID/BSSID for possible reassociation, 553 * and notifies cfg80211. 554 */ 555 void nxpwifi_reset_connect_state(struct nxpwifi_private *priv, u16 reason_code, 556 bool from_ap) 557 { 558 struct nxpwifi_adapter *adapter = priv->adapter; 559 560 if (!priv->media_connected) 561 return; 562 563 nxpwifi_dbg(adapter, INFO, 564 "info: handles disconnect event\n"); 565 566 priv->media_connected = false; 567 568 priv->auth_flag = 0; 569 priv->auth_alg = WLAN_AUTH_NONE; 570 571 priv->scan_block = false; 572 priv->port_open = false; 573 574 /* Free Tx and Rx packets, report disconnect to upper layer */ 575 nxpwifi_clean_txrx(priv); 576 577 /* Reset SNR/NF/RSSI values */ 578 priv->data_rssi_last = 0; 579 priv->data_nf_last = 0; 580 priv->data_rssi_avg = 0; 581 priv->data_nf_avg = 0; 582 priv->bcn_rssi_last = 0; 583 priv->bcn_nf_last = 0; 584 priv->bcn_rssi_avg = 0; 585 priv->bcn_nf_avg = 0; 586 priv->rxpd_rate = 0; 587 priv->rxpd_htinfo = 0; 588 priv->sec_info.wpa_enabled = false; 589 priv->sec_info.wpa2_enabled = false; 590 priv->wpa_ie_len = 0; 591 592 priv->sec_info.encryption_mode = 0; 593 594 /* Enable auto data rate */ 595 priv->is_data_rate_auto = true; 596 priv->data_rate = 0; 597 598 priv->assoc_resp_ht_param = 0; 599 priv->ht_param_present = false; 600 601 if ((GET_BSS_ROLE(priv) == NXPWIFI_BSS_ROLE_STA || 602 GET_BSS_ROLE(priv) == NXPWIFI_BSS_ROLE_UAP) && priv->hist_data) 603 nxpwifi_hist_data_reset(priv); 604 605 /* 606 * Memorize the previous SSID and BSSID so 607 * it could be used for re-assoc 608 */ 609 610 nxpwifi_dbg(adapter, INFO, 611 "info: previous SSID=%s, SSID len=%u\n", 612 priv->prev_ssid.ssid, priv->prev_ssid.ssid_len); 613 614 nxpwifi_dbg(adapter, INFO, 615 "info: current SSID=%s, SSID len=%u\n", 616 priv->curr_bss_params.bss_descriptor.ssid.ssid, 617 priv->curr_bss_params.bss_descriptor.ssid.ssid_len); 618 619 memcpy(&priv->prev_ssid, 620 &priv->curr_bss_params.bss_descriptor.ssid, 621 sizeof(struct cfg80211_ssid)); 622 623 memcpy(priv->prev_bssid, 624 priv->curr_bss_params.bss_descriptor.mac_address, ETH_ALEN); 625 626 /* Need to erase the current SSID and BSSID info */ 627 memset(&priv->curr_bss_params, 0x00, sizeof(priv->curr_bss_params)); 628 629 adapter->tx_lock_flag = false; 630 adapter->pps_uapsd_mode = false; 631 632 if (test_bit(NXPWIFI_IS_CMD_TIMEDOUT, &adapter->work_flags) && 633 adapter->curr_cmd) 634 return; 635 636 priv->media_connected = false; 637 nxpwifi_dbg(adapter, MSG, 638 "info: successfully disconnected from %pM: reason code %d\n", 639 priv->cfg_bssid, reason_code); 640 641 if (priv->bss_mode == NL80211_IFTYPE_STATION) { 642 if (adapter->host_mlme_link_lost) 643 nxpwifi_host_mlme_disconnect(adapter->priv_link_lost, 644 reason_code, NULL); 645 else 646 cfg80211_disconnected(priv->netdev, reason_code, NULL, 647 0, !from_ap, GFP_KERNEL); 648 } 649 eth_zero_addr(priv->cfg_bssid); 650 651 nxpwifi_stop_net_dev_queue(priv->netdev, adapter); 652 netif_carrier_off(priv->netdev); 653 654 if (!ISSUPP_FIRMWARE_SUPPLICANT(priv->adapter->fw_cap_info)) 655 return; 656 657 nxpwifi_send_cmd(priv, HOST_CMD_GTK_REKEY_OFFLOAD_CFG, 658 HOST_ACT_GEN_REMOVE, 0, NULL, false); 659 } 660 661 void nxpwifi_reset_conn_state_work(struct wiphy *wiphy, struct wiphy_work *work) 662 { 663 struct nxpwifi_private *priv = container_of(work, 664 struct nxpwifi_private, 665 reset_conn_state_work); 666 667 nxpwifi_reset_connect_state(priv, priv->last_deauth_reason, true); 668 } 669 670 void nxpwifi_process_multi_chan_event(struct nxpwifi_private *priv, 671 struct sk_buff *event_skb) 672 { 673 struct nxpwifi_ie_types_multi_chan_info *chan_info; 674 struct nxpwifi_ie_types_mc_group_info *grp_info; 675 struct nxpwifi_adapter *adapter = priv->adapter; 676 struct nxpwifi_ie_types_header *tlv; 677 u16 tlv_buf_left, tlv_type, tlv_len; 678 int intf_num, bss_type, bss_num, i; 679 struct nxpwifi_private *intf_priv; 680 681 tlv_buf_left = event_skb->len - sizeof(u32); 682 chan_info = (void *)event_skb->data + sizeof(u32); 683 684 if (le16_to_cpu(chan_info->header.type) != TLV_TYPE_MULTI_CHAN_INFO || 685 tlv_buf_left < sizeof(struct nxpwifi_ie_types_multi_chan_info)) { 686 nxpwifi_dbg(adapter, ERROR, 687 "unknown TLV in chan_info event\n"); 688 return; 689 } 690 691 adapter->usb_mc_status = le16_to_cpu(chan_info->status); 692 nxpwifi_dbg(adapter, EVENT, "multi chan operation %s\n", 693 adapter->usb_mc_status ? "started" : "over"); 694 695 tlv_buf_left -= sizeof(struct nxpwifi_ie_types_multi_chan_info); 696 tlv = (struct nxpwifi_ie_types_header *)chan_info->tlv_buffer; 697 698 while (tlv_buf_left >= (int)sizeof(struct nxpwifi_ie_types_header)) { 699 tlv_type = le16_to_cpu(tlv->type); 700 tlv_len = le16_to_cpu(tlv->len); 701 if ((sizeof(struct nxpwifi_ie_types_header) + tlv_len) > 702 tlv_buf_left) { 703 nxpwifi_dbg(adapter, ERROR, "wrong tlv: tlvLen=%d,\t" 704 "tlvBufLeft=%d\n", tlv_len, tlv_buf_left); 705 break; 706 } 707 if (tlv_type != TLV_TYPE_MC_GROUP_INFO) { 708 nxpwifi_dbg(adapter, ERROR, "wrong tlv type: 0x%x\n", 709 tlv_type); 710 break; 711 } 712 713 grp_info = (struct nxpwifi_ie_types_mc_group_info *)tlv; 714 intf_num = grp_info->intf_num; 715 for (i = 0; i < intf_num; i++) { 716 bss_type = grp_info->bss_type_numlist[i] >> 4; 717 bss_num = grp_info->bss_type_numlist[i] & BSS_NUM_MASK; 718 intf_priv = nxpwifi_get_priv_by_id(adapter, bss_num, 719 bss_type); 720 if (!intf_priv) { 721 nxpwifi_dbg(adapter, ERROR, 722 "Invalid bss_type bss_num\t" 723 "in multi channel event\n"); 724 continue; 725 } 726 } 727 728 tlv_buf_left -= sizeof(struct nxpwifi_ie_types_header) + 729 tlv_len; 730 tlv = (void *)((u8 *)tlv + tlv_len + 731 sizeof(struct nxpwifi_ie_types_header)); 732 } 733 } 734 735 void nxpwifi_process_tx_pause_event(struct nxpwifi_private *priv, 736 struct sk_buff *event_skb) 737 { 738 struct nxpwifi_ie_types_header *tlv; 739 u16 tlv_type, tlv_len; 740 int tlv_buf_left; 741 742 if (!priv->media_connected) { 743 nxpwifi_dbg(priv->adapter, ERROR, 744 "tx_pause event while disconnected; bss_role=%d\n", 745 priv->bss_role); 746 return; 747 } 748 749 tlv_buf_left = event_skb->len - sizeof(u32); 750 tlv = (void *)event_skb->data + sizeof(u32); 751 752 while (tlv_buf_left >= (int)sizeof(struct nxpwifi_ie_types_header)) { 753 tlv_type = le16_to_cpu(tlv->type); 754 tlv_len = le16_to_cpu(tlv->len); 755 if ((sizeof(struct nxpwifi_ie_types_header) + tlv_len) > 756 tlv_buf_left) { 757 nxpwifi_dbg(priv->adapter, ERROR, 758 "wrong tlv: tlvLen=%d, tlvBufLeft=%d\n", 759 tlv_len, tlv_buf_left); 760 break; 761 } 762 if (tlv_type == TLV_TYPE_TX_PAUSE) { 763 if (GET_BSS_ROLE(priv) == NXPWIFI_BSS_ROLE_STA) 764 nxpwifi_process_sta_tx_pause(priv, tlv); 765 else 766 nxpwifi_process_uap_tx_pause(priv, tlv); 767 } 768 769 tlv_buf_left -= sizeof(struct nxpwifi_ie_types_header) + 770 tlv_len; 771 tlv = (void *)((u8 *)tlv + tlv_len + 772 sizeof(struct nxpwifi_ie_types_header)); 773 } 774 } 775 776 /* 777 * Handle BT coexistence event. Parse TLVs and update 778 * coexistence aggregation window and scan timing parameters. 779 */ 780 void nxpwifi_bt_coex_wlan_param_update_event(struct nxpwifi_private *priv, 781 struct sk_buff *event_skb) 782 { 783 struct nxpwifi_adapter *adapter = priv->adapter; 784 struct nxpwifi_ie_types_header *tlv; 785 struct nxpwifi_ie_types_btcoex_aggr_win_size *winsizetlv; 786 struct nxpwifi_ie_types_btcoex_scan_time *scantlv; 787 s32 len = event_skb->len - sizeof(u32); 788 u8 *cur_ptr = event_skb->data + sizeof(u32); 789 u16 tlv_type, tlv_len; 790 791 while (len >= sizeof(struct nxpwifi_ie_types_header)) { 792 tlv = (struct nxpwifi_ie_types_header *)cur_ptr; 793 tlv_len = le16_to_cpu(tlv->len); 794 tlv_type = le16_to_cpu(tlv->type); 795 796 if ((tlv_len + sizeof(struct nxpwifi_ie_types_header)) > len) 797 break; 798 switch (tlv_type) { 799 case TLV_BTCOEX_WL_AGGR_WINSIZE: 800 winsizetlv = 801 (struct nxpwifi_ie_types_btcoex_aggr_win_size *)tlv; 802 adapter->coex_win_size = winsizetlv->coex_win_size; 803 adapter->coex_tx_win_size = 804 winsizetlv->tx_win_size; 805 adapter->coex_rx_win_size = 806 winsizetlv->rx_win_size; 807 nxpwifi_coex_ampdu_rxwinsize(adapter); 808 nxpwifi_update_ampdu_txwinsize(adapter); 809 break; 810 811 case TLV_BTCOEX_WL_SCANTIME: 812 scantlv = 813 (struct nxpwifi_ie_types_btcoex_scan_time *)tlv; 814 adapter->coex_scan = scantlv->coex_scan; 815 adapter->coex_min_scan_time = le16_to_cpu(scantlv->min_scan_time); 816 adapter->coex_max_scan_time = le16_to_cpu(scantlv->max_scan_time); 817 break; 818 819 default: 820 break; 821 } 822 823 len -= tlv_len + sizeof(struct nxpwifi_ie_types_header); 824 cur_ptr += tlv_len + 825 sizeof(struct nxpwifi_ie_types_header); 826 } 827 828 nxpwifi_dbg(adapter, INFO, "coex_scan=%d min_scan=%d coex_win=%d, tx_win=%d rx_win=%d\n", 829 adapter->coex_scan, adapter->coex_min_scan_time, 830 adapter->coex_win_size, adapter->coex_tx_win_size, 831 adapter->coex_rx_win_size); 832 } 833 834 /* 835 * Dispatch station firmware event based on event_cause. 836 * Looks up the handler in the station event table and invokes it. 837 */ 838 int nxpwifi_process_sta_event(struct nxpwifi_private *priv) 839 { 840 struct nxpwifi_adapter *adapter = priv->adapter; 841 u32 eventcause = adapter->event_cause; 842 int evt, ret = 0; 843 844 for (evt = 0; evt < ARRAY_SIZE(evt_table_sta); evt++) { 845 if (eventcause == evt_table_sta[evt].event_cause) { 846 if (evt_table_sta[evt].event_handler) 847 ret = evt_table_sta[evt].event_handler(priv); 848 break; 849 } 850 } 851 852 if (evt == ARRAY_SIZE(evt_table_sta)) 853 nxpwifi_dbg(adapter, EVENT, 854 "%s: unknown event id: %#x\n", 855 __func__, eventcause); 856 else 857 nxpwifi_dbg(adapter, EVENT, 858 "%s: event id: %#x\n", 859 __func__, eventcause); 860 861 return ret; 862 } 863