This source file includes following definitions.
- mwifiex_check_ibss_peer_capabilities
- mwifiex_reset_connect_state
- mwifiex_parse_tdls_event
- mwifiex_process_uap_tx_pause
- mwifiex_process_sta_tx_pause
- mwifiex_process_multi_chan_event
- mwifiex_process_tx_pause_event
- mwifiex_bt_coex_wlan_param_update_event
- mwifiex_fw_dump_info_event
- mwifiex_process_sta_event
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
30 static 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 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
136 void 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
252 static 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
343 static 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
349 tp = (void *)tlv;
350 mwifiex_dbg(priv->adapter, EVENT,
351 "uap tx_pause: %pM pause=%d, pkts=%d\n",
352 tp->peermac, tp->tx_pause,
353 tp->pkt_cnt);
354
355 if (ether_addr_equal(tp->peermac, priv->netdev->dev_addr)) {
356 if (tp->tx_pause)
357 priv->port_open = false;
358 else
359 priv->port_open = true;
360 } else if (is_multicast_ether_addr(tp->peermac)) {
361 mwifiex_update_ralist_tx_pause(priv, tp->peermac, tp->tx_pause);
362 } else {
363 spin_lock_bh(&priv->sta_list_spinlock);
364 sta_ptr = mwifiex_get_sta_entry(priv, tp->peermac);
365 if (sta_ptr && sta_ptr->tx_pause != tp->tx_pause) {
366 sta_ptr->tx_pause = tp->tx_pause;
367 mwifiex_update_ralist_tx_pause(priv, tp->peermac,
368 tp->tx_pause);
369 }
370 spin_unlock_bh(&priv->sta_list_spinlock);
371 }
372 }
373
374 static void mwifiex_process_sta_tx_pause(struct mwifiex_private *priv,
375 struct mwifiex_ie_types_header *tlv)
376 {
377 struct mwifiex_tx_pause_tlv *tp;
378 struct mwifiex_sta_node *sta_ptr;
379 int status;
380
381 tp = (void *)tlv;
382 mwifiex_dbg(priv->adapter, EVENT,
383 "sta tx_pause: %pM pause=%d, pkts=%d\n",
384 tp->peermac, tp->tx_pause,
385 tp->pkt_cnt);
386
387 if (ether_addr_equal(tp->peermac, priv->cfg_bssid)) {
388 if (tp->tx_pause)
389 priv->port_open = false;
390 else
391 priv->port_open = true;
392 } else {
393 if (!ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info))
394 return;
395
396 status = mwifiex_get_tdls_link_status(priv, tp->peermac);
397 if (mwifiex_is_tdls_link_setup(status)) {
398 spin_lock_bh(&priv->sta_list_spinlock);
399 sta_ptr = mwifiex_get_sta_entry(priv, tp->peermac);
400 if (sta_ptr && sta_ptr->tx_pause != tp->tx_pause) {
401 sta_ptr->tx_pause = tp->tx_pause;
402 mwifiex_update_ralist_tx_pause(priv,
403 tp->peermac,
404 tp->tx_pause);
405 }
406 spin_unlock_bh(&priv->sta_list_spinlock);
407 }
408 }
409 }
410
411 void 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
490 void 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
535 void 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 static void
590 mwifiex_fw_dump_info_event(struct mwifiex_private *priv,
591 struct sk_buff *event_skb)
592 {
593 struct mwifiex_adapter *adapter = priv->adapter;
594 struct mwifiex_fw_dump_header *fw_dump_hdr =
595 (void *)adapter->event_body;
596
597 if (adapter->iface_type != MWIFIEX_USB) {
598 mwifiex_dbg(adapter, MSG,
599 "event is not on usb interface, ignore it\n");
600 return;
601 }
602
603 if (!adapter->devdump_data) {
604
605
606
607 adapter->devdump_data = vzalloc(MWIFIEX_FW_DUMP_SIZE);
608 if (!adapter->devdump_data) {
609 mwifiex_dbg(adapter, ERROR,
610 "vzalloc devdump data failure!\n");
611 return;
612 }
613
614 mwifiex_drv_info_dump(adapter);
615
616
617
618
619
620
621 mod_timer(&adapter->devdump_timer,
622 jiffies + msecs_to_jiffies(MWIFIEX_TIMER_10S));
623 }
624
625
626 if (adapter->devdump_len + event_skb->len >= MWIFIEX_FW_DUMP_SIZE)
627 goto upload_dump;
628
629 memmove(adapter->devdump_data + adapter->devdump_len,
630 adapter->event_skb->data, event_skb->len);
631 adapter->devdump_len += event_skb->len;
632
633 if (le16_to_cpu(fw_dump_hdr->type == FW_DUMP_INFO_ENDED)) {
634 mwifiex_dbg(adapter, MSG,
635 "receive end of transmission flag event!\n");
636 goto upload_dump;
637 }
638 return;
639
640 upload_dump:
641 del_timer_sync(&adapter->devdump_timer);
642 mwifiex_upload_device_dump(adapter);
643 }
644
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 int mwifiex_process_sta_event(struct mwifiex_private *priv)
700 {
701 struct mwifiex_adapter *adapter = priv->adapter;
702 int ret = 0, i;
703 u32 eventcause = adapter->event_cause;
704 u16 ctrl, reason_code;
705 u8 ibss_sta_addr[ETH_ALEN];
706 struct mwifiex_sta_node *sta_ptr;
707
708 switch (eventcause) {
709 case EVENT_DUMMY_HOST_WAKEUP_SIGNAL:
710 mwifiex_dbg(adapter, ERROR,
711 "invalid EVENT: DUMMY_HOST_WAKEUP_SIGNAL, ignore it\n");
712 break;
713 case EVENT_LINK_SENSED:
714 mwifiex_dbg(adapter, EVENT, "event: LINK_SENSED\n");
715 if (!netif_carrier_ok(priv->netdev))
716 netif_carrier_on(priv->netdev);
717 mwifiex_wake_up_net_dev_queue(priv->netdev, adapter);
718 break;
719
720 case EVENT_DEAUTHENTICATED:
721 mwifiex_dbg(adapter, EVENT, "event: Deauthenticated\n");
722 if (priv->wps.session_enable) {
723 mwifiex_dbg(adapter, INFO,
724 "info: receive deauth event in wps session\n");
725 break;
726 }
727 adapter->dbg.num_event_deauth++;
728 if (priv->media_connected) {
729 reason_code =
730 get_unaligned_le16(adapter->event_body);
731 mwifiex_reset_connect_state(priv, reason_code, true);
732 }
733 break;
734
735 case EVENT_DISASSOCIATED:
736 mwifiex_dbg(adapter, EVENT, "event: Disassociated\n");
737 if (priv->wps.session_enable) {
738 mwifiex_dbg(adapter, INFO,
739 "info: receive disassoc event in wps session\n");
740 break;
741 }
742 adapter->dbg.num_event_disassoc++;
743 if (priv->media_connected) {
744 reason_code =
745 get_unaligned_le16(adapter->event_body);
746 mwifiex_reset_connect_state(priv, reason_code, true);
747 }
748 break;
749
750 case EVENT_LINK_LOST:
751 mwifiex_dbg(adapter, EVENT, "event: Link lost\n");
752 adapter->dbg.num_event_link_lost++;
753 if (priv->media_connected) {
754 reason_code =
755 get_unaligned_le16(adapter->event_body);
756 mwifiex_reset_connect_state(priv, reason_code, true);
757 }
758 break;
759
760 case EVENT_PS_SLEEP:
761 mwifiex_dbg(adapter, EVENT, "info: EVENT: SLEEP\n");
762
763 adapter->ps_state = PS_STATE_PRE_SLEEP;
764
765 mwifiex_check_ps_cond(adapter);
766 break;
767
768 case EVENT_PS_AWAKE:
769 mwifiex_dbg(adapter, EVENT, "info: EVENT: AWAKE\n");
770 if (!adapter->pps_uapsd_mode &&
771 (priv->port_open ||
772 (priv->bss_mode == NL80211_IFTYPE_ADHOC)) &&
773 priv->media_connected && adapter->sleep_period.period) {
774 adapter->pps_uapsd_mode = true;
775 mwifiex_dbg(adapter, EVENT,
776 "event: PPS/UAPSD mode activated\n");
777 }
778 adapter->tx_lock_flag = false;
779 if (adapter->pps_uapsd_mode && adapter->gen_null_pkt) {
780 if (mwifiex_check_last_packet_indication(priv)) {
781 if (adapter->data_sent ||
782 (adapter->if_ops.is_port_ready &&
783 !adapter->if_ops.is_port_ready(priv))) {
784 adapter->ps_state = PS_STATE_AWAKE;
785 adapter->pm_wakeup_card_req = false;
786 adapter->pm_wakeup_fw_try = false;
787 del_timer(&adapter->wakeup_timer);
788 break;
789 }
790 if (!mwifiex_send_null_packet
791 (priv,
792 MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET |
793 MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET))
794 adapter->ps_state =
795 PS_STATE_SLEEP;
796 return 0;
797 }
798 }
799 adapter->ps_state = PS_STATE_AWAKE;
800 adapter->pm_wakeup_card_req = false;
801 adapter->pm_wakeup_fw_try = false;
802 del_timer(&adapter->wakeup_timer);
803
804 break;
805
806 case EVENT_DEEP_SLEEP_AWAKE:
807 adapter->if_ops.wakeup_complete(adapter);
808 mwifiex_dbg(adapter, EVENT, "event: DS_AWAKE\n");
809 if (adapter->is_deep_sleep)
810 adapter->is_deep_sleep = false;
811 break;
812
813 case EVENT_HS_ACT_REQ:
814 mwifiex_dbg(adapter, EVENT, "event: HS_ACT_REQ\n");
815 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_HS_CFG_ENH,
816 0, 0, NULL, false);
817 break;
818
819 case EVENT_MIC_ERR_UNICAST:
820 mwifiex_dbg(adapter, EVENT, "event: UNICAST MIC ERROR\n");
821 cfg80211_michael_mic_failure(priv->netdev, priv->cfg_bssid,
822 NL80211_KEYTYPE_PAIRWISE,
823 -1, NULL, GFP_KERNEL);
824 break;
825
826 case EVENT_MIC_ERR_MULTICAST:
827 mwifiex_dbg(adapter, EVENT, "event: MULTICAST MIC ERROR\n");
828 cfg80211_michael_mic_failure(priv->netdev, priv->cfg_bssid,
829 NL80211_KEYTYPE_GROUP,
830 -1, NULL, GFP_KERNEL);
831 break;
832 case EVENT_MIB_CHANGED:
833 case EVENT_INIT_DONE:
834 break;
835
836 case EVENT_ADHOC_BCN_LOST:
837 mwifiex_dbg(adapter, EVENT, "event: ADHOC_BCN_LOST\n");
838 priv->adhoc_is_link_sensed = false;
839 mwifiex_clean_txrx(priv);
840 mwifiex_stop_net_dev_queue(priv->netdev, adapter);
841 if (netif_carrier_ok(priv->netdev))
842 netif_carrier_off(priv->netdev);
843 break;
844
845 case EVENT_BG_SCAN_REPORT:
846 mwifiex_dbg(adapter, EVENT, "event: BGS_REPORT\n");
847 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_BG_SCAN_QUERY,
848 HostCmd_ACT_GEN_GET, 0, NULL, false);
849 break;
850
851 case EVENT_BG_SCAN_STOPPED:
852 dev_dbg(adapter->dev, "event: BGS_STOPPED\n");
853 cfg80211_sched_scan_stopped(priv->wdev.wiphy, 0);
854 if (priv->sched_scanning)
855 priv->sched_scanning = false;
856 break;
857
858 case EVENT_PORT_RELEASE:
859 mwifiex_dbg(adapter, EVENT, "event: PORT RELEASE\n");
860 priv->port_open = true;
861 break;
862
863 case EVENT_EXT_SCAN_REPORT:
864 mwifiex_dbg(adapter, EVENT, "event: EXT_SCAN Report\n");
865
866
867
868 if (adapter->ext_scan && (!priv->scan_aborting ||
869 !netif_running(priv->netdev)))
870 ret = mwifiex_handle_event_ext_scan_report(priv,
871 adapter->event_skb->data);
872
873 break;
874
875 case EVENT_WMM_STATUS_CHANGE:
876 mwifiex_dbg(adapter, EVENT, "event: WMM status changed\n");
877 ret = mwifiex_send_cmd(priv, HostCmd_CMD_WMM_GET_STATUS,
878 0, 0, NULL, false);
879 break;
880
881 case EVENT_RSSI_LOW:
882 cfg80211_cqm_rssi_notify(priv->netdev,
883 NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
884 0, GFP_KERNEL);
885 mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO,
886 HostCmd_ACT_GEN_GET, 0, NULL, false);
887 priv->subsc_evt_rssi_state = RSSI_LOW_RECVD;
888 mwifiex_dbg(adapter, EVENT, "event: Beacon RSSI_LOW\n");
889 break;
890 case EVENT_SNR_LOW:
891 mwifiex_dbg(adapter, EVENT, "event: Beacon SNR_LOW\n");
892 break;
893 case EVENT_MAX_FAIL:
894 mwifiex_dbg(adapter, EVENT, "event: MAX_FAIL\n");
895 break;
896 case EVENT_RSSI_HIGH:
897 cfg80211_cqm_rssi_notify(priv->netdev,
898 NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
899 0, GFP_KERNEL);
900 mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO,
901 HostCmd_ACT_GEN_GET, 0, NULL, false);
902 priv->subsc_evt_rssi_state = RSSI_HIGH_RECVD;
903 mwifiex_dbg(adapter, EVENT, "event: Beacon RSSI_HIGH\n");
904 break;
905 case EVENT_SNR_HIGH:
906 mwifiex_dbg(adapter, EVENT, "event: Beacon SNR_HIGH\n");
907 break;
908 case EVENT_DATA_RSSI_LOW:
909 mwifiex_dbg(adapter, EVENT, "event: Data RSSI_LOW\n");
910 break;
911 case EVENT_DATA_SNR_LOW:
912 mwifiex_dbg(adapter, EVENT, "event: Data SNR_LOW\n");
913 break;
914 case EVENT_DATA_RSSI_HIGH:
915 mwifiex_dbg(adapter, EVENT, "event: Data RSSI_HIGH\n");
916 break;
917 case EVENT_DATA_SNR_HIGH:
918 mwifiex_dbg(adapter, EVENT, "event: Data SNR_HIGH\n");
919 break;
920 case EVENT_LINK_QUALITY:
921 mwifiex_dbg(adapter, EVENT, "event: Link Quality\n");
922 break;
923 case EVENT_PRE_BEACON_LOST:
924 mwifiex_dbg(adapter, EVENT, "event: Pre-Beacon Lost\n");
925 break;
926 case EVENT_IBSS_COALESCED:
927 mwifiex_dbg(adapter, EVENT, "event: IBSS_COALESCED\n");
928 ret = mwifiex_send_cmd(priv,
929 HostCmd_CMD_802_11_IBSS_COALESCING_STATUS,
930 HostCmd_ACT_GEN_GET, 0, NULL, false);
931 break;
932 case EVENT_IBSS_STA_CONNECT:
933 ether_addr_copy(ibss_sta_addr, adapter->event_body + 2);
934 mwifiex_dbg(adapter, EVENT, "event: IBSS_STA_CONNECT %pM\n",
935 ibss_sta_addr);
936 sta_ptr = mwifiex_add_sta_entry(priv, ibss_sta_addr);
937 if (sta_ptr && adapter->adhoc_11n_enabled) {
938 mwifiex_check_ibss_peer_capabilities(priv, sta_ptr,
939 adapter->event_skb);
940 if (sta_ptr->is_11n_enabled)
941 for (i = 0; i < MAX_NUM_TID; i++)
942 sta_ptr->ampdu_sta[i] =
943 priv->aggr_prio_tbl[i].ampdu_user;
944 else
945 for (i = 0; i < MAX_NUM_TID; i++)
946 sta_ptr->ampdu_sta[i] =
947 BA_STREAM_NOT_ALLOWED;
948 memset(sta_ptr->rx_seq, 0xff, sizeof(sta_ptr->rx_seq));
949 }
950
951 break;
952 case EVENT_IBSS_STA_DISCONNECT:
953 ether_addr_copy(ibss_sta_addr, adapter->event_body + 2);
954 mwifiex_dbg(adapter, EVENT, "event: IBSS_STA_DISCONNECT %pM\n",
955 ibss_sta_addr);
956 sta_ptr = mwifiex_get_sta_entry(priv, ibss_sta_addr);
957 if (sta_ptr && sta_ptr->is_11n_enabled) {
958 mwifiex_11n_del_rx_reorder_tbl_by_ta(priv,
959 ibss_sta_addr);
960 mwifiex_del_tx_ba_stream_tbl_by_ra(priv, ibss_sta_addr);
961 }
962 mwifiex_wmm_del_peer_ra_list(priv, ibss_sta_addr);
963 mwifiex_del_sta_entry(priv, ibss_sta_addr);
964 break;
965 case EVENT_ADDBA:
966 mwifiex_dbg(adapter, EVENT, "event: ADDBA Request\n");
967 mwifiex_send_cmd(priv, HostCmd_CMD_11N_ADDBA_RSP,
968 HostCmd_ACT_GEN_SET, 0,
969 adapter->event_body, false);
970 break;
971 case EVENT_DELBA:
972 mwifiex_dbg(adapter, EVENT, "event: DELBA Request\n");
973 mwifiex_11n_delete_ba_stream(priv, adapter->event_body);
974 break;
975 case EVENT_BA_STREAM_TIEMOUT:
976 mwifiex_dbg(adapter, EVENT, "event: BA Stream timeout\n");
977 mwifiex_11n_ba_stream_timeout(priv,
978 (struct host_cmd_ds_11n_batimeout
979 *)
980 adapter->event_body);
981 break;
982 case EVENT_AMSDU_AGGR_CTRL:
983 ctrl = get_unaligned_le16(adapter->event_body);
984 mwifiex_dbg(adapter, EVENT,
985 "event: AMSDU_AGGR_CTRL %d\n", ctrl);
986
987 adapter->tx_buf_size =
988 min_t(u16, adapter->curr_tx_buf_size, ctrl);
989 mwifiex_dbg(adapter, EVENT, "event: tx_buf_size %d\n",
990 adapter->tx_buf_size);
991 break;
992
993 case EVENT_WEP_ICV_ERR:
994 mwifiex_dbg(adapter, EVENT, "event: WEP ICV error\n");
995 break;
996
997 case EVENT_BW_CHANGE:
998 mwifiex_dbg(adapter, EVENT, "event: BW Change\n");
999 break;
1000
1001 case EVENT_HOSTWAKE_STAIE:
1002 mwifiex_dbg(adapter, EVENT,
1003 "event: HOSTWAKE_STAIE %d\n", eventcause);
1004 break;
1005
1006 case EVENT_REMAIN_ON_CHAN_EXPIRED:
1007 mwifiex_dbg(adapter, EVENT,
1008 "event: Remain on channel expired\n");
1009 cfg80211_remain_on_channel_expired(&priv->wdev,
1010 priv->roc_cfg.cookie,
1011 &priv->roc_cfg.chan,
1012 GFP_ATOMIC);
1013
1014 memset(&priv->roc_cfg, 0x00, sizeof(struct mwifiex_roc_cfg));
1015
1016 break;
1017
1018 case EVENT_CHANNEL_SWITCH_ANN:
1019 mwifiex_dbg(adapter, EVENT, "event: Channel Switch Announcement\n");
1020 priv->csa_expire_time =
1021 jiffies + msecs_to_jiffies(DFS_CHAN_MOVE_TIME);
1022 priv->csa_chan = priv->curr_bss_params.bss_descriptor.channel;
1023 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_DEAUTHENTICATE,
1024 HostCmd_ACT_GEN_SET, 0,
1025 priv->curr_bss_params.bss_descriptor.mac_address,
1026 false);
1027 break;
1028
1029 case EVENT_TDLS_GENERIC_EVENT:
1030 ret = mwifiex_parse_tdls_event(priv, adapter->event_skb);
1031 break;
1032
1033 case EVENT_TX_DATA_PAUSE:
1034 mwifiex_dbg(adapter, EVENT, "event: TX DATA PAUSE\n");
1035 mwifiex_process_tx_pause_event(priv, adapter->event_skb);
1036 break;
1037
1038 case EVENT_MULTI_CHAN_INFO:
1039 mwifiex_dbg(adapter, EVENT, "event: multi-chan info\n");
1040 mwifiex_process_multi_chan_event(priv, adapter->event_skb);
1041 break;
1042
1043 case EVENT_TX_STATUS_REPORT:
1044 mwifiex_dbg(adapter, EVENT, "event: TX_STATUS Report\n");
1045 mwifiex_parse_tx_status_event(priv, adapter->event_body);
1046 break;
1047
1048 case EVENT_CHANNEL_REPORT_RDY:
1049 mwifiex_dbg(adapter, EVENT, "event: Channel Report\n");
1050 ret = mwifiex_11h_handle_chanrpt_ready(priv,
1051 adapter->event_skb);
1052 break;
1053 case EVENT_RADAR_DETECTED:
1054 mwifiex_dbg(adapter, EVENT, "event: Radar detected\n");
1055 ret = mwifiex_11h_handle_radar_detected(priv,
1056 adapter->event_skb);
1057 break;
1058 case EVENT_BT_COEX_WLAN_PARA_CHANGE:
1059 dev_dbg(adapter->dev, "EVENT: BT coex wlan param update\n");
1060 mwifiex_bt_coex_wlan_param_update_event(priv,
1061 adapter->event_skb);
1062 break;
1063 case EVENT_RXBA_SYNC:
1064 dev_dbg(adapter->dev, "EVENT: RXBA_SYNC\n");
1065 mwifiex_11n_rxba_sync_event(priv, adapter->event_body,
1066 adapter->event_skb->len -
1067 sizeof(eventcause));
1068 break;
1069 case EVENT_FW_DUMP_INFO:
1070 mwifiex_dbg(adapter, EVENT, "event: firmware debug info\n");
1071 mwifiex_fw_dump_info_event(priv, adapter->event_skb);
1072 break;
1073
1074 case EVENT_UNKNOWN_DEBUG:
1075 mwifiex_dbg(adapter, EVENT, "event: debug\n");
1076 break;
1077 default:
1078 mwifiex_dbg(adapter, ERROR, "event: unknown event id: %#x\n",
1079 eventcause);
1080 break;
1081 }
1082
1083 return ret;
1084 }