1 /** @file mlan_sta_event.c
2 *
3 * @brief This file contains MLAN event handling.
4 *
5 *
6 * Copyright 2008-2022 NXP
7 *
8 * This software file (the File) is distributed by NXP
9 * under the terms of the GNU General Public License Version 2, June 1991
10 * (the License). You may use, redistribute and/or modify the File in
11 * accordance with the terms and conditions of the License, a copy of which
12 * is available by writing to the Free Software Foundation, Inc.,
13 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
14 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
15 *
16 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
18 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
19 * this warranty disclaimer.
20 *
21 */
22
23 /********************************************************
24 Change log:
25 10/13/2008: initial version
26 ********************************************************/
27
28 #include "mlan.h"
29 #include "mlan_join.h"
30 #include "mlan_util.h"
31 #include "mlan_fw.h"
32 #include "mlan_main.h"
33 #include "mlan_wmm.h"
34 #include "mlan_11n.h"
35 #include "mlan_11h.h"
36 #ifdef DRV_EMBEDDED_SUPPLICANT
37 #include "authenticator_api.h"
38 #endif
39 #ifdef PCIE
40 #include "mlan_pcie.h"
41 #endif /* PCIE */
42
43 /********************************************************
44 Global Variables
45 ********************************************************/
46
47 /********************************************************
48 Local Functions
49 ********************************************************/
50
51 /**
52 * @brief This function handles link lost, deauth and
53 * disassoc events.
54 *
55 * @param pmpriv A pointer to mlan_private structure
56 * @return N/A
57 */
wlan_handle_disconnect_event(pmlan_private pmpriv)58 static t_void wlan_handle_disconnect_event(pmlan_private pmpriv)
59 {
60 ENTER();
61
62 if (pmpriv->media_connected == MTRUE)
63 wlan_reset_connect_state(pmpriv, MTRUE);
64
65 LEAVE();
66 }
67
68 /**
69 * @brief This function will parse the TDLS event for further wlan action
70 *
71 * @param priv A pointer to mlan_private
72 * @param pevent A pointer to event buf
73 *
74 * @return N/A
75 */
wlan_parse_tdls_event(pmlan_private priv,pmlan_buffer pevent)76 static void wlan_parse_tdls_event(pmlan_private priv, pmlan_buffer pevent)
77 {
78 Event_tdls_generic *tdls_event =
79 (Event_tdls_generic *)(pevent->pbuf + pevent->data_offset +
80 sizeof(mlan_event_id));
81 sta_node *sta_ptr = MNULL;
82 pmlan_adapter pmadapter = priv->adapter;
83 t_u8 i = 0;
84 IEEEtypes_HTCap_t *pht_cap = MNULL;
85 t_u16 ie_len = 0;
86 mlan_ds_misc_tdls_oper tdls_oper;
87 t_u8 event_buf[100];
88 mlan_event *ptdls_event = (mlan_event *)event_buf;
89 tdls_tear_down_event *tdls_evt =
90 (tdls_tear_down_event *)ptdls_event->event_buf;
91 ENTER();
92
93 /* reason code is not mandatory, hence less by sizeof(t_u16) */
94 if (pevent->data_len < (sizeof(Event_tdls_generic) - sizeof(t_u16) -
95 sizeof(mlan_event_id))) {
96 PRINTM(MERROR, "Invalid length %d for TDLS event\n",
97 pevent->data_len);
98 LEAVE();
99 return;
100 }
101 sta_ptr = wlan_get_station_entry(priv, tdls_event->peer_mac_addr);
102 PRINTM(MEVENT, "TDLS_EVENT: %d " MACSTR "\n",
103 wlan_le16_to_cpu(tdls_event->event_type),
104 MAC2STR(tdls_event->peer_mac_addr));
105 switch (wlan_le16_to_cpu(tdls_event->event_type)) {
106 case TDLS_EVENT_TYPE_SETUP_REQ:
107 if (sta_ptr == MNULL) {
108 sta_ptr = wlan_add_station_entry(
109 priv, tdls_event->peer_mac_addr);
110 if (sta_ptr) {
111 sta_ptr->status = TDLS_SETUP_INPROGRESS;
112 wlan_hold_tdls_packets(
113 priv, tdls_event->peer_mac_addr);
114 }
115 }
116 break;
117
118 case TDLS_EVENT_TYPE_LINK_ESTABLISHED:
119 if (sta_ptr) {
120 sta_ptr->status = TDLS_SETUP_COMPLETE;
121 /* parse the TLV for station's capability */
122 ie_len = wlan_le16_to_cpu(
123 tdls_event->u.ie_data.ie_length);
124 if (ie_len) {
125 pht_cap = (IEEEtypes_HTCap_t *)
126 wlan_get_specific_ie(
127 priv,
128 tdls_event->u.ie_data.ie_ptr,
129 ie_len, HT_CAPABILITY, 0);
130 if (pht_cap) {
131 sta_ptr->is_11n_enabled = MTRUE;
132 if (GETHT_MAXAMSDU(
133 pht_cap->ht_cap.ht_cap_info))
134 sta_ptr->max_amsdu =
135 MLAN_TX_DATA_BUF_SIZE_8K;
136 else
137 sta_ptr->max_amsdu =
138 MLAN_TX_DATA_BUF_SIZE_4K;
139 }
140 }
141 for (i = 0; i < MAX_NUM_TID; i++) {
142 if (sta_ptr->is_11n_enabled ||
143 sta_ptr->is_11ax_enabled)
144 sta_ptr->ampdu_sta[i] =
145 priv->aggr_prio_tbl[i]
146 .ampdu_user;
147 else
148 sta_ptr->ampdu_sta[i] =
149 BA_STREAM_NOT_ALLOWED;
150 }
151 memset(priv->adapter, sta_ptr->rx_seq, 0xff,
152 sizeof(sta_ptr->rx_seq));
153 wlan_restore_tdls_packets(priv,
154 tdls_event->peer_mac_addr,
155 TDLS_SETUP_COMPLETE);
156 pmadapter->tdls_status = TDLS_IN_BASE_CHANNEL;
157 }
158 break;
159
160 case TDLS_EVENT_TYPE_SETUP_FAILURE:
161 wlan_restore_tdls_packets(priv, tdls_event->peer_mac_addr,
162 TDLS_SETUP_FAILURE);
163 if (sta_ptr)
164 wlan_delete_station_entry(priv,
165 tdls_event->peer_mac_addr);
166 if (MTRUE == wlan_is_station_list_empty(priv))
167 pmadapter->tdls_status = TDLS_NOT_SETUP;
168 else
169 pmadapter->tdls_status = TDLS_IN_BASE_CHANNEL;
170 break;
171 case TDLS_EVENT_TYPE_LINK_TORN_DOWN:
172 if (sta_ptr) {
173 if (sta_ptr->external_tdls) {
174 PRINTM(MMSG,
175 "Receive TDLS TEAR DOWN event, Disable TDLS LINK\n");
176 pmadapter->tdls_status = TDLS_TEAR_DOWN;
177 memset(pmadapter, &tdls_oper, 0,
178 sizeof(tdls_oper));
179 tdls_oper.tdls_action = WLAN_TDLS_DISABLE_LINK;
180 memcpy_ext(priv->adapter, tdls_oper.peer_mac,
181 tdls_event->peer_mac_addr,
182 MLAN_MAC_ADDR_LENGTH,
183 MLAN_MAC_ADDR_LENGTH);
184 /* Send command to firmware to delete tdls
185 * link*/
186 wlan_prepare_cmd(priv,
187 HostCmd_CMD_TDLS_OPERATION,
188 HostCmd_ACT_GEN_SET, 0,
189 (t_void *)MNULL, &tdls_oper);
190 ptdls_event->bss_index = priv->bss_index;
191 ptdls_event->event_id =
192 MLAN_EVENT_ID_DRV_TDLS_TEARDOWN_REQ;
193 ptdls_event->event_len =
194 sizeof(tdls_tear_down_event);
195 memcpy_ext(priv->adapter,
196 (t_u8 *)tdls_evt->peer_mac_addr,
197 tdls_event->peer_mac_addr,
198 MLAN_MAC_ADDR_LENGTH,
199 MLAN_MAC_ADDR_LENGTH);
200 tdls_evt->reason_code = wlan_le16_to_cpu(
201 tdls_event->u.reason_code);
202 wlan_recv_event(
203 priv,
204 MLAN_EVENT_ID_DRV_TDLS_TEARDOWN_REQ,
205 ptdls_event);
206 /* Signal MOAL to trigger mlan_main_process */
207 wlan_recv_event(
208 priv, MLAN_EVENT_ID_DRV_DEFER_HANDLING,
209 MNULL);
210 LEAVE();
211 return;
212 }
213 wlan_restore_tdls_packets(priv,
214 tdls_event->peer_mac_addr,
215 TDLS_TEAR_DOWN);
216 if (sta_ptr->is_11n_enabled ||
217 sta_ptr->is_11ax_enabled) {
218 wlan_cleanup_reorder_tbl(
219 priv, tdls_event->peer_mac_addr);
220 wlan_11n_cleanup_txbastream_tbl(
221 priv, tdls_event->peer_mac_addr);
222 }
223 wlan_delete_station_entry(priv,
224 tdls_event->peer_mac_addr);
225 if (MTRUE == wlan_is_station_list_empty(priv))
226 pmadapter->tdls_status = TDLS_NOT_SETUP;
227 else
228 pmadapter->tdls_status = TDLS_IN_BASE_CHANNEL;
229 }
230 break;
231 case TDLS_EVENT_TYPE_CHAN_SWITCH_RESULT:
232 PRINTM(MEVENT,
233 "TDLS_CHAN_SWITCH_RESULT: status=0x%x, reason=0x%x current_channel=%d\n",
234 tdls_event->u.switch_result.status,
235 tdls_event->u.switch_result.reason,
236 (int)tdls_event->u.switch_result.current_channel);
237 if (tdls_event->u.switch_result.status == MLAN_STATUS_SUCCESS) {
238 if (tdls_event->u.switch_result.current_channel ==
239 TDLS_BASE_CHANNEL) {
240 /* enable traffic to AP */
241 if (pmadapter->tdls_status !=
242 TDLS_IN_BASE_CHANNEL) {
243 wlan_update_non_tdls_ralist(
244 priv, tdls_event->peer_mac_addr,
245 MFALSE);
246 pmadapter->tdls_status =
247 TDLS_IN_BASE_CHANNEL;
248 }
249 } else if (tdls_event->u.switch_result.current_channel ==
250 TDLS_OFF_CHANNEL) {
251 /* pause traffic to AP */
252 if (pmadapter->tdls_status !=
253 TDLS_IN_OFF_CHANNEL) {
254 wlan_update_non_tdls_ralist(
255 priv, tdls_event->peer_mac_addr,
256 MTRUE);
257 pmadapter->tdls_status =
258 TDLS_IN_OFF_CHANNEL;
259 }
260 }
261 } else {
262 if (tdls_event->u.switch_result.current_channel ==
263 TDLS_BASE_CHANNEL)
264 pmadapter->tdls_status = TDLS_IN_BASE_CHANNEL;
265 else if (tdls_event->u.switch_result.current_channel ==
266 TDLS_OFF_CHANNEL)
267 pmadapter->tdls_status = TDLS_IN_OFF_CHANNEL;
268 }
269 break;
270 case TDLS_EVENT_TYPE_START_CHAN_SWITCH:
271 PRINTM(MEVENT, "TDLS start channel switch....\n");
272 pmadapter->tdls_status = TDLS_SWITCHING_CHANNEL;
273 break;
274 case TDLS_EVENT_TYPE_CHAN_SWITCH_STOPPED:
275 PRINTM(MEVENT, "TDLS channel switch stopped, reason=%d\n",
276 tdls_event->u.cs_stop_reason);
277 break;
278 case TDLS_EVENT_TYPE_DEBUG:
279 case TDLS_EVENT_TYPE_PACKET:
280 break;
281 default:
282 PRINTM(MERROR, "unknown event type %d\n",
283 wlan_le16_to_cpu(tdls_event->event_type));
284 break;
285 }
286 LEAVE();
287 }
288
289 /**
290 * @brief This function send the tdls teardown request event.
291 *
292 * @param priv A pointer to mlan_private
293 *
294 * @return N/A
295 */
wlan_send_tdls_tear_down_request(pmlan_private priv)296 static void wlan_send_tdls_tear_down_request(pmlan_private priv)
297 {
298 t_u8 event_buf[100];
299 mlan_event *ptdls_event = (mlan_event *)event_buf;
300 tdls_tear_down_event *tdls_evt =
301 (tdls_tear_down_event *)ptdls_event->event_buf;
302 sta_node *sta_ptr = MNULL;
303
304 ENTER();
305
306 sta_ptr = (sta_node *)util_peek_list(
307 priv->adapter->pmoal_handle, &priv->sta_list,
308 priv->adapter->callbacks.moal_spin_lock,
309 priv->adapter->callbacks.moal_spin_unlock);
310 if (!sta_ptr) {
311 LEAVE();
312 return;
313 }
314 while (sta_ptr != (sta_node *)&priv->sta_list) {
315 if (sta_ptr->external_tdls) {
316 ptdls_event->bss_index = priv->bss_index;
317 ptdls_event->event_id =
318 MLAN_EVENT_ID_DRV_TDLS_TEARDOWN_REQ;
319 ptdls_event->event_len = sizeof(tdls_tear_down_event);
320 memcpy_ext(priv->adapter,
321 (t_u8 *)tdls_evt->peer_mac_addr,
322 sta_ptr->mac_addr, MLAN_MAC_ADDR_LENGTH,
323 MLAN_MAC_ADDR_LENGTH);
324 tdls_evt->reason_code =
325 MLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED;
326 wlan_recv_event(priv,
327 MLAN_EVENT_ID_DRV_TDLS_TEARDOWN_REQ,
328 ptdls_event);
329 }
330 sta_ptr = sta_ptr->pnext;
331 }
332 LEAVE();
333 return;
334 }
335
336 /********************************************************
337 Global Functions
338 ********************************************************/
339 /**
340 * @brief This function handles disconnect event, reports disconnect
341 * to upper layer, cleans tx/rx packets,
342 * resets link state etc.
343 *
344 * @param priv A pointer to mlan_private structure
345 * @param drv_disconnect Flag indicating the driver should disconnect
346 * and flush pending packets.
347 *
348 * @return N/A
349 */
wlan_reset_connect_state(pmlan_private priv,t_u8 drv_disconnect)350 t_void wlan_reset_connect_state(pmlan_private priv, t_u8 drv_disconnect)
351 {
352 mlan_adapter *pmadapter = priv->adapter;
353 mlan_status ret = MLAN_STATUS_SUCCESS;
354 state_11d_t enable;
355 t_u8 event_buf[100];
356 mlan_event *pevent = (mlan_event *)event_buf;
357
358 ENTER();
359
360 PRINTM(MINFO, "Handles disconnect event.\n");
361
362 #ifdef UAP_SUPPORT
363 /* If DFS repeater mode is enabled and station interface disconnects
364 * then make sure that all uAPs are stopped.
365 */
366 if (pmadapter->dfs_repeater)
367 wlan_dfs_rep_disconnect(pmadapter);
368 #endif
369
370 if (drv_disconnect) {
371 priv->media_connected = MFALSE;
372 pmadapter->state_rdh.tx_block = MFALSE;
373 #ifdef UAP_SUPPORT
374 if (pmadapter->dfs_mode)
375 wlan_11h_update_dfs_master_state_on_disconect(priv);
376 else
377 #endif
378 wlan_11h_check_update_radar_det_state(priv);
379 }
380
381 if (priv->port_ctrl_mode == MTRUE) {
382 /* Close the port on Disconnect */
383 PRINTM(MINFO, "DISC: port_status = CLOSED\n");
384 priv->port_open = MFALSE;
385 }
386 memset(pmadapter, &priv->gtk_rekey, 0,
387 sizeof(mlan_ds_misc_gtk_rekey_data));
388 priv->tx_pause = MFALSE;
389 pmadapter->scan_block = MFALSE;
390
391 /* Reset SNR/NF/RSSI values */
392 priv->data_rssi_last = 0;
393 priv->data_nf_last = 0;
394 priv->data_rssi_avg = 0;
395 priv->data_nf_avg = 0;
396 priv->bcn_rssi_last = 0;
397 priv->bcn_nf_last = 0;
398 priv->bcn_rssi_avg = 0;
399 priv->bcn_nf_avg = 0;
400 priv->rxpd_rate = 0;
401 priv->rxpd_rate_info = 0;
402 priv->max_amsdu = 0;
403 priv->amsdu_disable = MFALSE;
404 wlan_coex_ampdu_rxwinsize(pmadapter);
405
406 priv->sec_info.ewpa_enabled = MFALSE;
407 priv->sec_info.wpa_enabled = MFALSE;
408 priv->sec_info.wpa2_enabled = MFALSE;
409 priv->wpa_ie_len = 0;
410 #ifdef DRV_EMBEDDED_SUPPLICANT
411 supplicantStopSessionTimer(priv->psapriv);
412 supplicantClrEncryptKey(priv->psapriv);
413 supplicantDisable(priv->psapriv);
414 #endif
415
416 priv->sec_info.wapi_enabled = MFALSE;
417 priv->wapi_ie_len = 0;
418 priv->sec_info.wapi_key_on = MFALSE;
419
420 priv->wps.session_enable = MFALSE;
421 memset(priv->adapter, (t_u8 *)&priv->wps.wps_ie, 0x00,
422 sizeof(priv->wps.wps_ie));
423 priv->sec_info.osen_enabled = MFALSE;
424 priv->osen_ie_len = 0;
425
426 priv->sec_info.encryption_mode = MLAN_ENCRYPTION_MODE_NONE;
427
428 /*Enable auto data rate */
429 priv->is_data_rate_auto = MTRUE;
430 priv->data_rate = 0;
431
432 if (priv->bss_mode == MLAN_BSS_MODE_IBSS) {
433 priv->adhoc_state = ADHOC_IDLE;
434 priv->adhoc_is_link_sensed = MFALSE;
435 priv->intf_state_11h.adhoc_auto_sel_chan = MTRUE;
436 }
437
438 if (drv_disconnect) {
439 /* Free Tx and Rx packets, report disconnect to upper layer */
440 wlan_clean_txrx(priv);
441
442 /* Need to erase the current SSID and BSSID info */
443 memset(pmadapter, &priv->curr_bss_params, 0x00,
444 sizeof(priv->curr_bss_params));
445 }
446 wlan_send_tdls_tear_down_request(priv);
447 wlan_delete_station_list(priv);
448 pmadapter->tdls_status = TDLS_NOT_SETUP;
449 priv->wmm_qosinfo = priv->saved_wmm_qosinfo;
450 pmadapter->sleep_period.period = pmadapter->saved_sleep_period.period;
451 pmadapter->tx_lock_flag = MFALSE;
452 pmadapter->pps_uapsd_mode = MFALSE;
453 pmadapter->delay_null_pkt = MFALSE;
454
455 if ((wlan_fw_11d_is_enabled(priv)) &&
456 (priv->state_11d.user_enable_11d == DISABLE_11D)) {
457 priv->state_11d.enable_11d = DISABLE_11D;
458 enable = DISABLE_11D;
459
460 /* Send cmd to FW to enable/disable 11D function */
461 ret = wlan_prepare_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
462 HostCmd_ACT_GEN_SET, Dot11D_i, MNULL,
463 &enable);
464 if (ret)
465 PRINTM(MERROR, "11D: Failed to enable 11D\n");
466 }
467 if (pmadapter->num_cmd_timeout && pmadapter->curr_cmd &&
468 (pmadapter->cmd_timer_is_set == MFALSE)) {
469 LEAVE();
470 return;
471 }
472
473 if (pmadapter->pending_disconnect_priv) {
474 LEAVE();
475 return;
476 }
477
478 pevent->bss_index = priv->bss_index;
479 pevent->event_id = MLAN_EVENT_ID_FW_DISCONNECTED;
480 pevent->event_len = sizeof(priv->disconnect_reason_code);
481 memcpy_ext(priv->adapter, pevent->event_buf,
482 &priv->disconnect_reason_code, pevent->event_len,
483 pevent->event_len);
484 wlan_recv_event(priv, MLAN_EVENT_ID_FW_DISCONNECTED, pevent);
485 priv->disconnect_reason_code = 0;
486
487 LEAVE();
488 }
489
490 /**
491 * @brief This function sends the OBSS scan parameters to the application
492 *
493 * @param pmpriv A pointer to mlan_private structure
494 *
495 * @return N/A
496 */
wlan_2040_coex_event(pmlan_private pmpriv)497 t_void wlan_2040_coex_event(pmlan_private pmpriv)
498 {
499 t_u8 event_buf[100];
500 mlan_event *pevent = (mlan_event *)event_buf;
501 t_u8 ele_len;
502
503 ENTER();
504
505 if (pmpriv->curr_bss_params.bss_descriptor.poverlap_bss_scan_param &&
506 pmpriv->curr_bss_params.bss_descriptor.poverlap_bss_scan_param
507 ->ieee_hdr.element_id == OVERLAPBSSSCANPARAM) {
508 ele_len = pmpriv->curr_bss_params.bss_descriptor
509 .poverlap_bss_scan_param->ieee_hdr.len;
510 pevent->bss_index = pmpriv->bss_index;
511 pevent->event_id = MLAN_EVENT_ID_DRV_OBSS_SCAN_PARAM;
512 pevent->event_len = ele_len;
513 /* Copy OBSS scan parameters */
514 memcpy_ext(pmpriv->adapter, (t_u8 *)pevent->event_buf,
515 (t_u8 *)&pmpriv->curr_bss_params.bss_descriptor
516 .poverlap_bss_scan_param->obss_scan_param,
517 ele_len, pevent->event_len);
518 wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_OBSS_SCAN_PARAM,
519 pevent);
520 }
521
522 LEAVE();
523 }
524
525 /**
526 * @brief This function will process tx pause event
527 *
528 * @param priv A pointer to mlan_private
529 * @param pevent A pointer to event buf
530 *
531 * @return N/A
532 */
wlan_process_sta_tx_pause_event(pmlan_private priv,pmlan_buffer pevent)533 static void wlan_process_sta_tx_pause_event(pmlan_private priv,
534 pmlan_buffer pevent)
535 {
536 t_u16 tlv_type, tlv_len;
537 int tlv_buf_left = pevent->data_len - sizeof(t_u32);
538 MrvlIEtypesHeader_t *tlv =
539 (MrvlIEtypesHeader_t *)(pevent->pbuf + pevent->data_offset +
540 sizeof(t_u32));
541 MrvlIEtypes_tx_pause_t *tx_pause_tlv;
542 sta_node *sta_ptr = MNULL;
543 tdlsStatus_e status;
544 t_u8 *bssid = MNULL;
545 ENTER();
546 if (priv->media_connected)
547 bssid = priv->curr_bss_params.bss_descriptor.mac_address;
548 while (tlv_buf_left >= (int)sizeof(MrvlIEtypesHeader_t)) {
549 tlv_type = wlan_le16_to_cpu(tlv->type);
550 tlv_len = wlan_le16_to_cpu(tlv->len);
551 if ((sizeof(MrvlIEtypesHeader_t) + tlv_len) >
552 (unsigned int)tlv_buf_left) {
553 PRINTM(MERROR, "wrong tlv: tlvLen=%d, tlvBufLeft=%d\n",
554 tlv_len, tlv_buf_left);
555 break;
556 }
557 if (tlv_type == TLV_TYPE_TX_PAUSE) {
558 tx_pause_tlv = (MrvlIEtypes_tx_pause_t *)tlv;
559 PRINTM(MCMND, "TxPause: " MACSTR " pause=%d, pkts=%d\n",
560 MAC2STR(tx_pause_tlv->peermac),
561 tx_pause_tlv->tx_pause, tx_pause_tlv->pkt_cnt);
562
563 if (bssid &&
564 !memcmp(priv->adapter, bssid, tx_pause_tlv->peermac,
565 MLAN_MAC_ADDR_LENGTH)) {
566 if (tx_pause_tlv->tx_pause)
567 priv->tx_pause = MTRUE;
568 else
569 priv->tx_pause = MFALSE;
570 } else {
571 status = wlan_get_tdls_link_status(
572 priv, tx_pause_tlv->peermac);
573 if (MTRUE == wlan_is_tdls_link_setup(status)) {
574 sta_ptr = wlan_get_station_entry(
575 priv, tx_pause_tlv->peermac);
576 if (sta_ptr) {
577 if (sta_ptr->tx_pause !=
578 tx_pause_tlv->tx_pause) {
579 sta_ptr->tx_pause =
580 tx_pause_tlv
581 ->tx_pause;
582 wlan_update_ralist_tx_pause(
583 priv,
584 tx_pause_tlv
585 ->peermac,
586 tx_pause_tlv
587 ->tx_pause);
588 }
589 }
590 }
591 }
592 }
593 tlv_buf_left -= (sizeof(MrvlIEtypesHeader_t) + tlv_len);
594 tlv = (MrvlIEtypesHeader_t *)((t_u8 *)tlv + tlv_len +
595 sizeof(MrvlIEtypesHeader_t));
596 }
597
598 LEAVE();
599 return;
600 }
601
602 /**
603 * @brief This function will print diconnect reason code according
604 * to IEEE 802.11 spec
605 *
606 * @param reason_code reason code for the deauth/disaccoc
607 * received from firmware
608 * @return N/A
609 */
wlan_print_disconnect_reason(t_u16 reason_code)610 static void wlan_print_disconnect_reason(t_u16 reason_code)
611 {
612 ENTER();
613
614 switch (reason_code) {
615 case MLAN_REASON_UNSPECIFIED:
616 PRINTM(MMSG, "wlan: REASON: Unspecified reason\n");
617 break;
618 case MLAN_REASON_PREV_AUTH_NOT_VALID:
619 PRINTM(MMSG,
620 "wlan: REASON: Previous authentication no longer valid\n");
621 break;
622 case MLAN_REASON_DEAUTH_LEAVING:
623 PRINTM(MMSG,
624 "wlan: REASON: (Deauth) Sending STA is leaving (or has left) IBSS or ESS\n");
625 break;
626 case MLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
627 PRINTM(MMSG,
628 "wlan: REASON: Disassociated due to inactivity \n");
629 break;
630 case MLAN_REASON_DISASSOC_AP_BUSY:
631 PRINTM(MMSG,
632 "wlan: REASON: (Disassociated) AP unable to handle all connected STAs\n");
633 break;
634 case MLAN_REASON_CLASS2_FRAME_FROM_NOAUTH_STA:
635 PRINTM(MMSG,
636 "wlan: REASON: Class 2 frame was received from nonauthenticated STA\n");
637 break;
638 case MLAN_REASON_CLASS3_FRAME_FROM_NOASSOC_STA:
639 PRINTM(MMSG,
640 "wlan: REASON: Class 3 frame was received from nonassociated STA\n");
641 break;
642 case MLAN_REASON_DISASSOC_STA_HAS_LEFT:
643 PRINTM(MMSG,
644 "wlan: REASON: (Disassocated) Sending STA is leaving (or has left) BSS\n");
645 break;
646 case MLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH:
647 PRINTM(MMSG,
648 "wlan: REASON: STA requesting (re)assoc is not authenticated with responding STA\n");
649 break;
650 default:
651 break;
652 }
653
654 LEAVE();
655 return;
656 }
657
658 /**
659 * @brief This function handles events generated by firmware
660 *
661 * @param priv A pointer to mlan_private structure
662 *
663 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
664 */
wlan_ops_sta_process_event(t_void * priv)665 mlan_status wlan_ops_sta_process_event(t_void *priv)
666 {
667 pmlan_private pmpriv = (pmlan_private)priv;
668 pmlan_adapter pmadapter = pmpriv->adapter;
669 mlan_status ret = MLAN_STATUS_SUCCESS;
670 t_u32 eventcause = pmadapter->event_cause;
671 t_u8 *event_buf = MNULL;
672 t_u8 *evt_buf = MNULL;
673 pmlan_buffer pmbuf = pmadapter->pmlan_buffer_event;
674 t_u16 reason_code;
675 pmlan_callbacks pcb = &pmadapter->callbacks;
676 mlan_event *pevent = MNULL;
677 t_u8 addr[MLAN_MAC_ADDR_LENGTH];
678 chan_band_info *pchan_band_info = MNULL;
679 t_u8 radar_chan;
680 t_u16 enable = 0;
681
682 ENTER();
683
684 if (!pmbuf) {
685 LEAVE();
686 return MLAN_STATUS_FAILURE;
687 }
688
689 /* Event length check */
690 if ((pmbuf->data_len - sizeof(eventcause)) > MAX_EVENT_SIZE) {
691 pmbuf->status_code = MLAN_ERROR_PKT_SIZE_INVALID;
692 LEAVE();
693 return MLAN_STATUS_FAILURE;
694 }
695
696 /* Allocate memory for event buffer */
697 ret = pcb->moal_malloc(pmadapter->pmoal_handle,
698 MAX_EVENT_SIZE + sizeof(mlan_event),
699 MLAN_MEM_DEF, &event_buf);
700 if ((ret != MLAN_STATUS_SUCCESS) || !event_buf) {
701 PRINTM(MERROR, "Could not allocate buffer for event buf\n");
702 if (pmbuf)
703 pmbuf->status_code = MLAN_ERROR_NO_MEM;
704 goto done;
705 }
706 pevent = (pmlan_event)event_buf;
707 memset(pmadapter, event_buf, 0, MAX_EVENT_SIZE);
708
709 if (eventcause != EVENT_PS_SLEEP && eventcause != EVENT_PS_AWAKE &&
710 pmbuf->data_len > sizeof(eventcause))
711 DBG_HEXDUMP(MEVT_D, "EVENT", pmbuf->pbuf + pmbuf->data_offset,
712 pmbuf->data_len);
713
714 switch (eventcause) {
715 case EVENT_DUMMY_HOST_WAKEUP_SIGNAL:
716 PRINTM(MERROR,
717 "Invalid EVENT: DUMMY_HOST_WAKEUP_SIGNAL, ignoring it\n");
718 break;
719 case EVENT_LINK_SENSED:
720 PRINTM(MEVENT, "EVENT: LINK_SENSED\n");
721 pmpriv->adhoc_is_link_sensed = MTRUE;
722 wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_ADHOC_LINK_SENSED,
723 MNULL);
724 break;
725
726 case EVENT_DEAUTHENTICATED:
727 if (pmpriv->wps.session_enable) {
728 PRINTM(MMSG,
729 "wlan: Receive deauth event in wps session\n");
730 break;
731 }
732 reason_code = wlan_le16_to_cpu(*(t_u16 *)(pmbuf->pbuf +
733 pmbuf->data_offset +
734 sizeof(eventcause)));
735 PRINTM(MMSG, "wlan: EVENT: Deauthenticated (reason 0x%x)\n",
736 reason_code);
737 wlan_print_disconnect_reason(reason_code);
738 pmpriv->disconnect_reason_code = reason_code;
739 pmadapter->dbg.num_event_deauth++;
740 wlan_handle_disconnect_event(pmpriv);
741
742 break;
743
744 case EVENT_DISASSOCIATED:
745 if (pmpriv->wps.session_enable) {
746 PRINTM(MMSG,
747 "wlan: Receive disassociate event in wps session\n");
748 break;
749 }
750 reason_code = wlan_le16_to_cpu(*(t_u16 *)(pmbuf->pbuf +
751 pmbuf->data_offset +
752 sizeof(eventcause)));
753 PRINTM(MMSG, "wlan: EVENT: Disassociated (reason 0x%x)\n",
754 reason_code);
755 wlan_print_disconnect_reason(reason_code);
756 pmpriv->disconnect_reason_code = reason_code;
757 pmadapter->dbg.num_event_disassoc++;
758 wlan_handle_disconnect_event(pmpriv);
759 break;
760
761 case EVENT_LINK_LOST:
762 reason_code = wlan_le16_to_cpu(*(t_u16 *)(pmbuf->pbuf +
763 pmbuf->data_offset +
764 sizeof(eventcause)));
765 PRINTM(MMSG, "wlan: EVENT: Link lost (reason 0x%x)\n",
766 reason_code);
767 pmpriv->disconnect_reason_code = reason_code;
768 pmadapter->dbg.num_event_link_lost++;
769 wlan_handle_disconnect_event(pmpriv);
770 break;
771
772 case EVENT_PS_SLEEP:
773 PRINTM(MINFO, "EVENT: SLEEP\n");
774 PRINTM_NETINTF(MEVENT, pmpriv);
775 PRINTM(MEVENT, "_");
776
777 /* Handle unexpected PS SLEEP event */
778 if (pmadapter->ps_state == PS_STATE_SLEEP_CFM)
779 break;
780 pmadapter->ps_state = PS_STATE_PRE_SLEEP;
781
782 wlan_check_ps_cond(pmadapter);
783 break;
784
785 case EVENT_PS_AWAKE:
786 PRINTM(MINFO, "EVENT: AWAKE\n");
787 PRINTM_NETINTF(MEVENT, pmpriv);
788 PRINTM(MEVENT, "|");
789 if (!pmadapter->pps_uapsd_mode && pmpriv->media_connected &&
790 (pmpriv->port_open || !pmpriv->port_ctrl_mode) &&
791 pmadapter->sleep_period.period) {
792 pmadapter->pps_uapsd_mode = MTRUE;
793 PRINTM(MEVENT, "PPS/UAPSD mode activated\n");
794 }
795 /* Handle unexpected PS AWAKE event */
796 if (pmadapter->ps_state == PS_STATE_SLEEP_CFM)
797 break;
798 pmadapter->tx_lock_flag = MFALSE;
799 if (pmadapter->pps_uapsd_mode && pmadapter->gen_null_pkt) {
800 if (MTRUE ==
801 wlan_check_last_packet_indication(pmpriv)) {
802 if (!pmadapter->data_sent) {
803 if (wlan_send_null_packet(
804 pmpriv,
805 MRVDRV_TxPD_POWER_MGMT_NULL_PACKET |
806 MRVDRV_TxPD_POWER_MGMT_LAST_PACKET) ==
807 MLAN_STATUS_SUCCESS) {
808 ret = MLAN_STATUS_SUCCESS;
809 goto done;
810 }
811 }
812 }
813 }
814 pmadapter->ps_state = PS_STATE_AWAKE;
815 pmadapter->pm_wakeup_card_req = MFALSE;
816 pmadapter->pm_wakeup_fw_try = MFALSE;
817 break;
818
819 case EVENT_HS_ACT_REQ:
820 PRINTM(MEVENT, "EVENT: HS_ACT_REQ\n");
821 ret = wlan_prepare_cmd(priv, HostCmd_CMD_802_11_HS_CFG_ENH, 0,
822 0, MNULL, MNULL);
823 break;
824 case EVENT_MIC_ERR_UNICAST:
825 PRINTM(MEVENT, "EVENT: UNICAST MIC ERROR\n");
826 wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_MIC_ERR_UNI, MNULL);
827 break;
828
829 case EVENT_MIC_ERR_MULTICAST:
830 PRINTM(MEVENT, "EVENT: MULTICAST MIC ERROR\n");
831 wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_MIC_ERR_MUL, MNULL);
832 break;
833 case EVENT_MIB_CHANGED:
834 case EVENT_INIT_DONE:
835 break;
836
837 case EVENT_ADHOC_BCN_LOST:
838 PRINTM(MEVENT, "EVENT: ADHOC_BCN_LOST\n");
839 pmpriv->adhoc_is_link_sensed = MFALSE;
840 wlan_clean_txrx(pmpriv);
841 wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_ADHOC_LINK_LOST,
842 MNULL);
843 break;
844 case EVENT_ASSOC_REQ_IE:
845 pmpriv->assoc_req_size = pmbuf->data_len - sizeof(eventcause);
846 evt_buf =
847 (pmbuf->pbuf + pmbuf->data_offset + sizeof(eventcause));
848 memcpy_ext(pmpriv->adapter, pmpriv->assoc_req_buf, evt_buf,
849 pmbuf->data_len - sizeof(eventcause),
850 MRVDRV_ASSOC_RSP_BUF_SIZE);
851 break;
852
853 case EVENT_FW_DEBUG_INFO:
854 pevent->bss_index = pmpriv->bss_index;
855 pevent->event_id = MLAN_EVENT_ID_FW_DEBUG_INFO;
856 pevent->event_len = pmbuf->data_len - sizeof(eventcause);
857 memcpy_ext(pmadapter, (t_u8 *)pevent->event_buf,
858 pmbuf->pbuf + pmbuf->data_offset +
859 sizeof(eventcause),
860 pevent->event_len, pevent->event_len);
861 PRINTM(MEVENT, "EVENT: FW Debug Info %s\n",
862 (t_u8 *)pevent->event_buf);
863 wlan_recv_event(pmpriv, pevent->event_id, pevent);
864 break;
865
866 case EVENT_BG_SCAN_REPORT:
867 PRINTM(MEVENT, "EVENT: BGS_REPORT\n");
868 pmadapter->bgscan_reported = MTRUE;
869 wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_BG_SCAN, MNULL);
870 break;
871 case EVENT_BG_SCAN_STOPPED:
872 PRINTM(MEVENT, "EVENT: BGS_STOPPED\n");
873 wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_BG_SCAN_STOPPED,
874 MNULL);
875 break;
876
877 case EVENT_PORT_RELEASE:
878 PRINTM(MEVENT, "EVENT: PORT RELEASE\n");
879 /* Open the port for e-supp mode */
880 if (pmpriv->port_ctrl_mode == MTRUE) {
881 PRINTM(MINFO, "PORT_REL: port_status = OPEN\n");
882 pmpriv->port_open = MTRUE;
883 }
884 pmadapter->scan_block = MFALSE;
885 wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_PORT_RELEASE, MNULL);
886 /* Send OBSS scan param to the application */
887 wlan_2040_coex_event(pmpriv);
888 break;
889
890 case EVENT_STOP_TX:
891 PRINTM(MEVENT, "EVENT: Stop Tx (%#x)\n", eventcause);
892 wlan_11h_tx_disable(pmpriv); /* this fn will send event up to
893 MOAL */
894 break;
895 case EVENT_START_TX:
896 PRINTM(MEVENT, "EVENT: Start Tx (%#x)\n", eventcause);
897 wlan_11h_tx_enable(pmpriv); /* this fn will send event up to
898 MOAL */
899 break;
900 case EVENT_CHANNEL_SWITCH:
901 PRINTM(MEVENT, "EVENT: Channel Switch (%#x)\n", eventcause);
902 if (pmadapter->ecsa_enable) {
903 MrvlIEtypes_channel_band_t *pchan_info =
904 (MrvlIEtypes_channel_band_t
905 *)(pmadapter->event_body);
906 t_u8 channel = pchan_info->channel;
907 chan_freq_power_t *cfp = MNULL;
908 DBG_HEXDUMP(MCMD_D, "chan band config",
909 (t_u8 *)pchan_info,
910 sizeof(MrvlIEtypes_channel_band_t));
911 PRINTM(MEVENT, "Switch to channel %d success!\n",
912 channel);
913 #define MAX_CHANNEL_BAND_B 14
914 if (channel <= MAX_CHANNEL_BAND_B)
915 cfp = wlan_find_cfp_by_band_and_channel(
916 pmadapter, BAND_B, channel);
917 else
918 cfp = wlan_find_cfp_by_band_and_channel(
919 pmadapter, BAND_A, channel);
920 pmpriv->curr_bss_params.bss_descriptor.channel =
921 channel;
922 if (cfp)
923 pmpriv->curr_bss_params.bss_descriptor.freq =
924 cfp->freq;
925 else
926 pmpriv->curr_bss_params.bss_descriptor.freq = 0;
927 #ifdef UAP_SUPPORT
928 if (pmpriv->adapter->dfs_mode)
929 wlan_11h_update_dfs_master_state_by_sta(pmpriv);
930 #endif
931 if (pmpriv->adapter->state_rdh.stage ==
932 RDH_SET_CUSTOM_IE) {
933 pmadapter->state_rdh.stage =
934 RDH_RESTART_TRAFFIC;
935 wlan_11h_radar_detected_handling(pmadapter,
936 pmpriv);
937 }
938 pmadapter->state_rdh.tx_block = MFALSE;
939 /* Setup event buffer */
940 pevent->bss_index = pmpriv->bss_index;
941 pevent->event_id =
942 MLAN_EVENT_ID_FW_CHAN_SWITCH_COMPLETE;
943 pevent->event_len = sizeof(chan_band_info);
944 pchan_band_info = (chan_band_info *)pevent->event_buf;
945 /* Copy event data */
946 memcpy_ext(pmadapter, (t_u8 *)&pchan_band_info->bandcfg,
947 (t_u8 *)&pchan_info->bandcfg,
948 sizeof(pchan_info->bandcfg),
949 sizeof(pchan_band_info->bandcfg));
950 pchan_band_info->channel = pchan_info->channel;
951 if (pchan_band_info->bandcfg.chanWidth == CHAN_BW_80MHZ)
952 pchan_band_info->center_chan =
953 wlan_get_center_freq_idx(
954 priv, BAND_AAC,
955 pchan_info->channel,
956 CHANNEL_BW_80MHZ);
957 wlan_recv_event(pmpriv,
958 MLAN_EVENT_ID_FW_CHAN_SWITCH_COMPLETE,
959 pevent);
960 }
961 break;
962 case EVENT_CHANNEL_SWITCH_ANN:
963 PRINTM_NETINTF(MEVENT, pmpriv);
964 PRINTM(MEVENT, "EVENT: Channel Switch Announcement\n");
965 /* Here, pass up event first, as handling will send deauth */
966 wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_CHANNEL_SWITCH_ANN,
967 MNULL);
968 wlan_11h_handle_event_chanswann(pmpriv);
969 break;
970 case EVENT_RADAR_DETECTED:
971 PRINTM_NETINTF(MEVENT, pmpriv);
972 PRINTM(MEVENT, "EVENT: Radar Detected\n");
973
974 /* Send as passthru first, this event can cause other events */
975 pevent->bss_index = pmpriv->bss_index;
976 pevent->event_id = MLAN_EVENT_ID_DRV_PASSTHRU;
977 pevent->event_len = pmbuf->data_len;
978 memcpy_ext(pmadapter, (t_u8 *)pevent->event_buf,
979 pmbuf->pbuf + pmbuf->data_offset, pevent->event_len,
980 pevent->event_len);
981 wlan_recv_event(pmpriv, pevent->event_id, pevent);
982
983 if (pmadapter->state_rdh.stage == RDH_OFF) {
984 pmadapter->state_rdh.stage = RDH_CHK_INTFS;
985 wlan_11h_radar_detected_handling(pmadapter, pmpriv);
986 } else {
987 PRINTM(MEVENT, "Ignore Event Radar Detected - handling"
988 " already in progress.\n");
989 }
990
991 break;
992
993 case EVENT_CHANNEL_REPORT_RDY:
994 PRINTM_NETINTF(MEVENT, pmpriv);
995 PRINTM(MEVENT, "EVENT: Channel Report Ready\n");
996 pevent->bss_index = pmpriv->bss_index;
997 pevent->event_id = MLAN_EVENT_ID_FW_CHANNEL_REPORT_RDY;
998 pevent->event_len = pmbuf->data_len - sizeof(eventcause);
999 /* Copy event data */
1000 memcpy_ext(pmadapter, (t_u8 *)pevent->event_buf,
1001 pmbuf->pbuf + pmbuf->data_offset +
1002 sizeof(eventcause),
1003 pevent->event_len, pevent->event_len);
1004 /* Handle / pass event data */
1005 ret = wlan_11h_handle_event_chanrpt_ready(pmpriv, pevent,
1006 &radar_chan, 0);
1007 /* Also send this event as passthru */
1008 pevent->event_id = MLAN_EVENT_ID_DRV_PASSTHRU;
1009 pevent->event_len = pmbuf->data_len;
1010 memcpy_ext(pmadapter, (t_u8 *)pevent->event_buf,
1011 pmbuf->pbuf + pmbuf->data_offset, pevent->event_len,
1012 pevent->event_len);
1013 wlan_recv_event(pmpriv, pevent->event_id, pevent);
1014 /* Send up this Event to unblock MOAL waitqueue */
1015 wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_MEAS_REPORT, MNULL);
1016 break;
1017 case EVENT_EXT_SCAN_REPORT:
1018 PRINTM(MEVENT, "EVENT: EXT_SCAN Report (%d)\n",
1019 pmbuf->data_len);
1020 if (pmadapter->pscan_ioctl_req && pmadapter->ext_scan)
1021 ret = wlan_handle_event_ext_scan_report(priv, pmbuf);
1022 break;
1023 case EVENT_EXT_SCAN_STATUS_REPORT:
1024 PRINTM(MEVENT, "EVENT: EXT_SCAN status report (%d)\n",
1025 pmbuf->data_len);
1026 pmadapter->ext_scan_timeout = MFALSE;
1027 ret = wlan_handle_event_ext_scan_status(priv, pmbuf);
1028 break;
1029 case EVENT_MEAS_REPORT_RDY:
1030 PRINTM(MEVENT, "EVENT: Measurement Report Ready (%#x)\n",
1031 eventcause);
1032 ret = wlan_prepare_cmd(priv, HostCmd_CMD_MEASUREMENT_REPORT,
1033 HostCmd_ACT_GEN_SET, 0, MNULL, MNULL);
1034 break;
1035 case EVENT_WMM_STATUS_CHANGE:
1036 if (pmbuf &&
1037 pmbuf->data_len >
1038 sizeof(eventcause) + sizeof(MrvlIEtypesHeader_t)) {
1039 PRINTM(MEVENT, "EVENT: WMM status changed: %d\n",
1040 pmbuf->data_len);
1041
1042 evt_buf = (pmbuf->pbuf + pmbuf->data_offset +
1043 sizeof(eventcause));
1044
1045 wlan_ret_wmm_get_status(pmpriv, evt_buf,
1046 pmbuf->data_len -
1047 sizeof(eventcause));
1048 } else {
1049 PRINTM(MEVENT, "EVENT: WMM status changed\n");
1050 ret = wlan_cmd_wmm_status_change(pmpriv);
1051 }
1052 break;
1053
1054 case EVENT_RSSI_LOW:
1055 PRINTM(MEVENT, "EVENT: Beacon RSSI_LOW\n");
1056 pevent->bss_index = pmpriv->bss_index;
1057 pevent->event_id = MLAN_EVENT_ID_FW_BCN_RSSI_LOW;
1058 pevent->event_len = sizeof(t_u16);
1059 /** Fw send bcnRssi low value in event reason field*/
1060 memcpy_ext(pmadapter, (t_u8 *)pevent->event_buf,
1061 (t_u8 *)&pmadapter->event_body, pevent->event_len,
1062 pevent->event_len);
1063 wlan_recv_event(pmpriv, pevent->event_id, pevent);
1064 break;
1065 case EVENT_SNR_LOW:
1066 PRINTM(MEVENT, "EVENT: Beacon SNR_LOW\n");
1067 wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_BCN_SNR_LOW, MNULL);
1068 break;
1069 case EVENT_MAX_FAIL:
1070 PRINTM(MEVENT, "EVENT: MAX_FAIL\n");
1071 wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_MAX_FAIL, MNULL);
1072 break;
1073 case EVENT_RSSI_HIGH:
1074 PRINTM(MEVENT, "EVENT: Beacon RSSI_HIGH\n");
1075 pevent->bss_index = pmpriv->bss_index;
1076 pevent->event_id = MLAN_EVENT_ID_FW_BCN_RSSI_HIGH;
1077 pevent->event_len = sizeof(t_u16);
1078 /** Fw send bcnRssi high value in event reason field*/
1079 memcpy_ext(pmadapter, (t_u8 *)pevent->event_buf,
1080 (t_u8 *)&pmadapter->event_body, pevent->event_len,
1081 pevent->event_len);
1082 wlan_recv_event(pmpriv, pevent->event_id, pevent);
1083 break;
1084 case EVENT_SNR_HIGH:
1085 PRINTM(MEVENT, "EVENT: Beacon SNR_HIGH\n");
1086 wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_BCN_SNR_HIGH, MNULL);
1087 break;
1088 case EVENT_DATA_RSSI_LOW:
1089 PRINTM(MEVENT, "EVENT: Data RSSI_LOW\n");
1090 wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_DATA_RSSI_LOW, MNULL);
1091 break;
1092 case EVENT_DATA_SNR_LOW:
1093 PRINTM(MEVENT, "EVENT: Data SNR_LOW\n");
1094 wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_DATA_SNR_LOW, MNULL);
1095 break;
1096 case EVENT_DATA_RSSI_HIGH:
1097 PRINTM(MEVENT, "EVENT: Data RSSI_HIGH\n");
1098 wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_DATA_RSSI_HIGH, MNULL);
1099 break;
1100 case EVENT_DATA_SNR_HIGH:
1101 PRINTM(MEVENT, "EVENT: Data SNR_HIGH\n");
1102 wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_DATA_SNR_HIGH, MNULL);
1103 break;
1104 case EVENT_LINK_QUALITY:
1105 PRINTM(MEVENT, "EVENT: Link Quality\n");
1106 wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_LINK_QUALITY, MNULL);
1107 break;
1108 case EVENT_PRE_BEACON_LOST:
1109 PRINTM(MEVENT, "EVENT: Pre-Beacon Lost\n");
1110 wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_PRE_BCN_LOST, MNULL);
1111 break;
1112 case EVENT_IBSS_COALESCED:
1113 PRINTM(MEVENT, "EVENT: IBSS_COALESCED\n");
1114 ret = wlan_prepare_cmd(
1115 pmpriv, HostCmd_CMD_802_11_IBSS_COALESCING_STATUS,
1116 HostCmd_ACT_GEN_GET, 0, MNULL, MNULL);
1117 break;
1118 case EVENT_ADDBA:
1119 PRINTM(MEVENT, "EVENT: ADDBA Request\n");
1120 if (pmpriv->media_connected == MTRUE)
1121 ret = wlan_prepare_cmd(pmpriv,
1122 HostCmd_CMD_11N_ADDBA_RSP,
1123 HostCmd_ACT_GEN_SET, 0, MNULL,
1124 pmadapter->event_body);
1125 else
1126 PRINTM(MERROR,
1127 "Ignore ADDBA Request event in disconnected state\n");
1128 break;
1129 case EVENT_DELBA:
1130 PRINTM(MEVENT, "EVENT: DELBA Request\n");
1131 if (pmpriv->media_connected == MTRUE)
1132 wlan_11n_delete_bastream(pmpriv, pmadapter->event_body);
1133 else
1134 PRINTM(MERROR,
1135 "Ignore DELBA Request event in disconnected state\n");
1136 break;
1137 case EVENT_BA_STREAM_TIMEOUT:
1138 PRINTM(MEVENT, "EVENT: BA Stream timeout\n");
1139 if (pmpriv->media_connected == MTRUE)
1140 wlan_11n_ba_stream_timeout(
1141 pmpriv, (HostCmd_DS_11N_BATIMEOUT *)
1142 pmadapter->event_body);
1143 else
1144 PRINTM(MERROR,
1145 "Ignore BA Stream timeout event in disconnected state\n");
1146 break;
1147 case EVENT_RXBA_SYNC:
1148 PRINTM(MEVENT, "EVENT: RXBA_SYNC\n");
1149 wlan_11n_rxba_sync_event(pmpriv, pmadapter->event_body,
1150 pmbuf->data_len - sizeof(eventcause));
1151 break;
1152 case EVENT_AMSDU_AGGR_CTRL:
1153 PRINTM(MEVENT, "EVENT: AMSDU_AGGR_CTRL %d\n",
1154 *(t_u16 *)pmadapter->event_body);
1155 pmadapter->tx_buf_size =
1156 MIN(pmadapter->curr_tx_buf_size,
1157 wlan_le16_to_cpu(*(t_u16 *)pmadapter->event_body));
1158 if (pmbuf->data_len == sizeof(eventcause) + sizeof(t_u32)) {
1159 enable = wlan_le16_to_cpu(
1160 *(t_u16 *)(pmadapter->event_body +
1161 sizeof(t_u16)));
1162 if (enable)
1163 pmpriv->amsdu_disable = MFALSE;
1164 else
1165 pmpriv->amsdu_disable = MTRUE;
1166 PRINTM(MEVENT, "amsdu_disable=%d\n",
1167 pmpriv->amsdu_disable);
1168 }
1169 PRINTM(MEVENT, "tx_buf_size %d\n", pmadapter->tx_buf_size);
1170 break;
1171
1172 case EVENT_WEP_ICV_ERR:
1173 PRINTM(MEVENT, "EVENT: WEP ICV error\n");
1174 pevent->bss_index = pmpriv->bss_index;
1175 pevent->event_id = MLAN_EVENT_ID_FW_WEP_ICV_ERR;
1176 pevent->event_len = sizeof(Event_WEP_ICV_ERR);
1177 memcpy_ext(pmadapter, (t_u8 *)pevent->event_buf,
1178 pmadapter->event_body, pevent->event_len,
1179 pevent->event_len);
1180 wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_WEP_ICV_ERR, pevent);
1181 break;
1182
1183 case EVENT_BW_CHANGE:
1184 PRINTM(MEVENT, "EVENT: BW Change\n");
1185 pevent->bss_index = pmpriv->bss_index;
1186 pevent->event_id = MLAN_EVENT_ID_FW_BW_CHANGED;
1187 pevent->event_len = sizeof(t_u8);
1188 /* Copy event body from the event buffer */
1189 memcpy_ext(pmadapter, (t_u8 *)pevent->event_buf,
1190 pmadapter->event_body, pevent->event_len,
1191 pevent->event_len);
1192 #ifdef UAP_SUPPORT
1193 if (pmadapter->dfs_repeater)
1194 wlan_dfs_rep_bw_change(pmadapter);
1195 #endif
1196 wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_BW_CHANGED, pevent);
1197 break;
1198
1199 #ifdef WIFI_DIRECT_SUPPORT
1200 case EVENT_WIFIDIRECT_GENERIC_EVENT:
1201 PRINTM(MEVENT, "EVENT: WIFIDIRECT event %d\n", eventcause);
1202 pevent->bss_index = pmpriv->bss_index;
1203 pevent->event_id = MLAN_EVENT_ID_DRV_PASSTHRU;
1204 pevent->event_len = pmbuf->data_len;
1205 memcpy_ext(pmadapter, (t_u8 *)pevent->event_buf,
1206 pmbuf->pbuf + pmbuf->data_offset, pevent->event_len,
1207 pevent->event_len);
1208 wlan_recv_event(pmpriv, pevent->event_id, pevent);
1209 break;
1210 case EVENT_WIFIDIRECT_SERVICE_DISCOVERY:
1211 PRINTM(MEVENT, "EVENT: WIFIDIRECT service discovery event %d\n",
1212 eventcause);
1213 pevent->bss_index = pmpriv->bss_index;
1214 pevent->event_id = MLAN_EVENT_ID_DRV_PASSTHRU;
1215 pevent->event_len = pmbuf->data_len;
1216 memcpy_ext(pmadapter, (t_u8 *)pevent->event_buf,
1217 pmbuf->pbuf + pmbuf->data_offset, pevent->event_len,
1218 pevent->event_len);
1219 wlan_recv_event(pmpriv, pevent->event_id, pevent);
1220 break;
1221 #endif /* WIFI_DIRECT_SUPPORT */
1222 case EVENT_REMAIN_ON_CHANNEL_EXPIRED:
1223 PRINTM_NETINTF(MEVENT, pmpriv);
1224 PRINTM(MEVENT, "EVENT: REMAIN_ON_CHANNEL_EXPIRED reason=%d\n",
1225 *(t_u16 *)pmadapter->event_body);
1226 wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_FLUSH_RX_WORK, MNULL);
1227 wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_REMAIN_ON_CHAN_EXPIRED,
1228 MNULL);
1229 break;
1230 case EVENT_TDLS_GENERIC_EVENT:
1231 PRINTM(MEVENT, "EVENT: TDLS event %d\n", eventcause);
1232 wlan_parse_tdls_event(pmpriv, pmbuf);
1233 pevent->bss_index = pmpriv->bss_index;
1234 pevent->event_id = MLAN_EVENT_ID_DRV_PASSTHRU;
1235 pevent->event_len = pmbuf->data_len;
1236 memcpy_ext(pmadapter, (t_u8 *)pevent->event_buf,
1237 pmbuf->pbuf + pmbuf->data_offset, pevent->event_len,
1238 pevent->event_len);
1239 wlan_recv_event(pmpriv, pevent->event_id, pevent);
1240 break;
1241
1242 case EVENT_TX_DATA_PAUSE:
1243 PRINTM(MEVENT, "EVENT: TX_DATA_PAUSE\n");
1244 wlan_process_sta_tx_pause_event(priv, pmbuf);
1245 break;
1246
1247 case EVENT_IBSS_STATION_CONNECT:
1248 break;
1249 case EVENT_IBSS_STATION_DISCONNECT:
1250 break;
1251 case EVENT_SAD_REPORT: {
1252 #ifdef DEBUG_LEVEL1
1253 t_u8 *pevt_dat =
1254 pmbuf->pbuf + pmbuf->data_offset + sizeof(t_u32);
1255 #endif
1256 PRINTM(MEVENT,
1257 "EVENT: Antenna Diversity %d (%d, %d, %d, %d)\n",
1258 eventcause, pevt_dat[0] + 1, pevt_dat[1] + 1,
1259 pevt_dat[2], pevt_dat[3]);
1260 } break;
1261
1262 case EVENT_FW_DUMP_INFO:
1263 PRINTM(MINFO, "EVENT: Dump FW info\n");
1264 pevent->bss_index = pmpriv->bss_index;
1265 pevent->event_id = MLAN_EVENT_ID_FW_DUMP_INFO;
1266 pevent->event_len = pmbuf->data_len;
1267 memcpy_ext(pmadapter, (t_u8 *)pevent->event_buf,
1268 pmbuf->pbuf + pmbuf->data_offset, pevent->event_len,
1269 pevent->event_len);
1270 wlan_recv_event(pmpriv, pevent->event_id, pevent);
1271 break;
1272 case EVENT_TX_STATUS_REPORT:
1273 PRINTM(MINFO, "EVENT: TX_STATUS\n");
1274 pevent->bss_index = pmpriv->bss_index;
1275 pevent->event_id = MLAN_EVENT_ID_FW_TX_STATUS;
1276 pevent->event_len = pmbuf->data_len;
1277 memcpy_ext(pmadapter, (t_u8 *)pevent->event_buf,
1278 pmbuf->pbuf + pmbuf->data_offset, pevent->event_len,
1279 pevent->event_len);
1280
1281 wlan_recv_event(pmpriv, pevent->event_id, pevent);
1282 break;
1283 case EVENT_BT_COEX_WLAN_PARA_CHANGE:
1284 PRINTM(MEVENT, "EVENT: BT coex wlan param update\n");
1285 wlan_bt_coex_wlan_param_update_event(pmpriv, pmbuf);
1286 break;
1287
1288 #if defined(PCIE)
1289 case EVENT_SSU_DUMP_DMA:
1290 PRINTM(MEVENT, "EVENT: EVENT_SSU_DUMP_DMA\n");
1291 if (!pmadapter->ssu_buf || !pmadapter->ssu_buf->pbuf)
1292 break;
1293
1294 /* If ADMA is supported, SSU header could not be received with
1295 * SSU data. Instead, SSU header is received through this event.
1296 * So, copy the header into the buffer before passing the buffer
1297 * to upper layer for file writting
1298 */
1299 memcpy_ext(pmadapter,
1300 (t_u8 *)pmadapter->ssu_buf->pbuf +
1301 pmadapter->ssu_buf->data_offset,
1302 pmbuf->pbuf + pmbuf->data_offset +
1303 sizeof(eventcause),
1304 (pmbuf->data_len - sizeof(eventcause)),
1305 (pmbuf->data_len - sizeof(eventcause)));
1306
1307 DBG_HEXDUMP(MEVT_D, "SSU data",
1308 (t_u8 *)pmadapter->ssu_buf->pbuf +
1309 pmadapter->ssu_buf->data_offset,
1310 512);
1311 pevent->bss_index = pmpriv->bss_index;
1312 pevent->event_id = MLAN_EVENT_ID_SSU_DUMP_FILE;
1313 pevent->event_len = MLAN_SSU_BUF_SIZE;
1314 *(t_ptr *)pevent->event_buf = (t_ptr)pmadapter->ssu_buf->pbuf +
1315 pmadapter->ssu_buf->data_offset;
1316 wlan_recv_event(pmpriv, pevent->event_id, pevent);
1317 wlan_free_ssu_pcie_buf(pmadapter);
1318 break;
1319 #endif
1320 case EVENT_CSI:
1321 PRINTM(MEVENT, "EVENT: EVENT_CSI on STA\n");
1322 wlan_process_csi_event(pmpriv);
1323 break;
1324 case EVENT_MEF_HOST_WAKEUP:
1325 PRINTM(MEVENT, "EVENT: EVENT_MEF_HOST_WAKEUP len=%d\n",
1326 pmbuf->data_len);
1327 break;
1328 case EVENT_MANAGEMENT_FRAME_WAKEUP:
1329 PRINTM(MEVENT, "EVENT: EVENT_MANAGEMENT_FRAME_WAKEUP HOST\n");
1330 break;
1331 case EVENT_ROAM_OFFLOAD:
1332 memcpy_ext(pmadapter, addr,
1333 pmpriv->curr_bss_params.bss_descriptor.mac_address,
1334 MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
1335 memcpy_ext(pmadapter,
1336 pmpriv->curr_bss_params.bss_descriptor.mac_address,
1337 (t_u8 *)(pmadapter->event_body + 2),
1338 MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
1339 /** replace ralist's mac address with new mac address */
1340 if (0 ==
1341 wlan_ralist_update(
1342 pmpriv, addr,
1343 pmpriv->curr_bss_params.bss_descriptor.mac_address))
1344 wlan_ralist_add(pmpriv,
1345 pmpriv->curr_bss_params.bss_descriptor
1346 .mac_address);
1347 wlan_11n_cleanup_reorder_tbl(pmpriv);
1348 wlan_11n_deleteall_txbastream_tbl(pmpriv);
1349 /*Update the BSS for inform kernel, otherwise kernel will give
1350 * warning for not find BSS*/
1351 memcpy_ext(pmadapter, (t_u8 *)&pmadapter->pscan_table[0],
1352 (t_u8 *)&pmpriv->curr_bss_params.bss_descriptor,
1353 sizeof(BSSDescriptor_t), sizeof(BSSDescriptor_t));
1354 if (!pmadapter->num_in_scan_table)
1355 pmadapter->num_in_scan_table = 1;
1356 PRINTM(MEVENT, "EVENT: ROAM OFFLOAD IN FW SUCCESS\n");
1357 pevent->bss_index = pmpriv->bss_index;
1358 pevent->event_id = MLAN_EVENT_ID_FW_ROAM_OFFLOAD_RESULT;
1359 /** Drop event id length and 2 bytes reverved length*/
1360 pevent->event_len = pmbuf->data_len - sizeof(eventcause) - 2;
1361 memcpy_ext(pmadapter, (t_u8 *)pevent->event_buf,
1362 pmadapter->event_body + 2, pevent->event_len,
1363 pevent->event_len);
1364 wlan_recv_event(pmpriv, pevent->event_id, pevent);
1365 break;
1366 case EVENT_CLOUD_KEEP_ALIVE_RETRY_FAIL:
1367 break;
1368 case EVENT_VDLL_IND:
1369 wlan_process_vdll_event(pmpriv, pmbuf);
1370 break;
1371 case EVENT_FW_HANG_REPORT:
1372 if (pmbuf->data_len < (sizeof(eventcause) + sizeof(t_u16))) {
1373 PRINTM(MEVENT,
1374 "EVENT: EVENT_FW_HANG_REPORT skip for len too short: %d\n",
1375 pmbuf->data_len);
1376 break;
1377 }
1378 PRINTM(MEVENT, "EVENT: EVENT_FW_HANG_REPORT reasoncode=%d\n",
1379 wlan_le16_to_cpu(*(t_u16 *)(pmbuf->pbuf +
1380 pmbuf->data_offset +
1381 sizeof(eventcause))));
1382 pmadapter->fw_hang_report = MTRUE;
1383 wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_DBG_DUMP, MNULL);
1384 break;
1385 case CHAN_LOAD_EVENT: {
1386 t_u8 *ptr = MNULL;
1387 HostCmd_DS_GET_CH_LOAD *cfg_cmd = MNULL;
1388 ptr = (t_u8 *)(pmbuf->pbuf + pmbuf->data_offset);
1389 ptr += 4; /* data start */
1390 cfg_cmd = (HostCmd_DS_GET_CH_LOAD *)ptr;
1391 pmpriv->ch_load_param = wlan_le16_to_cpu(cfg_cmd->ch_load);
1392 pmpriv->noise = wlan_le16_to_cpu(cfg_cmd->noise);
1393 pmpriv->rx_quality = wlan_le16_to_cpu(cfg_cmd->rx_quality);
1394 break;
1395 }
1396 default:
1397 PRINTM(MEVENT, "EVENT: unknown event id: %#x\n", eventcause);
1398 wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_UNKNOWN, MNULL);
1399 break;
1400 }
1401 done:
1402 if (event_buf)
1403 pcb->moal_mfree(pmadapter->pmoal_handle, event_buf);
1404 LEAVE();
1405 return ret;
1406 }
1407