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 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 | ||
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 | static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | 127 | static 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 | ||
201 | int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | 203 | int 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 | } |
369 | EXPORT_SYMBOL(ieee80211_start_tx_ba_session); | 355 | EXPORT_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 | ||
437 | void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | 424 | void 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 | } |
486 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); | 474 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); |
487 | 475 | ||
488 | void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, | 476 | void 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 | ||
540 | int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | 530 | int 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 | } |
565 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_session); | 545 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_session); |
566 | 546 | ||
567 | void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | 547 | void 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 | } |
630 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb); | 611 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb); |
631 | 612 | ||
632 | void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, | 613 | void 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); |