0001
0002
0003
0004
0005
0006
0007
0008 #include "decl.h"
0009 #include "main.h"
0010 #include "11n.h"
0011
0012 #define MWIFIEX_BSS_START_EVT_FIX_SIZE 12
0013
0014 static int mwifiex_check_uap_capabilities(struct mwifiex_private *priv,
0015 struct sk_buff *event)
0016 {
0017 int evt_len;
0018 u8 *curr;
0019 u16 tlv_len;
0020 struct mwifiex_ie_types_data *tlv_hdr;
0021 struct ieee_types_wmm_parameter *wmm_param_ie = NULL;
0022 int mask = IEEE80211_WMM_IE_AP_QOSINFO_PARAM_SET_CNT_MASK;
0023
0024 priv->wmm_enabled = false;
0025 skb_pull(event, MWIFIEX_BSS_START_EVT_FIX_SIZE);
0026 evt_len = event->len;
0027 curr = event->data;
0028
0029 mwifiex_dbg_dump(priv->adapter, EVT_D, "uap capabilities:",
0030 event->data, event->len);
0031
0032 skb_push(event, MWIFIEX_BSS_START_EVT_FIX_SIZE);
0033
0034 while ((evt_len >= sizeof(tlv_hdr->header))) {
0035 tlv_hdr = (struct mwifiex_ie_types_data *)curr;
0036 tlv_len = le16_to_cpu(tlv_hdr->header.len);
0037
0038 if (evt_len < tlv_len + sizeof(tlv_hdr->header))
0039 break;
0040
0041 switch (le16_to_cpu(tlv_hdr->header.type)) {
0042 case WLAN_EID_HT_CAPABILITY:
0043 priv->ap_11n_enabled = true;
0044 break;
0045
0046 case WLAN_EID_VHT_CAPABILITY:
0047 priv->ap_11ac_enabled = true;
0048 break;
0049
0050 case WLAN_EID_VENDOR_SPECIFIC:
0051
0052
0053
0054 wmm_param_ie = (void *)(curr + 2);
0055 wmm_param_ie->vend_hdr.len = (u8)tlv_len;
0056 wmm_param_ie->vend_hdr.element_id =
0057 WLAN_EID_VENDOR_SPECIFIC;
0058 mwifiex_dbg(priv->adapter, EVENT,
0059 "info: check uap capabilities:\t"
0060 "wmm parameter set count: %d\n",
0061 wmm_param_ie->qos_info_bitmap & mask);
0062
0063 mwifiex_wmm_setup_ac_downgrade(priv);
0064 priv->wmm_enabled = true;
0065 mwifiex_wmm_setup_queue_priorities(priv, wmm_param_ie);
0066 break;
0067
0068 default:
0069 break;
0070 }
0071
0072 curr += (tlv_len + sizeof(tlv_hdr->header));
0073 evt_len -= (tlv_len + sizeof(tlv_hdr->header));
0074 }
0075
0076 return 0;
0077 }
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094 int mwifiex_process_uap_event(struct mwifiex_private *priv)
0095 {
0096 struct mwifiex_adapter *adapter = priv->adapter;
0097 int len, i;
0098 u32 eventcause = adapter->event_cause;
0099 struct station_info *sinfo;
0100 struct mwifiex_assoc_event *event;
0101 struct mwifiex_sta_node *node;
0102 u8 *deauth_mac;
0103 struct host_cmd_ds_11n_batimeout *ba_timeout;
0104 u16 ctrl;
0105
0106 switch (eventcause) {
0107 case EVENT_UAP_STA_ASSOC:
0108 sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL);
0109 if (!sinfo)
0110 return -ENOMEM;
0111
0112 event = (struct mwifiex_assoc_event *)
0113 (adapter->event_body + MWIFIEX_UAP_EVENT_EXTRA_HEADER);
0114 if (le16_to_cpu(event->type) == TLV_TYPE_UAP_MGMT_FRAME) {
0115 len = -1;
0116
0117 if (ieee80211_is_assoc_req(event->frame_control))
0118 len = 0;
0119 else if (ieee80211_is_reassoc_req(event->frame_control))
0120
0121
0122
0123 len = ETH_ALEN;
0124
0125 if (len != -1) {
0126 sinfo->assoc_req_ies = &event->data[len];
0127 len = (u8 *)sinfo->assoc_req_ies -
0128 (u8 *)&event->frame_control;
0129 sinfo->assoc_req_ies_len =
0130 le16_to_cpu(event->len) - (u16)len;
0131 }
0132 }
0133 cfg80211_new_sta(priv->netdev, event->sta_addr, sinfo,
0134 GFP_KERNEL);
0135
0136 node = mwifiex_add_sta_entry(priv, event->sta_addr);
0137 if (!node) {
0138 mwifiex_dbg(adapter, ERROR,
0139 "could not create station entry!\n");
0140 kfree(sinfo);
0141 return -1;
0142 }
0143
0144 if (!priv->ap_11n_enabled) {
0145 kfree(sinfo);
0146 break;
0147 }
0148
0149 mwifiex_set_sta_ht_cap(priv, sinfo->assoc_req_ies,
0150 sinfo->assoc_req_ies_len, node);
0151
0152 for (i = 0; i < MAX_NUM_TID; i++) {
0153 if (node->is_11n_enabled)
0154 node->ampdu_sta[i] =
0155 priv->aggr_prio_tbl[i].ampdu_user;
0156 else
0157 node->ampdu_sta[i] = BA_STREAM_NOT_ALLOWED;
0158 }
0159 memset(node->rx_seq, 0xff, sizeof(node->rx_seq));
0160 kfree(sinfo);
0161 break;
0162 case EVENT_UAP_STA_DEAUTH:
0163 deauth_mac = adapter->event_body +
0164 MWIFIEX_UAP_EVENT_EXTRA_HEADER;
0165 cfg80211_del_sta(priv->netdev, deauth_mac, GFP_KERNEL);
0166
0167 if (priv->ap_11n_enabled) {
0168 mwifiex_11n_del_rx_reorder_tbl_by_ta(priv, deauth_mac);
0169 mwifiex_del_tx_ba_stream_tbl_by_ra(priv, deauth_mac);
0170 }
0171 mwifiex_wmm_del_peer_ra_list(priv, deauth_mac);
0172 mwifiex_del_sta_entry(priv, deauth_mac);
0173 break;
0174 case EVENT_UAP_BSS_IDLE:
0175 priv->media_connected = false;
0176 priv->port_open = false;
0177 mwifiex_clean_txrx(priv);
0178 mwifiex_del_all_sta_list(priv);
0179 break;
0180 case EVENT_UAP_BSS_ACTIVE:
0181 priv->media_connected = true;
0182 priv->port_open = true;
0183 break;
0184 case EVENT_UAP_BSS_START:
0185 mwifiex_dbg(adapter, EVENT,
0186 "AP EVENT: event id: %#x\n", eventcause);
0187 priv->port_open = false;
0188 eth_hw_addr_set(priv->netdev, adapter->event_body + 2);
0189 if (priv->hist_data)
0190 mwifiex_hist_data_reset(priv);
0191 mwifiex_check_uap_capabilities(priv, adapter->event_skb);
0192 break;
0193 case EVENT_UAP_MIC_COUNTERMEASURES:
0194
0195 mwifiex_dbg(adapter, EVENT,
0196 "AP EVENT: event id: %#x\n", eventcause);
0197 break;
0198 case EVENT_AMSDU_AGGR_CTRL:
0199 ctrl = get_unaligned_le16(adapter->event_body);
0200 mwifiex_dbg(adapter, EVENT,
0201 "event: AMSDU_AGGR_CTRL %d\n", ctrl);
0202
0203 if (priv->media_connected) {
0204 adapter->tx_buf_size =
0205 min_t(u16, adapter->curr_tx_buf_size, ctrl);
0206 mwifiex_dbg(adapter, EVENT,
0207 "event: tx_buf_size %d\n",
0208 adapter->tx_buf_size);
0209 }
0210 break;
0211 case EVENT_ADDBA:
0212 mwifiex_dbg(adapter, EVENT, "event: ADDBA Request\n");
0213 if (priv->media_connected)
0214 mwifiex_send_cmd(priv, HostCmd_CMD_11N_ADDBA_RSP,
0215 HostCmd_ACT_GEN_SET, 0,
0216 adapter->event_body, false);
0217 break;
0218 case EVENT_DELBA:
0219 mwifiex_dbg(adapter, EVENT, "event: DELBA Request\n");
0220 if (priv->media_connected)
0221 mwifiex_11n_delete_ba_stream(priv, adapter->event_body);
0222 break;
0223 case EVENT_BA_STREAM_TIEMOUT:
0224 mwifiex_dbg(adapter, EVENT, "event: BA Stream timeout\n");
0225 if (priv->media_connected) {
0226 ba_timeout = (void *)adapter->event_body;
0227 mwifiex_11n_ba_stream_timeout(priv, ba_timeout);
0228 }
0229 break;
0230 case EVENT_EXT_SCAN_REPORT:
0231 mwifiex_dbg(adapter, EVENT, "event: EXT_SCAN Report\n");
0232 if (adapter->ext_scan)
0233 return mwifiex_handle_event_ext_scan_report(priv,
0234 adapter->event_skb->data);
0235 break;
0236 case EVENT_TX_STATUS_REPORT:
0237 mwifiex_dbg(adapter, EVENT, "event: TX_STATUS Report\n");
0238 mwifiex_parse_tx_status_event(priv, adapter->event_body);
0239 break;
0240 case EVENT_PS_SLEEP:
0241 mwifiex_dbg(adapter, EVENT, "info: EVENT: SLEEP\n");
0242
0243 adapter->ps_state = PS_STATE_PRE_SLEEP;
0244
0245 mwifiex_check_ps_cond(adapter);
0246 break;
0247
0248 case EVENT_PS_AWAKE:
0249 mwifiex_dbg(adapter, EVENT, "info: EVENT: AWAKE\n");
0250 if (!adapter->pps_uapsd_mode &&
0251 priv->media_connected && adapter->sleep_period.period) {
0252 adapter->pps_uapsd_mode = true;
0253 mwifiex_dbg(adapter, EVENT,
0254 "event: PPS/UAPSD mode activated\n");
0255 }
0256 adapter->tx_lock_flag = false;
0257 if (adapter->pps_uapsd_mode && adapter->gen_null_pkt) {
0258 if (mwifiex_check_last_packet_indication(priv)) {
0259 if (adapter->data_sent ||
0260 (adapter->if_ops.is_port_ready &&
0261 !adapter->if_ops.is_port_ready(priv))) {
0262 adapter->ps_state = PS_STATE_AWAKE;
0263 adapter->pm_wakeup_card_req = false;
0264 adapter->pm_wakeup_fw_try = false;
0265 break;
0266 }
0267 if (!mwifiex_send_null_packet
0268 (priv,
0269 MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET |
0270 MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET))
0271 adapter->ps_state =
0272 PS_STATE_SLEEP;
0273 return 0;
0274 }
0275 }
0276 adapter->ps_state = PS_STATE_AWAKE;
0277 adapter->pm_wakeup_card_req = false;
0278 adapter->pm_wakeup_fw_try = false;
0279 break;
0280
0281 case EVENT_CHANNEL_REPORT_RDY:
0282 mwifiex_dbg(adapter, EVENT, "event: Channel Report\n");
0283 mwifiex_11h_handle_chanrpt_ready(priv, adapter->event_skb);
0284 break;
0285 case EVENT_RADAR_DETECTED:
0286 mwifiex_dbg(adapter, EVENT, "event: Radar detected\n");
0287 mwifiex_11h_handle_radar_detected(priv, adapter->event_skb);
0288 break;
0289 case EVENT_BT_COEX_WLAN_PARA_CHANGE:
0290 mwifiex_dbg(adapter, EVENT, "event: BT coex wlan param update\n");
0291 mwifiex_bt_coex_wlan_param_update_event(priv,
0292 adapter->event_skb);
0293 break;
0294 case EVENT_TX_DATA_PAUSE:
0295 mwifiex_dbg(adapter, EVENT, "event: TX DATA PAUSE\n");
0296 mwifiex_process_tx_pause_event(priv, adapter->event_skb);
0297 break;
0298
0299 case EVENT_MULTI_CHAN_INFO:
0300 mwifiex_dbg(adapter, EVENT, "event: multi-chan info\n");
0301 mwifiex_process_multi_chan_event(priv, adapter->event_skb);
0302 break;
0303 case EVENT_RXBA_SYNC:
0304 dev_dbg(adapter->dev, "EVENT: RXBA_SYNC\n");
0305 mwifiex_11n_rxba_sync_event(priv, adapter->event_body,
0306 adapter->event_skb->len -
0307 sizeof(eventcause));
0308 break;
0309
0310 case EVENT_REMAIN_ON_CHAN_EXPIRED:
0311 mwifiex_dbg(adapter, EVENT,
0312 "event: uap: Remain on channel expired\n");
0313 cfg80211_remain_on_channel_expired(&priv->wdev,
0314 priv->roc_cfg.cookie,
0315 &priv->roc_cfg.chan,
0316 GFP_ATOMIC);
0317 memset(&priv->roc_cfg, 0x00, sizeof(struct mwifiex_roc_cfg));
0318 break;
0319
0320 default:
0321 mwifiex_dbg(adapter, EVENT,
0322 "event: unknown event id: %#x\n", eventcause);
0323 break;
0324 }
0325
0326 return 0;
0327 }
0328
0329
0330
0331
0332
0333 void mwifiex_uap_del_sta_data(struct mwifiex_private *priv,
0334 struct mwifiex_sta_node *node)
0335 {
0336 if (priv->ap_11n_enabled && node->is_11n_enabled) {
0337 mwifiex_11n_del_rx_reorder_tbl_by_ta(priv, node->mac_addr);
0338 mwifiex_del_tx_ba_stream_tbl_by_ra(priv, node->mac_addr);
0339 }
0340 mwifiex_del_sta_entry(priv, node->mac_addr);
0341
0342 return;
0343 }