0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 #include <linux/ieee80211.h>
0039 #include <linux/slab.h>
0040 #include <linux/export.h>
0041 #include <net/mac80211.h>
0042 #include "ieee80211_i.h"
0043 #include "driver-ops.h"
0044
0045 static void ieee80211_free_tid_rx(struct rcu_head *h)
0046 {
0047 struct tid_ampdu_rx *tid_rx =
0048 container_of(h, struct tid_ampdu_rx, rcu_head);
0049 int i;
0050
0051 for (i = 0; i < tid_rx->buf_size; i++)
0052 __skb_queue_purge(&tid_rx->reorder_buf[i]);
0053 kfree(tid_rx->reorder_buf);
0054 kfree(tid_rx->reorder_time);
0055 kfree(tid_rx);
0056 }
0057
0058 void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
0059 u16 initiator, u16 reason, bool tx)
0060 {
0061 struct ieee80211_local *local = sta->local;
0062 struct tid_ampdu_rx *tid_rx;
0063 struct ieee80211_ampdu_params params = {
0064 .sta = &sta->sta,
0065 .action = IEEE80211_AMPDU_RX_STOP,
0066 .tid = tid,
0067 .amsdu = false,
0068 .timeout = 0,
0069 .ssn = 0,
0070 };
0071
0072 lockdep_assert_held(&sta->ampdu_mlme.mtx);
0073
0074 tid_rx = rcu_dereference_protected(sta->ampdu_mlme.tid_rx[tid],
0075 lockdep_is_held(&sta->ampdu_mlme.mtx));
0076
0077 if (!test_bit(tid, sta->ampdu_mlme.agg_session_valid))
0078 return;
0079
0080 RCU_INIT_POINTER(sta->ampdu_mlme.tid_rx[tid], NULL);
0081 __clear_bit(tid, sta->ampdu_mlme.agg_session_valid);
0082
0083 ht_dbg(sta->sdata,
0084 "Rx BA session stop requested for %pM tid %u %s reason: %d\n",
0085 sta->sta.addr, tid,
0086 initiator == WLAN_BACK_RECIPIENT ? "recipient" : "initiator",
0087 (int)reason);
0088
0089 if (drv_ampdu_action(local, sta->sdata, ¶ms))
0090 sdata_info(sta->sdata,
0091 "HW problem - can not stop rx aggregation for %pM tid %d\n",
0092 sta->sta.addr, tid);
0093
0094
0095 if (initiator == WLAN_BACK_RECIPIENT && tx)
0096 ieee80211_send_delba(sta->sdata, sta->sta.addr,
0097 tid, WLAN_BACK_RECIPIENT, reason);
0098
0099
0100
0101
0102
0103 if (!tid_rx)
0104 return;
0105
0106 del_timer_sync(&tid_rx->session_timer);
0107
0108
0109 spin_lock_bh(&tid_rx->reorder_lock);
0110 tid_rx->removed = true;
0111 spin_unlock_bh(&tid_rx->reorder_lock);
0112 del_timer_sync(&tid_rx->reorder_timer);
0113
0114 call_rcu(&tid_rx->rcu_head, ieee80211_free_tid_rx);
0115 }
0116
0117 void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
0118 u16 initiator, u16 reason, bool tx)
0119 {
0120 mutex_lock(&sta->ampdu_mlme.mtx);
0121 ___ieee80211_stop_rx_ba_session(sta, tid, initiator, reason, tx);
0122 mutex_unlock(&sta->ampdu_mlme.mtx);
0123 }
0124
0125 void ieee80211_stop_rx_ba_session(struct ieee80211_vif *vif, u16 ba_rx_bitmap,
0126 const u8 *addr)
0127 {
0128 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
0129 struct sta_info *sta;
0130 int i;
0131
0132 rcu_read_lock();
0133 sta = sta_info_get_bss(sdata, addr);
0134 if (!sta) {
0135 rcu_read_unlock();
0136 return;
0137 }
0138
0139 for (i = 0; i < IEEE80211_NUM_TIDS; i++)
0140 if (ba_rx_bitmap & BIT(i))
0141 set_bit(i, sta->ampdu_mlme.tid_rx_stop_requested);
0142
0143 ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work);
0144 rcu_read_unlock();
0145 }
0146 EXPORT_SYMBOL(ieee80211_stop_rx_ba_session);
0147
0148
0149
0150
0151
0152 static void sta_rx_agg_session_timer_expired(struct timer_list *t)
0153 {
0154 struct tid_ampdu_rx *tid_rx = from_timer(tid_rx, t, session_timer);
0155 struct sta_info *sta = tid_rx->sta;
0156 u8 tid = tid_rx->tid;
0157 unsigned long timeout;
0158
0159 timeout = tid_rx->last_rx + TU_TO_JIFFIES(tid_rx->timeout);
0160 if (time_is_after_jiffies(timeout)) {
0161 mod_timer(&tid_rx->session_timer, timeout);
0162 return;
0163 }
0164
0165 ht_dbg(sta->sdata, "RX session timer expired on %pM tid %d\n",
0166 sta->sta.addr, tid);
0167
0168 set_bit(tid, sta->ampdu_mlme.tid_rx_timer_expired);
0169 ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work);
0170 }
0171
0172 static void sta_rx_agg_reorder_timer_expired(struct timer_list *t)
0173 {
0174 struct tid_ampdu_rx *tid_rx = from_timer(tid_rx, t, reorder_timer);
0175
0176 rcu_read_lock();
0177 ieee80211_release_reorder_timeout(tid_rx->sta, tid_rx->tid);
0178 rcu_read_unlock();
0179 }
0180
0181 static void ieee80211_add_addbaext(struct ieee80211_sub_if_data *sdata,
0182 struct sk_buff *skb,
0183 const struct ieee80211_addba_ext_ie *req,
0184 u16 buf_size)
0185 {
0186 struct ieee80211_supported_band *sband;
0187 struct ieee80211_addba_ext_ie *resp;
0188 const struct ieee80211_sta_he_cap *he_cap;
0189 u8 frag_level, cap_frag_level;
0190 u8 *pos;
0191
0192 sband = ieee80211_get_sband(sdata);
0193 if (!sband)
0194 return;
0195 he_cap = ieee80211_get_he_iftype_cap(sband,
0196 ieee80211_vif_type_p2p(&sdata->vif));
0197 if (!he_cap)
0198 return;
0199
0200 pos = skb_put_zero(skb, 2 + sizeof(struct ieee80211_addba_ext_ie));
0201 *pos++ = WLAN_EID_ADDBA_EXT;
0202 *pos++ = sizeof(struct ieee80211_addba_ext_ie);
0203 resp = (struct ieee80211_addba_ext_ie *)pos;
0204 resp->data = req->data & IEEE80211_ADDBA_EXT_NO_FRAG;
0205
0206 frag_level = u32_get_bits(req->data,
0207 IEEE80211_ADDBA_EXT_FRAG_LEVEL_MASK);
0208 cap_frag_level = u32_get_bits(he_cap->he_cap_elem.mac_cap_info[0],
0209 IEEE80211_HE_MAC_CAP0_DYNAMIC_FRAG_MASK);
0210 if (frag_level > cap_frag_level)
0211 frag_level = cap_frag_level;
0212 resp->data |= u8_encode_bits(frag_level,
0213 IEEE80211_ADDBA_EXT_FRAG_LEVEL_MASK);
0214 resp->data |= u8_encode_bits(buf_size >> IEEE80211_ADDBA_EXT_BUF_SIZE_SHIFT,
0215 IEEE80211_ADDBA_EXT_BUF_SIZE_MASK);
0216 }
0217
0218 static void ieee80211_send_addba_resp(struct sta_info *sta, u8 *da, u16 tid,
0219 u8 dialog_token, u16 status, u16 policy,
0220 u16 buf_size, u16 timeout,
0221 const struct ieee80211_addba_ext_ie *addbaext)
0222 {
0223 struct ieee80211_sub_if_data *sdata = sta->sdata;
0224 struct ieee80211_local *local = sdata->local;
0225 struct sk_buff *skb;
0226 struct ieee80211_mgmt *mgmt;
0227 bool amsdu = ieee80211_hw_check(&local->hw, SUPPORTS_AMSDU_IN_AMPDU);
0228 u16 capab;
0229
0230 skb = dev_alloc_skb(sizeof(*mgmt) +
0231 2 + sizeof(struct ieee80211_addba_ext_ie) +
0232 local->hw.extra_tx_headroom);
0233 if (!skb)
0234 return;
0235
0236 skb_reserve(skb, local->hw.extra_tx_headroom);
0237 mgmt = skb_put_zero(skb, 24);
0238 memcpy(mgmt->da, da, ETH_ALEN);
0239 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
0240 if (sdata->vif.type == NL80211_IFTYPE_AP ||
0241 sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
0242 sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
0243 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
0244 else if (sdata->vif.type == NL80211_IFTYPE_STATION)
0245 memcpy(mgmt->bssid, sdata->deflink.u.mgd.bssid, ETH_ALEN);
0246 else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
0247 memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN);
0248
0249 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
0250 IEEE80211_STYPE_ACTION);
0251
0252 skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_resp));
0253 mgmt->u.action.category = WLAN_CATEGORY_BACK;
0254 mgmt->u.action.u.addba_resp.action_code = WLAN_ACTION_ADDBA_RESP;
0255 mgmt->u.action.u.addba_resp.dialog_token = dialog_token;
0256
0257 capab = u16_encode_bits(amsdu, IEEE80211_ADDBA_PARAM_AMSDU_MASK);
0258 capab |= u16_encode_bits(policy, IEEE80211_ADDBA_PARAM_POLICY_MASK);
0259 capab |= u16_encode_bits(tid, IEEE80211_ADDBA_PARAM_TID_MASK);
0260 capab |= u16_encode_bits(buf_size, IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK);
0261
0262 mgmt->u.action.u.addba_resp.capab = cpu_to_le16(capab);
0263 mgmt->u.action.u.addba_resp.timeout = cpu_to_le16(timeout);
0264 mgmt->u.action.u.addba_resp.status = cpu_to_le16(status);
0265
0266 if (sta->sta.deflink.he_cap.has_he && addbaext)
0267 ieee80211_add_addbaext(sdata, skb, addbaext, buf_size);
0268
0269 ieee80211_tx_skb(sdata, skb);
0270 }
0271
0272 void ___ieee80211_start_rx_ba_session(struct sta_info *sta,
0273 u8 dialog_token, u16 timeout,
0274 u16 start_seq_num, u16 ba_policy, u16 tid,
0275 u16 buf_size, bool tx, bool auto_seq,
0276 const struct ieee80211_addba_ext_ie *addbaext)
0277 {
0278 struct ieee80211_local *local = sta->sdata->local;
0279 struct tid_ampdu_rx *tid_agg_rx;
0280 struct ieee80211_ampdu_params params = {
0281 .sta = &sta->sta,
0282 .action = IEEE80211_AMPDU_RX_START,
0283 .tid = tid,
0284 .amsdu = false,
0285 .timeout = timeout,
0286 .ssn = start_seq_num,
0287 };
0288 int i, ret = -EOPNOTSUPP;
0289 u16 status = WLAN_STATUS_REQUEST_DECLINED;
0290 u16 max_buf_size;
0291
0292 if (tid >= IEEE80211_FIRST_TSPEC_TSID) {
0293 ht_dbg(sta->sdata,
0294 "STA %pM requests BA session on unsupported tid %d\n",
0295 sta->sta.addr, tid);
0296 goto end;
0297 }
0298
0299 if (!sta->sta.deflink.ht_cap.ht_supported &&
0300 sta->sdata->vif.bss_conf.chandef.chan->band != NL80211_BAND_6GHZ) {
0301 ht_dbg(sta->sdata,
0302 "STA %pM erroneously requests BA session on tid %d w/o QoS\n",
0303 sta->sta.addr, tid);
0304
0305 goto end;
0306 }
0307
0308 if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) {
0309 ht_dbg(sta->sdata,
0310 "Suspend in progress - Denying ADDBA request (%pM tid %d)\n",
0311 sta->sta.addr, tid);
0312 goto end;
0313 }
0314
0315 if (sta->sta.deflink.eht_cap.has_eht)
0316 max_buf_size = IEEE80211_MAX_AMPDU_BUF_EHT;
0317 else if (sta->sta.deflink.he_cap.has_he)
0318 max_buf_size = IEEE80211_MAX_AMPDU_BUF_HE;
0319 else
0320 max_buf_size = IEEE80211_MAX_AMPDU_BUF_HT;
0321
0322
0323
0324
0325
0326 if (((ba_policy != 1) &&
0327 (!(sta->sta.deflink.ht_cap.cap & IEEE80211_HT_CAP_DELAY_BA))) ||
0328 (buf_size > max_buf_size)) {
0329 status = WLAN_STATUS_INVALID_QOS_PARAM;
0330 ht_dbg_ratelimited(sta->sdata,
0331 "AddBA Req with bad params from %pM on tid %u. policy %d, buffer size %d\n",
0332 sta->sta.addr, tid, ba_policy, buf_size);
0333 goto end;
0334 }
0335
0336 if (buf_size == 0)
0337 buf_size = max_buf_size;
0338
0339
0340 if (buf_size > sta->sta.max_rx_aggregation_subframes)
0341 buf_size = sta->sta.max_rx_aggregation_subframes;
0342 params.buf_size = buf_size;
0343
0344 ht_dbg(sta->sdata, "AddBA Req buf_size=%d for %pM\n",
0345 buf_size, sta->sta.addr);
0346
0347
0348 lockdep_assert_held(&sta->ampdu_mlme.mtx);
0349
0350 if (test_bit(tid, sta->ampdu_mlme.agg_session_valid)) {
0351 if (sta->ampdu_mlme.tid_rx_token[tid] == dialog_token) {
0352 struct tid_ampdu_rx *tid_rx;
0353
0354 ht_dbg_ratelimited(sta->sdata,
0355 "updated AddBA Req from %pM on tid %u\n",
0356 sta->sta.addr, tid);
0357
0358
0359
0360
0361
0362 rcu_read_lock();
0363 tid_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]);
0364 if (tid_rx && tid_rx->timeout == timeout)
0365 status = WLAN_STATUS_SUCCESS;
0366 else
0367 status = WLAN_STATUS_REQUEST_DECLINED;
0368 rcu_read_unlock();
0369 goto end;
0370 }
0371
0372 ht_dbg_ratelimited(sta->sdata,
0373 "unexpected AddBA Req from %pM on tid %u\n",
0374 sta->sta.addr, tid);
0375
0376
0377 ___ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT,
0378 WLAN_STATUS_UNSPECIFIED_QOS,
0379 false);
0380 }
0381
0382 if (ieee80211_hw_check(&local->hw, SUPPORTS_REORDERING_BUFFER)) {
0383 ret = drv_ampdu_action(local, sta->sdata, ¶ms);
0384 ht_dbg(sta->sdata,
0385 "Rx A-MPDU request on %pM tid %d result %d\n",
0386 sta->sta.addr, tid, ret);
0387 if (!ret)
0388 status = WLAN_STATUS_SUCCESS;
0389 goto end;
0390 }
0391
0392
0393 tid_agg_rx = kzalloc(sizeof(*tid_agg_rx), GFP_KERNEL);
0394 if (!tid_agg_rx)
0395 goto end;
0396
0397 spin_lock_init(&tid_agg_rx->reorder_lock);
0398
0399
0400 timer_setup(&tid_agg_rx->session_timer,
0401 sta_rx_agg_session_timer_expired, TIMER_DEFERRABLE);
0402
0403
0404 timer_setup(&tid_agg_rx->reorder_timer,
0405 sta_rx_agg_reorder_timer_expired, 0);
0406
0407
0408 tid_agg_rx->reorder_buf =
0409 kcalloc(buf_size, sizeof(struct sk_buff_head), GFP_KERNEL);
0410 tid_agg_rx->reorder_time =
0411 kcalloc(buf_size, sizeof(unsigned long), GFP_KERNEL);
0412 if (!tid_agg_rx->reorder_buf || !tid_agg_rx->reorder_time) {
0413 kfree(tid_agg_rx->reorder_buf);
0414 kfree(tid_agg_rx->reorder_time);
0415 kfree(tid_agg_rx);
0416 goto end;
0417 }
0418
0419 for (i = 0; i < buf_size; i++)
0420 __skb_queue_head_init(&tid_agg_rx->reorder_buf[i]);
0421
0422 ret = drv_ampdu_action(local, sta->sdata, ¶ms);
0423 ht_dbg(sta->sdata, "Rx A-MPDU request on %pM tid %d result %d\n",
0424 sta->sta.addr, tid, ret);
0425 if (ret) {
0426 kfree(tid_agg_rx->reorder_buf);
0427 kfree(tid_agg_rx->reorder_time);
0428 kfree(tid_agg_rx);
0429 goto end;
0430 }
0431
0432
0433 tid_agg_rx->ssn = start_seq_num;
0434 tid_agg_rx->head_seq_num = start_seq_num;
0435 tid_agg_rx->buf_size = buf_size;
0436 tid_agg_rx->timeout = timeout;
0437 tid_agg_rx->stored_mpdu_num = 0;
0438 tid_agg_rx->auto_seq = auto_seq;
0439 tid_agg_rx->started = false;
0440 tid_agg_rx->reorder_buf_filtered = 0;
0441 tid_agg_rx->tid = tid;
0442 tid_agg_rx->sta = sta;
0443 status = WLAN_STATUS_SUCCESS;
0444
0445
0446 rcu_assign_pointer(sta->ampdu_mlme.tid_rx[tid], tid_agg_rx);
0447
0448 if (timeout) {
0449 mod_timer(&tid_agg_rx->session_timer, TU_TO_EXP_TIME(timeout));
0450 tid_agg_rx->last_rx = jiffies;
0451 }
0452
0453 end:
0454 if (status == WLAN_STATUS_SUCCESS) {
0455 __set_bit(tid, sta->ampdu_mlme.agg_session_valid);
0456 __clear_bit(tid, sta->ampdu_mlme.unexpected_agg);
0457 sta->ampdu_mlme.tid_rx_token[tid] = dialog_token;
0458 }
0459
0460 if (tx)
0461 ieee80211_send_addba_resp(sta, sta->sta.addr, tid,
0462 dialog_token, status, 1, buf_size,
0463 timeout, addbaext);
0464 }
0465
0466 static void __ieee80211_start_rx_ba_session(struct sta_info *sta,
0467 u8 dialog_token, u16 timeout,
0468 u16 start_seq_num, u16 ba_policy,
0469 u16 tid, u16 buf_size, bool tx,
0470 bool auto_seq,
0471 const struct ieee80211_addba_ext_ie *addbaext)
0472 {
0473 mutex_lock(&sta->ampdu_mlme.mtx);
0474 ___ieee80211_start_rx_ba_session(sta, dialog_token, timeout,
0475 start_seq_num, ba_policy, tid,
0476 buf_size, tx, auto_seq, addbaext);
0477 mutex_unlock(&sta->ampdu_mlme.mtx);
0478 }
0479
0480 void ieee80211_process_addba_request(struct ieee80211_local *local,
0481 struct sta_info *sta,
0482 struct ieee80211_mgmt *mgmt,
0483 size_t len)
0484 {
0485 u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num;
0486 struct ieee802_11_elems *elems = NULL;
0487 u8 dialog_token;
0488 int ies_len;
0489
0490
0491 dialog_token = mgmt->u.action.u.addba_req.dialog_token;
0492 timeout = le16_to_cpu(mgmt->u.action.u.addba_req.timeout);
0493 start_seq_num =
0494 le16_to_cpu(mgmt->u.action.u.addba_req.start_seq_num) >> 4;
0495
0496 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab);
0497 ba_policy = (capab & IEEE80211_ADDBA_PARAM_POLICY_MASK) >> 1;
0498 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
0499 buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6;
0500
0501 ies_len = len - offsetof(struct ieee80211_mgmt,
0502 u.action.u.addba_req.variable);
0503 if (ies_len) {
0504 elems = ieee802_11_parse_elems(mgmt->u.action.u.addba_req.variable,
0505 ies_len, true, NULL);
0506 if (!elems || elems->parse_error)
0507 goto free;
0508 }
0509
0510 if (sta->sta.deflink.eht_cap.has_eht && elems && elems->addba_ext_ie) {
0511 u8 buf_size_1k = u8_get_bits(elems->addba_ext_ie->data,
0512 IEEE80211_ADDBA_EXT_BUF_SIZE_MASK);
0513
0514 buf_size |= buf_size_1k << IEEE80211_ADDBA_EXT_BUF_SIZE_SHIFT;
0515 }
0516
0517 __ieee80211_start_rx_ba_session(sta, dialog_token, timeout,
0518 start_seq_num, ba_policy, tid,
0519 buf_size, true, false,
0520 elems ? elems->addba_ext_ie : NULL);
0521 free:
0522 kfree(elems);
0523 }
0524
0525 void ieee80211_manage_rx_ba_offl(struct ieee80211_vif *vif,
0526 const u8 *addr, unsigned int tid)
0527 {
0528 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
0529 struct ieee80211_local *local = sdata->local;
0530 struct sta_info *sta;
0531
0532 rcu_read_lock();
0533 sta = sta_info_get_bss(sdata, addr);
0534 if (!sta)
0535 goto unlock;
0536
0537 set_bit(tid, sta->ampdu_mlme.tid_rx_manage_offl);
0538 ieee80211_queue_work(&local->hw, &sta->ampdu_mlme.work);
0539 unlock:
0540 rcu_read_unlock();
0541 }
0542 EXPORT_SYMBOL(ieee80211_manage_rx_ba_offl);
0543
0544 void ieee80211_rx_ba_timer_expired(struct ieee80211_vif *vif,
0545 const u8 *addr, unsigned int tid)
0546 {
0547 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
0548 struct ieee80211_local *local = sdata->local;
0549 struct sta_info *sta;
0550
0551 rcu_read_lock();
0552 sta = sta_info_get_bss(sdata, addr);
0553 if (!sta)
0554 goto unlock;
0555
0556 set_bit(tid, sta->ampdu_mlme.tid_rx_timer_expired);
0557 ieee80211_queue_work(&local->hw, &sta->ampdu_mlme.work);
0558
0559 unlock:
0560 rcu_read_unlock();
0561 }
0562 EXPORT_SYMBOL(ieee80211_rx_ba_timer_expired);