xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/marvell/mwifiex/uap_event.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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