diff options
Diffstat (limited to 'net/mac80211/agg-tx.c')
-rw-r--r-- | net/mac80211/agg-tx.c | 103 |
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 | ||
97 | void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn) | 97 | void 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 | ||
126 | int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | 127 | int ___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 | ||
205 | int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | 207 | int 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 | } |
373 | EXPORT_SYMBOL(ieee80211_start_tx_ba_session); | 359 | EXPORT_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 | ||
441 | void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | 428 | void 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 | } |
490 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); | 478 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); |
491 | 479 | ||
492 | void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, | 480 | void 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 | ||
539 | int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | 529 | int 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 | } |
564 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_session); | 544 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_session); |
565 | 545 | ||
566 | void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | 546 | void 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 | } |
629 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb); | 610 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb); |
630 | 611 | ||
631 | void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, | 612 | void 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); |