0001
0002
0003
0004
0005
0006
0007
0008 #include "decl.h"
0009 #include "ioctl.h"
0010 #include "util.h"
0011 #include "fw.h"
0012 #include "main.h"
0013 #include "wmm.h"
0014 #include "11n.h"
0015
0016 #define MWIFIEX_IBSS_CONNECT_EVT_FIX_SIZE 12
0017
0018 static int mwifiex_check_ibss_peer_capabilities(struct mwifiex_private *priv,
0019 struct mwifiex_sta_node *sta_ptr,
0020 struct sk_buff *event)
0021 {
0022 int evt_len, ele_len;
0023 u8 *curr;
0024 struct ieee_types_header *ele_hdr;
0025 struct mwifiex_ie_types_mgmt_frame *tlv_mgmt_frame;
0026 const struct ieee80211_ht_cap *ht_cap;
0027 const struct ieee80211_vht_cap *vht_cap;
0028
0029 skb_pull(event, MWIFIEX_IBSS_CONNECT_EVT_FIX_SIZE);
0030 evt_len = event->len;
0031 curr = event->data;
0032
0033 mwifiex_dbg_dump(priv->adapter, EVT_D, "ibss peer capabilities:",
0034 event->data, event->len);
0035
0036 skb_push(event, MWIFIEX_IBSS_CONNECT_EVT_FIX_SIZE);
0037
0038 tlv_mgmt_frame = (void *)curr;
0039 if (evt_len >= sizeof(*tlv_mgmt_frame) &&
0040 le16_to_cpu(tlv_mgmt_frame->header.type) ==
0041 TLV_TYPE_UAP_MGMT_FRAME) {
0042
0043
0044
0045
0046 evt_len = le16_to_cpu(tlv_mgmt_frame->header.len);
0047 curr += (sizeof(*tlv_mgmt_frame) + 12);
0048 } else {
0049 mwifiex_dbg(priv->adapter, MSG,
0050 "management frame tlv not found!\n");
0051 return 0;
0052 }
0053
0054 while (evt_len >= sizeof(*ele_hdr)) {
0055 ele_hdr = (struct ieee_types_header *)curr;
0056 ele_len = ele_hdr->len;
0057
0058 if (evt_len < ele_len + sizeof(*ele_hdr))
0059 break;
0060
0061 switch (ele_hdr->element_id) {
0062 case WLAN_EID_HT_CAPABILITY:
0063 sta_ptr->is_11n_enabled = true;
0064 ht_cap = (void *)(ele_hdr + 2);
0065 sta_ptr->max_amsdu = le16_to_cpu(ht_cap->cap_info) &
0066 IEEE80211_HT_CAP_MAX_AMSDU ?
0067 MWIFIEX_TX_DATA_BUF_SIZE_8K :
0068 MWIFIEX_TX_DATA_BUF_SIZE_4K;
0069 mwifiex_dbg(priv->adapter, INFO,
0070 "11n enabled!, max_amsdu : %d\n",
0071 sta_ptr->max_amsdu);
0072 break;
0073
0074 case WLAN_EID_VHT_CAPABILITY:
0075 sta_ptr->is_11ac_enabled = true;
0076 vht_cap = (void *)(ele_hdr + 2);
0077
0078 switch (le32_to_cpu(vht_cap->vht_cap_info) & 0x3) {
0079 case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454:
0080 sta_ptr->max_amsdu =
0081 MWIFIEX_TX_DATA_BUF_SIZE_12K;
0082 break;
0083 case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991:
0084 sta_ptr->max_amsdu =
0085 MWIFIEX_TX_DATA_BUF_SIZE_8K;
0086 break;
0087 case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895:
0088 sta_ptr->max_amsdu =
0089 MWIFIEX_TX_DATA_BUF_SIZE_4K;
0090 break;
0091 default:
0092 break;
0093 }
0094
0095 mwifiex_dbg(priv->adapter, INFO,
0096 "11ac enabled!, max_amsdu : %d\n",
0097 sta_ptr->max_amsdu);
0098 break;
0099 default:
0100 break;
0101 }
0102
0103 curr += (ele_len + sizeof(*ele_hdr));
0104 evt_len -= (ele_len + sizeof(*ele_hdr));
0105 }
0106
0107 return 0;
0108 }
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125 void mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code,
0126 bool from_ap)
0127 {
0128 struct mwifiex_adapter *adapter = priv->adapter;
0129
0130 if (!priv->media_connected)
0131 return;
0132
0133 mwifiex_dbg(adapter, INFO,
0134 "info: handles disconnect event\n");
0135
0136 priv->media_connected = false;
0137
0138 priv->scan_block = false;
0139 priv->port_open = false;
0140
0141 if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
0142 ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info)) {
0143 mwifiex_disable_all_tdls_links(priv);
0144
0145 if (priv->adapter->auto_tdls)
0146 mwifiex_clean_auto_tdls(priv);
0147 }
0148
0149
0150 mwifiex_clean_txrx(priv);
0151
0152
0153 priv->data_rssi_last = 0;
0154 priv->data_nf_last = 0;
0155 priv->data_rssi_avg = 0;
0156 priv->data_nf_avg = 0;
0157 priv->bcn_rssi_last = 0;
0158 priv->bcn_nf_last = 0;
0159 priv->bcn_rssi_avg = 0;
0160 priv->bcn_nf_avg = 0;
0161 priv->rxpd_rate = 0;
0162 priv->rxpd_htinfo = 0;
0163 priv->sec_info.wpa_enabled = false;
0164 priv->sec_info.wpa2_enabled = false;
0165 priv->wpa_ie_len = 0;
0166
0167 priv->sec_info.wapi_enabled = false;
0168 priv->wapi_ie_len = 0;
0169 priv->sec_info.wapi_key_on = false;
0170
0171 priv->sec_info.encryption_mode = 0;
0172
0173
0174 priv->is_data_rate_auto = true;
0175 priv->data_rate = 0;
0176
0177 priv->assoc_resp_ht_param = 0;
0178 priv->ht_param_present = false;
0179
0180 if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA ||
0181 GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) && priv->hist_data)
0182 mwifiex_hist_data_reset(priv);
0183
0184 if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
0185 priv->adhoc_state = ADHOC_IDLE;
0186 priv->adhoc_is_link_sensed = false;
0187 }
0188
0189
0190
0191
0192
0193
0194 mwifiex_dbg(adapter, INFO,
0195 "info: previous SSID=%s, SSID len=%u\n",
0196 priv->prev_ssid.ssid, priv->prev_ssid.ssid_len);
0197
0198 mwifiex_dbg(adapter, INFO,
0199 "info: current SSID=%s, SSID len=%u\n",
0200 priv->curr_bss_params.bss_descriptor.ssid.ssid,
0201 priv->curr_bss_params.bss_descriptor.ssid.ssid_len);
0202
0203 memcpy(&priv->prev_ssid,
0204 &priv->curr_bss_params.bss_descriptor.ssid,
0205 sizeof(struct cfg80211_ssid));
0206
0207 memcpy(priv->prev_bssid,
0208 priv->curr_bss_params.bss_descriptor.mac_address, ETH_ALEN);
0209
0210
0211 memset(&priv->curr_bss_params, 0x00, sizeof(priv->curr_bss_params));
0212
0213 adapter->tx_lock_flag = false;
0214 adapter->pps_uapsd_mode = false;
0215
0216 if (test_bit(MWIFIEX_IS_CMD_TIMEDOUT, &adapter->work_flags) &&
0217 adapter->curr_cmd)
0218 return;
0219 priv->media_connected = false;
0220 mwifiex_dbg(adapter, MSG,
0221 "info: successfully disconnected from %pM: reason code %d\n",
0222 priv->cfg_bssid, reason_code);
0223 if (priv->bss_mode == NL80211_IFTYPE_STATION ||
0224 priv->bss_mode == NL80211_IFTYPE_P2P_CLIENT) {
0225 cfg80211_disconnected(priv->netdev, reason_code, NULL, 0,
0226 !from_ap, GFP_KERNEL);
0227 }
0228 eth_zero_addr(priv->cfg_bssid);
0229
0230 mwifiex_stop_net_dev_queue(priv->netdev, adapter);
0231 if (netif_carrier_ok(priv->netdev))
0232 netif_carrier_off(priv->netdev);
0233
0234 if (!ISSUPP_FIRMWARE_SUPPLICANT(priv->adapter->fw_cap_info))
0235 return;
0236
0237 mwifiex_send_cmd(priv, HostCmd_CMD_GTK_REKEY_OFFLOAD_CFG,
0238 HostCmd_ACT_GEN_REMOVE, 0, NULL, false);
0239 }
0240
0241 static int mwifiex_parse_tdls_event(struct mwifiex_private *priv,
0242 struct sk_buff *event_skb)
0243 {
0244 int ret = 0;
0245 struct mwifiex_adapter *adapter = priv->adapter;
0246 struct mwifiex_sta_node *sta_ptr;
0247 struct mwifiex_tdls_generic_event *tdls_evt =
0248 (void *)event_skb->data + sizeof(adapter->event_cause);
0249 u8 *mac = tdls_evt->peer_mac;
0250
0251
0252 if (event_skb->len < (sizeof(struct mwifiex_tdls_generic_event) -
0253 sizeof(u16) - sizeof(adapter->event_cause))) {
0254 mwifiex_dbg(adapter, ERROR, "Invalid event length!\n");
0255 return -1;
0256 }
0257
0258 sta_ptr = mwifiex_get_sta_entry(priv, tdls_evt->peer_mac);
0259 if (!sta_ptr) {
0260 mwifiex_dbg(adapter, ERROR, "cannot get sta entry!\n");
0261 return -1;
0262 }
0263
0264 switch (le16_to_cpu(tdls_evt->type)) {
0265 case TDLS_EVENT_LINK_TEAR_DOWN:
0266 cfg80211_tdls_oper_request(priv->netdev,
0267 tdls_evt->peer_mac,
0268 NL80211_TDLS_TEARDOWN,
0269 le16_to_cpu(tdls_evt->u.reason_code),
0270 GFP_KERNEL);
0271 break;
0272 case TDLS_EVENT_CHAN_SWITCH_RESULT:
0273 mwifiex_dbg(adapter, EVENT, "tdls channel switch result :\n");
0274 mwifiex_dbg(adapter, EVENT,
0275 "status=0x%x, reason=0x%x cur_chan=%d\n",
0276 tdls_evt->u.switch_result.status,
0277 tdls_evt->u.switch_result.reason,
0278 tdls_evt->u.switch_result.cur_chan);
0279
0280
0281 if (tdls_evt->u.switch_result.status != 0) {
0282 switch (tdls_evt->u.switch_result.cur_chan) {
0283 case TDLS_BASE_CHANNEL:
0284 sta_ptr->tdls_status = TDLS_IN_BASE_CHAN;
0285 break;
0286 case TDLS_OFF_CHANNEL:
0287 sta_ptr->tdls_status = TDLS_IN_OFF_CHAN;
0288 break;
0289 default:
0290 break;
0291 }
0292 return ret;
0293 }
0294
0295
0296 switch (tdls_evt->u.switch_result.cur_chan) {
0297 case TDLS_BASE_CHANNEL:
0298 if (sta_ptr->tdls_status == TDLS_IN_BASE_CHAN)
0299 break;
0300 mwifiex_update_ralist_tx_pause_in_tdls_cs(priv, mac,
0301 false);
0302 sta_ptr->tdls_status = TDLS_IN_BASE_CHAN;
0303 break;
0304 case TDLS_OFF_CHANNEL:
0305 if (sta_ptr->tdls_status == TDLS_IN_OFF_CHAN)
0306 break;
0307 mwifiex_update_ralist_tx_pause_in_tdls_cs(priv, mac,
0308 true);
0309 sta_ptr->tdls_status = TDLS_IN_OFF_CHAN;
0310 break;
0311 default:
0312 break;
0313 }
0314
0315 break;
0316 case TDLS_EVENT_START_CHAN_SWITCH:
0317 mwifiex_dbg(adapter, EVENT, "tdls start channel switch...\n");
0318 sta_ptr->tdls_status = TDLS_CHAN_SWITCHING;
0319 break;
0320 case TDLS_EVENT_CHAN_SWITCH_STOPPED:
0321 mwifiex_dbg(adapter, EVENT,
0322 "tdls chan switch stopped, reason=%d\n",
0323 tdls_evt->u.cs_stop_reason);
0324 break;
0325 default:
0326 break;
0327 }
0328
0329 return ret;
0330 }
0331
0332 static void mwifiex_process_uap_tx_pause(struct mwifiex_private *priv,
0333 struct mwifiex_ie_types_header *tlv)
0334 {
0335 struct mwifiex_tx_pause_tlv *tp;
0336 struct mwifiex_sta_node *sta_ptr;
0337
0338 tp = (void *)tlv;
0339 mwifiex_dbg(priv->adapter, EVENT,
0340 "uap tx_pause: %pM pause=%d, pkts=%d\n",
0341 tp->peermac, tp->tx_pause,
0342 tp->pkt_cnt);
0343
0344 if (ether_addr_equal(tp->peermac, priv->netdev->dev_addr)) {
0345 if (tp->tx_pause)
0346 priv->port_open = false;
0347 else
0348 priv->port_open = true;
0349 } else if (is_multicast_ether_addr(tp->peermac)) {
0350 mwifiex_update_ralist_tx_pause(priv, tp->peermac, tp->tx_pause);
0351 } else {
0352 spin_lock_bh(&priv->sta_list_spinlock);
0353 sta_ptr = mwifiex_get_sta_entry(priv, tp->peermac);
0354 if (sta_ptr && sta_ptr->tx_pause != tp->tx_pause) {
0355 sta_ptr->tx_pause = tp->tx_pause;
0356 spin_unlock_bh(&priv->sta_list_spinlock);
0357 mwifiex_update_ralist_tx_pause(priv, tp->peermac,
0358 tp->tx_pause);
0359 } else {
0360 spin_unlock_bh(&priv->sta_list_spinlock);
0361 }
0362 }
0363 }
0364
0365 static void mwifiex_process_sta_tx_pause(struct mwifiex_private *priv,
0366 struct mwifiex_ie_types_header *tlv)
0367 {
0368 struct mwifiex_tx_pause_tlv *tp;
0369 struct mwifiex_sta_node *sta_ptr;
0370 int status;
0371
0372 tp = (void *)tlv;
0373 mwifiex_dbg(priv->adapter, EVENT,
0374 "sta tx_pause: %pM pause=%d, pkts=%d\n",
0375 tp->peermac, tp->tx_pause,
0376 tp->pkt_cnt);
0377
0378 if (ether_addr_equal(tp->peermac, priv->cfg_bssid)) {
0379 if (tp->tx_pause)
0380 priv->port_open = false;
0381 else
0382 priv->port_open = true;
0383 } else {
0384 if (!ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info))
0385 return;
0386
0387 status = mwifiex_get_tdls_link_status(priv, tp->peermac);
0388 if (mwifiex_is_tdls_link_setup(status)) {
0389 spin_lock_bh(&priv->sta_list_spinlock);
0390 sta_ptr = mwifiex_get_sta_entry(priv, tp->peermac);
0391 if (sta_ptr && sta_ptr->tx_pause != tp->tx_pause) {
0392 sta_ptr->tx_pause = tp->tx_pause;
0393 spin_unlock_bh(&priv->sta_list_spinlock);
0394 mwifiex_update_ralist_tx_pause(priv,
0395 tp->peermac,
0396 tp->tx_pause);
0397 } else {
0398 spin_unlock_bh(&priv->sta_list_spinlock);
0399 }
0400 }
0401 }
0402 }
0403
0404 void mwifiex_process_multi_chan_event(struct mwifiex_private *priv,
0405 struct sk_buff *event_skb)
0406 {
0407 struct mwifiex_ie_types_multi_chan_info *chan_info;
0408 struct mwifiex_ie_types_mc_group_info *grp_info;
0409 struct mwifiex_adapter *adapter = priv->adapter;
0410 struct mwifiex_ie_types_header *tlv;
0411 u16 tlv_buf_left, tlv_type, tlv_len;
0412 int intf_num, bss_type, bss_num, i;
0413 struct mwifiex_private *intf_priv;
0414
0415 tlv_buf_left = event_skb->len - sizeof(u32);
0416 chan_info = (void *)event_skb->data + sizeof(u32);
0417
0418 if (le16_to_cpu(chan_info->header.type) != TLV_TYPE_MULTI_CHAN_INFO ||
0419 tlv_buf_left < sizeof(struct mwifiex_ie_types_multi_chan_info)) {
0420 mwifiex_dbg(adapter, ERROR,
0421 "unknown TLV in chan_info event\n");
0422 return;
0423 }
0424
0425 adapter->usb_mc_status = le16_to_cpu(chan_info->status);
0426 mwifiex_dbg(adapter, EVENT, "multi chan operation %s\n",
0427 adapter->usb_mc_status ? "started" : "over");
0428
0429 tlv_buf_left -= sizeof(struct mwifiex_ie_types_multi_chan_info);
0430 tlv = (struct mwifiex_ie_types_header *)chan_info->tlv_buffer;
0431
0432 while (tlv_buf_left >= (int)sizeof(struct mwifiex_ie_types_header)) {
0433 tlv_type = le16_to_cpu(tlv->type);
0434 tlv_len = le16_to_cpu(tlv->len);
0435 if ((sizeof(struct mwifiex_ie_types_header) + tlv_len) >
0436 tlv_buf_left) {
0437 mwifiex_dbg(adapter, ERROR, "wrong tlv: tlvLen=%d,\t"
0438 "tlvBufLeft=%d\n", tlv_len, tlv_buf_left);
0439 break;
0440 }
0441 if (tlv_type != TLV_TYPE_MC_GROUP_INFO) {
0442 mwifiex_dbg(adapter, ERROR, "wrong tlv type: 0x%x\n",
0443 tlv_type);
0444 break;
0445 }
0446
0447 grp_info = (struct mwifiex_ie_types_mc_group_info *)tlv;
0448 intf_num = grp_info->intf_num;
0449 for (i = 0; i < intf_num; i++) {
0450 bss_type = grp_info->bss_type_numlist[i] >> 4;
0451 bss_num = grp_info->bss_type_numlist[i] & BSS_NUM_MASK;
0452 intf_priv = mwifiex_get_priv_by_id(adapter, bss_num,
0453 bss_type);
0454 if (!intf_priv) {
0455 mwifiex_dbg(adapter, ERROR,
0456 "Invalid bss_type bss_num\t"
0457 "in multi channel event\n");
0458 continue;
0459 }
0460 if (adapter->iface_type == MWIFIEX_USB) {
0461 u8 ep;
0462
0463 ep = grp_info->hid_num.usb_ep_num;
0464 if (ep == MWIFIEX_USB_EP_DATA ||
0465 ep == MWIFIEX_USB_EP_DATA_CH2)
0466 intf_priv->usb_port = ep;
0467 }
0468 }
0469
0470 tlv_buf_left -= sizeof(struct mwifiex_ie_types_header) +
0471 tlv_len;
0472 tlv = (void *)((u8 *)tlv + tlv_len +
0473 sizeof(struct mwifiex_ie_types_header));
0474 }
0475
0476 if (adapter->iface_type == MWIFIEX_USB) {
0477 adapter->tx_lock_flag = true;
0478 adapter->usb_mc_setup = true;
0479 mwifiex_multi_chan_resync(adapter);
0480 }
0481 }
0482
0483 void mwifiex_process_tx_pause_event(struct mwifiex_private *priv,
0484 struct sk_buff *event_skb)
0485 {
0486 struct mwifiex_ie_types_header *tlv;
0487 u16 tlv_type, tlv_len;
0488 int tlv_buf_left;
0489
0490 if (!priv->media_connected) {
0491 mwifiex_dbg(priv->adapter, ERROR,
0492 "tx_pause event while disconnected; bss_role=%d\n",
0493 priv->bss_role);
0494 return;
0495 }
0496
0497 tlv_buf_left = event_skb->len - sizeof(u32);
0498 tlv = (void *)event_skb->data + sizeof(u32);
0499
0500 while (tlv_buf_left >= (int)sizeof(struct mwifiex_ie_types_header)) {
0501 tlv_type = le16_to_cpu(tlv->type);
0502 tlv_len = le16_to_cpu(tlv->len);
0503 if ((sizeof(struct mwifiex_ie_types_header) + tlv_len) >
0504 tlv_buf_left) {
0505 mwifiex_dbg(priv->adapter, ERROR,
0506 "wrong tlv: tlvLen=%d, tlvBufLeft=%d\n",
0507 tlv_len, tlv_buf_left);
0508 break;
0509 }
0510 if (tlv_type == TLV_TYPE_TX_PAUSE) {
0511 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA)
0512 mwifiex_process_sta_tx_pause(priv, tlv);
0513 else
0514 mwifiex_process_uap_tx_pause(priv, tlv);
0515 }
0516
0517 tlv_buf_left -= sizeof(struct mwifiex_ie_types_header) +
0518 tlv_len;
0519 tlv = (void *)((u8 *)tlv + tlv_len +
0520 sizeof(struct mwifiex_ie_types_header));
0521 }
0522
0523 }
0524
0525
0526
0527
0528 void mwifiex_bt_coex_wlan_param_update_event(struct mwifiex_private *priv,
0529 struct sk_buff *event_skb)
0530 {
0531 struct mwifiex_adapter *adapter = priv->adapter;
0532 struct mwifiex_ie_types_header *tlv;
0533 struct mwifiex_ie_types_btcoex_aggr_win_size *winsizetlv;
0534 struct mwifiex_ie_types_btcoex_scan_time *scantlv;
0535 s32 len = event_skb->len - sizeof(u32);
0536 u8 *cur_ptr = event_skb->data + sizeof(u32);
0537 u16 tlv_type, tlv_len;
0538
0539 while (len >= sizeof(struct mwifiex_ie_types_header)) {
0540 tlv = (struct mwifiex_ie_types_header *)cur_ptr;
0541 tlv_len = le16_to_cpu(tlv->len);
0542 tlv_type = le16_to_cpu(tlv->type);
0543
0544 if ((tlv_len + sizeof(struct mwifiex_ie_types_header)) > len)
0545 break;
0546 switch (tlv_type) {
0547 case TLV_BTCOEX_WL_AGGR_WINSIZE:
0548 winsizetlv =
0549 (struct mwifiex_ie_types_btcoex_aggr_win_size *)tlv;
0550 adapter->coex_win_size = winsizetlv->coex_win_size;
0551 adapter->coex_tx_win_size =
0552 winsizetlv->tx_win_size;
0553 adapter->coex_rx_win_size =
0554 winsizetlv->rx_win_size;
0555 mwifiex_coex_ampdu_rxwinsize(adapter);
0556 mwifiex_update_ampdu_txwinsize(adapter);
0557 break;
0558
0559 case TLV_BTCOEX_WL_SCANTIME:
0560 scantlv =
0561 (struct mwifiex_ie_types_btcoex_scan_time *)tlv;
0562 adapter->coex_scan = scantlv->coex_scan;
0563 adapter->coex_min_scan_time = le16_to_cpu(scantlv->min_scan_time);
0564 adapter->coex_max_scan_time = le16_to_cpu(scantlv->max_scan_time);
0565 break;
0566
0567 default:
0568 break;
0569 }
0570
0571 len -= tlv_len + sizeof(struct mwifiex_ie_types_header);
0572 cur_ptr += tlv_len +
0573 sizeof(struct mwifiex_ie_types_header);
0574 }
0575
0576 dev_dbg(adapter->dev, "coex_scan=%d min_scan=%d coex_win=%d, tx_win=%d rx_win=%d\n",
0577 adapter->coex_scan, adapter->coex_min_scan_time,
0578 adapter->coex_win_size, adapter->coex_tx_win_size,
0579 adapter->coex_rx_win_size);
0580 }
0581
0582 static void
0583 mwifiex_fw_dump_info_event(struct mwifiex_private *priv,
0584 struct sk_buff *event_skb)
0585 {
0586 struct mwifiex_adapter *adapter = priv->adapter;
0587 struct mwifiex_fw_dump_header *fw_dump_hdr =
0588 (void *)adapter->event_body;
0589
0590 if (adapter->iface_type != MWIFIEX_USB) {
0591 mwifiex_dbg(adapter, MSG,
0592 "event is not on usb interface, ignore it\n");
0593 return;
0594 }
0595
0596 if (!adapter->devdump_data) {
0597
0598
0599
0600 adapter->devdump_data = vzalloc(MWIFIEX_FW_DUMP_SIZE);
0601 if (!adapter->devdump_data) {
0602 mwifiex_dbg(adapter, ERROR,
0603 "vzalloc devdump data failure!\n");
0604 return;
0605 }
0606
0607 mwifiex_drv_info_dump(adapter);
0608
0609
0610
0611
0612
0613
0614 mod_timer(&adapter->devdump_timer,
0615 jiffies + msecs_to_jiffies(MWIFIEX_TIMER_10S));
0616 }
0617
0618
0619 if (adapter->devdump_len + event_skb->len >= MWIFIEX_FW_DUMP_SIZE)
0620 goto upload_dump;
0621
0622 memmove(adapter->devdump_data + adapter->devdump_len,
0623 adapter->event_skb->data, event_skb->len);
0624 adapter->devdump_len += event_skb->len;
0625
0626 if (le16_to_cpu(fw_dump_hdr->type == FW_DUMP_INFO_ENDED)) {
0627 mwifiex_dbg(adapter, MSG,
0628 "receive end of transmission flag event!\n");
0629 goto upload_dump;
0630 }
0631 return;
0632
0633 upload_dump:
0634 del_timer_sync(&adapter->devdump_timer);
0635 mwifiex_upload_device_dump(adapter);
0636 }
0637
0638
0639
0640
0641
0642
0643
0644
0645
0646
0647
0648
0649
0650
0651
0652
0653
0654
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664
0665
0666
0667
0668
0669
0670
0671
0672
0673
0674
0675
0676
0677
0678
0679
0680
0681
0682
0683
0684
0685
0686
0687
0688
0689
0690
0691
0692 int mwifiex_process_sta_event(struct mwifiex_private *priv)
0693 {
0694 struct mwifiex_adapter *adapter = priv->adapter;
0695 int ret = 0, i;
0696 u32 eventcause = adapter->event_cause;
0697 u16 ctrl, reason_code;
0698 u8 ibss_sta_addr[ETH_ALEN];
0699 struct mwifiex_sta_node *sta_ptr;
0700
0701 switch (eventcause) {
0702 case EVENT_DUMMY_HOST_WAKEUP_SIGNAL:
0703 mwifiex_dbg(adapter, ERROR,
0704 "invalid EVENT: DUMMY_HOST_WAKEUP_SIGNAL, ignore it\n");
0705 break;
0706 case EVENT_LINK_SENSED:
0707 mwifiex_dbg(adapter, EVENT, "event: LINK_SENSED\n");
0708 if (!netif_carrier_ok(priv->netdev))
0709 netif_carrier_on(priv->netdev);
0710 mwifiex_wake_up_net_dev_queue(priv->netdev, adapter);
0711 break;
0712
0713 case EVENT_DEAUTHENTICATED:
0714 mwifiex_dbg(adapter, EVENT, "event: Deauthenticated\n");
0715 if (priv->wps.session_enable) {
0716 mwifiex_dbg(adapter, INFO,
0717 "info: receive deauth event in wps session\n");
0718 break;
0719 }
0720 adapter->dbg.num_event_deauth++;
0721 if (priv->media_connected) {
0722 reason_code =
0723 get_unaligned_le16(adapter->event_body);
0724 mwifiex_reset_connect_state(priv, reason_code, true);
0725 }
0726 break;
0727
0728 case EVENT_DISASSOCIATED:
0729 mwifiex_dbg(adapter, EVENT, "event: Disassociated\n");
0730 if (priv->wps.session_enable) {
0731 mwifiex_dbg(adapter, INFO,
0732 "info: receive disassoc event in wps session\n");
0733 break;
0734 }
0735 adapter->dbg.num_event_disassoc++;
0736 if (priv->media_connected) {
0737 reason_code =
0738 get_unaligned_le16(adapter->event_body);
0739 mwifiex_reset_connect_state(priv, reason_code, true);
0740 }
0741 break;
0742
0743 case EVENT_LINK_LOST:
0744 mwifiex_dbg(adapter, EVENT, "event: Link lost\n");
0745 adapter->dbg.num_event_link_lost++;
0746 if (priv->media_connected) {
0747 reason_code =
0748 get_unaligned_le16(adapter->event_body);
0749 mwifiex_reset_connect_state(priv, reason_code, true);
0750 }
0751 break;
0752
0753 case EVENT_PS_SLEEP:
0754 mwifiex_dbg(adapter, EVENT, "info: EVENT: SLEEP\n");
0755
0756 adapter->ps_state = PS_STATE_PRE_SLEEP;
0757
0758 mwifiex_check_ps_cond(adapter);
0759 break;
0760
0761 case EVENT_PS_AWAKE:
0762 mwifiex_dbg(adapter, EVENT, "info: EVENT: AWAKE\n");
0763 if (!adapter->pps_uapsd_mode &&
0764 (priv->port_open ||
0765 (priv->bss_mode == NL80211_IFTYPE_ADHOC)) &&
0766 priv->media_connected && adapter->sleep_period.period) {
0767 adapter->pps_uapsd_mode = true;
0768 mwifiex_dbg(adapter, EVENT,
0769 "event: PPS/UAPSD mode activated\n");
0770 }
0771 adapter->tx_lock_flag = false;
0772 if (adapter->pps_uapsd_mode && adapter->gen_null_pkt) {
0773 if (mwifiex_check_last_packet_indication(priv)) {
0774 if (adapter->data_sent ||
0775 (adapter->if_ops.is_port_ready &&
0776 !adapter->if_ops.is_port_ready(priv))) {
0777 adapter->ps_state = PS_STATE_AWAKE;
0778 adapter->pm_wakeup_card_req = false;
0779 adapter->pm_wakeup_fw_try = false;
0780 del_timer(&adapter->wakeup_timer);
0781 break;
0782 }
0783 if (!mwifiex_send_null_packet
0784 (priv,
0785 MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET |
0786 MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET))
0787 adapter->ps_state =
0788 PS_STATE_SLEEP;
0789 return 0;
0790 }
0791 }
0792 adapter->ps_state = PS_STATE_AWAKE;
0793 adapter->pm_wakeup_card_req = false;
0794 adapter->pm_wakeup_fw_try = false;
0795 del_timer(&adapter->wakeup_timer);
0796
0797 break;
0798
0799 case EVENT_DEEP_SLEEP_AWAKE:
0800 adapter->if_ops.wakeup_complete(adapter);
0801 mwifiex_dbg(adapter, EVENT, "event: DS_AWAKE\n");
0802 if (adapter->is_deep_sleep)
0803 adapter->is_deep_sleep = false;
0804 break;
0805
0806 case EVENT_HS_ACT_REQ:
0807 mwifiex_dbg(adapter, EVENT, "event: HS_ACT_REQ\n");
0808 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_HS_CFG_ENH,
0809 0, 0, NULL, false);
0810 break;
0811
0812 case EVENT_MIC_ERR_UNICAST:
0813 mwifiex_dbg(adapter, EVENT, "event: UNICAST MIC ERROR\n");
0814 cfg80211_michael_mic_failure(priv->netdev, priv->cfg_bssid,
0815 NL80211_KEYTYPE_PAIRWISE,
0816 -1, NULL, GFP_KERNEL);
0817 break;
0818
0819 case EVENT_MIC_ERR_MULTICAST:
0820 mwifiex_dbg(adapter, EVENT, "event: MULTICAST MIC ERROR\n");
0821 cfg80211_michael_mic_failure(priv->netdev, priv->cfg_bssid,
0822 NL80211_KEYTYPE_GROUP,
0823 -1, NULL, GFP_KERNEL);
0824 break;
0825 case EVENT_MIB_CHANGED:
0826 case EVENT_INIT_DONE:
0827 break;
0828
0829 case EVENT_ADHOC_BCN_LOST:
0830 mwifiex_dbg(adapter, EVENT, "event: ADHOC_BCN_LOST\n");
0831 priv->adhoc_is_link_sensed = false;
0832 mwifiex_clean_txrx(priv);
0833 mwifiex_stop_net_dev_queue(priv->netdev, adapter);
0834 if (netif_carrier_ok(priv->netdev))
0835 netif_carrier_off(priv->netdev);
0836 break;
0837
0838 case EVENT_BG_SCAN_REPORT:
0839 mwifiex_dbg(adapter, EVENT, "event: BGS_REPORT\n");
0840 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_BG_SCAN_QUERY,
0841 HostCmd_ACT_GEN_GET, 0, NULL, false);
0842 break;
0843
0844 case EVENT_BG_SCAN_STOPPED:
0845 dev_dbg(adapter->dev, "event: BGS_STOPPED\n");
0846 cfg80211_sched_scan_stopped(priv->wdev.wiphy, 0);
0847 if (priv->sched_scanning)
0848 priv->sched_scanning = false;
0849 break;
0850
0851 case EVENT_PORT_RELEASE:
0852 mwifiex_dbg(adapter, EVENT, "event: PORT RELEASE\n");
0853 priv->port_open = true;
0854 break;
0855
0856 case EVENT_EXT_SCAN_REPORT:
0857 mwifiex_dbg(adapter, EVENT, "event: EXT_SCAN Report\n");
0858
0859
0860
0861 if (adapter->ext_scan && (!priv->scan_aborting ||
0862 !netif_running(priv->netdev)))
0863 ret = mwifiex_handle_event_ext_scan_report(priv,
0864 adapter->event_skb->data);
0865
0866 break;
0867
0868 case EVENT_WMM_STATUS_CHANGE:
0869 mwifiex_dbg(adapter, EVENT, "event: WMM status changed\n");
0870 ret = mwifiex_send_cmd(priv, HostCmd_CMD_WMM_GET_STATUS,
0871 0, 0, NULL, false);
0872 break;
0873
0874 case EVENT_RSSI_LOW:
0875 cfg80211_cqm_rssi_notify(priv->netdev,
0876 NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
0877 0, GFP_KERNEL);
0878 mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO,
0879 HostCmd_ACT_GEN_GET, 0, NULL, false);
0880 priv->subsc_evt_rssi_state = RSSI_LOW_RECVD;
0881 mwifiex_dbg(adapter, EVENT, "event: Beacon RSSI_LOW\n");
0882 break;
0883 case EVENT_SNR_LOW:
0884 mwifiex_dbg(adapter, EVENT, "event: Beacon SNR_LOW\n");
0885 break;
0886 case EVENT_MAX_FAIL:
0887 mwifiex_dbg(adapter, EVENT, "event: MAX_FAIL\n");
0888 break;
0889 case EVENT_RSSI_HIGH:
0890 cfg80211_cqm_rssi_notify(priv->netdev,
0891 NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
0892 0, GFP_KERNEL);
0893 mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO,
0894 HostCmd_ACT_GEN_GET, 0, NULL, false);
0895 priv->subsc_evt_rssi_state = RSSI_HIGH_RECVD;
0896 mwifiex_dbg(adapter, EVENT, "event: Beacon RSSI_HIGH\n");
0897 break;
0898 case EVENT_SNR_HIGH:
0899 mwifiex_dbg(adapter, EVENT, "event: Beacon SNR_HIGH\n");
0900 break;
0901 case EVENT_DATA_RSSI_LOW:
0902 mwifiex_dbg(adapter, EVENT, "event: Data RSSI_LOW\n");
0903 break;
0904 case EVENT_DATA_SNR_LOW:
0905 mwifiex_dbg(adapter, EVENT, "event: Data SNR_LOW\n");
0906 break;
0907 case EVENT_DATA_RSSI_HIGH:
0908 mwifiex_dbg(adapter, EVENT, "event: Data RSSI_HIGH\n");
0909 break;
0910 case EVENT_DATA_SNR_HIGH:
0911 mwifiex_dbg(adapter, EVENT, "event: Data SNR_HIGH\n");
0912 break;
0913 case EVENT_LINK_QUALITY:
0914 mwifiex_dbg(adapter, EVENT, "event: Link Quality\n");
0915 break;
0916 case EVENT_PRE_BEACON_LOST:
0917 mwifiex_dbg(adapter, EVENT, "event: Pre-Beacon Lost\n");
0918 break;
0919 case EVENT_IBSS_COALESCED:
0920 mwifiex_dbg(adapter, EVENT, "event: IBSS_COALESCED\n");
0921 ret = mwifiex_send_cmd(priv,
0922 HostCmd_CMD_802_11_IBSS_COALESCING_STATUS,
0923 HostCmd_ACT_GEN_GET, 0, NULL, false);
0924 break;
0925 case EVENT_IBSS_STA_CONNECT:
0926 ether_addr_copy(ibss_sta_addr, adapter->event_body + 2);
0927 mwifiex_dbg(adapter, EVENT, "event: IBSS_STA_CONNECT %pM\n",
0928 ibss_sta_addr);
0929 sta_ptr = mwifiex_add_sta_entry(priv, ibss_sta_addr);
0930 if (sta_ptr && adapter->adhoc_11n_enabled) {
0931 mwifiex_check_ibss_peer_capabilities(priv, sta_ptr,
0932 adapter->event_skb);
0933 if (sta_ptr->is_11n_enabled)
0934 for (i = 0; i < MAX_NUM_TID; i++)
0935 sta_ptr->ampdu_sta[i] =
0936 priv->aggr_prio_tbl[i].ampdu_user;
0937 else
0938 for (i = 0; i < MAX_NUM_TID; i++)
0939 sta_ptr->ampdu_sta[i] =
0940 BA_STREAM_NOT_ALLOWED;
0941 memset(sta_ptr->rx_seq, 0xff, sizeof(sta_ptr->rx_seq));
0942 }
0943
0944 break;
0945 case EVENT_IBSS_STA_DISCONNECT:
0946 ether_addr_copy(ibss_sta_addr, adapter->event_body + 2);
0947 mwifiex_dbg(adapter, EVENT, "event: IBSS_STA_DISCONNECT %pM\n",
0948 ibss_sta_addr);
0949 sta_ptr = mwifiex_get_sta_entry(priv, ibss_sta_addr);
0950 if (sta_ptr && sta_ptr->is_11n_enabled) {
0951 mwifiex_11n_del_rx_reorder_tbl_by_ta(priv,
0952 ibss_sta_addr);
0953 mwifiex_del_tx_ba_stream_tbl_by_ra(priv, ibss_sta_addr);
0954 }
0955 mwifiex_wmm_del_peer_ra_list(priv, ibss_sta_addr);
0956 mwifiex_del_sta_entry(priv, ibss_sta_addr);
0957 break;
0958 case EVENT_ADDBA:
0959 mwifiex_dbg(adapter, EVENT, "event: ADDBA Request\n");
0960 mwifiex_send_cmd(priv, HostCmd_CMD_11N_ADDBA_RSP,
0961 HostCmd_ACT_GEN_SET, 0,
0962 adapter->event_body, false);
0963 break;
0964 case EVENT_DELBA:
0965 mwifiex_dbg(adapter, EVENT, "event: DELBA Request\n");
0966 mwifiex_11n_delete_ba_stream(priv, adapter->event_body);
0967 break;
0968 case EVENT_BA_STREAM_TIEMOUT:
0969 mwifiex_dbg(adapter, EVENT, "event: BA Stream timeout\n");
0970 mwifiex_11n_ba_stream_timeout(priv,
0971 (struct host_cmd_ds_11n_batimeout
0972 *)
0973 adapter->event_body);
0974 break;
0975 case EVENT_AMSDU_AGGR_CTRL:
0976 ctrl = get_unaligned_le16(adapter->event_body);
0977 mwifiex_dbg(adapter, EVENT,
0978 "event: AMSDU_AGGR_CTRL %d\n", ctrl);
0979
0980 adapter->tx_buf_size =
0981 min_t(u16, adapter->curr_tx_buf_size, ctrl);
0982 mwifiex_dbg(adapter, EVENT, "event: tx_buf_size %d\n",
0983 adapter->tx_buf_size);
0984 break;
0985
0986 case EVENT_WEP_ICV_ERR:
0987 mwifiex_dbg(adapter, EVENT, "event: WEP ICV error\n");
0988 break;
0989
0990 case EVENT_BW_CHANGE:
0991 mwifiex_dbg(adapter, EVENT, "event: BW Change\n");
0992 break;
0993
0994 case EVENT_HOSTWAKE_STAIE:
0995 mwifiex_dbg(adapter, EVENT,
0996 "event: HOSTWAKE_STAIE %d\n", eventcause);
0997 break;
0998
0999 case EVENT_REMAIN_ON_CHAN_EXPIRED:
1000 mwifiex_dbg(adapter, EVENT,
1001 "event: Remain on channel expired\n");
1002 cfg80211_remain_on_channel_expired(&priv->wdev,
1003 priv->roc_cfg.cookie,
1004 &priv->roc_cfg.chan,
1005 GFP_ATOMIC);
1006
1007 memset(&priv->roc_cfg, 0x00, sizeof(struct mwifiex_roc_cfg));
1008
1009 break;
1010
1011 case EVENT_CHANNEL_SWITCH_ANN:
1012 mwifiex_dbg(adapter, EVENT, "event: Channel Switch Announcement\n");
1013 priv->csa_expire_time =
1014 jiffies + msecs_to_jiffies(DFS_CHAN_MOVE_TIME);
1015 priv->csa_chan = priv->curr_bss_params.bss_descriptor.channel;
1016 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_DEAUTHENTICATE,
1017 HostCmd_ACT_GEN_SET, 0,
1018 priv->curr_bss_params.bss_descriptor.mac_address,
1019 false);
1020 break;
1021
1022 case EVENT_TDLS_GENERIC_EVENT:
1023 ret = mwifiex_parse_tdls_event(priv, adapter->event_skb);
1024 break;
1025
1026 case EVENT_TX_DATA_PAUSE:
1027 mwifiex_dbg(adapter, EVENT, "event: TX DATA PAUSE\n");
1028 mwifiex_process_tx_pause_event(priv, adapter->event_skb);
1029 break;
1030
1031 case EVENT_MULTI_CHAN_INFO:
1032 mwifiex_dbg(adapter, EVENT, "event: multi-chan info\n");
1033 mwifiex_process_multi_chan_event(priv, adapter->event_skb);
1034 break;
1035
1036 case EVENT_TX_STATUS_REPORT:
1037 mwifiex_dbg(adapter, EVENT, "event: TX_STATUS Report\n");
1038 mwifiex_parse_tx_status_event(priv, adapter->event_body);
1039 break;
1040
1041 case EVENT_CHANNEL_REPORT_RDY:
1042 mwifiex_dbg(adapter, EVENT, "event: Channel Report\n");
1043 ret = mwifiex_11h_handle_chanrpt_ready(priv,
1044 adapter->event_skb);
1045 break;
1046 case EVENT_RADAR_DETECTED:
1047 mwifiex_dbg(adapter, EVENT, "event: Radar detected\n");
1048 ret = mwifiex_11h_handle_radar_detected(priv,
1049 adapter->event_skb);
1050 break;
1051 case EVENT_BT_COEX_WLAN_PARA_CHANGE:
1052 dev_dbg(adapter->dev, "EVENT: BT coex wlan param update\n");
1053 if (adapter->ignore_btcoex_events)
1054 break;
1055
1056 mwifiex_bt_coex_wlan_param_update_event(priv,
1057 adapter->event_skb);
1058 break;
1059 case EVENT_RXBA_SYNC:
1060 dev_dbg(adapter->dev, "EVENT: RXBA_SYNC\n");
1061 mwifiex_11n_rxba_sync_event(priv, adapter->event_body,
1062 adapter->event_skb->len -
1063 sizeof(eventcause));
1064 break;
1065 case EVENT_FW_DUMP_INFO:
1066 mwifiex_dbg(adapter, EVENT, "event: firmware debug info\n");
1067 mwifiex_fw_dump_info_event(priv, adapter->event_skb);
1068 break;
1069
1070 case EVENT_UNKNOWN_DEBUG:
1071 mwifiex_dbg(adapter, EVENT, "event: debug\n");
1072 break;
1073 default:
1074 mwifiex_dbg(adapter, ERROR, "event: unknown event id: %#x\n",
1075 eventcause);
1076 break;
1077 }
1078
1079 return ret;
1080 }