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 b09948ceec4a..b50b2bc3b8c5 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 */
@@ -196,11 +198,11 @@ static inline int ieee80211_ac_from_tid(int tid)
196 return ieee802_1d_to_ac[tid & 7]; 198 return ieee802_1d_to_ac[tid & 7];
197} 199}
198 200
199int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) 201int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
200{ 202{
201 struct ieee80211_local *local = hw_to_local(hw); 203 struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
202 struct sta_info *sta; 204 struct ieee80211_sub_if_data *sdata = sta->sdata;
203 struct ieee80211_sub_if_data *sdata; 205 struct ieee80211_local *local = sdata->local;
204 u8 *state; 206 u8 *state;
205 int ret = 0; 207 int ret = 0;
206 u16 start_seq_num; 208 u16 start_seq_num;
@@ -208,52 +210,37 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
208 if (WARN_ON(!local->ops->ampdu_action)) 210 if (WARN_ON(!local->ops->ampdu_action))
209 return -EINVAL; 211 return -EINVAL;
210 212
211 if ((tid >= STA_TID_NUM) || !(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION)) 213 if ((tid >= STA_TID_NUM) ||
214 !(local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION))
212 return -EINVAL; 215 return -EINVAL;
213 216
214#ifdef CONFIG_MAC80211_HT_DEBUG 217#ifdef CONFIG_MAC80211_HT_DEBUG
215 printk(KERN_DEBUG "Open BA session requested for %pM tid %u\n", 218 printk(KERN_DEBUG "Open BA session requested for %pM tid %u\n",
216 ra, tid); 219 pubsta->addr, tid);
217#endif /* CONFIG_MAC80211_HT_DEBUG */ 220#endif /* CONFIG_MAC80211_HT_DEBUG */
218 221
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 /* 222 /*
231 * The aggregation code is not prepared to handle 223 * The aggregation code is not prepared to handle
232 * anything but STA/AP due to the BSSID handling. 224 * anything but STA/AP due to the BSSID handling.
233 * IBSS could work in the code but isn't supported 225 * IBSS could work in the code but isn't supported
234 * by drivers or the standard. 226 * by drivers or the standard.
235 */ 227 */
236 if (sta->sdata->vif.type != NL80211_IFTYPE_STATION && 228 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
237 sta->sdata->vif.type != NL80211_IFTYPE_AP_VLAN && 229 sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
238 sta->sdata->vif.type != NL80211_IFTYPE_AP) { 230 sdata->vif.type != NL80211_IFTYPE_AP)
239 ret = -EINVAL; 231 return -EINVAL;
240 goto unlock;
241 }
242 232
243 if (test_sta_flags(sta, WLAN_STA_SUSPEND)) { 233 if (test_sta_flags(sta, WLAN_STA_SUSPEND)) {
244#ifdef CONFIG_MAC80211_HT_DEBUG 234#ifdef CONFIG_MAC80211_HT_DEBUG
245 printk(KERN_DEBUG "Suspend in progress. " 235 printk(KERN_DEBUG "Suspend in progress. "
246 "Denying BA session request\n"); 236 "Denying BA session request\n");
247#endif 237#endif
248 ret = -EINVAL; 238 return -EINVAL;
249 goto unlock;
250 } 239 }
251 240
252 spin_lock_bh(&sta->lock); 241 spin_lock_bh(&sta->lock);
253 spin_lock(&local->ampdu_lock); 242 spin_lock(&local->ampdu_lock);
254 243
255 sdata = sta->sdata;
256
257 /* we have tried too many times, receiver does not want A-MPDU */ 244 /* 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) { 245 if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) {
259 ret = -EBUSY; 246 ret = -EBUSY;
@@ -310,8 +297,9 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
310 297
311 start_seq_num = sta->tid_seq[tid]; 298 start_seq_num = sta->tid_seq[tid];
312 299
313 ret = drv_ampdu_action(local, IEEE80211_AMPDU_TX_START, 300 ret = drv_ampdu_action(local, &sdata->vif,
314 &sta->sta, tid, &start_seq_num); 301 IEEE80211_AMPDU_TX_START,
302 pubsta, tid, &start_seq_num);
315 303
316 if (ret) { 304 if (ret) {
317#ifdef CONFIG_MAC80211_HT_DEBUG 305#ifdef CONFIG_MAC80211_HT_DEBUG
@@ -336,7 +324,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
336 sta->ampdu_mlme.dialog_token_allocator; 324 sta->ampdu_mlme.dialog_token_allocator;
337 sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num; 325 sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num;
338 326
339 ieee80211_send_addba_request(sta->sdata, ra, tid, 327 ieee80211_send_addba_request(sdata, pubsta->addr, tid,
340 sta->ampdu_mlme.tid_tx[tid]->dialog_token, 328 sta->ampdu_mlme.tid_tx[tid]->dialog_token,
341 sta->ampdu_mlme.tid_tx[tid]->ssn, 329 sta->ampdu_mlme.tid_tx[tid]->ssn,
342 0x40, 5000); 330 0x40, 5000);
@@ -348,7 +336,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
348#ifdef CONFIG_MAC80211_HT_DEBUG 336#ifdef CONFIG_MAC80211_HT_DEBUG
349 printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid); 337 printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid);
350#endif 338#endif
351 goto unlock; 339 return 0;
352 340
353 err_free: 341 err_free:
354 kfree(sta->ampdu_mlme.tid_tx[tid]); 342 kfree(sta->ampdu_mlme.tid_tx[tid]);
@@ -360,8 +348,6 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
360 err_unlock_sta: 348 err_unlock_sta:
361 spin_unlock(&local->ampdu_lock); 349 spin_unlock(&local->ampdu_lock);
362 spin_unlock_bh(&sta->lock); 350 spin_unlock_bh(&sta->lock);
363 unlock:
364 rcu_read_unlock();
365 return ret; 351 return ret;
366} 352}
367EXPORT_SYMBOL(ieee80211_start_tx_ba_session); 353EXPORT_SYMBOL(ieee80211_start_tx_ba_session);
@@ -428,13 +414,15 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
428 ieee80211_agg_splice_finish(local, sta, tid); 414 ieee80211_agg_splice_finish(local, sta, tid);
429 spin_unlock(&local->ampdu_lock); 415 spin_unlock(&local->ampdu_lock);
430 416
431 drv_ampdu_action(local, IEEE80211_AMPDU_TX_OPERATIONAL, 417 drv_ampdu_action(local, &sta->sdata->vif,
418 IEEE80211_AMPDU_TX_OPERATIONAL,
432 &sta->sta, tid, NULL); 419 &sta->sta, tid, NULL);
433} 420}
434 421
435void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) 422void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid)
436{ 423{
437 struct ieee80211_local *local = hw_to_local(hw); 424 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
425 struct ieee80211_local *local = sdata->local;
438 struct sta_info *sta; 426 struct sta_info *sta;
439 u8 *state; 427 u8 *state;
440 428
@@ -483,10 +471,11 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
483} 471}
484EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); 472EXPORT_SYMBOL(ieee80211_start_tx_ba_cb);
485 473
486void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, 474void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
487 const u8 *ra, u16 tid) 475 const u8 *ra, u16 tid)
488{ 476{
489 struct ieee80211_local *local = hw_to_local(hw); 477 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
478 struct ieee80211_local *local = sdata->local;
490 struct ieee80211_ra_tid *ra_tid; 479 struct ieee80211_ra_tid *ra_tid;
491 struct sk_buff *skb = dev_alloc_skb(0); 480 struct sk_buff *skb = dev_alloc_skb(0);
492 481
@@ -501,6 +490,7 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
501 ra_tid = (struct ieee80211_ra_tid *) &skb->cb; 490 ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
502 memcpy(&ra_tid->ra, ra, ETH_ALEN); 491 memcpy(&ra_tid->ra, ra, ETH_ALEN);
503 ra_tid->tid = tid; 492 ra_tid->tid = tid;
493 ra_tid->vif = vif;
504 494
505 skb->pkt_type = IEEE80211_ADDBA_MSG; 495 skb->pkt_type = IEEE80211_ADDBA_MSG;
506 skb_queue_tail(&local->skb_queue, skb); 496 skb_queue_tail(&local->skb_queue, skb);
@@ -535,13 +525,12 @@ int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
535 return ret; 525 return ret;
536} 526}
537 527
538int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, 528int ieee80211_stop_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
539 u8 *ra, u16 tid,
540 enum ieee80211_back_parties initiator) 529 enum ieee80211_back_parties initiator)
541{ 530{
542 struct ieee80211_local *local = hw_to_local(hw); 531 struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
543 struct sta_info *sta; 532 struct ieee80211_sub_if_data *sdata = sta->sdata;
544 int ret = 0; 533 struct ieee80211_local *local = sdata->local;
545 534
546 if (WARN_ON(!local->ops->ampdu_action)) 535 if (WARN_ON(!local->ops->ampdu_action))
547 return -EINVAL; 536 return -EINVAL;
@@ -549,22 +538,14 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
549 if (tid >= STA_TID_NUM) 538 if (tid >= STA_TID_NUM)
550 return -EINVAL; 539 return -EINVAL;
551 540
552 rcu_read_lock(); 541 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} 542}
563EXPORT_SYMBOL(ieee80211_stop_tx_ba_session); 543EXPORT_SYMBOL(ieee80211_stop_tx_ba_session);
564 544
565void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) 545void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)
566{ 546{
567 struct ieee80211_local *local = hw_to_local(hw); 547 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
548 struct ieee80211_local *local = sdata->local;
568 struct sta_info *sta; 549 struct sta_info *sta;
569 u8 *state; 550 u8 *state;
570 551
@@ -627,10 +608,11 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
627} 608}
628EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb); 609EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb);
629 610
630void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, 611void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
631 const u8 *ra, u16 tid) 612 const u8 *ra, u16 tid)
632{ 613{
633 struct ieee80211_local *local = hw_to_local(hw); 614 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
615 struct ieee80211_local *local = sdata->local;
634 struct ieee80211_ra_tid *ra_tid; 616 struct ieee80211_ra_tid *ra_tid;
635 struct sk_buff *skb = dev_alloc_skb(0); 617 struct sk_buff *skb = dev_alloc_skb(0);
636 618
@@ -645,6 +627,7 @@ void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
645 ra_tid = (struct ieee80211_ra_tid *) &skb->cb; 627 ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
646 memcpy(&ra_tid->ra, ra, ETH_ALEN); 628 memcpy(&ra_tid->ra, ra, ETH_ALEN);
647 ra_tid->tid = tid; 629 ra_tid->tid = tid;
630 ra_tid->vif = vif;
648 631
649 skb->pkt_type = IEEE80211_DELBA_MSG; 632 skb->pkt_type = IEEE80211_DELBA_MSG;
650 skb_queue_tail(&local->skb_queue, skb); 633 skb_queue_tail(&local->skb_queue, skb);