1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * NXP Wireless LAN device driver: AP event handling
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Copyright 2011-2020 NXP
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * This software file (the "File") is distributed by NXP
7*4882a593Smuzhiyun * under the terms of the GNU General Public License Version 2, June 1991
8*4882a593Smuzhiyun * (the "License"). You may use, redistribute and/or modify this File in
9*4882a593Smuzhiyun * accordance with the terms and conditions of the License, a copy of which
10*4882a593Smuzhiyun * is available by writing to the Free Software Foundation, Inc.,
11*4882a593Smuzhiyun * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12*4882a593Smuzhiyun * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13*4882a593Smuzhiyun *
14*4882a593Smuzhiyun * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15*4882a593Smuzhiyun * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16*4882a593Smuzhiyun * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17*4882a593Smuzhiyun * this warranty disclaimer.
18*4882a593Smuzhiyun */
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun #include "decl.h"
21*4882a593Smuzhiyun #include "main.h"
22*4882a593Smuzhiyun #include "11n.h"
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun #define MWIFIEX_BSS_START_EVT_FIX_SIZE 12
25*4882a593Smuzhiyun
mwifiex_check_uap_capabilities(struct mwifiex_private * priv,struct sk_buff * event)26*4882a593Smuzhiyun static int mwifiex_check_uap_capabilities(struct mwifiex_private *priv,
27*4882a593Smuzhiyun struct sk_buff *event)
28*4882a593Smuzhiyun {
29*4882a593Smuzhiyun int evt_len;
30*4882a593Smuzhiyun u8 *curr;
31*4882a593Smuzhiyun u16 tlv_len;
32*4882a593Smuzhiyun struct mwifiex_ie_types_data *tlv_hdr;
33*4882a593Smuzhiyun struct ieee_types_wmm_parameter *wmm_param_ie = NULL;
34*4882a593Smuzhiyun int mask = IEEE80211_WMM_IE_AP_QOSINFO_PARAM_SET_CNT_MASK;
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun priv->wmm_enabled = false;
37*4882a593Smuzhiyun skb_pull(event, MWIFIEX_BSS_START_EVT_FIX_SIZE);
38*4882a593Smuzhiyun evt_len = event->len;
39*4882a593Smuzhiyun curr = event->data;
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun mwifiex_dbg_dump(priv->adapter, EVT_D, "uap capabilities:",
42*4882a593Smuzhiyun event->data, event->len);
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun skb_push(event, MWIFIEX_BSS_START_EVT_FIX_SIZE);
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun while ((evt_len >= sizeof(tlv_hdr->header))) {
47*4882a593Smuzhiyun tlv_hdr = (struct mwifiex_ie_types_data *)curr;
48*4882a593Smuzhiyun tlv_len = le16_to_cpu(tlv_hdr->header.len);
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun if (evt_len < tlv_len + sizeof(tlv_hdr->header))
51*4882a593Smuzhiyun break;
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun switch (le16_to_cpu(tlv_hdr->header.type)) {
54*4882a593Smuzhiyun case WLAN_EID_HT_CAPABILITY:
55*4882a593Smuzhiyun priv->ap_11n_enabled = true;
56*4882a593Smuzhiyun break;
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun case WLAN_EID_VHT_CAPABILITY:
59*4882a593Smuzhiyun priv->ap_11ac_enabled = true;
60*4882a593Smuzhiyun break;
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun case WLAN_EID_VENDOR_SPECIFIC:
63*4882a593Smuzhiyun /* Point the regular IEEE IE 2 bytes into the Marvell IE
64*4882a593Smuzhiyun * and setup the IEEE IE type and length byte fields
65*4882a593Smuzhiyun */
66*4882a593Smuzhiyun wmm_param_ie = (void *)(curr + 2);
67*4882a593Smuzhiyun wmm_param_ie->vend_hdr.len = (u8)tlv_len;
68*4882a593Smuzhiyun wmm_param_ie->vend_hdr.element_id =
69*4882a593Smuzhiyun WLAN_EID_VENDOR_SPECIFIC;
70*4882a593Smuzhiyun mwifiex_dbg(priv->adapter, EVENT,
71*4882a593Smuzhiyun "info: check uap capabilities:\t"
72*4882a593Smuzhiyun "wmm parameter set count: %d\n",
73*4882a593Smuzhiyun wmm_param_ie->qos_info_bitmap & mask);
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun mwifiex_wmm_setup_ac_downgrade(priv);
76*4882a593Smuzhiyun priv->wmm_enabled = true;
77*4882a593Smuzhiyun mwifiex_wmm_setup_queue_priorities(priv, wmm_param_ie);
78*4882a593Smuzhiyun break;
79*4882a593Smuzhiyun
80*4882a593Smuzhiyun default:
81*4882a593Smuzhiyun break;
82*4882a593Smuzhiyun }
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun curr += (tlv_len + sizeof(tlv_hdr->header));
85*4882a593Smuzhiyun evt_len -= (tlv_len + sizeof(tlv_hdr->header));
86*4882a593Smuzhiyun }
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun return 0;
89*4882a593Smuzhiyun }
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun /*
92*4882a593Smuzhiyun * This function handles AP interface specific events generated by firmware.
93*4882a593Smuzhiyun *
94*4882a593Smuzhiyun * Event specific routines are called by this function based
95*4882a593Smuzhiyun * upon the generated event cause.
96*4882a593Smuzhiyun *
97*4882a593Smuzhiyun *
98*4882a593Smuzhiyun * Events supported for AP -
99*4882a593Smuzhiyun * - EVENT_UAP_STA_ASSOC
100*4882a593Smuzhiyun * - EVENT_UAP_STA_DEAUTH
101*4882a593Smuzhiyun * - EVENT_UAP_BSS_ACTIVE
102*4882a593Smuzhiyun * - EVENT_UAP_BSS_START
103*4882a593Smuzhiyun * - EVENT_UAP_BSS_IDLE
104*4882a593Smuzhiyun * - EVENT_UAP_MIC_COUNTERMEASURES:
105*4882a593Smuzhiyun */
mwifiex_process_uap_event(struct mwifiex_private * priv)106*4882a593Smuzhiyun int mwifiex_process_uap_event(struct mwifiex_private *priv)
107*4882a593Smuzhiyun {
108*4882a593Smuzhiyun struct mwifiex_adapter *adapter = priv->adapter;
109*4882a593Smuzhiyun int len, i;
110*4882a593Smuzhiyun u32 eventcause = adapter->event_cause;
111*4882a593Smuzhiyun struct station_info *sinfo;
112*4882a593Smuzhiyun struct mwifiex_assoc_event *event;
113*4882a593Smuzhiyun struct mwifiex_sta_node *node;
114*4882a593Smuzhiyun u8 *deauth_mac;
115*4882a593Smuzhiyun struct host_cmd_ds_11n_batimeout *ba_timeout;
116*4882a593Smuzhiyun u16 ctrl;
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun switch (eventcause) {
119*4882a593Smuzhiyun case EVENT_UAP_STA_ASSOC:
120*4882a593Smuzhiyun sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL);
121*4882a593Smuzhiyun if (!sinfo)
122*4882a593Smuzhiyun return -ENOMEM;
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun event = (struct mwifiex_assoc_event *)
125*4882a593Smuzhiyun (adapter->event_body + MWIFIEX_UAP_EVENT_EXTRA_HEADER);
126*4882a593Smuzhiyun if (le16_to_cpu(event->type) == TLV_TYPE_UAP_MGMT_FRAME) {
127*4882a593Smuzhiyun len = -1;
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun if (ieee80211_is_assoc_req(event->frame_control))
130*4882a593Smuzhiyun len = 0;
131*4882a593Smuzhiyun else if (ieee80211_is_reassoc_req(event->frame_control))
132*4882a593Smuzhiyun /* There will be ETH_ALEN bytes of
133*4882a593Smuzhiyun * current_ap_addr before the re-assoc ies.
134*4882a593Smuzhiyun */
135*4882a593Smuzhiyun len = ETH_ALEN;
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun if (len != -1) {
138*4882a593Smuzhiyun sinfo->assoc_req_ies = &event->data[len];
139*4882a593Smuzhiyun len = (u8 *)sinfo->assoc_req_ies -
140*4882a593Smuzhiyun (u8 *)&event->frame_control;
141*4882a593Smuzhiyun sinfo->assoc_req_ies_len =
142*4882a593Smuzhiyun le16_to_cpu(event->len) - (u16)len;
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun }
145*4882a593Smuzhiyun cfg80211_new_sta(priv->netdev, event->sta_addr, sinfo,
146*4882a593Smuzhiyun GFP_KERNEL);
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun node = mwifiex_add_sta_entry(priv, event->sta_addr);
149*4882a593Smuzhiyun if (!node) {
150*4882a593Smuzhiyun mwifiex_dbg(adapter, ERROR,
151*4882a593Smuzhiyun "could not create station entry!\n");
152*4882a593Smuzhiyun kfree(sinfo);
153*4882a593Smuzhiyun return -1;
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun if (!priv->ap_11n_enabled) {
157*4882a593Smuzhiyun kfree(sinfo);
158*4882a593Smuzhiyun break;
159*4882a593Smuzhiyun }
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun mwifiex_set_sta_ht_cap(priv, sinfo->assoc_req_ies,
162*4882a593Smuzhiyun sinfo->assoc_req_ies_len, node);
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun for (i = 0; i < MAX_NUM_TID; i++) {
165*4882a593Smuzhiyun if (node->is_11n_enabled)
166*4882a593Smuzhiyun node->ampdu_sta[i] =
167*4882a593Smuzhiyun priv->aggr_prio_tbl[i].ampdu_user;
168*4882a593Smuzhiyun else
169*4882a593Smuzhiyun node->ampdu_sta[i] = BA_STREAM_NOT_ALLOWED;
170*4882a593Smuzhiyun }
171*4882a593Smuzhiyun memset(node->rx_seq, 0xff, sizeof(node->rx_seq));
172*4882a593Smuzhiyun kfree(sinfo);
173*4882a593Smuzhiyun break;
174*4882a593Smuzhiyun case EVENT_UAP_STA_DEAUTH:
175*4882a593Smuzhiyun deauth_mac = adapter->event_body +
176*4882a593Smuzhiyun MWIFIEX_UAP_EVENT_EXTRA_HEADER;
177*4882a593Smuzhiyun cfg80211_del_sta(priv->netdev, deauth_mac, GFP_KERNEL);
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun if (priv->ap_11n_enabled) {
180*4882a593Smuzhiyun mwifiex_11n_del_rx_reorder_tbl_by_ta(priv, deauth_mac);
181*4882a593Smuzhiyun mwifiex_del_tx_ba_stream_tbl_by_ra(priv, deauth_mac);
182*4882a593Smuzhiyun }
183*4882a593Smuzhiyun mwifiex_wmm_del_peer_ra_list(priv, deauth_mac);
184*4882a593Smuzhiyun mwifiex_del_sta_entry(priv, deauth_mac);
185*4882a593Smuzhiyun break;
186*4882a593Smuzhiyun case EVENT_UAP_BSS_IDLE:
187*4882a593Smuzhiyun priv->media_connected = false;
188*4882a593Smuzhiyun priv->port_open = false;
189*4882a593Smuzhiyun mwifiex_clean_txrx(priv);
190*4882a593Smuzhiyun mwifiex_del_all_sta_list(priv);
191*4882a593Smuzhiyun break;
192*4882a593Smuzhiyun case EVENT_UAP_BSS_ACTIVE:
193*4882a593Smuzhiyun priv->media_connected = true;
194*4882a593Smuzhiyun priv->port_open = true;
195*4882a593Smuzhiyun break;
196*4882a593Smuzhiyun case EVENT_UAP_BSS_START:
197*4882a593Smuzhiyun mwifiex_dbg(adapter, EVENT,
198*4882a593Smuzhiyun "AP EVENT: event id: %#x\n", eventcause);
199*4882a593Smuzhiyun priv->port_open = false;
200*4882a593Smuzhiyun memcpy(priv->netdev->dev_addr, adapter->event_body + 2,
201*4882a593Smuzhiyun ETH_ALEN);
202*4882a593Smuzhiyun if (priv->hist_data)
203*4882a593Smuzhiyun mwifiex_hist_data_reset(priv);
204*4882a593Smuzhiyun mwifiex_check_uap_capabilities(priv, adapter->event_skb);
205*4882a593Smuzhiyun break;
206*4882a593Smuzhiyun case EVENT_UAP_MIC_COUNTERMEASURES:
207*4882a593Smuzhiyun /* For future development */
208*4882a593Smuzhiyun mwifiex_dbg(adapter, EVENT,
209*4882a593Smuzhiyun "AP EVENT: event id: %#x\n", eventcause);
210*4882a593Smuzhiyun break;
211*4882a593Smuzhiyun case EVENT_AMSDU_AGGR_CTRL:
212*4882a593Smuzhiyun ctrl = get_unaligned_le16(adapter->event_body);
213*4882a593Smuzhiyun mwifiex_dbg(adapter, EVENT,
214*4882a593Smuzhiyun "event: AMSDU_AGGR_CTRL %d\n", ctrl);
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun if (priv->media_connected) {
217*4882a593Smuzhiyun adapter->tx_buf_size =
218*4882a593Smuzhiyun min_t(u16, adapter->curr_tx_buf_size, ctrl);
219*4882a593Smuzhiyun mwifiex_dbg(adapter, EVENT,
220*4882a593Smuzhiyun "event: tx_buf_size %d\n",
221*4882a593Smuzhiyun adapter->tx_buf_size);
222*4882a593Smuzhiyun }
223*4882a593Smuzhiyun break;
224*4882a593Smuzhiyun case EVENT_ADDBA:
225*4882a593Smuzhiyun mwifiex_dbg(adapter, EVENT, "event: ADDBA Request\n");
226*4882a593Smuzhiyun if (priv->media_connected)
227*4882a593Smuzhiyun mwifiex_send_cmd(priv, HostCmd_CMD_11N_ADDBA_RSP,
228*4882a593Smuzhiyun HostCmd_ACT_GEN_SET, 0,
229*4882a593Smuzhiyun adapter->event_body, false);
230*4882a593Smuzhiyun break;
231*4882a593Smuzhiyun case EVENT_DELBA:
232*4882a593Smuzhiyun mwifiex_dbg(adapter, EVENT, "event: DELBA Request\n");
233*4882a593Smuzhiyun if (priv->media_connected)
234*4882a593Smuzhiyun mwifiex_11n_delete_ba_stream(priv, adapter->event_body);
235*4882a593Smuzhiyun break;
236*4882a593Smuzhiyun case EVENT_BA_STREAM_TIEMOUT:
237*4882a593Smuzhiyun mwifiex_dbg(adapter, EVENT, "event: BA Stream timeout\n");
238*4882a593Smuzhiyun if (priv->media_connected) {
239*4882a593Smuzhiyun ba_timeout = (void *)adapter->event_body;
240*4882a593Smuzhiyun mwifiex_11n_ba_stream_timeout(priv, ba_timeout);
241*4882a593Smuzhiyun }
242*4882a593Smuzhiyun break;
243*4882a593Smuzhiyun case EVENT_EXT_SCAN_REPORT:
244*4882a593Smuzhiyun mwifiex_dbg(adapter, EVENT, "event: EXT_SCAN Report\n");
245*4882a593Smuzhiyun if (adapter->ext_scan)
246*4882a593Smuzhiyun return mwifiex_handle_event_ext_scan_report(priv,
247*4882a593Smuzhiyun adapter->event_skb->data);
248*4882a593Smuzhiyun break;
249*4882a593Smuzhiyun case EVENT_TX_STATUS_REPORT:
250*4882a593Smuzhiyun mwifiex_dbg(adapter, EVENT, "event: TX_STATUS Report\n");
251*4882a593Smuzhiyun mwifiex_parse_tx_status_event(priv, adapter->event_body);
252*4882a593Smuzhiyun break;
253*4882a593Smuzhiyun case EVENT_PS_SLEEP:
254*4882a593Smuzhiyun mwifiex_dbg(adapter, EVENT, "info: EVENT: SLEEP\n");
255*4882a593Smuzhiyun
256*4882a593Smuzhiyun adapter->ps_state = PS_STATE_PRE_SLEEP;
257*4882a593Smuzhiyun
258*4882a593Smuzhiyun mwifiex_check_ps_cond(adapter);
259*4882a593Smuzhiyun break;
260*4882a593Smuzhiyun
261*4882a593Smuzhiyun case EVENT_PS_AWAKE:
262*4882a593Smuzhiyun mwifiex_dbg(adapter, EVENT, "info: EVENT: AWAKE\n");
263*4882a593Smuzhiyun if (!adapter->pps_uapsd_mode &&
264*4882a593Smuzhiyun priv->media_connected && adapter->sleep_period.period) {
265*4882a593Smuzhiyun adapter->pps_uapsd_mode = true;
266*4882a593Smuzhiyun mwifiex_dbg(adapter, EVENT,
267*4882a593Smuzhiyun "event: PPS/UAPSD mode activated\n");
268*4882a593Smuzhiyun }
269*4882a593Smuzhiyun adapter->tx_lock_flag = false;
270*4882a593Smuzhiyun if (adapter->pps_uapsd_mode && adapter->gen_null_pkt) {
271*4882a593Smuzhiyun if (mwifiex_check_last_packet_indication(priv)) {
272*4882a593Smuzhiyun if (adapter->data_sent ||
273*4882a593Smuzhiyun (adapter->if_ops.is_port_ready &&
274*4882a593Smuzhiyun !adapter->if_ops.is_port_ready(priv))) {
275*4882a593Smuzhiyun adapter->ps_state = PS_STATE_AWAKE;
276*4882a593Smuzhiyun adapter->pm_wakeup_card_req = false;
277*4882a593Smuzhiyun adapter->pm_wakeup_fw_try = false;
278*4882a593Smuzhiyun break;
279*4882a593Smuzhiyun }
280*4882a593Smuzhiyun if (!mwifiex_send_null_packet
281*4882a593Smuzhiyun (priv,
282*4882a593Smuzhiyun MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET |
283*4882a593Smuzhiyun MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET))
284*4882a593Smuzhiyun adapter->ps_state =
285*4882a593Smuzhiyun PS_STATE_SLEEP;
286*4882a593Smuzhiyun return 0;
287*4882a593Smuzhiyun }
288*4882a593Smuzhiyun }
289*4882a593Smuzhiyun adapter->ps_state = PS_STATE_AWAKE;
290*4882a593Smuzhiyun adapter->pm_wakeup_card_req = false;
291*4882a593Smuzhiyun adapter->pm_wakeup_fw_try = false;
292*4882a593Smuzhiyun break;
293*4882a593Smuzhiyun
294*4882a593Smuzhiyun case EVENT_CHANNEL_REPORT_RDY:
295*4882a593Smuzhiyun mwifiex_dbg(adapter, EVENT, "event: Channel Report\n");
296*4882a593Smuzhiyun mwifiex_11h_handle_chanrpt_ready(priv, adapter->event_skb);
297*4882a593Smuzhiyun break;
298*4882a593Smuzhiyun case EVENT_RADAR_DETECTED:
299*4882a593Smuzhiyun mwifiex_dbg(adapter, EVENT, "event: Radar detected\n");
300*4882a593Smuzhiyun mwifiex_11h_handle_radar_detected(priv, adapter->event_skb);
301*4882a593Smuzhiyun break;
302*4882a593Smuzhiyun case EVENT_BT_COEX_WLAN_PARA_CHANGE:
303*4882a593Smuzhiyun mwifiex_dbg(adapter, EVENT, "event: BT coex wlan param update\n");
304*4882a593Smuzhiyun mwifiex_bt_coex_wlan_param_update_event(priv,
305*4882a593Smuzhiyun adapter->event_skb);
306*4882a593Smuzhiyun break;
307*4882a593Smuzhiyun case EVENT_TX_DATA_PAUSE:
308*4882a593Smuzhiyun mwifiex_dbg(adapter, EVENT, "event: TX DATA PAUSE\n");
309*4882a593Smuzhiyun mwifiex_process_tx_pause_event(priv, adapter->event_skb);
310*4882a593Smuzhiyun break;
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun case EVENT_MULTI_CHAN_INFO:
313*4882a593Smuzhiyun mwifiex_dbg(adapter, EVENT, "event: multi-chan info\n");
314*4882a593Smuzhiyun mwifiex_process_multi_chan_event(priv, adapter->event_skb);
315*4882a593Smuzhiyun break;
316*4882a593Smuzhiyun case EVENT_RXBA_SYNC:
317*4882a593Smuzhiyun dev_dbg(adapter->dev, "EVENT: RXBA_SYNC\n");
318*4882a593Smuzhiyun mwifiex_11n_rxba_sync_event(priv, adapter->event_body,
319*4882a593Smuzhiyun adapter->event_skb->len -
320*4882a593Smuzhiyun sizeof(eventcause));
321*4882a593Smuzhiyun break;
322*4882a593Smuzhiyun
323*4882a593Smuzhiyun case EVENT_REMAIN_ON_CHAN_EXPIRED:
324*4882a593Smuzhiyun mwifiex_dbg(adapter, EVENT,
325*4882a593Smuzhiyun "event: uap: Remain on channel expired\n");
326*4882a593Smuzhiyun cfg80211_remain_on_channel_expired(&priv->wdev,
327*4882a593Smuzhiyun priv->roc_cfg.cookie,
328*4882a593Smuzhiyun &priv->roc_cfg.chan,
329*4882a593Smuzhiyun GFP_ATOMIC);
330*4882a593Smuzhiyun memset(&priv->roc_cfg, 0x00, sizeof(struct mwifiex_roc_cfg));
331*4882a593Smuzhiyun break;
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun default:
334*4882a593Smuzhiyun mwifiex_dbg(adapter, EVENT,
335*4882a593Smuzhiyun "event: unknown event id: %#x\n", eventcause);
336*4882a593Smuzhiyun break;
337*4882a593Smuzhiyun }
338*4882a593Smuzhiyun
339*4882a593Smuzhiyun return 0;
340*4882a593Smuzhiyun }
341*4882a593Smuzhiyun
342*4882a593Smuzhiyun /* This function deletes station entry from associated station list.
343*4882a593Smuzhiyun * Also if both AP and STA are 11n enabled, RxReorder tables and TxBA stream
344*4882a593Smuzhiyun * tables created for this station are deleted.
345*4882a593Smuzhiyun */
mwifiex_uap_del_sta_data(struct mwifiex_private * priv,struct mwifiex_sta_node * node)346*4882a593Smuzhiyun void mwifiex_uap_del_sta_data(struct mwifiex_private *priv,
347*4882a593Smuzhiyun struct mwifiex_sta_node *node)
348*4882a593Smuzhiyun {
349*4882a593Smuzhiyun if (priv->ap_11n_enabled && node->is_11n_enabled) {
350*4882a593Smuzhiyun mwifiex_11n_del_rx_reorder_tbl_by_ta(priv, node->mac_addr);
351*4882a593Smuzhiyun mwifiex_del_tx_ba_stream_tbl_by_ra(priv, node->mac_addr);
352*4882a593Smuzhiyun }
353*4882a593Smuzhiyun mwifiex_del_sta_entry(priv, node->mac_addr);
354*4882a593Smuzhiyun
355*4882a593Smuzhiyun return;
356*4882a593Smuzhiyun }
357