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 89e238b001de..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,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
126int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, 127int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
@@ -143,7 +144,8 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
143 *state = HT_AGG_STATE_REQ_STOP_BA_MSK | 144 *state = HT_AGG_STATE_REQ_STOP_BA_MSK |
144 (initiator << HT_AGG_STATE_INITIATOR_SHIFT); 145 (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
145 146
146 ret = drv_ampdu_action(local, IEEE80211_AMPDU_TX_STOP, 147 ret = drv_ampdu_action(local, &sta->sdata->vif,
148 IEEE80211_AMPDU_TX_STOP,
147 &sta->sta, tid, NULL); 149 &sta->sta, tid, NULL);
148 150
149 /* HW shall not deny going back to legacy */ 151 /* HW shall not deny going back to legacy */
@@ -202,11 +204,11 @@ static inline int ieee80211_ac_from_tid(int tid)
202 return ieee802_1d_to_ac[tid & 7]; 204 return ieee802_1d_to_ac[tid & 7];
203} 205}
204 206
205int 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)
206{ 208{
207 struct ieee80211_local *local = hw_to_local(hw); 209 struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
208 struct sta_info *sta; 210 struct ieee80211_sub_if_data *sdata = sta->sdata;
209 struct ieee80211_sub_if_data *sdata; 211 struct ieee80211_local *local = sdata->local;
210 u8 *state; 212 u8 *state;
211 int ret = 0; 213 int ret = 0;
212 u16 start_seq_num; 214 u16 start_seq_num;
@@ -214,52 +216,37 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
214 if (WARN_ON(!local->ops->ampdu_action)) 216 if (WARN_ON(!local->ops->ampdu_action))
215 return -EINVAL; 217 return -EINVAL;
216 218
217 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))
218 return -EINVAL; 221 return -EINVAL;
219 222
220#ifdef CONFIG_MAC80211_HT_DEBUG 223#ifdef CONFIG_MAC80211_HT_DEBUG
221 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",
222 ra, tid); 225 pubsta->addr, tid);
223#endif /* CONFIG_MAC80211_HT_DEBUG */ 226#endif /* CONFIG_MAC80211_HT_DEBUG */
224 227
225 rcu_read_lock();
226
227 sta = sta_info_get(local, ra);
228 if (!sta) {
229#ifdef CONFIG_MAC80211_HT_DEBUG
230 printk(KERN_DEBUG "Could not find the station\n");
231#endif
232 ret = -ENOENT;
233 goto unlock;
234 }
235
236 /* 228 /*
237 * The aggregation code is not prepared to handle 229 * The aggregation code is not prepared to handle
238 * anything but STA/AP due to the BSSID handling. 230 * anything but STA/AP due to the BSSID handling.
239 * IBSS could work in the code but isn't supported 231 * IBSS could work in the code but isn't supported
240 * by drivers or the standard. 232 * by drivers or the standard.
241 */ 233 */
242 if (sta->sdata->vif.type != NL80211_IFTYPE_STATION && 234 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
243 sta->sdata->vif.type != NL80211_IFTYPE_AP_VLAN && 235 sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
244 sta->sdata->vif.type != NL80211_IFTYPE_AP) { 236 sdata->vif.type != NL80211_IFTYPE_AP)
245 ret = -EINVAL; 237 return -EINVAL;
246 goto unlock;
247 }
248 238
249 if (test_sta_flags(sta, WLAN_STA_SUSPEND)) { 239 if (test_sta_flags(sta, WLAN_STA_SUSPEND)) {
250#ifdef CONFIG_MAC80211_HT_DEBUG 240#ifdef CONFIG_MAC80211_HT_DEBUG
251 printk(KERN_DEBUG "Suspend in progress. " 241 printk(KERN_DEBUG "Suspend in progress. "
252 "Denying BA session request\n"); 242 "Denying BA session request\n");
253#endif 243#endif
254 ret = -EINVAL; 244 return -EINVAL;
255 goto unlock;
256 } 245 }
257 246
258 spin_lock_bh(&sta->lock); 247 spin_lock_bh(&sta->lock);
259 spin_lock(&local->ampdu_lock); 248 spin_lock(&local->ampdu_lock);
260 249
261 sdata = sta->sdata;
262
263 /* 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 */
264 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) {
265 ret = -EBUSY; 252 ret = -EBUSY;
@@ -316,8 +303,9 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
316 303
317 start_seq_num = sta->tid_seq[tid]; 304 start_seq_num = sta->tid_seq[tid];
318 305
319 ret = drv_ampdu_action(local, IEEE80211_AMPDU_TX_START, 306 ret = drv_ampdu_action(local, &sdata->vif,
320 &sta->sta, tid, &start_seq_num); 307 IEEE80211_AMPDU_TX_START,
308 pubsta, tid, &start_seq_num);
321 309
322 if (ret) { 310 if (ret) {
323#ifdef CONFIG_MAC80211_HT_DEBUG 311#ifdef CONFIG_MAC80211_HT_DEBUG
@@ -342,7 +330,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
342 sta->ampdu_mlme.dialog_token_allocator; 330 sta->ampdu_mlme.dialog_token_allocator;
343 sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num; 331 sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num;
344 332
345 ieee80211_send_addba_request(sta->sdata, ra, tid, 333 ieee80211_send_addba_request(sdata, pubsta->addr, tid,
346 sta->ampdu_mlme.tid_tx[tid]->dialog_token, 334 sta->ampdu_mlme.tid_tx[tid]->dialog_token,
347 sta->ampdu_mlme.tid_tx[tid]->ssn, 335 sta->ampdu_mlme.tid_tx[tid]->ssn,
348 0x40, 5000); 336 0x40, 5000);
@@ -354,7 +342,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
354#ifdef CONFIG_MAC80211_HT_DEBUG 342#ifdef CONFIG_MAC80211_HT_DEBUG
355 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);
356#endif 344#endif
357 goto unlock; 345 return 0;
358 346
359 err_free: 347 err_free:
360 kfree(sta->ampdu_mlme.tid_tx[tid]); 348 kfree(sta->ampdu_mlme.tid_tx[tid]);
@@ -366,8 +354,6 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
366 err_unlock_sta: 354 err_unlock_sta:
367 spin_unlock(&local->ampdu_lock); 355 spin_unlock(&local->ampdu_lock);
368 spin_unlock_bh(&sta->lock); 356 spin_unlock_bh(&sta->lock);
369 unlock:
370 rcu_read_unlock();
371 return ret; 357 return ret;
372} 358}
373EXPORT_SYMBOL(ieee80211_start_tx_ba_session); 359EXPORT_SYMBOL(ieee80211_start_tx_ba_session);
@@ -434,13 +420,15 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
434 ieee80211_agg_splice_finish(local, sta, tid); 420 ieee80211_agg_splice_finish(local, sta, tid);
435 spin_unlock(&local->ampdu_lock); 421 spin_unlock(&local->ampdu_lock);
436 422
437 drv_ampdu_action(local, IEEE80211_AMPDU_TX_OPERATIONAL, 423 drv_ampdu_action(local, &sta->sdata->vif,
424 IEEE80211_AMPDU_TX_OPERATIONAL,
438 &sta->sta, tid, NULL); 425 &sta->sta, tid, NULL);
439} 426}
440 427
441void 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)
442{ 429{
443 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;
444 struct sta_info *sta; 432 struct sta_info *sta;
445 u8 *state; 433 u8 *state;
446 434
@@ -489,10 +477,11 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
489} 477}
490EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); 478EXPORT_SYMBOL(ieee80211_start_tx_ba_cb);
491 479
492void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, 480void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
493 const u8 *ra, u16 tid) 481 const u8 *ra, u16 tid)
494{ 482{
495 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;
496 struct ieee80211_ra_tid *ra_tid; 485 struct ieee80211_ra_tid *ra_tid;
497 struct sk_buff *skb = dev_alloc_skb(0); 486 struct sk_buff *skb = dev_alloc_skb(0);
498 487
@@ -507,6 +496,7 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
507 ra_tid = (struct ieee80211_ra_tid *) &skb->cb; 496 ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
508 memcpy(&ra_tid->ra, ra, ETH_ALEN); 497 memcpy(&ra_tid->ra, ra, ETH_ALEN);
509 ra_tid->tid = tid; 498 ra_tid->tid = tid;
499 ra_tid->vif = vif;
510 500
511 skb->pkt_type = IEEE80211_ADDBA_MSG; 501 skb->pkt_type = IEEE80211_ADDBA_MSG;
512 skb_queue_tail(&local->skb_queue, skb); 502 skb_queue_tail(&local->skb_queue, skb);
@@ -536,13 +526,12 @@ int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
536 return ret; 526 return ret;
537} 527}
538 528
539int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, 529int ieee80211_stop_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
540 u8 *ra, u16 tid,
541 enum ieee80211_back_parties initiator) 530 enum ieee80211_back_parties initiator)
542{ 531{
543 struct ieee80211_local *local = hw_to_local(hw); 532 struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
544 struct sta_info *sta; 533 struct ieee80211_sub_if_data *sdata = sta->sdata;
545 int ret = 0; 534 struct ieee80211_local *local = sdata->local;
546 535
547 if (!local->ops->ampdu_action) 536 if (!local->ops->ampdu_action)
548 return -EINVAL; 537 return -EINVAL;
@@ -550,22 +539,14 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
550 if (tid >= STA_TID_NUM) 539 if (tid >= STA_TID_NUM)
551 return -EINVAL; 540 return -EINVAL;
552 541
553 rcu_read_lock(); 542 return __ieee80211_stop_tx_ba_session(sta, tid, initiator);
554 sta = sta_info_get(local, ra);
555 if (!sta) {
556 rcu_read_unlock();
557 return -ENOENT;
558 }
559
560 ret = __ieee80211_stop_tx_ba_session(sta, tid, initiator);
561 rcu_read_unlock();
562 return ret;
563} 543}
564EXPORT_SYMBOL(ieee80211_stop_tx_ba_session); 544EXPORT_SYMBOL(ieee80211_stop_tx_ba_session);
565 545
566void 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)
567{ 547{
568 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;
569 struct sta_info *sta; 550 struct sta_info *sta;
570 u8 *state; 551 u8 *state;
571 552
@@ -628,10 +609,11 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
628} 609}
629EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb); 610EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb);
630 611
631void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, 612void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
632 const u8 *ra, u16 tid) 613 const u8 *ra, u16 tid)
633{ 614{
634 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;
635 struct ieee80211_ra_tid *ra_tid; 617 struct ieee80211_ra_tid *ra_tid;
636 struct sk_buff *skb = dev_alloc_skb(0); 618 struct sk_buff *skb = dev_alloc_skb(0);
637 619
@@ -646,6 +628,7 @@ void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
646 ra_tid = (struct ieee80211_ra_tid *) &skb->cb; 628 ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
647 memcpy(&ra_tid->ra, ra, ETH_ALEN); 629 memcpy(&ra_tid->ra, ra, ETH_ALEN);
648 ra_tid->tid = tid; 630 ra_tid->tid = tid;
631 ra_tid->vif = vif;
649 632
650 skb->pkt_type = IEEE80211_DELBA_MSG; 633 skb->pkt_type = IEEE80211_DELBA_MSG;
651 skb_queue_tail(&local->skb_queue, skb); 634 skb_queue_tail(&local->skb_queue, skb);