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