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 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 | ||
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 */ |
@@ -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 | ||
199 | int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | 201 | int 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 | } |
367 | EXPORT_SYMBOL(ieee80211_start_tx_ba_session); | 353 | EXPORT_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 | ||
435 | void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | 422 | void 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 | } |
484 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); | 472 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); |
485 | 473 | ||
486 | void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, | 474 | void 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 | ||
538 | int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | 528 | int 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 | } |
563 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_session); | 543 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_session); |
564 | 544 | ||
565 | void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | 545 | void 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 | } |
628 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb); | 609 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb); |
629 | 610 | ||
630 | void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, | 611 | void 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); |