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