18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * NXP Wireless LAN device driver: station event handling 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Copyright 2011-2020 NXP 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * This software file (the "File") is distributed by NXP 78c2ecf20Sopenharmony_ci * under the terms of the GNU General Public License Version 2, June 1991 88c2ecf20Sopenharmony_ci * (the "License"). You may use, redistribute and/or modify this File in 98c2ecf20Sopenharmony_ci * accordance with the terms and conditions of the License, a copy of which 108c2ecf20Sopenharmony_ci * is available by writing to the Free Software Foundation, Inc., 118c2ecf20Sopenharmony_ci * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the 128c2ecf20Sopenharmony_ci * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. 138c2ecf20Sopenharmony_ci * 148c2ecf20Sopenharmony_ci * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 158c2ecf20Sopenharmony_ci * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 168c2ecf20Sopenharmony_ci * ARE EXPRESSLY DISCLAIMED. The License provides additional details about 178c2ecf20Sopenharmony_ci * this warranty disclaimer. 188c2ecf20Sopenharmony_ci */ 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci#include "decl.h" 218c2ecf20Sopenharmony_ci#include "ioctl.h" 228c2ecf20Sopenharmony_ci#include "util.h" 238c2ecf20Sopenharmony_ci#include "fw.h" 248c2ecf20Sopenharmony_ci#include "main.h" 258c2ecf20Sopenharmony_ci#include "wmm.h" 268c2ecf20Sopenharmony_ci#include "11n.h" 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci#define MWIFIEX_IBSS_CONNECT_EVT_FIX_SIZE 12 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_cistatic int mwifiex_check_ibss_peer_capabilities(struct mwifiex_private *priv, 318c2ecf20Sopenharmony_ci struct mwifiex_sta_node *sta_ptr, 328c2ecf20Sopenharmony_ci struct sk_buff *event) 338c2ecf20Sopenharmony_ci{ 348c2ecf20Sopenharmony_ci int evt_len, ele_len; 358c2ecf20Sopenharmony_ci u8 *curr; 368c2ecf20Sopenharmony_ci struct ieee_types_header *ele_hdr; 378c2ecf20Sopenharmony_ci struct mwifiex_ie_types_mgmt_frame *tlv_mgmt_frame; 388c2ecf20Sopenharmony_ci const struct ieee80211_ht_cap *ht_cap; 398c2ecf20Sopenharmony_ci const struct ieee80211_vht_cap *vht_cap; 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci skb_pull(event, MWIFIEX_IBSS_CONNECT_EVT_FIX_SIZE); 428c2ecf20Sopenharmony_ci evt_len = event->len; 438c2ecf20Sopenharmony_ci curr = event->data; 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci mwifiex_dbg_dump(priv->adapter, EVT_D, "ibss peer capabilities:", 468c2ecf20Sopenharmony_ci event->data, event->len); 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci skb_push(event, MWIFIEX_IBSS_CONNECT_EVT_FIX_SIZE); 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci tlv_mgmt_frame = (void *)curr; 518c2ecf20Sopenharmony_ci if (evt_len >= sizeof(*tlv_mgmt_frame) && 528c2ecf20Sopenharmony_ci le16_to_cpu(tlv_mgmt_frame->header.type) == 538c2ecf20Sopenharmony_ci TLV_TYPE_UAP_MGMT_FRAME) { 548c2ecf20Sopenharmony_ci /* Locate curr pointer to the start of beacon tlv, 558c2ecf20Sopenharmony_ci * timestamp 8 bytes, beacon intervel 2 bytes, 568c2ecf20Sopenharmony_ci * capability info 2 bytes, totally 12 byte beacon header 578c2ecf20Sopenharmony_ci */ 588c2ecf20Sopenharmony_ci evt_len = le16_to_cpu(tlv_mgmt_frame->header.len); 598c2ecf20Sopenharmony_ci curr += (sizeof(*tlv_mgmt_frame) + 12); 608c2ecf20Sopenharmony_ci } else { 618c2ecf20Sopenharmony_ci mwifiex_dbg(priv->adapter, MSG, 628c2ecf20Sopenharmony_ci "management frame tlv not found!\n"); 638c2ecf20Sopenharmony_ci return 0; 648c2ecf20Sopenharmony_ci } 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci while (evt_len >= sizeof(*ele_hdr)) { 678c2ecf20Sopenharmony_ci ele_hdr = (struct ieee_types_header *)curr; 688c2ecf20Sopenharmony_ci ele_len = ele_hdr->len; 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci if (evt_len < ele_len + sizeof(*ele_hdr)) 718c2ecf20Sopenharmony_ci break; 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci switch (ele_hdr->element_id) { 748c2ecf20Sopenharmony_ci case WLAN_EID_HT_CAPABILITY: 758c2ecf20Sopenharmony_ci sta_ptr->is_11n_enabled = true; 768c2ecf20Sopenharmony_ci ht_cap = (void *)(ele_hdr + 2); 778c2ecf20Sopenharmony_ci sta_ptr->max_amsdu = le16_to_cpu(ht_cap->cap_info) & 788c2ecf20Sopenharmony_ci IEEE80211_HT_CAP_MAX_AMSDU ? 798c2ecf20Sopenharmony_ci MWIFIEX_TX_DATA_BUF_SIZE_8K : 808c2ecf20Sopenharmony_ci MWIFIEX_TX_DATA_BUF_SIZE_4K; 818c2ecf20Sopenharmony_ci mwifiex_dbg(priv->adapter, INFO, 828c2ecf20Sopenharmony_ci "11n enabled!, max_amsdu : %d\n", 838c2ecf20Sopenharmony_ci sta_ptr->max_amsdu); 848c2ecf20Sopenharmony_ci break; 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci case WLAN_EID_VHT_CAPABILITY: 878c2ecf20Sopenharmony_ci sta_ptr->is_11ac_enabled = true; 888c2ecf20Sopenharmony_ci vht_cap = (void *)(ele_hdr + 2); 898c2ecf20Sopenharmony_ci /* check VHT MAXMPDU capability */ 908c2ecf20Sopenharmony_ci switch (le32_to_cpu(vht_cap->vht_cap_info) & 0x3) { 918c2ecf20Sopenharmony_ci case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454: 928c2ecf20Sopenharmony_ci sta_ptr->max_amsdu = 938c2ecf20Sopenharmony_ci MWIFIEX_TX_DATA_BUF_SIZE_12K; 948c2ecf20Sopenharmony_ci break; 958c2ecf20Sopenharmony_ci case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991: 968c2ecf20Sopenharmony_ci sta_ptr->max_amsdu = 978c2ecf20Sopenharmony_ci MWIFIEX_TX_DATA_BUF_SIZE_8K; 988c2ecf20Sopenharmony_ci break; 998c2ecf20Sopenharmony_ci case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895: 1008c2ecf20Sopenharmony_ci sta_ptr->max_amsdu = 1018c2ecf20Sopenharmony_ci MWIFIEX_TX_DATA_BUF_SIZE_4K; 1028c2ecf20Sopenharmony_ci default: 1038c2ecf20Sopenharmony_ci break; 1048c2ecf20Sopenharmony_ci } 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci mwifiex_dbg(priv->adapter, INFO, 1078c2ecf20Sopenharmony_ci "11ac enabled!, max_amsdu : %d\n", 1088c2ecf20Sopenharmony_ci sta_ptr->max_amsdu); 1098c2ecf20Sopenharmony_ci break; 1108c2ecf20Sopenharmony_ci default: 1118c2ecf20Sopenharmony_ci break; 1128c2ecf20Sopenharmony_ci } 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci curr += (ele_len + sizeof(*ele_hdr)); 1158c2ecf20Sopenharmony_ci evt_len -= (ele_len + sizeof(*ele_hdr)); 1168c2ecf20Sopenharmony_ci } 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci return 0; 1198c2ecf20Sopenharmony_ci} 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci/* 1228c2ecf20Sopenharmony_ci * This function resets the connection state. 1238c2ecf20Sopenharmony_ci * 1248c2ecf20Sopenharmony_ci * The function is invoked after receiving a disconnect event from firmware, 1258c2ecf20Sopenharmony_ci * and performs the following actions - 1268c2ecf20Sopenharmony_ci * - Set media status to disconnected 1278c2ecf20Sopenharmony_ci * - Clean up Tx and Rx packets 1288c2ecf20Sopenharmony_ci * - Resets SNR/NF/RSSI value in driver 1298c2ecf20Sopenharmony_ci * - Resets security configurations in driver 1308c2ecf20Sopenharmony_ci * - Enables auto data rate 1318c2ecf20Sopenharmony_ci * - Saves the previous SSID and BSSID so that they can 1328c2ecf20Sopenharmony_ci * be used for re-association, if required 1338c2ecf20Sopenharmony_ci * - Erases current SSID and BSSID information 1348c2ecf20Sopenharmony_ci * - Sends a disconnect event to upper layers/applications. 1358c2ecf20Sopenharmony_ci */ 1368c2ecf20Sopenharmony_civoid mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code, 1378c2ecf20Sopenharmony_ci bool from_ap) 1388c2ecf20Sopenharmony_ci{ 1398c2ecf20Sopenharmony_ci struct mwifiex_adapter *adapter = priv->adapter; 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci if (!priv->media_connected) 1428c2ecf20Sopenharmony_ci return; 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, INFO, 1458c2ecf20Sopenharmony_ci "info: handles disconnect event\n"); 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci priv->media_connected = false; 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci priv->scan_block = false; 1508c2ecf20Sopenharmony_ci priv->port_open = false; 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) && 1538c2ecf20Sopenharmony_ci ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info)) { 1548c2ecf20Sopenharmony_ci mwifiex_disable_all_tdls_links(priv); 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci if (priv->adapter->auto_tdls) 1578c2ecf20Sopenharmony_ci mwifiex_clean_auto_tdls(priv); 1588c2ecf20Sopenharmony_ci } 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci /* Free Tx and Rx packets, report disconnect to upper layer */ 1618c2ecf20Sopenharmony_ci mwifiex_clean_txrx(priv); 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci /* Reset SNR/NF/RSSI values */ 1648c2ecf20Sopenharmony_ci priv->data_rssi_last = 0; 1658c2ecf20Sopenharmony_ci priv->data_nf_last = 0; 1668c2ecf20Sopenharmony_ci priv->data_rssi_avg = 0; 1678c2ecf20Sopenharmony_ci priv->data_nf_avg = 0; 1688c2ecf20Sopenharmony_ci priv->bcn_rssi_last = 0; 1698c2ecf20Sopenharmony_ci priv->bcn_nf_last = 0; 1708c2ecf20Sopenharmony_ci priv->bcn_rssi_avg = 0; 1718c2ecf20Sopenharmony_ci priv->bcn_nf_avg = 0; 1728c2ecf20Sopenharmony_ci priv->rxpd_rate = 0; 1738c2ecf20Sopenharmony_ci priv->rxpd_htinfo = 0; 1748c2ecf20Sopenharmony_ci priv->sec_info.wpa_enabled = false; 1758c2ecf20Sopenharmony_ci priv->sec_info.wpa2_enabled = false; 1768c2ecf20Sopenharmony_ci priv->wpa_ie_len = 0; 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_ci priv->sec_info.wapi_enabled = false; 1798c2ecf20Sopenharmony_ci priv->wapi_ie_len = 0; 1808c2ecf20Sopenharmony_ci priv->sec_info.wapi_key_on = false; 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci priv->sec_info.encryption_mode = 0; 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci /* Enable auto data rate */ 1858c2ecf20Sopenharmony_ci priv->is_data_rate_auto = true; 1868c2ecf20Sopenharmony_ci priv->data_rate = 0; 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci priv->assoc_resp_ht_param = 0; 1898c2ecf20Sopenharmony_ci priv->ht_param_present = false; 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA || 1928c2ecf20Sopenharmony_ci GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) && priv->hist_data) 1938c2ecf20Sopenharmony_ci mwifiex_hist_data_reset(priv); 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_ci if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { 1968c2ecf20Sopenharmony_ci priv->adhoc_state = ADHOC_IDLE; 1978c2ecf20Sopenharmony_ci priv->adhoc_is_link_sensed = false; 1988c2ecf20Sopenharmony_ci } 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci /* 2018c2ecf20Sopenharmony_ci * Memorize the previous SSID and BSSID so 2028c2ecf20Sopenharmony_ci * it could be used for re-assoc 2038c2ecf20Sopenharmony_ci */ 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, INFO, 2068c2ecf20Sopenharmony_ci "info: previous SSID=%s, SSID len=%u\n", 2078c2ecf20Sopenharmony_ci priv->prev_ssid.ssid, priv->prev_ssid.ssid_len); 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, INFO, 2108c2ecf20Sopenharmony_ci "info: current SSID=%s, SSID len=%u\n", 2118c2ecf20Sopenharmony_ci priv->curr_bss_params.bss_descriptor.ssid.ssid, 2128c2ecf20Sopenharmony_ci priv->curr_bss_params.bss_descriptor.ssid.ssid_len); 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci memcpy(&priv->prev_ssid, 2158c2ecf20Sopenharmony_ci &priv->curr_bss_params.bss_descriptor.ssid, 2168c2ecf20Sopenharmony_ci sizeof(struct cfg80211_ssid)); 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_ci memcpy(priv->prev_bssid, 2198c2ecf20Sopenharmony_ci priv->curr_bss_params.bss_descriptor.mac_address, ETH_ALEN); 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ci /* Need to erase the current SSID and BSSID info */ 2228c2ecf20Sopenharmony_ci memset(&priv->curr_bss_params, 0x00, sizeof(priv->curr_bss_params)); 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci adapter->tx_lock_flag = false; 2258c2ecf20Sopenharmony_ci adapter->pps_uapsd_mode = false; 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_ci if (test_bit(MWIFIEX_IS_CMD_TIMEDOUT, &adapter->work_flags) && 2288c2ecf20Sopenharmony_ci adapter->curr_cmd) 2298c2ecf20Sopenharmony_ci return; 2308c2ecf20Sopenharmony_ci priv->media_connected = false; 2318c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, MSG, 2328c2ecf20Sopenharmony_ci "info: successfully disconnected from %pM: reason code %d\n", 2338c2ecf20Sopenharmony_ci priv->cfg_bssid, reason_code); 2348c2ecf20Sopenharmony_ci if (priv->bss_mode == NL80211_IFTYPE_STATION || 2358c2ecf20Sopenharmony_ci priv->bss_mode == NL80211_IFTYPE_P2P_CLIENT) { 2368c2ecf20Sopenharmony_ci cfg80211_disconnected(priv->netdev, reason_code, NULL, 0, 2378c2ecf20Sopenharmony_ci !from_ap, GFP_KERNEL); 2388c2ecf20Sopenharmony_ci } 2398c2ecf20Sopenharmony_ci eth_zero_addr(priv->cfg_bssid); 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci mwifiex_stop_net_dev_queue(priv->netdev, adapter); 2428c2ecf20Sopenharmony_ci if (netif_carrier_ok(priv->netdev)) 2438c2ecf20Sopenharmony_ci netif_carrier_off(priv->netdev); 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci if (!ISSUPP_FIRMWARE_SUPPLICANT(priv->adapter->fw_cap_info)) 2468c2ecf20Sopenharmony_ci return; 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci mwifiex_send_cmd(priv, HostCmd_CMD_GTK_REKEY_OFFLOAD_CFG, 2498c2ecf20Sopenharmony_ci HostCmd_ACT_GEN_REMOVE, 0, NULL, false); 2508c2ecf20Sopenharmony_ci} 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_cistatic int mwifiex_parse_tdls_event(struct mwifiex_private *priv, 2538c2ecf20Sopenharmony_ci struct sk_buff *event_skb) 2548c2ecf20Sopenharmony_ci{ 2558c2ecf20Sopenharmony_ci int ret = 0; 2568c2ecf20Sopenharmony_ci struct mwifiex_adapter *adapter = priv->adapter; 2578c2ecf20Sopenharmony_ci struct mwifiex_sta_node *sta_ptr; 2588c2ecf20Sopenharmony_ci struct mwifiex_tdls_generic_event *tdls_evt = 2598c2ecf20Sopenharmony_ci (void *)event_skb->data + sizeof(adapter->event_cause); 2608c2ecf20Sopenharmony_ci u8 *mac = tdls_evt->peer_mac; 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_ci /* reserved 2 bytes are not mandatory in tdls event */ 2638c2ecf20Sopenharmony_ci if (event_skb->len < (sizeof(struct mwifiex_tdls_generic_event) - 2648c2ecf20Sopenharmony_ci sizeof(u16) - sizeof(adapter->event_cause))) { 2658c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, ERROR, "Invalid event length!\n"); 2668c2ecf20Sopenharmony_ci return -1; 2678c2ecf20Sopenharmony_ci } 2688c2ecf20Sopenharmony_ci 2698c2ecf20Sopenharmony_ci sta_ptr = mwifiex_get_sta_entry(priv, tdls_evt->peer_mac); 2708c2ecf20Sopenharmony_ci if (!sta_ptr) { 2718c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, ERROR, "cannot get sta entry!\n"); 2728c2ecf20Sopenharmony_ci return -1; 2738c2ecf20Sopenharmony_ci } 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_ci switch (le16_to_cpu(tdls_evt->type)) { 2768c2ecf20Sopenharmony_ci case TDLS_EVENT_LINK_TEAR_DOWN: 2778c2ecf20Sopenharmony_ci cfg80211_tdls_oper_request(priv->netdev, 2788c2ecf20Sopenharmony_ci tdls_evt->peer_mac, 2798c2ecf20Sopenharmony_ci NL80211_TDLS_TEARDOWN, 2808c2ecf20Sopenharmony_ci le16_to_cpu(tdls_evt->u.reason_code), 2818c2ecf20Sopenharmony_ci GFP_KERNEL); 2828c2ecf20Sopenharmony_ci break; 2838c2ecf20Sopenharmony_ci case TDLS_EVENT_CHAN_SWITCH_RESULT: 2848c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "tdls channel switch result :\n"); 2858c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, 2868c2ecf20Sopenharmony_ci "status=0x%x, reason=0x%x cur_chan=%d\n", 2878c2ecf20Sopenharmony_ci tdls_evt->u.switch_result.status, 2888c2ecf20Sopenharmony_ci tdls_evt->u.switch_result.reason, 2898c2ecf20Sopenharmony_ci tdls_evt->u.switch_result.cur_chan); 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_ci /* tdls channel switch failed */ 2928c2ecf20Sopenharmony_ci if (tdls_evt->u.switch_result.status != 0) { 2938c2ecf20Sopenharmony_ci switch (tdls_evt->u.switch_result.cur_chan) { 2948c2ecf20Sopenharmony_ci case TDLS_BASE_CHANNEL: 2958c2ecf20Sopenharmony_ci sta_ptr->tdls_status = TDLS_IN_BASE_CHAN; 2968c2ecf20Sopenharmony_ci break; 2978c2ecf20Sopenharmony_ci case TDLS_OFF_CHANNEL: 2988c2ecf20Sopenharmony_ci sta_ptr->tdls_status = TDLS_IN_OFF_CHAN; 2998c2ecf20Sopenharmony_ci break; 3008c2ecf20Sopenharmony_ci default: 3018c2ecf20Sopenharmony_ci break; 3028c2ecf20Sopenharmony_ci } 3038c2ecf20Sopenharmony_ci return ret; 3048c2ecf20Sopenharmony_ci } 3058c2ecf20Sopenharmony_ci 3068c2ecf20Sopenharmony_ci /* tdls channel switch success */ 3078c2ecf20Sopenharmony_ci switch (tdls_evt->u.switch_result.cur_chan) { 3088c2ecf20Sopenharmony_ci case TDLS_BASE_CHANNEL: 3098c2ecf20Sopenharmony_ci if (sta_ptr->tdls_status == TDLS_IN_BASE_CHAN) 3108c2ecf20Sopenharmony_ci break; 3118c2ecf20Sopenharmony_ci mwifiex_update_ralist_tx_pause_in_tdls_cs(priv, mac, 3128c2ecf20Sopenharmony_ci false); 3138c2ecf20Sopenharmony_ci sta_ptr->tdls_status = TDLS_IN_BASE_CHAN; 3148c2ecf20Sopenharmony_ci break; 3158c2ecf20Sopenharmony_ci case TDLS_OFF_CHANNEL: 3168c2ecf20Sopenharmony_ci if (sta_ptr->tdls_status == TDLS_IN_OFF_CHAN) 3178c2ecf20Sopenharmony_ci break; 3188c2ecf20Sopenharmony_ci mwifiex_update_ralist_tx_pause_in_tdls_cs(priv, mac, 3198c2ecf20Sopenharmony_ci true); 3208c2ecf20Sopenharmony_ci sta_ptr->tdls_status = TDLS_IN_OFF_CHAN; 3218c2ecf20Sopenharmony_ci break; 3228c2ecf20Sopenharmony_ci default: 3238c2ecf20Sopenharmony_ci break; 3248c2ecf20Sopenharmony_ci } 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_ci break; 3278c2ecf20Sopenharmony_ci case TDLS_EVENT_START_CHAN_SWITCH: 3288c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "tdls start channel switch...\n"); 3298c2ecf20Sopenharmony_ci sta_ptr->tdls_status = TDLS_CHAN_SWITCHING; 3308c2ecf20Sopenharmony_ci break; 3318c2ecf20Sopenharmony_ci case TDLS_EVENT_CHAN_SWITCH_STOPPED: 3328c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, 3338c2ecf20Sopenharmony_ci "tdls chan switch stopped, reason=%d\n", 3348c2ecf20Sopenharmony_ci tdls_evt->u.cs_stop_reason); 3358c2ecf20Sopenharmony_ci break; 3368c2ecf20Sopenharmony_ci default: 3378c2ecf20Sopenharmony_ci break; 3388c2ecf20Sopenharmony_ci } 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_ci return ret; 3418c2ecf20Sopenharmony_ci} 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_cistatic void mwifiex_process_uap_tx_pause(struct mwifiex_private *priv, 3448c2ecf20Sopenharmony_ci struct mwifiex_ie_types_header *tlv) 3458c2ecf20Sopenharmony_ci{ 3468c2ecf20Sopenharmony_ci struct mwifiex_tx_pause_tlv *tp; 3478c2ecf20Sopenharmony_ci struct mwifiex_sta_node *sta_ptr; 3488c2ecf20Sopenharmony_ci 3498c2ecf20Sopenharmony_ci tp = (void *)tlv; 3508c2ecf20Sopenharmony_ci mwifiex_dbg(priv->adapter, EVENT, 3518c2ecf20Sopenharmony_ci "uap tx_pause: %pM pause=%d, pkts=%d\n", 3528c2ecf20Sopenharmony_ci tp->peermac, tp->tx_pause, 3538c2ecf20Sopenharmony_ci tp->pkt_cnt); 3548c2ecf20Sopenharmony_ci 3558c2ecf20Sopenharmony_ci if (ether_addr_equal(tp->peermac, priv->netdev->dev_addr)) { 3568c2ecf20Sopenharmony_ci if (tp->tx_pause) 3578c2ecf20Sopenharmony_ci priv->port_open = false; 3588c2ecf20Sopenharmony_ci else 3598c2ecf20Sopenharmony_ci priv->port_open = true; 3608c2ecf20Sopenharmony_ci } else if (is_multicast_ether_addr(tp->peermac)) { 3618c2ecf20Sopenharmony_ci mwifiex_update_ralist_tx_pause(priv, tp->peermac, tp->tx_pause); 3628c2ecf20Sopenharmony_ci } else { 3638c2ecf20Sopenharmony_ci spin_lock_bh(&priv->sta_list_spinlock); 3648c2ecf20Sopenharmony_ci sta_ptr = mwifiex_get_sta_entry(priv, tp->peermac); 3658c2ecf20Sopenharmony_ci if (sta_ptr && sta_ptr->tx_pause != tp->tx_pause) { 3668c2ecf20Sopenharmony_ci sta_ptr->tx_pause = tp->tx_pause; 3678c2ecf20Sopenharmony_ci spin_unlock_bh(&priv->sta_list_spinlock); 3688c2ecf20Sopenharmony_ci mwifiex_update_ralist_tx_pause(priv, tp->peermac, 3698c2ecf20Sopenharmony_ci tp->tx_pause); 3708c2ecf20Sopenharmony_ci } else { 3718c2ecf20Sopenharmony_ci spin_unlock_bh(&priv->sta_list_spinlock); 3728c2ecf20Sopenharmony_ci } 3738c2ecf20Sopenharmony_ci } 3748c2ecf20Sopenharmony_ci} 3758c2ecf20Sopenharmony_ci 3768c2ecf20Sopenharmony_cistatic void mwifiex_process_sta_tx_pause(struct mwifiex_private *priv, 3778c2ecf20Sopenharmony_ci struct mwifiex_ie_types_header *tlv) 3788c2ecf20Sopenharmony_ci{ 3798c2ecf20Sopenharmony_ci struct mwifiex_tx_pause_tlv *tp; 3808c2ecf20Sopenharmony_ci struct mwifiex_sta_node *sta_ptr; 3818c2ecf20Sopenharmony_ci int status; 3828c2ecf20Sopenharmony_ci 3838c2ecf20Sopenharmony_ci tp = (void *)tlv; 3848c2ecf20Sopenharmony_ci mwifiex_dbg(priv->adapter, EVENT, 3858c2ecf20Sopenharmony_ci "sta tx_pause: %pM pause=%d, pkts=%d\n", 3868c2ecf20Sopenharmony_ci tp->peermac, tp->tx_pause, 3878c2ecf20Sopenharmony_ci tp->pkt_cnt); 3888c2ecf20Sopenharmony_ci 3898c2ecf20Sopenharmony_ci if (ether_addr_equal(tp->peermac, priv->cfg_bssid)) { 3908c2ecf20Sopenharmony_ci if (tp->tx_pause) 3918c2ecf20Sopenharmony_ci priv->port_open = false; 3928c2ecf20Sopenharmony_ci else 3938c2ecf20Sopenharmony_ci priv->port_open = true; 3948c2ecf20Sopenharmony_ci } else { 3958c2ecf20Sopenharmony_ci if (!ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info)) 3968c2ecf20Sopenharmony_ci return; 3978c2ecf20Sopenharmony_ci 3988c2ecf20Sopenharmony_ci status = mwifiex_get_tdls_link_status(priv, tp->peermac); 3998c2ecf20Sopenharmony_ci if (mwifiex_is_tdls_link_setup(status)) { 4008c2ecf20Sopenharmony_ci spin_lock_bh(&priv->sta_list_spinlock); 4018c2ecf20Sopenharmony_ci sta_ptr = mwifiex_get_sta_entry(priv, tp->peermac); 4028c2ecf20Sopenharmony_ci if (sta_ptr && sta_ptr->tx_pause != tp->tx_pause) { 4038c2ecf20Sopenharmony_ci sta_ptr->tx_pause = tp->tx_pause; 4048c2ecf20Sopenharmony_ci spin_unlock_bh(&priv->sta_list_spinlock); 4058c2ecf20Sopenharmony_ci mwifiex_update_ralist_tx_pause(priv, 4068c2ecf20Sopenharmony_ci tp->peermac, 4078c2ecf20Sopenharmony_ci tp->tx_pause); 4088c2ecf20Sopenharmony_ci } else { 4098c2ecf20Sopenharmony_ci spin_unlock_bh(&priv->sta_list_spinlock); 4108c2ecf20Sopenharmony_ci } 4118c2ecf20Sopenharmony_ci } 4128c2ecf20Sopenharmony_ci } 4138c2ecf20Sopenharmony_ci} 4148c2ecf20Sopenharmony_ci 4158c2ecf20Sopenharmony_civoid mwifiex_process_multi_chan_event(struct mwifiex_private *priv, 4168c2ecf20Sopenharmony_ci struct sk_buff *event_skb) 4178c2ecf20Sopenharmony_ci{ 4188c2ecf20Sopenharmony_ci struct mwifiex_ie_types_multi_chan_info *chan_info; 4198c2ecf20Sopenharmony_ci struct mwifiex_ie_types_mc_group_info *grp_info; 4208c2ecf20Sopenharmony_ci struct mwifiex_adapter *adapter = priv->adapter; 4218c2ecf20Sopenharmony_ci struct mwifiex_ie_types_header *tlv; 4228c2ecf20Sopenharmony_ci u16 tlv_buf_left, tlv_type, tlv_len; 4238c2ecf20Sopenharmony_ci int intf_num, bss_type, bss_num, i; 4248c2ecf20Sopenharmony_ci struct mwifiex_private *intf_priv; 4258c2ecf20Sopenharmony_ci 4268c2ecf20Sopenharmony_ci tlv_buf_left = event_skb->len - sizeof(u32); 4278c2ecf20Sopenharmony_ci chan_info = (void *)event_skb->data + sizeof(u32); 4288c2ecf20Sopenharmony_ci 4298c2ecf20Sopenharmony_ci if (le16_to_cpu(chan_info->header.type) != TLV_TYPE_MULTI_CHAN_INFO || 4308c2ecf20Sopenharmony_ci tlv_buf_left < sizeof(struct mwifiex_ie_types_multi_chan_info)) { 4318c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, ERROR, 4328c2ecf20Sopenharmony_ci "unknown TLV in chan_info event\n"); 4338c2ecf20Sopenharmony_ci return; 4348c2ecf20Sopenharmony_ci } 4358c2ecf20Sopenharmony_ci 4368c2ecf20Sopenharmony_ci adapter->usb_mc_status = le16_to_cpu(chan_info->status); 4378c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "multi chan operation %s\n", 4388c2ecf20Sopenharmony_ci adapter->usb_mc_status ? "started" : "over"); 4398c2ecf20Sopenharmony_ci 4408c2ecf20Sopenharmony_ci tlv_buf_left -= sizeof(struct mwifiex_ie_types_multi_chan_info); 4418c2ecf20Sopenharmony_ci tlv = (struct mwifiex_ie_types_header *)chan_info->tlv_buffer; 4428c2ecf20Sopenharmony_ci 4438c2ecf20Sopenharmony_ci while (tlv_buf_left >= (int)sizeof(struct mwifiex_ie_types_header)) { 4448c2ecf20Sopenharmony_ci tlv_type = le16_to_cpu(tlv->type); 4458c2ecf20Sopenharmony_ci tlv_len = le16_to_cpu(tlv->len); 4468c2ecf20Sopenharmony_ci if ((sizeof(struct mwifiex_ie_types_header) + tlv_len) > 4478c2ecf20Sopenharmony_ci tlv_buf_left) { 4488c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, ERROR, "wrong tlv: tlvLen=%d,\t" 4498c2ecf20Sopenharmony_ci "tlvBufLeft=%d\n", tlv_len, tlv_buf_left); 4508c2ecf20Sopenharmony_ci break; 4518c2ecf20Sopenharmony_ci } 4528c2ecf20Sopenharmony_ci if (tlv_type != TLV_TYPE_MC_GROUP_INFO) { 4538c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, ERROR, "wrong tlv type: 0x%x\n", 4548c2ecf20Sopenharmony_ci tlv_type); 4558c2ecf20Sopenharmony_ci break; 4568c2ecf20Sopenharmony_ci } 4578c2ecf20Sopenharmony_ci 4588c2ecf20Sopenharmony_ci grp_info = (struct mwifiex_ie_types_mc_group_info *)tlv; 4598c2ecf20Sopenharmony_ci intf_num = grp_info->intf_num; 4608c2ecf20Sopenharmony_ci for (i = 0; i < intf_num; i++) { 4618c2ecf20Sopenharmony_ci bss_type = grp_info->bss_type_numlist[i] >> 4; 4628c2ecf20Sopenharmony_ci bss_num = grp_info->bss_type_numlist[i] & BSS_NUM_MASK; 4638c2ecf20Sopenharmony_ci intf_priv = mwifiex_get_priv_by_id(adapter, bss_num, 4648c2ecf20Sopenharmony_ci bss_type); 4658c2ecf20Sopenharmony_ci if (!intf_priv) { 4668c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, ERROR, 4678c2ecf20Sopenharmony_ci "Invalid bss_type bss_num\t" 4688c2ecf20Sopenharmony_ci "in multi channel event\n"); 4698c2ecf20Sopenharmony_ci continue; 4708c2ecf20Sopenharmony_ci } 4718c2ecf20Sopenharmony_ci if (adapter->iface_type == MWIFIEX_USB) { 4728c2ecf20Sopenharmony_ci u8 ep; 4738c2ecf20Sopenharmony_ci 4748c2ecf20Sopenharmony_ci ep = grp_info->hid_num.usb_ep_num; 4758c2ecf20Sopenharmony_ci if (ep == MWIFIEX_USB_EP_DATA || 4768c2ecf20Sopenharmony_ci ep == MWIFIEX_USB_EP_DATA_CH2) 4778c2ecf20Sopenharmony_ci intf_priv->usb_port = ep; 4788c2ecf20Sopenharmony_ci } 4798c2ecf20Sopenharmony_ci } 4808c2ecf20Sopenharmony_ci 4818c2ecf20Sopenharmony_ci tlv_buf_left -= sizeof(struct mwifiex_ie_types_header) + 4828c2ecf20Sopenharmony_ci tlv_len; 4838c2ecf20Sopenharmony_ci tlv = (void *)((u8 *)tlv + tlv_len + 4848c2ecf20Sopenharmony_ci sizeof(struct mwifiex_ie_types_header)); 4858c2ecf20Sopenharmony_ci } 4868c2ecf20Sopenharmony_ci 4878c2ecf20Sopenharmony_ci if (adapter->iface_type == MWIFIEX_USB) { 4888c2ecf20Sopenharmony_ci adapter->tx_lock_flag = true; 4898c2ecf20Sopenharmony_ci adapter->usb_mc_setup = true; 4908c2ecf20Sopenharmony_ci mwifiex_multi_chan_resync(adapter); 4918c2ecf20Sopenharmony_ci } 4928c2ecf20Sopenharmony_ci} 4938c2ecf20Sopenharmony_ci 4948c2ecf20Sopenharmony_civoid mwifiex_process_tx_pause_event(struct mwifiex_private *priv, 4958c2ecf20Sopenharmony_ci struct sk_buff *event_skb) 4968c2ecf20Sopenharmony_ci{ 4978c2ecf20Sopenharmony_ci struct mwifiex_ie_types_header *tlv; 4988c2ecf20Sopenharmony_ci u16 tlv_type, tlv_len; 4998c2ecf20Sopenharmony_ci int tlv_buf_left; 5008c2ecf20Sopenharmony_ci 5018c2ecf20Sopenharmony_ci if (!priv->media_connected) { 5028c2ecf20Sopenharmony_ci mwifiex_dbg(priv->adapter, ERROR, 5038c2ecf20Sopenharmony_ci "tx_pause event while disconnected; bss_role=%d\n", 5048c2ecf20Sopenharmony_ci priv->bss_role); 5058c2ecf20Sopenharmony_ci return; 5068c2ecf20Sopenharmony_ci } 5078c2ecf20Sopenharmony_ci 5088c2ecf20Sopenharmony_ci tlv_buf_left = event_skb->len - sizeof(u32); 5098c2ecf20Sopenharmony_ci tlv = (void *)event_skb->data + sizeof(u32); 5108c2ecf20Sopenharmony_ci 5118c2ecf20Sopenharmony_ci while (tlv_buf_left >= (int)sizeof(struct mwifiex_ie_types_header)) { 5128c2ecf20Sopenharmony_ci tlv_type = le16_to_cpu(tlv->type); 5138c2ecf20Sopenharmony_ci tlv_len = le16_to_cpu(tlv->len); 5148c2ecf20Sopenharmony_ci if ((sizeof(struct mwifiex_ie_types_header) + tlv_len) > 5158c2ecf20Sopenharmony_ci tlv_buf_left) { 5168c2ecf20Sopenharmony_ci mwifiex_dbg(priv->adapter, ERROR, 5178c2ecf20Sopenharmony_ci "wrong tlv: tlvLen=%d, tlvBufLeft=%d\n", 5188c2ecf20Sopenharmony_ci tlv_len, tlv_buf_left); 5198c2ecf20Sopenharmony_ci break; 5208c2ecf20Sopenharmony_ci } 5218c2ecf20Sopenharmony_ci if (tlv_type == TLV_TYPE_TX_PAUSE) { 5228c2ecf20Sopenharmony_ci if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) 5238c2ecf20Sopenharmony_ci mwifiex_process_sta_tx_pause(priv, tlv); 5248c2ecf20Sopenharmony_ci else 5258c2ecf20Sopenharmony_ci mwifiex_process_uap_tx_pause(priv, tlv); 5268c2ecf20Sopenharmony_ci } 5278c2ecf20Sopenharmony_ci 5288c2ecf20Sopenharmony_ci tlv_buf_left -= sizeof(struct mwifiex_ie_types_header) + 5298c2ecf20Sopenharmony_ci tlv_len; 5308c2ecf20Sopenharmony_ci tlv = (void *)((u8 *)tlv + tlv_len + 5318c2ecf20Sopenharmony_ci sizeof(struct mwifiex_ie_types_header)); 5328c2ecf20Sopenharmony_ci } 5338c2ecf20Sopenharmony_ci 5348c2ecf20Sopenharmony_ci} 5358c2ecf20Sopenharmony_ci 5368c2ecf20Sopenharmony_ci/* 5378c2ecf20Sopenharmony_ci* This function handles coex events generated by firmware 5388c2ecf20Sopenharmony_ci*/ 5398c2ecf20Sopenharmony_civoid mwifiex_bt_coex_wlan_param_update_event(struct mwifiex_private *priv, 5408c2ecf20Sopenharmony_ci struct sk_buff *event_skb) 5418c2ecf20Sopenharmony_ci{ 5428c2ecf20Sopenharmony_ci struct mwifiex_adapter *adapter = priv->adapter; 5438c2ecf20Sopenharmony_ci struct mwifiex_ie_types_header *tlv; 5448c2ecf20Sopenharmony_ci struct mwifiex_ie_types_btcoex_aggr_win_size *winsizetlv; 5458c2ecf20Sopenharmony_ci struct mwifiex_ie_types_btcoex_scan_time *scantlv; 5468c2ecf20Sopenharmony_ci s32 len = event_skb->len - sizeof(u32); 5478c2ecf20Sopenharmony_ci u8 *cur_ptr = event_skb->data + sizeof(u32); 5488c2ecf20Sopenharmony_ci u16 tlv_type, tlv_len; 5498c2ecf20Sopenharmony_ci 5508c2ecf20Sopenharmony_ci while (len >= sizeof(struct mwifiex_ie_types_header)) { 5518c2ecf20Sopenharmony_ci tlv = (struct mwifiex_ie_types_header *)cur_ptr; 5528c2ecf20Sopenharmony_ci tlv_len = le16_to_cpu(tlv->len); 5538c2ecf20Sopenharmony_ci tlv_type = le16_to_cpu(tlv->type); 5548c2ecf20Sopenharmony_ci 5558c2ecf20Sopenharmony_ci if ((tlv_len + sizeof(struct mwifiex_ie_types_header)) > len) 5568c2ecf20Sopenharmony_ci break; 5578c2ecf20Sopenharmony_ci switch (tlv_type) { 5588c2ecf20Sopenharmony_ci case TLV_BTCOEX_WL_AGGR_WINSIZE: 5598c2ecf20Sopenharmony_ci winsizetlv = 5608c2ecf20Sopenharmony_ci (struct mwifiex_ie_types_btcoex_aggr_win_size *)tlv; 5618c2ecf20Sopenharmony_ci adapter->coex_win_size = winsizetlv->coex_win_size; 5628c2ecf20Sopenharmony_ci adapter->coex_tx_win_size = 5638c2ecf20Sopenharmony_ci winsizetlv->tx_win_size; 5648c2ecf20Sopenharmony_ci adapter->coex_rx_win_size = 5658c2ecf20Sopenharmony_ci winsizetlv->rx_win_size; 5668c2ecf20Sopenharmony_ci mwifiex_coex_ampdu_rxwinsize(adapter); 5678c2ecf20Sopenharmony_ci mwifiex_update_ampdu_txwinsize(adapter); 5688c2ecf20Sopenharmony_ci break; 5698c2ecf20Sopenharmony_ci 5708c2ecf20Sopenharmony_ci case TLV_BTCOEX_WL_SCANTIME: 5718c2ecf20Sopenharmony_ci scantlv = 5728c2ecf20Sopenharmony_ci (struct mwifiex_ie_types_btcoex_scan_time *)tlv; 5738c2ecf20Sopenharmony_ci adapter->coex_scan = scantlv->coex_scan; 5748c2ecf20Sopenharmony_ci adapter->coex_min_scan_time = le16_to_cpu(scantlv->min_scan_time); 5758c2ecf20Sopenharmony_ci adapter->coex_max_scan_time = le16_to_cpu(scantlv->max_scan_time); 5768c2ecf20Sopenharmony_ci break; 5778c2ecf20Sopenharmony_ci 5788c2ecf20Sopenharmony_ci default: 5798c2ecf20Sopenharmony_ci break; 5808c2ecf20Sopenharmony_ci } 5818c2ecf20Sopenharmony_ci 5828c2ecf20Sopenharmony_ci len -= tlv_len + sizeof(struct mwifiex_ie_types_header); 5838c2ecf20Sopenharmony_ci cur_ptr += tlv_len + 5848c2ecf20Sopenharmony_ci sizeof(struct mwifiex_ie_types_header); 5858c2ecf20Sopenharmony_ci } 5868c2ecf20Sopenharmony_ci 5878c2ecf20Sopenharmony_ci dev_dbg(adapter->dev, "coex_scan=%d min_scan=%d coex_win=%d, tx_win=%d rx_win=%d\n", 5888c2ecf20Sopenharmony_ci adapter->coex_scan, adapter->coex_min_scan_time, 5898c2ecf20Sopenharmony_ci adapter->coex_win_size, adapter->coex_tx_win_size, 5908c2ecf20Sopenharmony_ci adapter->coex_rx_win_size); 5918c2ecf20Sopenharmony_ci} 5928c2ecf20Sopenharmony_ci 5938c2ecf20Sopenharmony_cistatic void 5948c2ecf20Sopenharmony_cimwifiex_fw_dump_info_event(struct mwifiex_private *priv, 5958c2ecf20Sopenharmony_ci struct sk_buff *event_skb) 5968c2ecf20Sopenharmony_ci{ 5978c2ecf20Sopenharmony_ci struct mwifiex_adapter *adapter = priv->adapter; 5988c2ecf20Sopenharmony_ci struct mwifiex_fw_dump_header *fw_dump_hdr = 5998c2ecf20Sopenharmony_ci (void *)adapter->event_body; 6008c2ecf20Sopenharmony_ci 6018c2ecf20Sopenharmony_ci if (adapter->iface_type != MWIFIEX_USB) { 6028c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, MSG, 6038c2ecf20Sopenharmony_ci "event is not on usb interface, ignore it\n"); 6048c2ecf20Sopenharmony_ci return; 6058c2ecf20Sopenharmony_ci } 6068c2ecf20Sopenharmony_ci 6078c2ecf20Sopenharmony_ci if (!adapter->devdump_data) { 6088c2ecf20Sopenharmony_ci /* When receive the first event, allocate device dump 6098c2ecf20Sopenharmony_ci * buffer, dump driver info. 6108c2ecf20Sopenharmony_ci */ 6118c2ecf20Sopenharmony_ci adapter->devdump_data = vzalloc(MWIFIEX_FW_DUMP_SIZE); 6128c2ecf20Sopenharmony_ci if (!adapter->devdump_data) { 6138c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, ERROR, 6148c2ecf20Sopenharmony_ci "vzalloc devdump data failure!\n"); 6158c2ecf20Sopenharmony_ci return; 6168c2ecf20Sopenharmony_ci } 6178c2ecf20Sopenharmony_ci 6188c2ecf20Sopenharmony_ci mwifiex_drv_info_dump(adapter); 6198c2ecf20Sopenharmony_ci 6208c2ecf20Sopenharmony_ci /* If no proceeded event arrive in 10s, upload device 6218c2ecf20Sopenharmony_ci * dump data, this will be useful if the end of 6228c2ecf20Sopenharmony_ci * transmission event get lost, in this cornel case, 6238c2ecf20Sopenharmony_ci * user would still get partial of the dump. 6248c2ecf20Sopenharmony_ci */ 6258c2ecf20Sopenharmony_ci mod_timer(&adapter->devdump_timer, 6268c2ecf20Sopenharmony_ci jiffies + msecs_to_jiffies(MWIFIEX_TIMER_10S)); 6278c2ecf20Sopenharmony_ci } 6288c2ecf20Sopenharmony_ci 6298c2ecf20Sopenharmony_ci /* Overflow check */ 6308c2ecf20Sopenharmony_ci if (adapter->devdump_len + event_skb->len >= MWIFIEX_FW_DUMP_SIZE) 6318c2ecf20Sopenharmony_ci goto upload_dump; 6328c2ecf20Sopenharmony_ci 6338c2ecf20Sopenharmony_ci memmove(adapter->devdump_data + adapter->devdump_len, 6348c2ecf20Sopenharmony_ci adapter->event_skb->data, event_skb->len); 6358c2ecf20Sopenharmony_ci adapter->devdump_len += event_skb->len; 6368c2ecf20Sopenharmony_ci 6378c2ecf20Sopenharmony_ci if (le16_to_cpu(fw_dump_hdr->type == FW_DUMP_INFO_ENDED)) { 6388c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, MSG, 6398c2ecf20Sopenharmony_ci "receive end of transmission flag event!\n"); 6408c2ecf20Sopenharmony_ci goto upload_dump; 6418c2ecf20Sopenharmony_ci } 6428c2ecf20Sopenharmony_ci return; 6438c2ecf20Sopenharmony_ci 6448c2ecf20Sopenharmony_ciupload_dump: 6458c2ecf20Sopenharmony_ci del_timer_sync(&adapter->devdump_timer); 6468c2ecf20Sopenharmony_ci mwifiex_upload_device_dump(adapter); 6478c2ecf20Sopenharmony_ci} 6488c2ecf20Sopenharmony_ci 6498c2ecf20Sopenharmony_ci/* 6508c2ecf20Sopenharmony_ci * This function handles events generated by firmware. 6518c2ecf20Sopenharmony_ci * 6528c2ecf20Sopenharmony_ci * This is a generic function and handles all events. 6538c2ecf20Sopenharmony_ci * 6548c2ecf20Sopenharmony_ci * Event specific routines are called by this function based 6558c2ecf20Sopenharmony_ci * upon the generated event cause. 6568c2ecf20Sopenharmony_ci * 6578c2ecf20Sopenharmony_ci * For the following events, the function just forwards them to upper 6588c2ecf20Sopenharmony_ci * layers, optionally recording the change - 6598c2ecf20Sopenharmony_ci * - EVENT_LINK_SENSED 6608c2ecf20Sopenharmony_ci * - EVENT_MIC_ERR_UNICAST 6618c2ecf20Sopenharmony_ci * - EVENT_MIC_ERR_MULTICAST 6628c2ecf20Sopenharmony_ci * - EVENT_PORT_RELEASE 6638c2ecf20Sopenharmony_ci * - EVENT_RSSI_LOW 6648c2ecf20Sopenharmony_ci * - EVENT_SNR_LOW 6658c2ecf20Sopenharmony_ci * - EVENT_MAX_FAIL 6668c2ecf20Sopenharmony_ci * - EVENT_RSSI_HIGH 6678c2ecf20Sopenharmony_ci * - EVENT_SNR_HIGH 6688c2ecf20Sopenharmony_ci * - EVENT_DATA_RSSI_LOW 6698c2ecf20Sopenharmony_ci * - EVENT_DATA_SNR_LOW 6708c2ecf20Sopenharmony_ci * - EVENT_DATA_RSSI_HIGH 6718c2ecf20Sopenharmony_ci * - EVENT_DATA_SNR_HIGH 6728c2ecf20Sopenharmony_ci * - EVENT_LINK_QUALITY 6738c2ecf20Sopenharmony_ci * - EVENT_PRE_BEACON_LOST 6748c2ecf20Sopenharmony_ci * - EVENT_IBSS_COALESCED 6758c2ecf20Sopenharmony_ci * - EVENT_IBSS_STA_CONNECT 6768c2ecf20Sopenharmony_ci * - EVENT_IBSS_STA_DISCONNECT 6778c2ecf20Sopenharmony_ci * - EVENT_WEP_ICV_ERR 6788c2ecf20Sopenharmony_ci * - EVENT_BW_CHANGE 6798c2ecf20Sopenharmony_ci * - EVENT_HOSTWAKE_STAIE 6808c2ecf20Sopenharmony_ci * 6818c2ecf20Sopenharmony_ci * For the following events, no action is taken - 6828c2ecf20Sopenharmony_ci * - EVENT_MIB_CHANGED 6838c2ecf20Sopenharmony_ci * - EVENT_INIT_DONE 6848c2ecf20Sopenharmony_ci * - EVENT_DUMMY_HOST_WAKEUP_SIGNAL 6858c2ecf20Sopenharmony_ci * 6868c2ecf20Sopenharmony_ci * Rest of the supported events requires driver handling - 6878c2ecf20Sopenharmony_ci * - EVENT_DEAUTHENTICATED 6888c2ecf20Sopenharmony_ci * - EVENT_DISASSOCIATED 6898c2ecf20Sopenharmony_ci * - EVENT_LINK_LOST 6908c2ecf20Sopenharmony_ci * - EVENT_PS_SLEEP 6918c2ecf20Sopenharmony_ci * - EVENT_PS_AWAKE 6928c2ecf20Sopenharmony_ci * - EVENT_DEEP_SLEEP_AWAKE 6938c2ecf20Sopenharmony_ci * - EVENT_HS_ACT_REQ 6948c2ecf20Sopenharmony_ci * - EVENT_ADHOC_BCN_LOST 6958c2ecf20Sopenharmony_ci * - EVENT_BG_SCAN_REPORT 6968c2ecf20Sopenharmony_ci * - EVENT_WMM_STATUS_CHANGE 6978c2ecf20Sopenharmony_ci * - EVENT_ADDBA 6988c2ecf20Sopenharmony_ci * - EVENT_DELBA 6998c2ecf20Sopenharmony_ci * - EVENT_BA_STREAM_TIEMOUT 7008c2ecf20Sopenharmony_ci * - EVENT_AMSDU_AGGR_CTRL 7018c2ecf20Sopenharmony_ci * - EVENT_FW_DUMP_INFO 7028c2ecf20Sopenharmony_ci */ 7038c2ecf20Sopenharmony_ciint mwifiex_process_sta_event(struct mwifiex_private *priv) 7048c2ecf20Sopenharmony_ci{ 7058c2ecf20Sopenharmony_ci struct mwifiex_adapter *adapter = priv->adapter; 7068c2ecf20Sopenharmony_ci int ret = 0, i; 7078c2ecf20Sopenharmony_ci u32 eventcause = adapter->event_cause; 7088c2ecf20Sopenharmony_ci u16 ctrl, reason_code; 7098c2ecf20Sopenharmony_ci u8 ibss_sta_addr[ETH_ALEN]; 7108c2ecf20Sopenharmony_ci struct mwifiex_sta_node *sta_ptr; 7118c2ecf20Sopenharmony_ci 7128c2ecf20Sopenharmony_ci switch (eventcause) { 7138c2ecf20Sopenharmony_ci case EVENT_DUMMY_HOST_WAKEUP_SIGNAL: 7148c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, ERROR, 7158c2ecf20Sopenharmony_ci "invalid EVENT: DUMMY_HOST_WAKEUP_SIGNAL, ignore it\n"); 7168c2ecf20Sopenharmony_ci break; 7178c2ecf20Sopenharmony_ci case EVENT_LINK_SENSED: 7188c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: LINK_SENSED\n"); 7198c2ecf20Sopenharmony_ci if (!netif_carrier_ok(priv->netdev)) 7208c2ecf20Sopenharmony_ci netif_carrier_on(priv->netdev); 7218c2ecf20Sopenharmony_ci mwifiex_wake_up_net_dev_queue(priv->netdev, adapter); 7228c2ecf20Sopenharmony_ci break; 7238c2ecf20Sopenharmony_ci 7248c2ecf20Sopenharmony_ci case EVENT_DEAUTHENTICATED: 7258c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: Deauthenticated\n"); 7268c2ecf20Sopenharmony_ci if (priv->wps.session_enable) { 7278c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, INFO, 7288c2ecf20Sopenharmony_ci "info: receive deauth event in wps session\n"); 7298c2ecf20Sopenharmony_ci break; 7308c2ecf20Sopenharmony_ci } 7318c2ecf20Sopenharmony_ci adapter->dbg.num_event_deauth++; 7328c2ecf20Sopenharmony_ci if (priv->media_connected) { 7338c2ecf20Sopenharmony_ci reason_code = 7348c2ecf20Sopenharmony_ci get_unaligned_le16(adapter->event_body); 7358c2ecf20Sopenharmony_ci mwifiex_reset_connect_state(priv, reason_code, true); 7368c2ecf20Sopenharmony_ci } 7378c2ecf20Sopenharmony_ci break; 7388c2ecf20Sopenharmony_ci 7398c2ecf20Sopenharmony_ci case EVENT_DISASSOCIATED: 7408c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: Disassociated\n"); 7418c2ecf20Sopenharmony_ci if (priv->wps.session_enable) { 7428c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, INFO, 7438c2ecf20Sopenharmony_ci "info: receive disassoc event in wps session\n"); 7448c2ecf20Sopenharmony_ci break; 7458c2ecf20Sopenharmony_ci } 7468c2ecf20Sopenharmony_ci adapter->dbg.num_event_disassoc++; 7478c2ecf20Sopenharmony_ci if (priv->media_connected) { 7488c2ecf20Sopenharmony_ci reason_code = 7498c2ecf20Sopenharmony_ci get_unaligned_le16(adapter->event_body); 7508c2ecf20Sopenharmony_ci mwifiex_reset_connect_state(priv, reason_code, true); 7518c2ecf20Sopenharmony_ci } 7528c2ecf20Sopenharmony_ci break; 7538c2ecf20Sopenharmony_ci 7548c2ecf20Sopenharmony_ci case EVENT_LINK_LOST: 7558c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: Link lost\n"); 7568c2ecf20Sopenharmony_ci adapter->dbg.num_event_link_lost++; 7578c2ecf20Sopenharmony_ci if (priv->media_connected) { 7588c2ecf20Sopenharmony_ci reason_code = 7598c2ecf20Sopenharmony_ci get_unaligned_le16(adapter->event_body); 7608c2ecf20Sopenharmony_ci mwifiex_reset_connect_state(priv, reason_code, true); 7618c2ecf20Sopenharmony_ci } 7628c2ecf20Sopenharmony_ci break; 7638c2ecf20Sopenharmony_ci 7648c2ecf20Sopenharmony_ci case EVENT_PS_SLEEP: 7658c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "info: EVENT: SLEEP\n"); 7668c2ecf20Sopenharmony_ci 7678c2ecf20Sopenharmony_ci adapter->ps_state = PS_STATE_PRE_SLEEP; 7688c2ecf20Sopenharmony_ci 7698c2ecf20Sopenharmony_ci mwifiex_check_ps_cond(adapter); 7708c2ecf20Sopenharmony_ci break; 7718c2ecf20Sopenharmony_ci 7728c2ecf20Sopenharmony_ci case EVENT_PS_AWAKE: 7738c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "info: EVENT: AWAKE\n"); 7748c2ecf20Sopenharmony_ci if (!adapter->pps_uapsd_mode && 7758c2ecf20Sopenharmony_ci (priv->port_open || 7768c2ecf20Sopenharmony_ci (priv->bss_mode == NL80211_IFTYPE_ADHOC)) && 7778c2ecf20Sopenharmony_ci priv->media_connected && adapter->sleep_period.period) { 7788c2ecf20Sopenharmony_ci adapter->pps_uapsd_mode = true; 7798c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, 7808c2ecf20Sopenharmony_ci "event: PPS/UAPSD mode activated\n"); 7818c2ecf20Sopenharmony_ci } 7828c2ecf20Sopenharmony_ci adapter->tx_lock_flag = false; 7838c2ecf20Sopenharmony_ci if (adapter->pps_uapsd_mode && adapter->gen_null_pkt) { 7848c2ecf20Sopenharmony_ci if (mwifiex_check_last_packet_indication(priv)) { 7858c2ecf20Sopenharmony_ci if (adapter->data_sent || 7868c2ecf20Sopenharmony_ci (adapter->if_ops.is_port_ready && 7878c2ecf20Sopenharmony_ci !adapter->if_ops.is_port_ready(priv))) { 7888c2ecf20Sopenharmony_ci adapter->ps_state = PS_STATE_AWAKE; 7898c2ecf20Sopenharmony_ci adapter->pm_wakeup_card_req = false; 7908c2ecf20Sopenharmony_ci adapter->pm_wakeup_fw_try = false; 7918c2ecf20Sopenharmony_ci del_timer(&adapter->wakeup_timer); 7928c2ecf20Sopenharmony_ci break; 7938c2ecf20Sopenharmony_ci } 7948c2ecf20Sopenharmony_ci if (!mwifiex_send_null_packet 7958c2ecf20Sopenharmony_ci (priv, 7968c2ecf20Sopenharmony_ci MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET | 7978c2ecf20Sopenharmony_ci MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET)) 7988c2ecf20Sopenharmony_ci adapter->ps_state = 7998c2ecf20Sopenharmony_ci PS_STATE_SLEEP; 8008c2ecf20Sopenharmony_ci return 0; 8018c2ecf20Sopenharmony_ci } 8028c2ecf20Sopenharmony_ci } 8038c2ecf20Sopenharmony_ci adapter->ps_state = PS_STATE_AWAKE; 8048c2ecf20Sopenharmony_ci adapter->pm_wakeup_card_req = false; 8058c2ecf20Sopenharmony_ci adapter->pm_wakeup_fw_try = false; 8068c2ecf20Sopenharmony_ci del_timer(&adapter->wakeup_timer); 8078c2ecf20Sopenharmony_ci 8088c2ecf20Sopenharmony_ci break; 8098c2ecf20Sopenharmony_ci 8108c2ecf20Sopenharmony_ci case EVENT_DEEP_SLEEP_AWAKE: 8118c2ecf20Sopenharmony_ci adapter->if_ops.wakeup_complete(adapter); 8128c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: DS_AWAKE\n"); 8138c2ecf20Sopenharmony_ci if (adapter->is_deep_sleep) 8148c2ecf20Sopenharmony_ci adapter->is_deep_sleep = false; 8158c2ecf20Sopenharmony_ci break; 8168c2ecf20Sopenharmony_ci 8178c2ecf20Sopenharmony_ci case EVENT_HS_ACT_REQ: 8188c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: HS_ACT_REQ\n"); 8198c2ecf20Sopenharmony_ci ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_HS_CFG_ENH, 8208c2ecf20Sopenharmony_ci 0, 0, NULL, false); 8218c2ecf20Sopenharmony_ci break; 8228c2ecf20Sopenharmony_ci 8238c2ecf20Sopenharmony_ci case EVENT_MIC_ERR_UNICAST: 8248c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: UNICAST MIC ERROR\n"); 8258c2ecf20Sopenharmony_ci cfg80211_michael_mic_failure(priv->netdev, priv->cfg_bssid, 8268c2ecf20Sopenharmony_ci NL80211_KEYTYPE_PAIRWISE, 8278c2ecf20Sopenharmony_ci -1, NULL, GFP_KERNEL); 8288c2ecf20Sopenharmony_ci break; 8298c2ecf20Sopenharmony_ci 8308c2ecf20Sopenharmony_ci case EVENT_MIC_ERR_MULTICAST: 8318c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: MULTICAST MIC ERROR\n"); 8328c2ecf20Sopenharmony_ci cfg80211_michael_mic_failure(priv->netdev, priv->cfg_bssid, 8338c2ecf20Sopenharmony_ci NL80211_KEYTYPE_GROUP, 8348c2ecf20Sopenharmony_ci -1, NULL, GFP_KERNEL); 8358c2ecf20Sopenharmony_ci break; 8368c2ecf20Sopenharmony_ci case EVENT_MIB_CHANGED: 8378c2ecf20Sopenharmony_ci case EVENT_INIT_DONE: 8388c2ecf20Sopenharmony_ci break; 8398c2ecf20Sopenharmony_ci 8408c2ecf20Sopenharmony_ci case EVENT_ADHOC_BCN_LOST: 8418c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: ADHOC_BCN_LOST\n"); 8428c2ecf20Sopenharmony_ci priv->adhoc_is_link_sensed = false; 8438c2ecf20Sopenharmony_ci mwifiex_clean_txrx(priv); 8448c2ecf20Sopenharmony_ci mwifiex_stop_net_dev_queue(priv->netdev, adapter); 8458c2ecf20Sopenharmony_ci if (netif_carrier_ok(priv->netdev)) 8468c2ecf20Sopenharmony_ci netif_carrier_off(priv->netdev); 8478c2ecf20Sopenharmony_ci break; 8488c2ecf20Sopenharmony_ci 8498c2ecf20Sopenharmony_ci case EVENT_BG_SCAN_REPORT: 8508c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: BGS_REPORT\n"); 8518c2ecf20Sopenharmony_ci ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_BG_SCAN_QUERY, 8528c2ecf20Sopenharmony_ci HostCmd_ACT_GEN_GET, 0, NULL, false); 8538c2ecf20Sopenharmony_ci break; 8548c2ecf20Sopenharmony_ci 8558c2ecf20Sopenharmony_ci case EVENT_BG_SCAN_STOPPED: 8568c2ecf20Sopenharmony_ci dev_dbg(adapter->dev, "event: BGS_STOPPED\n"); 8578c2ecf20Sopenharmony_ci cfg80211_sched_scan_stopped(priv->wdev.wiphy, 0); 8588c2ecf20Sopenharmony_ci if (priv->sched_scanning) 8598c2ecf20Sopenharmony_ci priv->sched_scanning = false; 8608c2ecf20Sopenharmony_ci break; 8618c2ecf20Sopenharmony_ci 8628c2ecf20Sopenharmony_ci case EVENT_PORT_RELEASE: 8638c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: PORT RELEASE\n"); 8648c2ecf20Sopenharmony_ci priv->port_open = true; 8658c2ecf20Sopenharmony_ci break; 8668c2ecf20Sopenharmony_ci 8678c2ecf20Sopenharmony_ci case EVENT_EXT_SCAN_REPORT: 8688c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: EXT_SCAN Report\n"); 8698c2ecf20Sopenharmony_ci /* We intend to skip this event during suspend, but handle 8708c2ecf20Sopenharmony_ci * it in interface disabled case 8718c2ecf20Sopenharmony_ci */ 8728c2ecf20Sopenharmony_ci if (adapter->ext_scan && (!priv->scan_aborting || 8738c2ecf20Sopenharmony_ci !netif_running(priv->netdev))) 8748c2ecf20Sopenharmony_ci ret = mwifiex_handle_event_ext_scan_report(priv, 8758c2ecf20Sopenharmony_ci adapter->event_skb->data); 8768c2ecf20Sopenharmony_ci 8778c2ecf20Sopenharmony_ci break; 8788c2ecf20Sopenharmony_ci 8798c2ecf20Sopenharmony_ci case EVENT_WMM_STATUS_CHANGE: 8808c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: WMM status changed\n"); 8818c2ecf20Sopenharmony_ci ret = mwifiex_send_cmd(priv, HostCmd_CMD_WMM_GET_STATUS, 8828c2ecf20Sopenharmony_ci 0, 0, NULL, false); 8838c2ecf20Sopenharmony_ci break; 8848c2ecf20Sopenharmony_ci 8858c2ecf20Sopenharmony_ci case EVENT_RSSI_LOW: 8868c2ecf20Sopenharmony_ci cfg80211_cqm_rssi_notify(priv->netdev, 8878c2ecf20Sopenharmony_ci NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW, 8888c2ecf20Sopenharmony_ci 0, GFP_KERNEL); 8898c2ecf20Sopenharmony_ci mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO, 8908c2ecf20Sopenharmony_ci HostCmd_ACT_GEN_GET, 0, NULL, false); 8918c2ecf20Sopenharmony_ci priv->subsc_evt_rssi_state = RSSI_LOW_RECVD; 8928c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: Beacon RSSI_LOW\n"); 8938c2ecf20Sopenharmony_ci break; 8948c2ecf20Sopenharmony_ci case EVENT_SNR_LOW: 8958c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: Beacon SNR_LOW\n"); 8968c2ecf20Sopenharmony_ci break; 8978c2ecf20Sopenharmony_ci case EVENT_MAX_FAIL: 8988c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: MAX_FAIL\n"); 8998c2ecf20Sopenharmony_ci break; 9008c2ecf20Sopenharmony_ci case EVENT_RSSI_HIGH: 9018c2ecf20Sopenharmony_ci cfg80211_cqm_rssi_notify(priv->netdev, 9028c2ecf20Sopenharmony_ci NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH, 9038c2ecf20Sopenharmony_ci 0, GFP_KERNEL); 9048c2ecf20Sopenharmony_ci mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO, 9058c2ecf20Sopenharmony_ci HostCmd_ACT_GEN_GET, 0, NULL, false); 9068c2ecf20Sopenharmony_ci priv->subsc_evt_rssi_state = RSSI_HIGH_RECVD; 9078c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: Beacon RSSI_HIGH\n"); 9088c2ecf20Sopenharmony_ci break; 9098c2ecf20Sopenharmony_ci case EVENT_SNR_HIGH: 9108c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: Beacon SNR_HIGH\n"); 9118c2ecf20Sopenharmony_ci break; 9128c2ecf20Sopenharmony_ci case EVENT_DATA_RSSI_LOW: 9138c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: Data RSSI_LOW\n"); 9148c2ecf20Sopenharmony_ci break; 9158c2ecf20Sopenharmony_ci case EVENT_DATA_SNR_LOW: 9168c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: Data SNR_LOW\n"); 9178c2ecf20Sopenharmony_ci break; 9188c2ecf20Sopenharmony_ci case EVENT_DATA_RSSI_HIGH: 9198c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: Data RSSI_HIGH\n"); 9208c2ecf20Sopenharmony_ci break; 9218c2ecf20Sopenharmony_ci case EVENT_DATA_SNR_HIGH: 9228c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: Data SNR_HIGH\n"); 9238c2ecf20Sopenharmony_ci break; 9248c2ecf20Sopenharmony_ci case EVENT_LINK_QUALITY: 9258c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: Link Quality\n"); 9268c2ecf20Sopenharmony_ci break; 9278c2ecf20Sopenharmony_ci case EVENT_PRE_BEACON_LOST: 9288c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: Pre-Beacon Lost\n"); 9298c2ecf20Sopenharmony_ci break; 9308c2ecf20Sopenharmony_ci case EVENT_IBSS_COALESCED: 9318c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: IBSS_COALESCED\n"); 9328c2ecf20Sopenharmony_ci ret = mwifiex_send_cmd(priv, 9338c2ecf20Sopenharmony_ci HostCmd_CMD_802_11_IBSS_COALESCING_STATUS, 9348c2ecf20Sopenharmony_ci HostCmd_ACT_GEN_GET, 0, NULL, false); 9358c2ecf20Sopenharmony_ci break; 9368c2ecf20Sopenharmony_ci case EVENT_IBSS_STA_CONNECT: 9378c2ecf20Sopenharmony_ci ether_addr_copy(ibss_sta_addr, adapter->event_body + 2); 9388c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: IBSS_STA_CONNECT %pM\n", 9398c2ecf20Sopenharmony_ci ibss_sta_addr); 9408c2ecf20Sopenharmony_ci sta_ptr = mwifiex_add_sta_entry(priv, ibss_sta_addr); 9418c2ecf20Sopenharmony_ci if (sta_ptr && adapter->adhoc_11n_enabled) { 9428c2ecf20Sopenharmony_ci mwifiex_check_ibss_peer_capabilities(priv, sta_ptr, 9438c2ecf20Sopenharmony_ci adapter->event_skb); 9448c2ecf20Sopenharmony_ci if (sta_ptr->is_11n_enabled) 9458c2ecf20Sopenharmony_ci for (i = 0; i < MAX_NUM_TID; i++) 9468c2ecf20Sopenharmony_ci sta_ptr->ampdu_sta[i] = 9478c2ecf20Sopenharmony_ci priv->aggr_prio_tbl[i].ampdu_user; 9488c2ecf20Sopenharmony_ci else 9498c2ecf20Sopenharmony_ci for (i = 0; i < MAX_NUM_TID; i++) 9508c2ecf20Sopenharmony_ci sta_ptr->ampdu_sta[i] = 9518c2ecf20Sopenharmony_ci BA_STREAM_NOT_ALLOWED; 9528c2ecf20Sopenharmony_ci memset(sta_ptr->rx_seq, 0xff, sizeof(sta_ptr->rx_seq)); 9538c2ecf20Sopenharmony_ci } 9548c2ecf20Sopenharmony_ci 9558c2ecf20Sopenharmony_ci break; 9568c2ecf20Sopenharmony_ci case EVENT_IBSS_STA_DISCONNECT: 9578c2ecf20Sopenharmony_ci ether_addr_copy(ibss_sta_addr, adapter->event_body + 2); 9588c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: IBSS_STA_DISCONNECT %pM\n", 9598c2ecf20Sopenharmony_ci ibss_sta_addr); 9608c2ecf20Sopenharmony_ci sta_ptr = mwifiex_get_sta_entry(priv, ibss_sta_addr); 9618c2ecf20Sopenharmony_ci if (sta_ptr && sta_ptr->is_11n_enabled) { 9628c2ecf20Sopenharmony_ci mwifiex_11n_del_rx_reorder_tbl_by_ta(priv, 9638c2ecf20Sopenharmony_ci ibss_sta_addr); 9648c2ecf20Sopenharmony_ci mwifiex_del_tx_ba_stream_tbl_by_ra(priv, ibss_sta_addr); 9658c2ecf20Sopenharmony_ci } 9668c2ecf20Sopenharmony_ci mwifiex_wmm_del_peer_ra_list(priv, ibss_sta_addr); 9678c2ecf20Sopenharmony_ci mwifiex_del_sta_entry(priv, ibss_sta_addr); 9688c2ecf20Sopenharmony_ci break; 9698c2ecf20Sopenharmony_ci case EVENT_ADDBA: 9708c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: ADDBA Request\n"); 9718c2ecf20Sopenharmony_ci mwifiex_send_cmd(priv, HostCmd_CMD_11N_ADDBA_RSP, 9728c2ecf20Sopenharmony_ci HostCmd_ACT_GEN_SET, 0, 9738c2ecf20Sopenharmony_ci adapter->event_body, false); 9748c2ecf20Sopenharmony_ci break; 9758c2ecf20Sopenharmony_ci case EVENT_DELBA: 9768c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: DELBA Request\n"); 9778c2ecf20Sopenharmony_ci mwifiex_11n_delete_ba_stream(priv, adapter->event_body); 9788c2ecf20Sopenharmony_ci break; 9798c2ecf20Sopenharmony_ci case EVENT_BA_STREAM_TIEMOUT: 9808c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: BA Stream timeout\n"); 9818c2ecf20Sopenharmony_ci mwifiex_11n_ba_stream_timeout(priv, 9828c2ecf20Sopenharmony_ci (struct host_cmd_ds_11n_batimeout 9838c2ecf20Sopenharmony_ci *) 9848c2ecf20Sopenharmony_ci adapter->event_body); 9858c2ecf20Sopenharmony_ci break; 9868c2ecf20Sopenharmony_ci case EVENT_AMSDU_AGGR_CTRL: 9878c2ecf20Sopenharmony_ci ctrl = get_unaligned_le16(adapter->event_body); 9888c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, 9898c2ecf20Sopenharmony_ci "event: AMSDU_AGGR_CTRL %d\n", ctrl); 9908c2ecf20Sopenharmony_ci 9918c2ecf20Sopenharmony_ci adapter->tx_buf_size = 9928c2ecf20Sopenharmony_ci min_t(u16, adapter->curr_tx_buf_size, ctrl); 9938c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: tx_buf_size %d\n", 9948c2ecf20Sopenharmony_ci adapter->tx_buf_size); 9958c2ecf20Sopenharmony_ci break; 9968c2ecf20Sopenharmony_ci 9978c2ecf20Sopenharmony_ci case EVENT_WEP_ICV_ERR: 9988c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: WEP ICV error\n"); 9998c2ecf20Sopenharmony_ci break; 10008c2ecf20Sopenharmony_ci 10018c2ecf20Sopenharmony_ci case EVENT_BW_CHANGE: 10028c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: BW Change\n"); 10038c2ecf20Sopenharmony_ci break; 10048c2ecf20Sopenharmony_ci 10058c2ecf20Sopenharmony_ci case EVENT_HOSTWAKE_STAIE: 10068c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, 10078c2ecf20Sopenharmony_ci "event: HOSTWAKE_STAIE %d\n", eventcause); 10088c2ecf20Sopenharmony_ci break; 10098c2ecf20Sopenharmony_ci 10108c2ecf20Sopenharmony_ci case EVENT_REMAIN_ON_CHAN_EXPIRED: 10118c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, 10128c2ecf20Sopenharmony_ci "event: Remain on channel expired\n"); 10138c2ecf20Sopenharmony_ci cfg80211_remain_on_channel_expired(&priv->wdev, 10148c2ecf20Sopenharmony_ci priv->roc_cfg.cookie, 10158c2ecf20Sopenharmony_ci &priv->roc_cfg.chan, 10168c2ecf20Sopenharmony_ci GFP_ATOMIC); 10178c2ecf20Sopenharmony_ci 10188c2ecf20Sopenharmony_ci memset(&priv->roc_cfg, 0x00, sizeof(struct mwifiex_roc_cfg)); 10198c2ecf20Sopenharmony_ci 10208c2ecf20Sopenharmony_ci break; 10218c2ecf20Sopenharmony_ci 10228c2ecf20Sopenharmony_ci case EVENT_CHANNEL_SWITCH_ANN: 10238c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: Channel Switch Announcement\n"); 10248c2ecf20Sopenharmony_ci priv->csa_expire_time = 10258c2ecf20Sopenharmony_ci jiffies + msecs_to_jiffies(DFS_CHAN_MOVE_TIME); 10268c2ecf20Sopenharmony_ci priv->csa_chan = priv->curr_bss_params.bss_descriptor.channel; 10278c2ecf20Sopenharmony_ci ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_DEAUTHENTICATE, 10288c2ecf20Sopenharmony_ci HostCmd_ACT_GEN_SET, 0, 10298c2ecf20Sopenharmony_ci priv->curr_bss_params.bss_descriptor.mac_address, 10308c2ecf20Sopenharmony_ci false); 10318c2ecf20Sopenharmony_ci break; 10328c2ecf20Sopenharmony_ci 10338c2ecf20Sopenharmony_ci case EVENT_TDLS_GENERIC_EVENT: 10348c2ecf20Sopenharmony_ci ret = mwifiex_parse_tdls_event(priv, adapter->event_skb); 10358c2ecf20Sopenharmony_ci break; 10368c2ecf20Sopenharmony_ci 10378c2ecf20Sopenharmony_ci case EVENT_TX_DATA_PAUSE: 10388c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: TX DATA PAUSE\n"); 10398c2ecf20Sopenharmony_ci mwifiex_process_tx_pause_event(priv, adapter->event_skb); 10408c2ecf20Sopenharmony_ci break; 10418c2ecf20Sopenharmony_ci 10428c2ecf20Sopenharmony_ci case EVENT_MULTI_CHAN_INFO: 10438c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: multi-chan info\n"); 10448c2ecf20Sopenharmony_ci mwifiex_process_multi_chan_event(priv, adapter->event_skb); 10458c2ecf20Sopenharmony_ci break; 10468c2ecf20Sopenharmony_ci 10478c2ecf20Sopenharmony_ci case EVENT_TX_STATUS_REPORT: 10488c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: TX_STATUS Report\n"); 10498c2ecf20Sopenharmony_ci mwifiex_parse_tx_status_event(priv, adapter->event_body); 10508c2ecf20Sopenharmony_ci break; 10518c2ecf20Sopenharmony_ci 10528c2ecf20Sopenharmony_ci case EVENT_CHANNEL_REPORT_RDY: 10538c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: Channel Report\n"); 10548c2ecf20Sopenharmony_ci ret = mwifiex_11h_handle_chanrpt_ready(priv, 10558c2ecf20Sopenharmony_ci adapter->event_skb); 10568c2ecf20Sopenharmony_ci break; 10578c2ecf20Sopenharmony_ci case EVENT_RADAR_DETECTED: 10588c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: Radar detected\n"); 10598c2ecf20Sopenharmony_ci ret = mwifiex_11h_handle_radar_detected(priv, 10608c2ecf20Sopenharmony_ci adapter->event_skb); 10618c2ecf20Sopenharmony_ci break; 10628c2ecf20Sopenharmony_ci case EVENT_BT_COEX_WLAN_PARA_CHANGE: 10638c2ecf20Sopenharmony_ci dev_dbg(adapter->dev, "EVENT: BT coex wlan param update\n"); 10648c2ecf20Sopenharmony_ci if (adapter->ignore_btcoex_events) 10658c2ecf20Sopenharmony_ci break; 10668c2ecf20Sopenharmony_ci 10678c2ecf20Sopenharmony_ci mwifiex_bt_coex_wlan_param_update_event(priv, 10688c2ecf20Sopenharmony_ci adapter->event_skb); 10698c2ecf20Sopenharmony_ci break; 10708c2ecf20Sopenharmony_ci case EVENT_RXBA_SYNC: 10718c2ecf20Sopenharmony_ci dev_dbg(adapter->dev, "EVENT: RXBA_SYNC\n"); 10728c2ecf20Sopenharmony_ci mwifiex_11n_rxba_sync_event(priv, adapter->event_body, 10738c2ecf20Sopenharmony_ci adapter->event_skb->len - 10748c2ecf20Sopenharmony_ci sizeof(eventcause)); 10758c2ecf20Sopenharmony_ci break; 10768c2ecf20Sopenharmony_ci case EVENT_FW_DUMP_INFO: 10778c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: firmware debug info\n"); 10788c2ecf20Sopenharmony_ci mwifiex_fw_dump_info_event(priv, adapter->event_skb); 10798c2ecf20Sopenharmony_ci break; 10808c2ecf20Sopenharmony_ci /* Debugging event; not used, but let's not print an ERROR for it. */ 10818c2ecf20Sopenharmony_ci case EVENT_UNKNOWN_DEBUG: 10828c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, EVENT, "event: debug\n"); 10838c2ecf20Sopenharmony_ci break; 10848c2ecf20Sopenharmony_ci default: 10858c2ecf20Sopenharmony_ci mwifiex_dbg(adapter, ERROR, "event: unknown event id: %#x\n", 10868c2ecf20Sopenharmony_ci eventcause); 10878c2ecf20Sopenharmony_ci break; 10888c2ecf20Sopenharmony_ci } 10898c2ecf20Sopenharmony_ci 10908c2ecf20Sopenharmony_ci return ret; 10918c2ecf20Sopenharmony_ci} 1092