aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/agg-tx.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/agg-tx.c')
-rw-r--r--net/mac80211/agg-tx.c103
1 files changed, 43 insertions, 60 deletions
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 206fd82f0c76..adf01fcd462e 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -91,7 +91,7 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
91 mgmt->u.action.u.addba_req.start_seq_num = 91 mgmt->u.action.u.addba_req.start_seq_num =
92 cpu_to_le16(start_seq_num << 4); 92 cpu_to_le16(start_seq_num << 4);
93 93
94 ieee80211_tx_skb(sdata, skb, 1); 94 ieee80211_tx_skb(sdata, skb);
95} 95}
96 96
97void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn) 97void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn)
@@ -120,7 +120,8 @@ void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u1
120 bar->control = cpu_to_le16(bar_control); 120 bar->control = cpu_to_le16(bar_control);
121 bar->start_seq_num = cpu_to_le16(ssn); 121 bar->start_seq_num = cpu_to_le16(ssn);
122 122
123 ieee80211_tx_skb(sdata, skb, 0); 123 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
124 ieee80211_tx_skb(sdata, skb);
124} 125}
125 126
126static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, 127static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
@@ -138,7 +139,8 @@ static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
138 *state = HT_AGG_STATE_REQ_STOP_BA_MSK | 139 *state = HT_AGG_STATE_REQ_STOP_BA_MSK |
139 (initiator << HT_AGG_STATE_INITIATOR_SHIFT); 140 (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
140 141
141 ret = drv_ampdu_action(local, IEEE80211_AMPDU_TX_STOP, 142 ret = drv_ampdu_action(local, &sta->sdata->vif,
143 IEEE80211_AMPDU_TX_STOP,
142 &sta->sta, tid, NULL); 144 &sta->sta, tid, NULL);
143 145
144 /* HW shall not deny going back to legacy */ 146 /* HW shall not deny going back to legacy */
@@ -198,11 +200,11 @@ static inline int ieee80211_ac_from_tid(int tid)
198 return ieee802_1d_to_ac[tid & 7]; 200 return ieee802_1d_to_ac[tid & 7];
199} 201}
200 202
201int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) 203int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
202{ 204{
203 struct ieee80211_local *local = hw_to_local(hw); 205 struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
204 struct sta_info *sta; 206 struct ieee80211_sub_if_data *sdata = sta->sdata;
205 struct ieee80211_sub_if_data *sdata; 207 struct ieee80211_local *local = sdata->local;
206 u8 *state; 208 u8 *state;
207 int ret = 0; 209 int ret = 0;
208 u16 start_seq_num; 210 u16 start_seq_num;
@@ -210,52 +212,37 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
210 if (WARN_ON(!local->ops->ampdu_action)) 212 if (WARN_ON(!local->ops->ampdu_action))
211 return -EINVAL; 213 return -EINVAL;
212 214
213 if ((tid >= STA_TID_NUM) || !(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION)) 215 if ((tid >= STA_TID_NUM) ||
216 !(local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION))
214 return -EINVAL; 217 return -EINVAL;
215 218
216#ifdef CONFIG_MAC80211_HT_DEBUG 219#ifdef CONFIG_MAC80211_HT_DEBUG
217 printk(KERN_DEBUG "Open BA session requested for %pM tid %u\n", 220 printk(KERN_DEBUG "Open BA session requested for %pM tid %u\n",
218 ra, tid); 221 pubsta->addr, tid);
219#endif /* CONFIG_MAC80211_HT_DEBUG */ 222#endif /* CONFIG_MAC80211_HT_DEBUG */
220 223
221 rcu_read_lock();
222
223 sta = sta_info_get(local, ra);
224 if (!sta) {
225#ifdef CONFIG_MAC80211_HT_DEBUG
226 printk(KERN_DEBUG "Could not find the station\n");
227#endif
228 ret = -ENOENT;
229 goto unlock;
230 }
231
232 /* 224 /*
233 * The aggregation code is not prepared to handle 225 * The aggregation code is not prepared to handle
234 * anything but STA/AP due to the BSSID handling. 226 * anything but STA/AP due to the BSSID handling.
235 * IBSS could work in the code but isn't supported 227 * IBSS could work in the code but isn't supported
236 * by drivers or the standard. 228 * by drivers or the standard.
237 */ 229 */
238 if (sta->sdata->vif.type != NL80211_IFTYPE_STATION && 230 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
239 sta->sdata->vif.type != NL80211_IFTYPE_AP_VLAN && 231 sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
240 sta->sdata->vif.type != NL80211_IFTYPE_AP) { 232 sdata->vif.type != NL80211_IFTYPE_AP)
241 ret = -EINVAL; 233 return -EINVAL;
242 goto unlock;
243 }
244 234
245 if (test_sta_flags(sta, WLAN_STA_SUSPEND)) { 235 if (test_sta_flags(sta, WLAN_STA_SUSPEND)) {
246#ifdef CONFIG_MAC80211_HT_DEBUG 236#ifdef CONFIG_MAC80211_HT_DEBUG
247 printk(KERN_DEBUG "Suspend in progress. " 237 printk(KERN_DEBUG "Suspend in progress. "
248 "Denying BA session request\n"); 238 "Denying BA session request\n");
249#endif 239#endif
250 ret = -EINVAL; 240 return -EINVAL;
251 goto unlock;
252 } 241 }
253 242
254 spin_lock_bh(&sta->lock); 243 spin_lock_bh(&sta->lock);
255 spin_lock(&local->ampdu_lock); 244 spin_lock(&local->ampdu_lock);
256 245
257 sdata = sta->sdata;
258
259 /* we have tried too many times, receiver does not want A-MPDU */ 246 /* we have tried too many times, receiver does not want A-MPDU */
260 if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) { 247 if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) {
261 ret = -EBUSY; 248 ret = -EBUSY;
@@ -312,8 +299,9 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
312 299
313 start_seq_num = sta->tid_seq[tid]; 300 start_seq_num = sta->tid_seq[tid];
314 301
315 ret = drv_ampdu_action(local, IEEE80211_AMPDU_TX_START, 302 ret = drv_ampdu_action(local, &sdata->vif,
316 &sta->sta, tid, &start_seq_num); 303 IEEE80211_AMPDU_TX_START,
304 pubsta, tid, &start_seq_num);
317 305
318 if (ret) { 306 if (ret) {
319#ifdef CONFIG_MAC80211_HT_DEBUG 307#ifdef CONFIG_MAC80211_HT_DEBUG
@@ -338,7 +326,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
338 sta->ampdu_mlme.dialog_token_allocator; 326 sta->ampdu_mlme.dialog_token_allocator;
339 sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num; 327 sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num;
340 328
341 ieee80211_send_addba_request(sta->sdata, ra, tid, 329 ieee80211_send_addba_request(sdata, pubsta->addr, tid,
342 sta->ampdu_mlme.tid_tx[tid]->dialog_token, 330 sta->ampdu_mlme.tid_tx[tid]->dialog_token,
343 sta->ampdu_mlme.tid_tx[tid]->ssn, 331 sta->ampdu_mlme.tid_tx[tid]->ssn,
344 0x40, 5000); 332 0x40, 5000);
@@ -350,7 +338,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
350#ifdef CONFIG_MAC80211_HT_DEBUG 338#ifdef CONFIG_MAC80211_HT_DEBUG
351 printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid); 339 printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid);
352#endif 340#endif
353 goto unlock; 341 return 0;
354 342
355 err_free: 343 err_free:
356 kfree(sta->ampdu_mlme.tid_tx[tid]); 344 kfree(sta->ampdu_mlme.tid_tx[tid]);
@@ -362,8 +350,6 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
362 err_unlock_sta: 350 err_unlock_sta:
363 spin_unlock(&local->ampdu_lock); 351 spin_unlock(&local->ampdu_lock);
364 spin_unlock_bh(&sta->lock); 352 spin_unlock_bh(&sta->lock);
365 unlock:
366 rcu_read_unlock();
367 return ret; 353 return ret;
368} 354}
369EXPORT_SYMBOL(ieee80211_start_tx_ba_session); 355EXPORT_SYMBOL(ieee80211_start_tx_ba_session);
@@ -430,13 +416,15 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
430 ieee80211_agg_splice_finish(local, sta, tid); 416 ieee80211_agg_splice_finish(local, sta, tid);
431 spin_unlock(&local->ampdu_lock); 417 spin_unlock(&local->ampdu_lock);
432 418
433 drv_ampdu_action(local, IEEE80211_AMPDU_TX_OPERATIONAL, 419 drv_ampdu_action(local, &sta->sdata->vif,
420 IEEE80211_AMPDU_TX_OPERATIONAL,
434 &sta->sta, tid, NULL); 421 &sta->sta, tid, NULL);
435} 422}
436 423
437void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) 424void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid)
438{ 425{
439 struct ieee80211_local *local = hw_to_local(hw); 426 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
427 struct ieee80211_local *local = sdata->local;
440 struct sta_info *sta; 428 struct sta_info *sta;
441 u8 *state; 429 u8 *state;
442 430
@@ -485,10 +473,11 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
485} 473}
486EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); 474EXPORT_SYMBOL(ieee80211_start_tx_ba_cb);
487 475
488void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, 476void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
489 const u8 *ra, u16 tid) 477 const u8 *ra, u16 tid)
490{ 478{
491 struct ieee80211_local *local = hw_to_local(hw); 479 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
480 struct ieee80211_local *local = sdata->local;
492 struct ieee80211_ra_tid *ra_tid; 481 struct ieee80211_ra_tid *ra_tid;
493 struct sk_buff *skb = dev_alloc_skb(0); 482 struct sk_buff *skb = dev_alloc_skb(0);
494 483
@@ -503,6 +492,7 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
503 ra_tid = (struct ieee80211_ra_tid *) &skb->cb; 492 ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
504 memcpy(&ra_tid->ra, ra, ETH_ALEN); 493 memcpy(&ra_tid->ra, ra, ETH_ALEN);
505 ra_tid->tid = tid; 494 ra_tid->tid = tid;
495 ra_tid->vif = vif;
506 496
507 skb->pkt_type = IEEE80211_ADDBA_MSG; 497 skb->pkt_type = IEEE80211_ADDBA_MSG;
508 skb_queue_tail(&local->skb_queue, skb); 498 skb_queue_tail(&local->skb_queue, skb);
@@ -537,13 +527,12 @@ int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
537 return ret; 527 return ret;
538} 528}
539 529
540int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, 530int ieee80211_stop_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
541 u8 *ra, u16 tid,
542 enum ieee80211_back_parties initiator) 531 enum ieee80211_back_parties initiator)
543{ 532{
544 struct ieee80211_local *local = hw_to_local(hw); 533 struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
545 struct sta_info *sta; 534 struct ieee80211_sub_if_data *sdata = sta->sdata;
546 int ret = 0; 535 struct ieee80211_local *local = sdata->local;
547 536
548 if (WARN_ON(!local->ops->ampdu_action)) 537 if (WARN_ON(!local->ops->ampdu_action))
549 return -EINVAL; 538 return -EINVAL;
@@ -551,22 +540,14 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
551 if (tid >= STA_TID_NUM) 540 if (tid >= STA_TID_NUM)
552 return -EINVAL; 541 return -EINVAL;
553 542
554 rcu_read_lock(); 543 return __ieee80211_stop_tx_ba_session(sta, tid, initiator);
555 sta = sta_info_get(local, ra);
556 if (!sta) {
557 rcu_read_unlock();
558 return -ENOENT;
559 }
560
561 ret = __ieee80211_stop_tx_ba_session(sta, tid, initiator);
562 rcu_read_unlock();
563 return ret;
564} 544}
565EXPORT_SYMBOL(ieee80211_stop_tx_ba_session); 545EXPORT_SYMBOL(ieee80211_stop_tx_ba_session);
566 546
567void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) 547void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)
568{ 548{
569 struct ieee80211_local *local = hw_to_local(hw); 549 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
550 struct ieee80211_local *local = sdata->local;
570 struct sta_info *sta; 551 struct sta_info *sta;
571 u8 *state; 552 u8 *state;
572 553
@@ -629,10 +610,11 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
629} 610}
630EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb); 611EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb);
631 612
632void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, 613void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
633 const u8 *ra, u16 tid) 614 const u8 *ra, u16 tid)
634{ 615{
635 struct ieee80211_local *local = hw_to_local(hw); 616 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
617 struct ieee80211_local *local = sdata->local;
636 struct ieee80211_ra_tid *ra_tid; 618 struct ieee80211_ra_tid *ra_tid;
637 struct sk_buff *skb = dev_alloc_skb(0); 619 struct sk_buff *skb = dev_alloc_skb(0);
638 620
@@ -647,6 +629,7 @@ void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
647 ra_tid = (struct ieee80211_ra_tid *) &skb->cb; 629 ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
648 memcpy(&ra_tid->ra, ra, ETH_ALEN); 630 memcpy(&ra_tid->ra, ra, ETH_ALEN);
649 ra_tid->tid = tid; 631 ra_tid->tid = tid;
632 ra_tid->vif = vif;
650 633
651 skb->pkt_type = IEEE80211_DELBA_MSG; 634 skb->pkt_type = IEEE80211_DELBA_MSG;
652 skb_queue_tail(&local->skb_queue, skb); 635 skb_queue_tail(&local->skb_queue, skb);