1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include "decl.h"
21#include "ioctl.h"
22#include "util.h"
23#include "fw.h"
24#include "main.h"
25#include "wmm.h"
26#include "11n.h"
27
28#define MWIFIEX_IBSS_CONNECT_EVT_FIX_SIZE 12
29
30static int mwifiex_check_ibss_peer_capabilties(struct mwifiex_private *priv,
31 struct mwifiex_sta_node *sta_ptr,
32 struct sk_buff *event)
33{
34 int evt_len, ele_len;
35 u8 *curr;
36 struct ieee_types_header *ele_hdr;
37 struct mwifiex_ie_types_mgmt_frame *tlv_mgmt_frame;
38 const struct ieee80211_ht_cap *ht_cap;
39 const struct ieee80211_vht_cap *vht_cap;
40
41 skb_pull(event, MWIFIEX_IBSS_CONNECT_EVT_FIX_SIZE);
42 evt_len = event->len;
43 curr = event->data;
44
45 mwifiex_dbg_dump(priv->adapter, EVT_D, "ibss peer capabilties:",
46 event->data, event->len);
47
48 skb_push(event, MWIFIEX_IBSS_CONNECT_EVT_FIX_SIZE);
49
50 tlv_mgmt_frame = (void *)curr;
51 if (evt_len >= sizeof(*tlv_mgmt_frame) &&
52 le16_to_cpu(tlv_mgmt_frame->header.type) ==
53 TLV_TYPE_UAP_MGMT_FRAME) {
54
55
56
57
58 evt_len = le16_to_cpu(tlv_mgmt_frame->header.len);
59 curr += (sizeof(*tlv_mgmt_frame) + 12);
60 } else {
61 mwifiex_dbg(priv->adapter, MSG,
62 "management frame tlv not found!\n");
63 return 0;
64 }
65
66 while (evt_len >= sizeof(*ele_hdr)) {
67 ele_hdr = (struct ieee_types_header *)curr;
68 ele_len = ele_hdr->len;
69
70 if (evt_len < ele_len + sizeof(*ele_hdr))
71 break;
72
73 switch (ele_hdr->element_id) {
74 case WLAN_EID_HT_CAPABILITY:
75 sta_ptr->is_11n_enabled = true;
76 ht_cap = (void *)(ele_hdr + 2);
77 sta_ptr->max_amsdu = le16_to_cpu(ht_cap->cap_info) &
78 IEEE80211_HT_CAP_MAX_AMSDU ?
79 MWIFIEX_TX_DATA_BUF_SIZE_8K :
80 MWIFIEX_TX_DATA_BUF_SIZE_4K;
81 mwifiex_dbg(priv->adapter, INFO,
82 "11n enabled!, max_amsdu : %d\n",
83 sta_ptr->max_amsdu);
84 break;
85
86 case WLAN_EID_VHT_CAPABILITY:
87 sta_ptr->is_11ac_enabled = true;
88 vht_cap = (void *)(ele_hdr + 2);
89
90 switch (le32_to_cpu(vht_cap->vht_cap_info) & 0x3) {
91 case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454:
92 sta_ptr->max_amsdu =
93 MWIFIEX_TX_DATA_BUF_SIZE_12K;
94 break;
95 case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991:
96 sta_ptr->max_amsdu =
97 MWIFIEX_TX_DATA_BUF_SIZE_8K;
98 break;
99 case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895:
100 sta_ptr->max_amsdu =
101 MWIFIEX_TX_DATA_BUF_SIZE_4K;
102 default:
103 break;
104 }
105
106 mwifiex_dbg(priv->adapter, INFO,
107 "11ac enabled!, max_amsdu : %d\n",
108 sta_ptr->max_amsdu);
109 break;
110 default:
111 break;
112 }
113
114 curr += (ele_len + sizeof(*ele_hdr));
115 evt_len -= (ele_len + sizeof(*ele_hdr));
116 }
117
118 return 0;
119}
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136void mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code,
137 bool from_ap)
138{
139 struct mwifiex_adapter *adapter = priv->adapter;
140
141 if (!priv->media_connected)
142 return;
143
144 mwifiex_dbg(adapter, INFO,
145 "info: handles disconnect event\n");
146
147 priv->media_connected = false;
148
149 priv->scan_block = false;
150 priv->port_open = false;
151
152 if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
153 ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info)) {
154 mwifiex_disable_all_tdls_links(priv);
155
156 if (priv->adapter->auto_tdls)
157 mwifiex_clean_auto_tdls(priv);
158 }
159
160
161 mwifiex_clean_txrx(priv);
162
163
164 priv->data_rssi_last = 0;
165 priv->data_nf_last = 0;
166 priv->data_rssi_avg = 0;
167 priv->data_nf_avg = 0;
168 priv->bcn_rssi_last = 0;
169 priv->bcn_nf_last = 0;
170 priv->bcn_rssi_avg = 0;
171 priv->bcn_nf_avg = 0;
172 priv->rxpd_rate = 0;
173 priv->rxpd_htinfo = 0;
174 priv->sec_info.wpa_enabled = false;
175 priv->sec_info.wpa2_enabled = false;
176 priv->wpa_ie_len = 0;
177
178 priv->sec_info.wapi_enabled = false;
179 priv->wapi_ie_len = 0;
180 priv->sec_info.wapi_key_on = false;
181
182 priv->sec_info.encryption_mode = 0;
183
184
185 priv->is_data_rate_auto = true;
186 priv->data_rate = 0;
187
188 priv->assoc_resp_ht_param = 0;
189 priv->ht_param_present = false;
190
191 if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA ||
192 GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) && priv->hist_data)
193 mwifiex_hist_data_reset(priv);
194
195 if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
196 priv->adhoc_state = ADHOC_IDLE;
197 priv->adhoc_is_link_sensed = false;
198 }
199
200
201
202
203
204
205 mwifiex_dbg(adapter, INFO,
206 "info: previous SSID=%s, SSID len=%u\n",
207 priv->prev_ssid.ssid, priv->prev_ssid.ssid_len);
208
209 mwifiex_dbg(adapter, INFO,
210 "info: current SSID=%s, SSID len=%u\n",
211 priv->curr_bss_params.bss_descriptor.ssid.ssid,
212 priv->curr_bss_params.bss_descriptor.ssid.ssid_len);
213
214 memcpy(&priv->prev_ssid,
215 &priv->curr_bss_params.bss_descriptor.ssid,
216 sizeof(struct cfg80211_ssid));
217
218 memcpy(priv->prev_bssid,
219 priv->curr_bss_params.bss_descriptor.mac_address, ETH_ALEN);
220
221
222 memset(&priv->curr_bss_params, 0x00, sizeof(priv->curr_bss_params));
223
224 adapter->tx_lock_flag = false;
225 adapter->pps_uapsd_mode = false;
226
227 if (adapter->is_cmd_timedout && adapter->curr_cmd)
228 return;
229 priv->media_connected = false;
230 mwifiex_dbg(adapter, MSG,
231 "info: successfully disconnected from %pM: reason code %d\n",
232 priv->cfg_bssid, reason_code);
233 if (priv->bss_mode == NL80211_IFTYPE_STATION ||
234 priv->bss_mode == NL80211_IFTYPE_P2P_CLIENT) {
235 cfg80211_disconnected(priv->netdev, reason_code, NULL, 0,
236 !from_ap, GFP_KERNEL);
237 }
238 eth_zero_addr(priv->cfg_bssid);
239
240 mwifiex_stop_net_dev_queue(priv->netdev, adapter);
241 if (netif_carrier_ok(priv->netdev))
242 netif_carrier_off(priv->netdev);
243
244 mwifiex_send_cmd(priv, HostCmd_CMD_GTK_REKEY_OFFLOAD_CFG,
245 HostCmd_ACT_GEN_REMOVE, 0, NULL, false);
246}
247
248static int mwifiex_parse_tdls_event(struct mwifiex_private *priv,
249 struct sk_buff *event_skb)
250{
251 int ret = 0;
252 struct mwifiex_adapter *adapter = priv->adapter;
253 struct mwifiex_sta_node *sta_ptr;
254 struct mwifiex_tdls_generic_event *tdls_evt =
255 (void *)event_skb->data + sizeof(adapter->event_cause);
256 u8 *mac = tdls_evt->peer_mac;
257
258
259 if (event_skb->len < (sizeof(struct mwifiex_tdls_generic_event) -
260 sizeof(u16) - sizeof(adapter->event_cause))) {
261 mwifiex_dbg(adapter, ERROR, "Invalid event length!\n");
262 return -1;
263 }
264
265 sta_ptr = mwifiex_get_sta_entry(priv, tdls_evt->peer_mac);
266 if (!sta_ptr) {
267 mwifiex_dbg(adapter, ERROR, "cannot get sta entry!\n");
268 return -1;
269 }
270
271 switch (le16_to_cpu(tdls_evt->type)) {
272 case TDLS_EVENT_LINK_TEAR_DOWN:
273 cfg80211_tdls_oper_request(priv->netdev,
274 tdls_evt->peer_mac,
275 NL80211_TDLS_TEARDOWN,
276 le16_to_cpu(tdls_evt->u.reason_code),
277 GFP_KERNEL);
278 break;
279 case TDLS_EVENT_CHAN_SWITCH_RESULT:
280 mwifiex_dbg(adapter, EVENT, "tdls channel switch result :\n");
281 mwifiex_dbg(adapter, EVENT,
282 "status=0x%x, reason=0x%x cur_chan=%d\n",
283 tdls_evt->u.switch_result.status,
284 tdls_evt->u.switch_result.reason,
285 tdls_evt->u.switch_result.cur_chan);
286
287
288 if (tdls_evt->u.switch_result.status != 0) {
289 switch (tdls_evt->u.switch_result.cur_chan) {
290 case TDLS_BASE_CHANNEL:
291 sta_ptr->tdls_status = TDLS_IN_BASE_CHAN;
292 break;
293 case TDLS_OFF_CHANNEL:
294 sta_ptr->tdls_status = TDLS_IN_OFF_CHAN;
295 break;
296 default:
297 break;
298 }
299 return ret;
300 }
301
302
303 switch (tdls_evt->u.switch_result.cur_chan) {
304 case TDLS_BASE_CHANNEL:
305 if (sta_ptr->tdls_status == TDLS_IN_BASE_CHAN)
306 break;
307 mwifiex_update_ralist_tx_pause_in_tdls_cs(priv, mac,
308 false);
309 sta_ptr->tdls_status = TDLS_IN_BASE_CHAN;
310 break;
311 case TDLS_OFF_CHANNEL:
312 if (sta_ptr->tdls_status == TDLS_IN_OFF_CHAN)
313 break;
314 mwifiex_update_ralist_tx_pause_in_tdls_cs(priv, mac,
315 true);
316 sta_ptr->tdls_status = TDLS_IN_OFF_CHAN;
317 break;
318 default:
319 break;
320 }
321
322 break;
323 case TDLS_EVENT_START_CHAN_SWITCH:
324 mwifiex_dbg(adapter, EVENT, "tdls start channel switch...\n");
325 sta_ptr->tdls_status = TDLS_CHAN_SWITCHING;
326 break;
327 case TDLS_EVENT_CHAN_SWITCH_STOPPED:
328 mwifiex_dbg(adapter, EVENT,
329 "tdls chan switch stopped, reason=%d\n",
330 tdls_evt->u.cs_stop_reason);
331 break;
332 default:
333 break;
334 }
335
336 return ret;
337}
338
339static void mwifiex_process_uap_tx_pause(struct mwifiex_private *priv,
340 struct mwifiex_ie_types_header *tlv)
341{
342 struct mwifiex_tx_pause_tlv *tp;
343 struct mwifiex_sta_node *sta_ptr;
344 unsigned long flags;
345
346 tp = (void *)tlv;
347 mwifiex_dbg(priv->adapter, EVENT,
348 "uap tx_pause: %pM pause=%d, pkts=%d\n",
349 tp->peermac, tp->tx_pause,
350 tp->pkt_cnt);
351
352 if (ether_addr_equal(tp->peermac, priv->netdev->dev_addr)) {
353 if (tp->tx_pause)
354 priv->port_open = false;
355 else
356 priv->port_open = true;
357 } else if (is_multicast_ether_addr(tp->peermac)) {
358 mwifiex_update_ralist_tx_pause(priv, tp->peermac, tp->tx_pause);
359 } else {
360 spin_lock_irqsave(&priv->sta_list_spinlock, flags);
361 sta_ptr = mwifiex_get_sta_entry(priv, tp->peermac);
362 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
363
364 if (sta_ptr && sta_ptr->tx_pause != tp->tx_pause) {
365 sta_ptr->tx_pause = tp->tx_pause;
366 mwifiex_update_ralist_tx_pause(priv, tp->peermac,
367 tp->tx_pause);
368 }
369 }
370}
371
372static void mwifiex_process_sta_tx_pause(struct mwifiex_private *priv,
373 struct mwifiex_ie_types_header *tlv)
374{
375 struct mwifiex_tx_pause_tlv *tp;
376 struct mwifiex_sta_node *sta_ptr;
377 int status;
378 unsigned long flags;
379
380 tp = (void *)tlv;
381 mwifiex_dbg(priv->adapter, EVENT,
382 "sta tx_pause: %pM pause=%d, pkts=%d\n",
383 tp->peermac, tp->tx_pause,
384 tp->pkt_cnt);
385
386 if (ether_addr_equal(tp->peermac, priv->cfg_bssid)) {
387 if (tp->tx_pause)
388 priv->port_open = false;
389 else
390 priv->port_open = true;
391 } else {
392 if (!ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info))
393 return;
394
395 status = mwifiex_get_tdls_link_status(priv, tp->peermac);
396 if (mwifiex_is_tdls_link_setup(status)) {
397 spin_lock_irqsave(&priv->sta_list_spinlock, flags);
398 sta_ptr = mwifiex_get_sta_entry(priv, tp->peermac);
399 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
400
401 if (sta_ptr && sta_ptr->tx_pause != tp->tx_pause) {
402 sta_ptr->tx_pause = tp->tx_pause;
403 mwifiex_update_ralist_tx_pause(priv,
404 tp->peermac,
405 tp->tx_pause);
406 }
407 }
408 }
409}
410
411void mwifiex_process_multi_chan_event(struct mwifiex_private *priv,
412 struct sk_buff *event_skb)
413{
414 struct mwifiex_ie_types_multi_chan_info *chan_info;
415 struct mwifiex_ie_types_mc_group_info *grp_info;
416 struct mwifiex_adapter *adapter = priv->adapter;
417 struct mwifiex_ie_types_header *tlv;
418 u16 tlv_buf_left, tlv_type, tlv_len;
419 int intf_num, bss_type, bss_num, i;
420 struct mwifiex_private *intf_priv;
421
422 tlv_buf_left = event_skb->len - sizeof(u32);
423 chan_info = (void *)event_skb->data + sizeof(u32);
424
425 if (le16_to_cpu(chan_info->header.type) != TLV_TYPE_MULTI_CHAN_INFO ||
426 tlv_buf_left < sizeof(struct mwifiex_ie_types_multi_chan_info)) {
427 mwifiex_dbg(adapter, ERROR,
428 "unknown TLV in chan_info event\n");
429 return;
430 }
431
432 adapter->usb_mc_status = le16_to_cpu(chan_info->status);
433 mwifiex_dbg(adapter, EVENT, "multi chan operation %s\n",
434 adapter->usb_mc_status ? "started" : "over");
435
436 tlv_buf_left -= sizeof(struct mwifiex_ie_types_multi_chan_info);
437 tlv = (struct mwifiex_ie_types_header *)chan_info->tlv_buffer;
438
439 while (tlv_buf_left >= (int)sizeof(struct mwifiex_ie_types_header)) {
440 tlv_type = le16_to_cpu(tlv->type);
441 tlv_len = le16_to_cpu(tlv->len);
442 if ((sizeof(struct mwifiex_ie_types_header) + tlv_len) >
443 tlv_buf_left) {
444 mwifiex_dbg(adapter, ERROR, "wrong tlv: tlvLen=%d,\t"
445 "tlvBufLeft=%d\n", tlv_len, tlv_buf_left);
446 break;
447 }
448 if (tlv_type != TLV_TYPE_MC_GROUP_INFO) {
449 mwifiex_dbg(adapter, ERROR, "wrong tlv type: 0x%x\n",
450 tlv_type);
451 break;
452 }
453
454 grp_info = (struct mwifiex_ie_types_mc_group_info *)tlv;
455 intf_num = grp_info->intf_num;
456 for (i = 0; i < intf_num; i++) {
457 bss_type = grp_info->bss_type_numlist[i] >> 4;
458 bss_num = grp_info->bss_type_numlist[i] & BSS_NUM_MASK;
459 intf_priv = mwifiex_get_priv_by_id(adapter, bss_num,
460 bss_type);
461 if (!intf_priv) {
462 mwifiex_dbg(adapter, ERROR,
463 "Invalid bss_type bss_num\t"
464 "in multi channel event\n");
465 continue;
466 }
467 if (adapter->iface_type == MWIFIEX_USB) {
468 u8 ep;
469
470 ep = grp_info->hid_num.usb_ep_num;
471 if (ep == MWIFIEX_USB_EP_DATA ||
472 ep == MWIFIEX_USB_EP_DATA_CH2)
473 intf_priv->usb_port = ep;
474 }
475 }
476
477 tlv_buf_left -= sizeof(struct mwifiex_ie_types_header) +
478 tlv_len;
479 tlv = (void *)((u8 *)tlv + tlv_len +
480 sizeof(struct mwifiex_ie_types_header));
481 }
482
483 if (adapter->iface_type == MWIFIEX_USB) {
484 adapter->tx_lock_flag = true;
485 adapter->usb_mc_setup = true;
486 mwifiex_multi_chan_resync(adapter);
487 }
488}
489
490void mwifiex_process_tx_pause_event(struct mwifiex_private *priv,
491 struct sk_buff *event_skb)
492{
493 struct mwifiex_ie_types_header *tlv;
494 u16 tlv_type, tlv_len;
495 int tlv_buf_left;
496
497 if (!priv->media_connected) {
498 mwifiex_dbg(priv->adapter, ERROR,
499 "tx_pause event while disconnected; bss_role=%d\n",
500 priv->bss_role);
501 return;
502 }
503
504 tlv_buf_left = event_skb->len - sizeof(u32);
505 tlv = (void *)event_skb->data + sizeof(u32);
506
507 while (tlv_buf_left >= (int)sizeof(struct mwifiex_ie_types_header)) {
508 tlv_type = le16_to_cpu(tlv->type);
509 tlv_len = le16_to_cpu(tlv->len);
510 if ((sizeof(struct mwifiex_ie_types_header) + tlv_len) >
511 tlv_buf_left) {
512 mwifiex_dbg(priv->adapter, ERROR,
513 "wrong tlv: tlvLen=%d, tlvBufLeft=%d\n",
514 tlv_len, tlv_buf_left);
515 break;
516 }
517 if (tlv_type == TLV_TYPE_TX_PAUSE) {
518 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA)
519 mwifiex_process_sta_tx_pause(priv, tlv);
520 else
521 mwifiex_process_uap_tx_pause(priv, tlv);
522 }
523
524 tlv_buf_left -= sizeof(struct mwifiex_ie_types_header) +
525 tlv_len;
526 tlv = (void *)((u8 *)tlv + tlv_len +
527 sizeof(struct mwifiex_ie_types_header));
528 }
529
530}
531
532
533
534
535void mwifiex_bt_coex_wlan_param_update_event(struct mwifiex_private *priv,
536 struct sk_buff *event_skb)
537{
538 struct mwifiex_adapter *adapter = priv->adapter;
539 struct mwifiex_ie_types_header *tlv;
540 struct mwifiex_ie_types_btcoex_aggr_win_size *winsizetlv;
541 struct mwifiex_ie_types_btcoex_scan_time *scantlv;
542 s32 len = event_skb->len - sizeof(u32);
543 u8 *cur_ptr = event_skb->data + sizeof(u32);
544 u16 tlv_type, tlv_len;
545
546 while (len >= sizeof(struct mwifiex_ie_types_header)) {
547 tlv = (struct mwifiex_ie_types_header *)cur_ptr;
548 tlv_len = le16_to_cpu(tlv->len);
549 tlv_type = le16_to_cpu(tlv->type);
550
551 if ((tlv_len + sizeof(struct mwifiex_ie_types_header)) > len)
552 break;
553 switch (tlv_type) {
554 case TLV_BTCOEX_WL_AGGR_WINSIZE:
555 winsizetlv =
556 (struct mwifiex_ie_types_btcoex_aggr_win_size *)tlv;
557 adapter->coex_win_size = winsizetlv->coex_win_size;
558 adapter->coex_tx_win_size =
559 winsizetlv->tx_win_size;
560 adapter->coex_rx_win_size =
561 winsizetlv->rx_win_size;
562 mwifiex_coex_ampdu_rxwinsize(adapter);
563 mwifiex_update_ampdu_txwinsize(adapter);
564 break;
565
566 case TLV_BTCOEX_WL_SCANTIME:
567 scantlv =
568 (struct mwifiex_ie_types_btcoex_scan_time *)tlv;
569 adapter->coex_scan = scantlv->coex_scan;
570 adapter->coex_min_scan_time = le16_to_cpu(scantlv->min_scan_time);
571 adapter->coex_max_scan_time = le16_to_cpu(scantlv->max_scan_time);
572 break;
573
574 default:
575 break;
576 }
577
578 len -= tlv_len + sizeof(struct mwifiex_ie_types_header);
579 cur_ptr += tlv_len +
580 sizeof(struct mwifiex_ie_types_header);
581 }
582
583 dev_dbg(adapter->dev, "coex_scan=%d min_scan=%d coex_win=%d, tx_win=%d rx_win=%d\n",
584 adapter->coex_scan, adapter->coex_min_scan_time,
585 adapter->coex_win_size, adapter->coex_tx_win_size,
586 adapter->coex_rx_win_size);
587}
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642int mwifiex_process_sta_event(struct mwifiex_private *priv)
643{
644 struct mwifiex_adapter *adapter = priv->adapter;
645 int ret = 0, i;
646 u32 eventcause = adapter->event_cause;
647 u16 ctrl, reason_code;
648 u8 ibss_sta_addr[ETH_ALEN];
649 struct mwifiex_sta_node *sta_ptr;
650
651 switch (eventcause) {
652 case EVENT_DUMMY_HOST_WAKEUP_SIGNAL:
653 mwifiex_dbg(adapter, ERROR,
654 "invalid EVENT: DUMMY_HOST_WAKEUP_SIGNAL, ignore it\n");
655 break;
656 case EVENT_LINK_SENSED:
657 mwifiex_dbg(adapter, EVENT, "event: LINK_SENSED\n");
658 if (!netif_carrier_ok(priv->netdev))
659 netif_carrier_on(priv->netdev);
660 mwifiex_wake_up_net_dev_queue(priv->netdev, adapter);
661 break;
662
663 case EVENT_DEAUTHENTICATED:
664 mwifiex_dbg(adapter, EVENT, "event: Deauthenticated\n");
665 if (priv->wps.session_enable) {
666 mwifiex_dbg(adapter, INFO,
667 "info: receive deauth event in wps session\n");
668 break;
669 }
670 adapter->dbg.num_event_deauth++;
671 if (priv->media_connected) {
672 reason_code =
673 get_unaligned_le16(adapter->event_body);
674 mwifiex_reset_connect_state(priv, reason_code, true);
675 }
676 break;
677
678 case EVENT_DISASSOCIATED:
679 mwifiex_dbg(adapter, EVENT, "event: Disassociated\n");
680 if (priv->wps.session_enable) {
681 mwifiex_dbg(adapter, INFO,
682 "info: receive disassoc event in wps session\n");
683 break;
684 }
685 adapter->dbg.num_event_disassoc++;
686 if (priv->media_connected) {
687 reason_code =
688 get_unaligned_le16(adapter->event_body);
689 mwifiex_reset_connect_state(priv, reason_code, true);
690 }
691 break;
692
693 case EVENT_LINK_LOST:
694 mwifiex_dbg(adapter, EVENT, "event: Link lost\n");
695 adapter->dbg.num_event_link_lost++;
696 if (priv->media_connected) {
697 reason_code =
698 get_unaligned_le16(adapter->event_body);
699 mwifiex_reset_connect_state(priv, reason_code, true);
700 }
701 break;
702
703 case EVENT_PS_SLEEP:
704 mwifiex_dbg(adapter, EVENT, "info: EVENT: SLEEP\n");
705
706 adapter->ps_state = PS_STATE_PRE_SLEEP;
707
708 mwifiex_check_ps_cond(adapter);
709 break;
710
711 case EVENT_PS_AWAKE:
712 mwifiex_dbg(adapter, EVENT, "info: EVENT: AWAKE\n");
713 if (!adapter->pps_uapsd_mode &&
714 (priv->port_open ||
715 (priv->bss_mode == NL80211_IFTYPE_ADHOC)) &&
716 priv->media_connected && adapter->sleep_period.period) {
717 adapter->pps_uapsd_mode = true;
718 mwifiex_dbg(adapter, EVENT,
719 "event: PPS/UAPSD mode activated\n");
720 }
721 adapter->tx_lock_flag = false;
722 if (adapter->pps_uapsd_mode && adapter->gen_null_pkt) {
723 if (mwifiex_check_last_packet_indication(priv)) {
724 if (adapter->data_sent ||
725 (adapter->if_ops.is_port_ready &&
726 !adapter->if_ops.is_port_ready(priv))) {
727 adapter->ps_state = PS_STATE_AWAKE;
728 adapter->pm_wakeup_card_req = false;
729 adapter->pm_wakeup_fw_try = false;
730 del_timer(&adapter->wakeup_timer);
731 break;
732 }
733 if (!mwifiex_send_null_packet
734 (priv,
735 MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET |
736 MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET))
737 adapter->ps_state =
738 PS_STATE_SLEEP;
739 return 0;
740 }
741 }
742 adapter->ps_state = PS_STATE_AWAKE;
743 adapter->pm_wakeup_card_req = false;
744 adapter->pm_wakeup_fw_try = false;
745 del_timer(&adapter->wakeup_timer);
746
747 break;
748
749 case EVENT_DEEP_SLEEP_AWAKE:
750 adapter->if_ops.wakeup_complete(adapter);
751 mwifiex_dbg(adapter, EVENT, "event: DS_AWAKE\n");
752 if (adapter->is_deep_sleep)
753 adapter->is_deep_sleep = false;
754 break;
755
756 case EVENT_HS_ACT_REQ:
757 mwifiex_dbg(adapter, EVENT, "event: HS_ACT_REQ\n");
758 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_HS_CFG_ENH,
759 0, 0, NULL, false);
760 break;
761
762 case EVENT_MIC_ERR_UNICAST:
763 mwifiex_dbg(adapter, EVENT, "event: UNICAST MIC ERROR\n");
764 cfg80211_michael_mic_failure(priv->netdev, priv->cfg_bssid,
765 NL80211_KEYTYPE_PAIRWISE,
766 -1, NULL, GFP_KERNEL);
767 break;
768
769 case EVENT_MIC_ERR_MULTICAST:
770 mwifiex_dbg(adapter, EVENT, "event: MULTICAST MIC ERROR\n");
771 cfg80211_michael_mic_failure(priv->netdev, priv->cfg_bssid,
772 NL80211_KEYTYPE_GROUP,
773 -1, NULL, GFP_KERNEL);
774 break;
775 case EVENT_MIB_CHANGED:
776 case EVENT_INIT_DONE:
777 break;
778
779 case EVENT_ADHOC_BCN_LOST:
780 mwifiex_dbg(adapter, EVENT, "event: ADHOC_BCN_LOST\n");
781 priv->adhoc_is_link_sensed = false;
782 mwifiex_clean_txrx(priv);
783 mwifiex_stop_net_dev_queue(priv->netdev, adapter);
784 if (netif_carrier_ok(priv->netdev))
785 netif_carrier_off(priv->netdev);
786 break;
787
788 case EVENT_BG_SCAN_REPORT:
789 mwifiex_dbg(adapter, EVENT, "event: BGS_REPORT\n");
790 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_BG_SCAN_QUERY,
791 HostCmd_ACT_GEN_GET, 0, NULL, false);
792 break;
793
794 case EVENT_BG_SCAN_STOPPED:
795 dev_dbg(adapter->dev, "event: BGS_STOPPED\n");
796 cfg80211_sched_scan_stopped(priv->wdev.wiphy, 0);
797 if (priv->sched_scanning)
798 priv->sched_scanning = false;
799 break;
800
801 case EVENT_PORT_RELEASE:
802 mwifiex_dbg(adapter, EVENT, "event: PORT RELEASE\n");
803 priv->port_open = true;
804 break;
805
806 case EVENT_EXT_SCAN_REPORT:
807 mwifiex_dbg(adapter, EVENT, "event: EXT_SCAN Report\n");
808
809
810
811 if (adapter->ext_scan && (!priv->scan_aborting ||
812 !netif_running(priv->netdev)))
813 ret = mwifiex_handle_event_ext_scan_report(priv,
814 adapter->event_skb->data);
815
816 break;
817
818 case EVENT_WMM_STATUS_CHANGE:
819 mwifiex_dbg(adapter, EVENT, "event: WMM status changed\n");
820 ret = mwifiex_send_cmd(priv, HostCmd_CMD_WMM_GET_STATUS,
821 0, 0, NULL, false);
822 break;
823
824 case EVENT_RSSI_LOW:
825 cfg80211_cqm_rssi_notify(priv->netdev,
826 NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
827 0, GFP_KERNEL);
828 mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO,
829 HostCmd_ACT_GEN_GET, 0, NULL, false);
830 priv->subsc_evt_rssi_state = RSSI_LOW_RECVD;
831 mwifiex_dbg(adapter, EVENT, "event: Beacon RSSI_LOW\n");
832 break;
833 case EVENT_SNR_LOW:
834 mwifiex_dbg(adapter, EVENT, "event: Beacon SNR_LOW\n");
835 break;
836 case EVENT_MAX_FAIL:
837 mwifiex_dbg(adapter, EVENT, "event: MAX_FAIL\n");
838 break;
839 case EVENT_RSSI_HIGH:
840 cfg80211_cqm_rssi_notify(priv->netdev,
841 NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
842 0, GFP_KERNEL);
843 mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO,
844 HostCmd_ACT_GEN_GET, 0, NULL, false);
845 priv->subsc_evt_rssi_state = RSSI_HIGH_RECVD;
846 mwifiex_dbg(adapter, EVENT, "event: Beacon RSSI_HIGH\n");
847 break;
848 case EVENT_SNR_HIGH:
849 mwifiex_dbg(adapter, EVENT, "event: Beacon SNR_HIGH\n");
850 break;
851 case EVENT_DATA_RSSI_LOW:
852 mwifiex_dbg(adapter, EVENT, "event: Data RSSI_LOW\n");
853 break;
854 case EVENT_DATA_SNR_LOW:
855 mwifiex_dbg(adapter, EVENT, "event: Data SNR_LOW\n");
856 break;
857 case EVENT_DATA_RSSI_HIGH:
858 mwifiex_dbg(adapter, EVENT, "event: Data RSSI_HIGH\n");
859 break;
860 case EVENT_DATA_SNR_HIGH:
861 mwifiex_dbg(adapter, EVENT, "event: Data SNR_HIGH\n");
862 break;
863 case EVENT_LINK_QUALITY:
864 mwifiex_dbg(adapter, EVENT, "event: Link Quality\n");
865 break;
866 case EVENT_PRE_BEACON_LOST:
867 mwifiex_dbg(adapter, EVENT, "event: Pre-Beacon Lost\n");
868 break;
869 case EVENT_IBSS_COALESCED:
870 mwifiex_dbg(adapter, EVENT, "event: IBSS_COALESCED\n");
871 ret = mwifiex_send_cmd(priv,
872 HostCmd_CMD_802_11_IBSS_COALESCING_STATUS,
873 HostCmd_ACT_GEN_GET, 0, NULL, false);
874 break;
875 case EVENT_IBSS_STA_CONNECT:
876 ether_addr_copy(ibss_sta_addr, adapter->event_body + 2);
877 mwifiex_dbg(adapter, EVENT, "event: IBSS_STA_CONNECT %pM\n",
878 ibss_sta_addr);
879 sta_ptr = mwifiex_add_sta_entry(priv, ibss_sta_addr);
880 if (sta_ptr && adapter->adhoc_11n_enabled) {
881 mwifiex_check_ibss_peer_capabilties(priv, sta_ptr,
882 adapter->event_skb);
883 if (sta_ptr->is_11n_enabled)
884 for (i = 0; i < MAX_NUM_TID; i++)
885 sta_ptr->ampdu_sta[i] =
886 priv->aggr_prio_tbl[i].ampdu_user;
887 else
888 for (i = 0; i < MAX_NUM_TID; i++)
889 sta_ptr->ampdu_sta[i] =
890 BA_STREAM_NOT_ALLOWED;
891 memset(sta_ptr->rx_seq, 0xff, sizeof(sta_ptr->rx_seq));
892 }
893
894 break;
895 case EVENT_IBSS_STA_DISCONNECT:
896 ether_addr_copy(ibss_sta_addr, adapter->event_body + 2);
897 mwifiex_dbg(adapter, EVENT, "event: IBSS_STA_DISCONNECT %pM\n",
898 ibss_sta_addr);
899 sta_ptr = mwifiex_get_sta_entry(priv, ibss_sta_addr);
900 if (sta_ptr && sta_ptr->is_11n_enabled) {
901 mwifiex_11n_del_rx_reorder_tbl_by_ta(priv,
902 ibss_sta_addr);
903 mwifiex_del_tx_ba_stream_tbl_by_ra(priv, ibss_sta_addr);
904 }
905 mwifiex_wmm_del_peer_ra_list(priv, ibss_sta_addr);
906 mwifiex_del_sta_entry(priv, ibss_sta_addr);
907 break;
908 case EVENT_ADDBA:
909 mwifiex_dbg(adapter, EVENT, "event: ADDBA Request\n");
910 mwifiex_send_cmd(priv, HostCmd_CMD_11N_ADDBA_RSP,
911 HostCmd_ACT_GEN_SET, 0,
912 adapter->event_body, false);
913 break;
914 case EVENT_DELBA:
915 mwifiex_dbg(adapter, EVENT, "event: DELBA Request\n");
916 mwifiex_11n_delete_ba_stream(priv, adapter->event_body);
917 break;
918 case EVENT_BA_STREAM_TIEMOUT:
919 mwifiex_dbg(adapter, EVENT, "event: BA Stream timeout\n");
920 mwifiex_11n_ba_stream_timeout(priv,
921 (struct host_cmd_ds_11n_batimeout
922 *)
923 adapter->event_body);
924 break;
925 case EVENT_AMSDU_AGGR_CTRL:
926 ctrl = get_unaligned_le16(adapter->event_body);
927 mwifiex_dbg(adapter, EVENT,
928 "event: AMSDU_AGGR_CTRL %d\n", ctrl);
929
930 adapter->tx_buf_size =
931 min_t(u16, adapter->curr_tx_buf_size, ctrl);
932 mwifiex_dbg(adapter, EVENT, "event: tx_buf_size %d\n",
933 adapter->tx_buf_size);
934 break;
935
936 case EVENT_WEP_ICV_ERR:
937 mwifiex_dbg(adapter, EVENT, "event: WEP ICV error\n");
938 break;
939
940 case EVENT_BW_CHANGE:
941 mwifiex_dbg(adapter, EVENT, "event: BW Change\n");
942 break;
943
944 case EVENT_HOSTWAKE_STAIE:
945 mwifiex_dbg(adapter, EVENT,
946 "event: HOSTWAKE_STAIE %d\n", eventcause);
947 break;
948
949 case EVENT_REMAIN_ON_CHAN_EXPIRED:
950 mwifiex_dbg(adapter, EVENT,
951 "event: Remain on channel expired\n");
952 cfg80211_remain_on_channel_expired(&priv->wdev,
953 priv->roc_cfg.cookie,
954 &priv->roc_cfg.chan,
955 GFP_ATOMIC);
956
957 memset(&priv->roc_cfg, 0x00, sizeof(struct mwifiex_roc_cfg));
958
959 break;
960
961 case EVENT_CHANNEL_SWITCH_ANN:
962 mwifiex_dbg(adapter, EVENT, "event: Channel Switch Announcement\n");
963 priv->csa_expire_time =
964 jiffies + msecs_to_jiffies(DFS_CHAN_MOVE_TIME);
965 priv->csa_chan = priv->curr_bss_params.bss_descriptor.channel;
966 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_DEAUTHENTICATE,
967 HostCmd_ACT_GEN_SET, 0,
968 priv->curr_bss_params.bss_descriptor.mac_address,
969 false);
970 break;
971
972 case EVENT_TDLS_GENERIC_EVENT:
973 ret = mwifiex_parse_tdls_event(priv, adapter->event_skb);
974 break;
975
976 case EVENT_TX_DATA_PAUSE:
977 mwifiex_dbg(adapter, EVENT, "event: TX DATA PAUSE\n");
978 mwifiex_process_tx_pause_event(priv, adapter->event_skb);
979 break;
980
981 case EVENT_MULTI_CHAN_INFO:
982 mwifiex_dbg(adapter, EVENT, "event: multi-chan info\n");
983 mwifiex_process_multi_chan_event(priv, adapter->event_skb);
984 break;
985
986 case EVENT_TX_STATUS_REPORT:
987 mwifiex_dbg(adapter, EVENT, "event: TX_STATUS Report\n");
988 mwifiex_parse_tx_status_event(priv, adapter->event_body);
989 break;
990
991 case EVENT_CHANNEL_REPORT_RDY:
992 mwifiex_dbg(adapter, EVENT, "event: Channel Report\n");
993 ret = mwifiex_11h_handle_chanrpt_ready(priv,
994 adapter->event_skb);
995 break;
996 case EVENT_RADAR_DETECTED:
997 mwifiex_dbg(adapter, EVENT, "event: Radar detected\n");
998 ret = mwifiex_11h_handle_radar_detected(priv,
999 adapter->event_skb);
1000 break;
1001 case EVENT_BT_COEX_WLAN_PARA_CHANGE:
1002 dev_dbg(adapter->dev, "EVENT: BT coex wlan param update\n");
1003 mwifiex_bt_coex_wlan_param_update_event(priv,
1004 adapter->event_skb);
1005 break;
1006 case EVENT_RXBA_SYNC:
1007 dev_dbg(adapter->dev, "EVENT: RXBA_SYNC\n");
1008 mwifiex_11n_rxba_sync_event(priv, adapter->event_body,
1009 adapter->event_skb->len -
1010 sizeof(eventcause));
1011 break;
1012
1013 case EVENT_UNKNOWN_DEBUG:
1014 mwifiex_dbg(adapter, EVENT, "event: debug\n");
1015 break;
1016 default:
1017 mwifiex_dbg(adapter, ERROR, "event: unknown event id: %#x\n",
1018 eventcause);
1019 break;
1020 }
1021
1022 return ret;
1023}
1024