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 (test_bit(MWIFIEX_IS_CMD_TIMEDOUT, &adapter->work_flags) &&
228 adapter->curr_cmd)
229 return;
230 priv->media_connected = false;
231 mwifiex_dbg(adapter, MSG,
232 "info: successfully disconnected from %pM: reason code %d\n",
233 priv->cfg_bssid, reason_code);
234 if (priv->bss_mode == NL80211_IFTYPE_STATION ||
235 priv->bss_mode == NL80211_IFTYPE_P2P_CLIENT) {
236 cfg80211_disconnected(priv->netdev, reason_code, NULL, 0,
237 !from_ap, GFP_KERNEL);
238 }
239 eth_zero_addr(priv->cfg_bssid);
240
241 mwifiex_stop_net_dev_queue(priv->netdev, adapter);
242 if (netif_carrier_ok(priv->netdev))
243 netif_carrier_off(priv->netdev);
244
245 if (!ISSUPP_FIRMWARE_SUPPLICANT(priv->adapter->fw_cap_info))
246 return;
247
248 mwifiex_send_cmd(priv, HostCmd_CMD_GTK_REKEY_OFFLOAD_CFG,
249 HostCmd_ACT_GEN_REMOVE, 0, NULL, false);
250}
251
252static int mwifiex_parse_tdls_event(struct mwifiex_private *priv,
253 struct sk_buff *event_skb)
254{
255 int ret = 0;
256 struct mwifiex_adapter *adapter = priv->adapter;
257 struct mwifiex_sta_node *sta_ptr;
258 struct mwifiex_tdls_generic_event *tdls_evt =
259 (void *)event_skb->data + sizeof(adapter->event_cause);
260 u8 *mac = tdls_evt->peer_mac;
261
262
263 if (event_skb->len < (sizeof(struct mwifiex_tdls_generic_event) -
264 sizeof(u16) - sizeof(adapter->event_cause))) {
265 mwifiex_dbg(adapter, ERROR, "Invalid event length!\n");
266 return -1;
267 }
268
269 sta_ptr = mwifiex_get_sta_entry(priv, tdls_evt->peer_mac);
270 if (!sta_ptr) {
271 mwifiex_dbg(adapter, ERROR, "cannot get sta entry!\n");
272 return -1;
273 }
274
275 switch (le16_to_cpu(tdls_evt->type)) {
276 case TDLS_EVENT_LINK_TEAR_DOWN:
277 cfg80211_tdls_oper_request(priv->netdev,
278 tdls_evt->peer_mac,
279 NL80211_TDLS_TEARDOWN,
280 le16_to_cpu(tdls_evt->u.reason_code),
281 GFP_KERNEL);
282 break;
283 case TDLS_EVENT_CHAN_SWITCH_RESULT:
284 mwifiex_dbg(adapter, EVENT, "tdls channel switch result :\n");
285 mwifiex_dbg(adapter, EVENT,
286 "status=0x%x, reason=0x%x cur_chan=%d\n",
287 tdls_evt->u.switch_result.status,
288 tdls_evt->u.switch_result.reason,
289 tdls_evt->u.switch_result.cur_chan);
290
291
292 if (tdls_evt->u.switch_result.status != 0) {
293 switch (tdls_evt->u.switch_result.cur_chan) {
294 case TDLS_BASE_CHANNEL:
295 sta_ptr->tdls_status = TDLS_IN_BASE_CHAN;
296 break;
297 case TDLS_OFF_CHANNEL:
298 sta_ptr->tdls_status = TDLS_IN_OFF_CHAN;
299 break;
300 default:
301 break;
302 }
303 return ret;
304 }
305
306
307 switch (tdls_evt->u.switch_result.cur_chan) {
308 case TDLS_BASE_CHANNEL:
309 if (sta_ptr->tdls_status == TDLS_IN_BASE_CHAN)
310 break;
311 mwifiex_update_ralist_tx_pause_in_tdls_cs(priv, mac,
312 false);
313 sta_ptr->tdls_status = TDLS_IN_BASE_CHAN;
314 break;
315 case TDLS_OFF_CHANNEL:
316 if (sta_ptr->tdls_status == TDLS_IN_OFF_CHAN)
317 break;
318 mwifiex_update_ralist_tx_pause_in_tdls_cs(priv, mac,
319 true);
320 sta_ptr->tdls_status = TDLS_IN_OFF_CHAN;
321 break;
322 default:
323 break;
324 }
325
326 break;
327 case TDLS_EVENT_START_CHAN_SWITCH:
328 mwifiex_dbg(adapter, EVENT, "tdls start channel switch...\n");
329 sta_ptr->tdls_status = TDLS_CHAN_SWITCHING;
330 break;
331 case TDLS_EVENT_CHAN_SWITCH_STOPPED:
332 mwifiex_dbg(adapter, EVENT,
333 "tdls chan switch stopped, reason=%d\n",
334 tdls_evt->u.cs_stop_reason);
335 break;
336 default:
337 break;
338 }
339
340 return ret;
341}
342
343static void mwifiex_process_uap_tx_pause(struct mwifiex_private *priv,
344 struct mwifiex_ie_types_header *tlv)
345{
346 struct mwifiex_tx_pause_tlv *tp;
347 struct mwifiex_sta_node *sta_ptr;
348 unsigned long flags;
349
350 tp = (void *)tlv;
351 mwifiex_dbg(priv->adapter, EVENT,
352 "uap tx_pause: %pM pause=%d, pkts=%d\n",
353 tp->peermac, tp->tx_pause,
354 tp->pkt_cnt);
355
356 if (ether_addr_equal(tp->peermac, priv->netdev->dev_addr)) {
357 if (tp->tx_pause)
358 priv->port_open = false;
359 else
360 priv->port_open = true;
361 } else if (is_multicast_ether_addr(tp->peermac)) {
362 mwifiex_update_ralist_tx_pause(priv, tp->peermac, tp->tx_pause);
363 } else {
364 spin_lock_irqsave(&priv->sta_list_spinlock, flags);
365 sta_ptr = mwifiex_get_sta_entry(priv, tp->peermac);
366 if (sta_ptr && sta_ptr->tx_pause != tp->tx_pause) {
367 sta_ptr->tx_pause = tp->tx_pause;
368 mwifiex_update_ralist_tx_pause(priv, tp->peermac,
369 tp->tx_pause);
370 }
371 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
372 }
373}
374
375static void mwifiex_process_sta_tx_pause(struct mwifiex_private *priv,
376 struct mwifiex_ie_types_header *tlv)
377{
378 struct mwifiex_tx_pause_tlv *tp;
379 struct mwifiex_sta_node *sta_ptr;
380 int status;
381 unsigned long flags;
382
383 tp = (void *)tlv;
384 mwifiex_dbg(priv->adapter, EVENT,
385 "sta tx_pause: %pM pause=%d, pkts=%d\n",
386 tp->peermac, tp->tx_pause,
387 tp->pkt_cnt);
388
389 if (ether_addr_equal(tp->peermac, priv->cfg_bssid)) {
390 if (tp->tx_pause)
391 priv->port_open = false;
392 else
393 priv->port_open = true;
394 } else {
395 if (!ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info))
396 return;
397
398 status = mwifiex_get_tdls_link_status(priv, tp->peermac);
399 if (mwifiex_is_tdls_link_setup(status)) {
400 spin_lock_irqsave(&priv->sta_list_spinlock, flags);
401 sta_ptr = mwifiex_get_sta_entry(priv, tp->peermac);
402 if (sta_ptr && sta_ptr->tx_pause != tp->tx_pause) {
403 sta_ptr->tx_pause = tp->tx_pause;
404 mwifiex_update_ralist_tx_pause(priv,
405 tp->peermac,
406 tp->tx_pause);
407 }
408 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
409 }
410 }
411}
412
413void mwifiex_process_multi_chan_event(struct mwifiex_private *priv,
414 struct sk_buff *event_skb)
415{
416 struct mwifiex_ie_types_multi_chan_info *chan_info;
417 struct mwifiex_ie_types_mc_group_info *grp_info;
418 struct mwifiex_adapter *adapter = priv->adapter;
419 struct mwifiex_ie_types_header *tlv;
420 u16 tlv_buf_left, tlv_type, tlv_len;
421 int intf_num, bss_type, bss_num, i;
422 struct mwifiex_private *intf_priv;
423
424 tlv_buf_left = event_skb->len - sizeof(u32);
425 chan_info = (void *)event_skb->data + sizeof(u32);
426
427 if (le16_to_cpu(chan_info->header.type) != TLV_TYPE_MULTI_CHAN_INFO ||
428 tlv_buf_left < sizeof(struct mwifiex_ie_types_multi_chan_info)) {
429 mwifiex_dbg(adapter, ERROR,
430 "unknown TLV in chan_info event\n");
431 return;
432 }
433
434 adapter->usb_mc_status = le16_to_cpu(chan_info->status);
435 mwifiex_dbg(adapter, EVENT, "multi chan operation %s\n",
436 adapter->usb_mc_status ? "started" : "over");
437
438 tlv_buf_left -= sizeof(struct mwifiex_ie_types_multi_chan_info);
439 tlv = (struct mwifiex_ie_types_header *)chan_info->tlv_buffer;
440
441 while (tlv_buf_left >= (int)sizeof(struct mwifiex_ie_types_header)) {
442 tlv_type = le16_to_cpu(tlv->type);
443 tlv_len = le16_to_cpu(tlv->len);
444 if ((sizeof(struct mwifiex_ie_types_header) + tlv_len) >
445 tlv_buf_left) {
446 mwifiex_dbg(adapter, ERROR, "wrong tlv: tlvLen=%d,\t"
447 "tlvBufLeft=%d\n", tlv_len, tlv_buf_left);
448 break;
449 }
450 if (tlv_type != TLV_TYPE_MC_GROUP_INFO) {
451 mwifiex_dbg(adapter, ERROR, "wrong tlv type: 0x%x\n",
452 tlv_type);
453 break;
454 }
455
456 grp_info = (struct mwifiex_ie_types_mc_group_info *)tlv;
457 intf_num = grp_info->intf_num;
458 for (i = 0; i < intf_num; i++) {
459 bss_type = grp_info->bss_type_numlist[i] >> 4;
460 bss_num = grp_info->bss_type_numlist[i] & BSS_NUM_MASK;
461 intf_priv = mwifiex_get_priv_by_id(adapter, bss_num,
462 bss_type);
463 if (!intf_priv) {
464 mwifiex_dbg(adapter, ERROR,
465 "Invalid bss_type bss_num\t"
466 "in multi channel event\n");
467 continue;
468 }
469 if (adapter->iface_type == MWIFIEX_USB) {
470 u8 ep;
471
472 ep = grp_info->hid_num.usb_ep_num;
473 if (ep == MWIFIEX_USB_EP_DATA ||
474 ep == MWIFIEX_USB_EP_DATA_CH2)
475 intf_priv->usb_port = ep;
476 }
477 }
478
479 tlv_buf_left -= sizeof(struct mwifiex_ie_types_header) +
480 tlv_len;
481 tlv = (void *)((u8 *)tlv + tlv_len +
482 sizeof(struct mwifiex_ie_types_header));
483 }
484
485 if (adapter->iface_type == MWIFIEX_USB) {
486 adapter->tx_lock_flag = true;
487 adapter->usb_mc_setup = true;
488 mwifiex_multi_chan_resync(adapter);
489 }
490}
491
492void mwifiex_process_tx_pause_event(struct mwifiex_private *priv,
493 struct sk_buff *event_skb)
494{
495 struct mwifiex_ie_types_header *tlv;
496 u16 tlv_type, tlv_len;
497 int tlv_buf_left;
498
499 if (!priv->media_connected) {
500 mwifiex_dbg(priv->adapter, ERROR,
501 "tx_pause event while disconnected; bss_role=%d\n",
502 priv->bss_role);
503 return;
504 }
505
506 tlv_buf_left = event_skb->len - sizeof(u32);
507 tlv = (void *)event_skb->data + sizeof(u32);
508
509 while (tlv_buf_left >= (int)sizeof(struct mwifiex_ie_types_header)) {
510 tlv_type = le16_to_cpu(tlv->type);
511 tlv_len = le16_to_cpu(tlv->len);
512 if ((sizeof(struct mwifiex_ie_types_header) + tlv_len) >
513 tlv_buf_left) {
514 mwifiex_dbg(priv->adapter, ERROR,
515 "wrong tlv: tlvLen=%d, tlvBufLeft=%d\n",
516 tlv_len, tlv_buf_left);
517 break;
518 }
519 if (tlv_type == TLV_TYPE_TX_PAUSE) {
520 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA)
521 mwifiex_process_sta_tx_pause(priv, tlv);
522 else
523 mwifiex_process_uap_tx_pause(priv, tlv);
524 }
525
526 tlv_buf_left -= sizeof(struct mwifiex_ie_types_header) +
527 tlv_len;
528 tlv = (void *)((u8 *)tlv + tlv_len +
529 sizeof(struct mwifiex_ie_types_header));
530 }
531
532}
533
534
535
536
537void mwifiex_bt_coex_wlan_param_update_event(struct mwifiex_private *priv,
538 struct sk_buff *event_skb)
539{
540 struct mwifiex_adapter *adapter = priv->adapter;
541 struct mwifiex_ie_types_header *tlv;
542 struct mwifiex_ie_types_btcoex_aggr_win_size *winsizetlv;
543 struct mwifiex_ie_types_btcoex_scan_time *scantlv;
544 s32 len = event_skb->len - sizeof(u32);
545 u8 *cur_ptr = event_skb->data + sizeof(u32);
546 u16 tlv_type, tlv_len;
547
548 while (len >= sizeof(struct mwifiex_ie_types_header)) {
549 tlv = (struct mwifiex_ie_types_header *)cur_ptr;
550 tlv_len = le16_to_cpu(tlv->len);
551 tlv_type = le16_to_cpu(tlv->type);
552
553 if ((tlv_len + sizeof(struct mwifiex_ie_types_header)) > len)
554 break;
555 switch (tlv_type) {
556 case TLV_BTCOEX_WL_AGGR_WINSIZE:
557 winsizetlv =
558 (struct mwifiex_ie_types_btcoex_aggr_win_size *)tlv;
559 adapter->coex_win_size = winsizetlv->coex_win_size;
560 adapter->coex_tx_win_size =
561 winsizetlv->tx_win_size;
562 adapter->coex_rx_win_size =
563 winsizetlv->rx_win_size;
564 mwifiex_coex_ampdu_rxwinsize(adapter);
565 mwifiex_update_ampdu_txwinsize(adapter);
566 break;
567
568 case TLV_BTCOEX_WL_SCANTIME:
569 scantlv =
570 (struct mwifiex_ie_types_btcoex_scan_time *)tlv;
571 adapter->coex_scan = scantlv->coex_scan;
572 adapter->coex_min_scan_time = le16_to_cpu(scantlv->min_scan_time);
573 adapter->coex_max_scan_time = le16_to_cpu(scantlv->max_scan_time);
574 break;
575
576 default:
577 break;
578 }
579
580 len -= tlv_len + sizeof(struct mwifiex_ie_types_header);
581 cur_ptr += tlv_len +
582 sizeof(struct mwifiex_ie_types_header);
583 }
584
585 dev_dbg(adapter->dev, "coex_scan=%d min_scan=%d coex_win=%d, tx_win=%d rx_win=%d\n",
586 adapter->coex_scan, adapter->coex_min_scan_time,
587 adapter->coex_win_size, adapter->coex_tx_win_size,
588 adapter->coex_rx_win_size);
589}
590
591static void
592mwifiex_fw_dump_info_event(struct mwifiex_private *priv,
593 struct sk_buff *event_skb)
594{
595 struct mwifiex_adapter *adapter = priv->adapter;
596 struct mwifiex_fw_dump_header *fw_dump_hdr =
597 (void *)adapter->event_body;
598
599 if (adapter->iface_type != MWIFIEX_USB) {
600 mwifiex_dbg(adapter, MSG,
601 "event is not on usb interface, ignore it\n");
602 return;
603 }
604
605 if (!adapter->devdump_data) {
606
607
608
609 adapter->devdump_data = vzalloc(MWIFIEX_FW_DUMP_SIZE);
610 if (!adapter->devdump_data) {
611 mwifiex_dbg(adapter, ERROR,
612 "vzalloc devdump data failure!\n");
613 return;
614 }
615
616 mwifiex_drv_info_dump(adapter);
617
618
619
620
621
622
623 mod_timer(&adapter->devdump_timer,
624 jiffies + msecs_to_jiffies(MWIFIEX_TIMER_10S));
625 }
626
627
628 if (adapter->devdump_len + event_skb->len >= MWIFIEX_FW_DUMP_SIZE)
629 goto upload_dump;
630
631 memmove(adapter->devdump_data + adapter->devdump_len,
632 adapter->event_skb->data, event_skb->len);
633 adapter->devdump_len += event_skb->len;
634
635 if (le16_to_cpu(fw_dump_hdr->type == FW_DUMP_INFO_ENDED)) {
636 mwifiex_dbg(adapter, MSG,
637 "receive end of transmission flag event!\n");
638 goto upload_dump;
639 }
640 return;
641
642upload_dump:
643 del_timer_sync(&adapter->devdump_timer);
644 mwifiex_upload_device_dump(adapter);
645}
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701int mwifiex_process_sta_event(struct mwifiex_private *priv)
702{
703 struct mwifiex_adapter *adapter = priv->adapter;
704 int ret = 0, i;
705 u32 eventcause = adapter->event_cause;
706 u16 ctrl, reason_code;
707 u8 ibss_sta_addr[ETH_ALEN];
708 struct mwifiex_sta_node *sta_ptr;
709
710 switch (eventcause) {
711 case EVENT_DUMMY_HOST_WAKEUP_SIGNAL:
712 mwifiex_dbg(adapter, ERROR,
713 "invalid EVENT: DUMMY_HOST_WAKEUP_SIGNAL, ignore it\n");
714 break;
715 case EVENT_LINK_SENSED:
716 mwifiex_dbg(adapter, EVENT, "event: LINK_SENSED\n");
717 if (!netif_carrier_ok(priv->netdev))
718 netif_carrier_on(priv->netdev);
719 mwifiex_wake_up_net_dev_queue(priv->netdev, adapter);
720 break;
721
722 case EVENT_DEAUTHENTICATED:
723 mwifiex_dbg(adapter, EVENT, "event: Deauthenticated\n");
724 if (priv->wps.session_enable) {
725 mwifiex_dbg(adapter, INFO,
726 "info: receive deauth event in wps session\n");
727 break;
728 }
729 adapter->dbg.num_event_deauth++;
730 if (priv->media_connected) {
731 reason_code =
732 get_unaligned_le16(adapter->event_body);
733 mwifiex_reset_connect_state(priv, reason_code, true);
734 }
735 break;
736
737 case EVENT_DISASSOCIATED:
738 mwifiex_dbg(adapter, EVENT, "event: Disassociated\n");
739 if (priv->wps.session_enable) {
740 mwifiex_dbg(adapter, INFO,
741 "info: receive disassoc event in wps session\n");
742 break;
743 }
744 adapter->dbg.num_event_disassoc++;
745 if (priv->media_connected) {
746 reason_code =
747 get_unaligned_le16(adapter->event_body);
748 mwifiex_reset_connect_state(priv, reason_code, true);
749 }
750 break;
751
752 case EVENT_LINK_LOST:
753 mwifiex_dbg(adapter, EVENT, "event: Link lost\n");
754 adapter->dbg.num_event_link_lost++;
755 if (priv->media_connected) {
756 reason_code =
757 get_unaligned_le16(adapter->event_body);
758 mwifiex_reset_connect_state(priv, reason_code, true);
759 }
760 break;
761
762 case EVENT_PS_SLEEP:
763 mwifiex_dbg(adapter, EVENT, "info: EVENT: SLEEP\n");
764
765 adapter->ps_state = PS_STATE_PRE_SLEEP;
766
767 mwifiex_check_ps_cond(adapter);
768 break;
769
770 case EVENT_PS_AWAKE:
771 mwifiex_dbg(adapter, EVENT, "info: EVENT: AWAKE\n");
772 if (!adapter->pps_uapsd_mode &&
773 (priv->port_open ||
774 (priv->bss_mode == NL80211_IFTYPE_ADHOC)) &&
775 priv->media_connected && adapter->sleep_period.period) {
776 adapter->pps_uapsd_mode = true;
777 mwifiex_dbg(adapter, EVENT,
778 "event: PPS/UAPSD mode activated\n");
779 }
780 adapter->tx_lock_flag = false;
781 if (adapter->pps_uapsd_mode && adapter->gen_null_pkt) {
782 if (mwifiex_check_last_packet_indication(priv)) {
783 if (adapter->data_sent ||
784 (adapter->if_ops.is_port_ready &&
785 !adapter->if_ops.is_port_ready(priv))) {
786 adapter->ps_state = PS_STATE_AWAKE;
787 adapter->pm_wakeup_card_req = false;
788 adapter->pm_wakeup_fw_try = false;
789 del_timer(&adapter->wakeup_timer);
790 break;
791 }
792 if (!mwifiex_send_null_packet
793 (priv,
794 MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET |
795 MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET))
796 adapter->ps_state =
797 PS_STATE_SLEEP;
798 return 0;
799 }
800 }
801 adapter->ps_state = PS_STATE_AWAKE;
802 adapter->pm_wakeup_card_req = false;
803 adapter->pm_wakeup_fw_try = false;
804 del_timer(&adapter->wakeup_timer);
805
806 break;
807
808 case EVENT_DEEP_SLEEP_AWAKE:
809 adapter->if_ops.wakeup_complete(adapter);
810 mwifiex_dbg(adapter, EVENT, "event: DS_AWAKE\n");
811 if (adapter->is_deep_sleep)
812 adapter->is_deep_sleep = false;
813 break;
814
815 case EVENT_HS_ACT_REQ:
816 mwifiex_dbg(adapter, EVENT, "event: HS_ACT_REQ\n");
817 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_HS_CFG_ENH,
818 0, 0, NULL, false);
819 break;
820
821 case EVENT_MIC_ERR_UNICAST:
822 mwifiex_dbg(adapter, EVENT, "event: UNICAST MIC ERROR\n");
823 cfg80211_michael_mic_failure(priv->netdev, priv->cfg_bssid,
824 NL80211_KEYTYPE_PAIRWISE,
825 -1, NULL, GFP_KERNEL);
826 break;
827
828 case EVENT_MIC_ERR_MULTICAST:
829 mwifiex_dbg(adapter, EVENT, "event: MULTICAST MIC ERROR\n");
830 cfg80211_michael_mic_failure(priv->netdev, priv->cfg_bssid,
831 NL80211_KEYTYPE_GROUP,
832 -1, NULL, GFP_KERNEL);
833 break;
834 case EVENT_MIB_CHANGED:
835 case EVENT_INIT_DONE:
836 break;
837
838 case EVENT_ADHOC_BCN_LOST:
839 mwifiex_dbg(adapter, EVENT, "event: ADHOC_BCN_LOST\n");
840 priv->adhoc_is_link_sensed = false;
841 mwifiex_clean_txrx(priv);
842 mwifiex_stop_net_dev_queue(priv->netdev, adapter);
843 if (netif_carrier_ok(priv->netdev))
844 netif_carrier_off(priv->netdev);
845 break;
846
847 case EVENT_BG_SCAN_REPORT:
848 mwifiex_dbg(adapter, EVENT, "event: BGS_REPORT\n");
849 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_BG_SCAN_QUERY,
850 HostCmd_ACT_GEN_GET, 0, NULL, false);
851 break;
852
853 case EVENT_BG_SCAN_STOPPED:
854 dev_dbg(adapter->dev, "event: BGS_STOPPED\n");
855 cfg80211_sched_scan_stopped(priv->wdev.wiphy, 0);
856 if (priv->sched_scanning)
857 priv->sched_scanning = false;
858 break;
859
860 case EVENT_PORT_RELEASE:
861 mwifiex_dbg(adapter, EVENT, "event: PORT RELEASE\n");
862 priv->port_open = true;
863 break;
864
865 case EVENT_EXT_SCAN_REPORT:
866 mwifiex_dbg(adapter, EVENT, "event: EXT_SCAN Report\n");
867
868
869
870 if (adapter->ext_scan && (!priv->scan_aborting ||
871 !netif_running(priv->netdev)))
872 ret = mwifiex_handle_event_ext_scan_report(priv,
873 adapter->event_skb->data);
874
875 break;
876
877 case EVENT_WMM_STATUS_CHANGE:
878 mwifiex_dbg(adapter, EVENT, "event: WMM status changed\n");
879 ret = mwifiex_send_cmd(priv, HostCmd_CMD_WMM_GET_STATUS,
880 0, 0, NULL, false);
881 break;
882
883 case EVENT_RSSI_LOW:
884 cfg80211_cqm_rssi_notify(priv->netdev,
885 NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
886 0, GFP_KERNEL);
887 mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO,
888 HostCmd_ACT_GEN_GET, 0, NULL, false);
889 priv->subsc_evt_rssi_state = RSSI_LOW_RECVD;
890 mwifiex_dbg(adapter, EVENT, "event: Beacon RSSI_LOW\n");
891 break;
892 case EVENT_SNR_LOW:
893 mwifiex_dbg(adapter, EVENT, "event: Beacon SNR_LOW\n");
894 break;
895 case EVENT_MAX_FAIL:
896 mwifiex_dbg(adapter, EVENT, "event: MAX_FAIL\n");
897 break;
898 case EVENT_RSSI_HIGH:
899 cfg80211_cqm_rssi_notify(priv->netdev,
900 NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
901 0, GFP_KERNEL);
902 mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO,
903 HostCmd_ACT_GEN_GET, 0, NULL, false);
904 priv->subsc_evt_rssi_state = RSSI_HIGH_RECVD;
905 mwifiex_dbg(adapter, EVENT, "event: Beacon RSSI_HIGH\n");
906 break;
907 case EVENT_SNR_HIGH:
908 mwifiex_dbg(adapter, EVENT, "event: Beacon SNR_HIGH\n");
909 break;
910 case EVENT_DATA_RSSI_LOW:
911 mwifiex_dbg(adapter, EVENT, "event: Data RSSI_LOW\n");
912 break;
913 case EVENT_DATA_SNR_LOW:
914 mwifiex_dbg(adapter, EVENT, "event: Data SNR_LOW\n");
915 break;
916 case EVENT_DATA_RSSI_HIGH:
917 mwifiex_dbg(adapter, EVENT, "event: Data RSSI_HIGH\n");
918 break;
919 case EVENT_DATA_SNR_HIGH:
920 mwifiex_dbg(adapter, EVENT, "event: Data SNR_HIGH\n");
921 break;
922 case EVENT_LINK_QUALITY:
923 mwifiex_dbg(adapter, EVENT, "event: Link Quality\n");
924 break;
925 case EVENT_PRE_BEACON_LOST:
926 mwifiex_dbg(adapter, EVENT, "event: Pre-Beacon Lost\n");
927 break;
928 case EVENT_IBSS_COALESCED:
929 mwifiex_dbg(adapter, EVENT, "event: IBSS_COALESCED\n");
930 ret = mwifiex_send_cmd(priv,
931 HostCmd_CMD_802_11_IBSS_COALESCING_STATUS,
932 HostCmd_ACT_GEN_GET, 0, NULL, false);
933 break;
934 case EVENT_IBSS_STA_CONNECT:
935 ether_addr_copy(ibss_sta_addr, adapter->event_body + 2);
936 mwifiex_dbg(adapter, EVENT, "event: IBSS_STA_CONNECT %pM\n",
937 ibss_sta_addr);
938 sta_ptr = mwifiex_add_sta_entry(priv, ibss_sta_addr);
939 if (sta_ptr && adapter->adhoc_11n_enabled) {
940 mwifiex_check_ibss_peer_capabilties(priv, sta_ptr,
941 adapter->event_skb);
942 if (sta_ptr->is_11n_enabled)
943 for (i = 0; i < MAX_NUM_TID; i++)
944 sta_ptr->ampdu_sta[i] =
945 priv->aggr_prio_tbl[i].ampdu_user;
946 else
947 for (i = 0; i < MAX_NUM_TID; i++)
948 sta_ptr->ampdu_sta[i] =
949 BA_STREAM_NOT_ALLOWED;
950 memset(sta_ptr->rx_seq, 0xff, sizeof(sta_ptr->rx_seq));
951 }
952
953 break;
954 case EVENT_IBSS_STA_DISCONNECT:
955 ether_addr_copy(ibss_sta_addr, adapter->event_body + 2);
956 mwifiex_dbg(adapter, EVENT, "event: IBSS_STA_DISCONNECT %pM\n",
957 ibss_sta_addr);
958 sta_ptr = mwifiex_get_sta_entry(priv, ibss_sta_addr);
959 if (sta_ptr && sta_ptr->is_11n_enabled) {
960 mwifiex_11n_del_rx_reorder_tbl_by_ta(priv,
961 ibss_sta_addr);
962 mwifiex_del_tx_ba_stream_tbl_by_ra(priv, ibss_sta_addr);
963 }
964 mwifiex_wmm_del_peer_ra_list(priv, ibss_sta_addr);
965 mwifiex_del_sta_entry(priv, ibss_sta_addr);
966 break;
967 case EVENT_ADDBA:
968 mwifiex_dbg(adapter, EVENT, "event: ADDBA Request\n");
969 mwifiex_send_cmd(priv, HostCmd_CMD_11N_ADDBA_RSP,
970 HostCmd_ACT_GEN_SET, 0,
971 adapter->event_body, false);
972 break;
973 case EVENT_DELBA:
974 mwifiex_dbg(adapter, EVENT, "event: DELBA Request\n");
975 mwifiex_11n_delete_ba_stream(priv, adapter->event_body);
976 break;
977 case EVENT_BA_STREAM_TIEMOUT:
978 mwifiex_dbg(adapter, EVENT, "event: BA Stream timeout\n");
979 mwifiex_11n_ba_stream_timeout(priv,
980 (struct host_cmd_ds_11n_batimeout
981 *)
982 adapter->event_body);
983 break;
984 case EVENT_AMSDU_AGGR_CTRL:
985 ctrl = get_unaligned_le16(adapter->event_body);
986 mwifiex_dbg(adapter, EVENT,
987 "event: AMSDU_AGGR_CTRL %d\n", ctrl);
988
989 adapter->tx_buf_size =
990 min_t(u16, adapter->curr_tx_buf_size, ctrl);
991 mwifiex_dbg(adapter, EVENT, "event: tx_buf_size %d\n",
992 adapter->tx_buf_size);
993 break;
994
995 case EVENT_WEP_ICV_ERR:
996 mwifiex_dbg(adapter, EVENT, "event: WEP ICV error\n");
997 break;
998
999 case EVENT_BW_CHANGE:
1000 mwifiex_dbg(adapter, EVENT, "event: BW Change\n");
1001 break;
1002
1003 case EVENT_HOSTWAKE_STAIE:
1004 mwifiex_dbg(adapter, EVENT,
1005 "event: HOSTWAKE_STAIE %d\n", eventcause);
1006 break;
1007
1008 case EVENT_REMAIN_ON_CHAN_EXPIRED:
1009 mwifiex_dbg(adapter, EVENT,
1010 "event: Remain on channel expired\n");
1011 cfg80211_remain_on_channel_expired(&priv->wdev,
1012 priv->roc_cfg.cookie,
1013 &priv->roc_cfg.chan,
1014 GFP_ATOMIC);
1015
1016 memset(&priv->roc_cfg, 0x00, sizeof(struct mwifiex_roc_cfg));
1017
1018 break;
1019
1020 case EVENT_CHANNEL_SWITCH_ANN:
1021 mwifiex_dbg(adapter, EVENT, "event: Channel Switch Announcement\n");
1022 priv->csa_expire_time =
1023 jiffies + msecs_to_jiffies(DFS_CHAN_MOVE_TIME);
1024 priv->csa_chan = priv->curr_bss_params.bss_descriptor.channel;
1025 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_DEAUTHENTICATE,
1026 HostCmd_ACT_GEN_SET, 0,
1027 priv->curr_bss_params.bss_descriptor.mac_address,
1028 false);
1029 break;
1030
1031 case EVENT_TDLS_GENERIC_EVENT:
1032 ret = mwifiex_parse_tdls_event(priv, adapter->event_skb);
1033 break;
1034
1035 case EVENT_TX_DATA_PAUSE:
1036 mwifiex_dbg(adapter, EVENT, "event: TX DATA PAUSE\n");
1037 mwifiex_process_tx_pause_event(priv, adapter->event_skb);
1038 break;
1039
1040 case EVENT_MULTI_CHAN_INFO:
1041 mwifiex_dbg(adapter, EVENT, "event: multi-chan info\n");
1042 mwifiex_process_multi_chan_event(priv, adapter->event_skb);
1043 break;
1044
1045 case EVENT_TX_STATUS_REPORT:
1046 mwifiex_dbg(adapter, EVENT, "event: TX_STATUS Report\n");
1047 mwifiex_parse_tx_status_event(priv, adapter->event_body);
1048 break;
1049
1050 case EVENT_CHANNEL_REPORT_RDY:
1051 mwifiex_dbg(adapter, EVENT, "event: Channel Report\n");
1052 ret = mwifiex_11h_handle_chanrpt_ready(priv,
1053 adapter->event_skb);
1054 break;
1055 case EVENT_RADAR_DETECTED:
1056 mwifiex_dbg(adapter, EVENT, "event: Radar detected\n");
1057 ret = mwifiex_11h_handle_radar_detected(priv,
1058 adapter->event_skb);
1059 break;
1060 case EVENT_BT_COEX_WLAN_PARA_CHANGE:
1061 dev_dbg(adapter->dev, "EVENT: BT coex wlan param update\n");
1062 mwifiex_bt_coex_wlan_param_update_event(priv,
1063 adapter->event_skb);
1064 break;
1065 case EVENT_RXBA_SYNC:
1066 dev_dbg(adapter->dev, "EVENT: RXBA_SYNC\n");
1067 mwifiex_11n_rxba_sync_event(priv, adapter->event_body,
1068 adapter->event_skb->len -
1069 sizeof(eventcause));
1070 break;
1071 case EVENT_FW_DUMP_INFO:
1072 mwifiex_dbg(adapter, EVENT, "event: firmware debug info\n");
1073 mwifiex_fw_dump_info_event(priv, adapter->event_skb);
1074 break;
1075
1076 case EVENT_UNKNOWN_DEBUG:
1077 mwifiex_dbg(adapter, EVENT, "event: debug\n");
1078 break;
1079 default:
1080 mwifiex_dbg(adapter, ERROR, "event: unknown event id: %#x\n",
1081 eventcause);
1082 break;
1083 }
1084
1085 return ret;
1086}
1087