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.c138
1 files changed, 59 insertions, 79 deletions
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index b09948ceec4a..5e3a7eccef5a 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,16 +120,22 @@ 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, 127int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
127 enum ieee80211_back_parties initiator) 128 enum ieee80211_back_parties initiator)
128{ 129{
129 struct ieee80211_local *local = sta->local; 130 struct ieee80211_local *local = sta->local;
130 int ret; 131 int ret;
131 u8 *state; 132 u8 *state;
132 133
134#ifdef CONFIG_MAC80211_HT_DEBUG
135 printk(KERN_DEBUG "Tx BA session stop requested for %pM tid %u\n",
136 sta->sta.addr, tid);
137#endif /* CONFIG_MAC80211_HT_DEBUG */
138
133 state = &sta->ampdu_mlme.tid_state_tx[tid]; 139 state = &sta->ampdu_mlme.tid_state_tx[tid];
134 140
135 if (*state == HT_AGG_STATE_OPERATIONAL) 141 if (*state == HT_AGG_STATE_OPERATIONAL)
@@ -138,12 +144,12 @@ static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
138 *state = HT_AGG_STATE_REQ_STOP_BA_MSK | 144 *state = HT_AGG_STATE_REQ_STOP_BA_MSK |
139 (initiator << HT_AGG_STATE_INITIATOR_SHIFT); 145 (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
140 146
141 ret = drv_ampdu_action(local, IEEE80211_AMPDU_TX_STOP, 147 ret = drv_ampdu_action(local, &sta->sdata->vif,
148 IEEE80211_AMPDU_TX_STOP,
142 &sta->sta, tid, NULL); 149 &sta->sta, tid, NULL);
143 150
144 /* HW shall not deny going back to legacy */ 151 /* HW shall not deny going back to legacy */
145 if (WARN_ON(ret)) { 152 if (WARN_ON(ret)) {
146 *state = HT_AGG_STATE_OPERATIONAL;
147 /* 153 /*
148 * We may have pending packets get stuck in this case... 154 * We may have pending packets get stuck in this case...
149 * Not bothering with a workaround for now. 155 * Not bothering with a workaround for now.
@@ -173,12 +179,14 @@ static void sta_addba_resp_timer_expired(unsigned long data)
173 179
174 /* check if the TID waits for addBA response */ 180 /* check if the TID waits for addBA response */
175 spin_lock_bh(&sta->lock); 181 spin_lock_bh(&sta->lock);
176 if (!(*state & HT_ADDBA_REQUESTED_MSK)) { 182 if ((*state & (HT_ADDBA_REQUESTED_MSK | HT_ADDBA_RECEIVED_MSK)) !=
183 HT_ADDBA_REQUESTED_MSK) {
177 spin_unlock_bh(&sta->lock); 184 spin_unlock_bh(&sta->lock);
178 *state = HT_AGG_STATE_IDLE; 185 *state = HT_AGG_STATE_IDLE;
179#ifdef CONFIG_MAC80211_HT_DEBUG 186#ifdef CONFIG_MAC80211_HT_DEBUG
180 printk(KERN_DEBUG "timer expired on tid %d but we are not " 187 printk(KERN_DEBUG "timer expired on tid %d but we are not "
181 "expecting addBA response there", tid); 188 "(or no longer) expecting addBA response there",
189 tid);
182#endif 190#endif
183 return; 191 return;
184 } 192 }
@@ -196,11 +204,11 @@ static inline int ieee80211_ac_from_tid(int tid)
196 return ieee802_1d_to_ac[tid & 7]; 204 return ieee802_1d_to_ac[tid & 7];
197} 205}
198 206
199int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) 207int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
200{ 208{
201 struct ieee80211_local *local = hw_to_local(hw); 209 struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
202 struct sta_info *sta; 210 struct ieee80211_sub_if_data *sdata = sta->sdata;
203 struct ieee80211_sub_if_data *sdata; 211 struct ieee80211_local *local = sdata->local;
204 u8 *state; 212 u8 *state;
205 int ret = 0; 213 int ret = 0;
206 u16 start_seq_num; 214 u16 start_seq_num;
@@ -208,52 +216,37 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
208 if (WARN_ON(!local->ops->ampdu_action)) 216 if (WARN_ON(!local->ops->ampdu_action))
209 return -EINVAL; 217 return -EINVAL;
210 218
211 if ((tid >= STA_TID_NUM) || !(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION)) 219 if ((tid >= STA_TID_NUM) ||
220 !(local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION))
212 return -EINVAL; 221 return -EINVAL;
213 222
214#ifdef CONFIG_MAC80211_HT_DEBUG 223#ifdef CONFIG_MAC80211_HT_DEBUG
215 printk(KERN_DEBUG "Open BA session requested for %pM tid %u\n", 224 printk(KERN_DEBUG "Open BA session requested for %pM tid %u\n",
216 ra, tid); 225 pubsta->addr, tid);
217#endif /* CONFIG_MAC80211_HT_DEBUG */ 226#endif /* CONFIG_MAC80211_HT_DEBUG */
218 227
219 rcu_read_lock();
220
221 sta = sta_info_get(local, ra);
222 if (!sta) {
223#ifdef CONFIG_MAC80211_HT_DEBUG
224 printk(KERN_DEBUG "Could not find the station\n");
225#endif
226 ret = -ENOENT;
227 goto unlock;
228 }
229
230 /* 228 /*
231 * The aggregation code is not prepared to handle 229 * The aggregation code is not prepared to handle
232 * anything but STA/AP due to the BSSID handling. 230 * anything but STA/AP due to the BSSID handling.
233 * IBSS could work in the code but isn't supported 231 * IBSS could work in the code but isn't supported
234 * by drivers or the standard. 232 * by drivers or the standard.
235 */ 233 */
236 if (sta->sdata->vif.type != NL80211_IFTYPE_STATION && 234 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
237 sta->sdata->vif.type != NL80211_IFTYPE_AP_VLAN && 235 sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
238 sta->sdata->vif.type != NL80211_IFTYPE_AP) { 236 sdata->vif.type != NL80211_IFTYPE_AP)
239 ret = -EINVAL; 237 return -EINVAL;
240 goto unlock;
241 }
242 238
243 if (test_sta_flags(sta, WLAN_STA_SUSPEND)) { 239 if (test_sta_flags(sta, WLAN_STA_SUSPEND)) {
244#ifdef CONFIG_MAC80211_HT_DEBUG 240#ifdef CONFIG_MAC80211_HT_DEBUG
245 printk(KERN_DEBUG "Suspend in progress. " 241 printk(KERN_DEBUG "Suspend in progress. "
246 "Denying BA session request\n"); 242 "Denying BA session request\n");
247#endif 243#endif
248 ret = -EINVAL; 244 return -EINVAL;
249 goto unlock;
250 } 245 }
251 246
252 spin_lock_bh(&sta->lock); 247 spin_lock_bh(&sta->lock);
253 spin_lock(&local->ampdu_lock); 248 spin_lock(&local->ampdu_lock);
254 249
255 sdata = sta->sdata;
256
257 /* we have tried too many times, receiver does not want A-MPDU */ 250 /* we have tried too many times, receiver does not want A-MPDU */
258 if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) { 251 if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) {
259 ret = -EBUSY; 252 ret = -EBUSY;
@@ -310,8 +303,9 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
310 303
311 start_seq_num = sta->tid_seq[tid]; 304 start_seq_num = sta->tid_seq[tid];
312 305
313 ret = drv_ampdu_action(local, IEEE80211_AMPDU_TX_START, 306 ret = drv_ampdu_action(local, &sdata->vif,
314 &sta->sta, tid, &start_seq_num); 307 IEEE80211_AMPDU_TX_START,
308 pubsta, tid, &start_seq_num);
315 309
316 if (ret) { 310 if (ret) {
317#ifdef CONFIG_MAC80211_HT_DEBUG 311#ifdef CONFIG_MAC80211_HT_DEBUG
@@ -336,7 +330,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
336 sta->ampdu_mlme.dialog_token_allocator; 330 sta->ampdu_mlme.dialog_token_allocator;
337 sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num; 331 sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num;
338 332
339 ieee80211_send_addba_request(sta->sdata, ra, tid, 333 ieee80211_send_addba_request(sdata, pubsta->addr, tid,
340 sta->ampdu_mlme.tid_tx[tid]->dialog_token, 334 sta->ampdu_mlme.tid_tx[tid]->dialog_token,
341 sta->ampdu_mlme.tid_tx[tid]->ssn, 335 sta->ampdu_mlme.tid_tx[tid]->ssn,
342 0x40, 5000); 336 0x40, 5000);
@@ -348,7 +342,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
348#ifdef CONFIG_MAC80211_HT_DEBUG 342#ifdef CONFIG_MAC80211_HT_DEBUG
349 printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid); 343 printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid);
350#endif 344#endif
351 goto unlock; 345 return 0;
352 346
353 err_free: 347 err_free:
354 kfree(sta->ampdu_mlme.tid_tx[tid]); 348 kfree(sta->ampdu_mlme.tid_tx[tid]);
@@ -360,8 +354,6 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
360 err_unlock_sta: 354 err_unlock_sta:
361 spin_unlock(&local->ampdu_lock); 355 spin_unlock(&local->ampdu_lock);
362 spin_unlock_bh(&sta->lock); 356 spin_unlock_bh(&sta->lock);
363 unlock:
364 rcu_read_unlock();
365 return ret; 357 return ret;
366} 358}
367EXPORT_SYMBOL(ieee80211_start_tx_ba_session); 359EXPORT_SYMBOL(ieee80211_start_tx_ba_session);
@@ -428,13 +420,15 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
428 ieee80211_agg_splice_finish(local, sta, tid); 420 ieee80211_agg_splice_finish(local, sta, tid);
429 spin_unlock(&local->ampdu_lock); 421 spin_unlock(&local->ampdu_lock);
430 422
431 drv_ampdu_action(local, IEEE80211_AMPDU_TX_OPERATIONAL, 423 drv_ampdu_action(local, &sta->sdata->vif,
424 IEEE80211_AMPDU_TX_OPERATIONAL,
432 &sta->sta, tid, NULL); 425 &sta->sta, tid, NULL);
433} 426}
434 427
435void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) 428void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid)
436{ 429{
437 struct ieee80211_local *local = hw_to_local(hw); 430 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
431 struct ieee80211_local *local = sdata->local;
438 struct sta_info *sta; 432 struct sta_info *sta;
439 u8 *state; 433 u8 *state;
440 434
@@ -483,10 +477,11 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
483} 477}
484EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); 478EXPORT_SYMBOL(ieee80211_start_tx_ba_cb);
485 479
486void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, 480void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
487 const u8 *ra, u16 tid) 481 const u8 *ra, u16 tid)
488{ 482{
489 struct ieee80211_local *local = hw_to_local(hw); 483 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
484 struct ieee80211_local *local = sdata->local;
490 struct ieee80211_ra_tid *ra_tid; 485 struct ieee80211_ra_tid *ra_tid;
491 struct sk_buff *skb = dev_alloc_skb(0); 486 struct sk_buff *skb = dev_alloc_skb(0);
492 487
@@ -501,6 +496,7 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
501 ra_tid = (struct ieee80211_ra_tid *) &skb->cb; 496 ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
502 memcpy(&ra_tid->ra, ra, ETH_ALEN); 497 memcpy(&ra_tid->ra, ra, ETH_ALEN);
503 ra_tid->tid = tid; 498 ra_tid->tid = tid;
499 ra_tid->vif = vif;
504 500
505 skb->pkt_type = IEEE80211_ADDBA_MSG; 501 skb->pkt_type = IEEE80211_ADDBA_MSG;
506 skb_queue_tail(&local->skb_queue, skb); 502 skb_queue_tail(&local->skb_queue, skb);
@@ -523,11 +519,6 @@ int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
523 goto unlock; 519 goto unlock;
524 } 520 }
525 521
526#ifdef CONFIG_MAC80211_HT_DEBUG
527 printk(KERN_DEBUG "Tx BA session stop requested for %pM tid %u\n",
528 sta->sta.addr, tid);
529#endif /* CONFIG_MAC80211_HT_DEBUG */
530
531 ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator); 522 ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator);
532 523
533 unlock: 524 unlock:
@@ -535,36 +526,27 @@ int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
535 return ret; 526 return ret;
536} 527}
537 528
538int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, 529int ieee80211_stop_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
539 u8 *ra, u16 tid,
540 enum ieee80211_back_parties initiator) 530 enum ieee80211_back_parties initiator)
541{ 531{
542 struct ieee80211_local *local = hw_to_local(hw); 532 struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
543 struct sta_info *sta; 533 struct ieee80211_sub_if_data *sdata = sta->sdata;
544 int ret = 0; 534 struct ieee80211_local *local = sdata->local;
545 535
546 if (WARN_ON(!local->ops->ampdu_action)) 536 if (!local->ops->ampdu_action)
547 return -EINVAL; 537 return -EINVAL;
548 538
549 if (tid >= STA_TID_NUM) 539 if (tid >= STA_TID_NUM)
550 return -EINVAL; 540 return -EINVAL;
551 541
552 rcu_read_lock(); 542 return __ieee80211_stop_tx_ba_session(sta, tid, initiator);
553 sta = sta_info_get(local, ra);
554 if (!sta) {
555 rcu_read_unlock();
556 return -ENOENT;
557 }
558
559 ret = __ieee80211_stop_tx_ba_session(sta, tid, initiator);
560 rcu_read_unlock();
561 return ret;
562} 543}
563EXPORT_SYMBOL(ieee80211_stop_tx_ba_session); 544EXPORT_SYMBOL(ieee80211_stop_tx_ba_session);
564 545
565void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) 546void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)
566{ 547{
567 struct ieee80211_local *local = hw_to_local(hw); 548 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
549 struct ieee80211_local *local = sdata->local;
568 struct sta_info *sta; 550 struct sta_info *sta;
569 u8 *state; 551 u8 *state;
570 552
@@ -627,10 +609,11 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
627} 609}
628EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb); 610EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb);
629 611
630void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, 612void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
631 const u8 *ra, u16 tid) 613 const u8 *ra, u16 tid)
632{ 614{
633 struct ieee80211_local *local = hw_to_local(hw); 615 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
616 struct ieee80211_local *local = sdata->local;
634 struct ieee80211_ra_tid *ra_tid; 617 struct ieee80211_ra_tid *ra_tid;
635 struct sk_buff *skb = dev_alloc_skb(0); 618 struct sk_buff *skb = dev_alloc_skb(0);
636 619
@@ -645,6 +628,7 @@ void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
645 ra_tid = (struct ieee80211_ra_tid *) &skb->cb; 628 ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
646 memcpy(&ra_tid->ra, ra, ETH_ALEN); 629 memcpy(&ra_tid->ra, ra, ETH_ALEN);
647 ra_tid->tid = tid; 630 ra_tid->tid = tid;
631 ra_tid->vif = vif;
648 632
649 skb->pkt_type = IEEE80211_DELBA_MSG; 633 skb->pkt_type = IEEE80211_DELBA_MSG;
650 skb_queue_tail(&local->skb_queue, skb); 634 skb_queue_tail(&local->skb_queue, skb);
@@ -666,21 +650,21 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
666 650
667 state = &sta->ampdu_mlme.tid_state_tx[tid]; 651 state = &sta->ampdu_mlme.tid_state_tx[tid];
668 652
669 del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
670
671 spin_lock_bh(&sta->lock); 653 spin_lock_bh(&sta->lock);
672 654
673 if (!(*state & HT_ADDBA_REQUESTED_MSK)) 655 if (!(*state & HT_ADDBA_REQUESTED_MSK))
674 goto timer_still_needed; 656 goto out;
675 657
676 if (mgmt->u.action.u.addba_resp.dialog_token != 658 if (mgmt->u.action.u.addba_resp.dialog_token !=
677 sta->ampdu_mlme.tid_tx[tid]->dialog_token) { 659 sta->ampdu_mlme.tid_tx[tid]->dialog_token) {
678#ifdef CONFIG_MAC80211_HT_DEBUG 660#ifdef CONFIG_MAC80211_HT_DEBUG
679 printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); 661 printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
680#endif /* CONFIG_MAC80211_HT_DEBUG */ 662#endif /* CONFIG_MAC80211_HT_DEBUG */
681 goto timer_still_needed; 663 goto out;
682 } 664 }
683 665
666 del_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
667
684#ifdef CONFIG_MAC80211_HT_DEBUG 668#ifdef CONFIG_MAC80211_HT_DEBUG
685 printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid); 669 printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid);
686#endif /* CONFIG_MAC80211_HT_DEBUG */ 670#endif /* CONFIG_MAC80211_HT_DEBUG */
@@ -699,10 +683,6 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
699 ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); 683 ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR);
700 } 684 }
701 685
702 goto out;
703
704 timer_still_needed:
705 add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
706 out: 686 out:
707 spin_unlock_bh(&sta->lock); 687 spin_unlock_bh(&sta->lock);
708} 688}