diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2009-11-16 06:00:38 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-11-18 17:09:15 -0500 |
commit | c951ad3550ab40071bb0f222ba6125845769c08a (patch) | |
tree | 9db1d3c110b359a34a3d706eaf40285cfa01550b /net/mac80211/agg-tx.c | |
parent | 3b53fde8ac40c4321389def14d7f4a9e14092fd3 (diff) |
mac80211: convert aggregation to operate on vifs/stas
The entire aggregation code currently operates on the
hw pointer and station addresses, but that needs to
change to make stations purely per-vif; As one step
preparing for that make the aggregation code callable
with the station, or by the combination of virtual
interface and station address.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/agg-tx.c')
-rw-r--r-- | net/mac80211/agg-tx.c | 96 |
1 files changed, 38 insertions, 58 deletions
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index b09948ceec4a..6ddd11466df2 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
@@ -138,7 +138,8 @@ static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | |||
138 | *state = HT_AGG_STATE_REQ_STOP_BA_MSK | | 138 | *state = HT_AGG_STATE_REQ_STOP_BA_MSK | |
139 | (initiator << HT_AGG_STATE_INITIATOR_SHIFT); | 139 | (initiator << HT_AGG_STATE_INITIATOR_SHIFT); |
140 | 140 | ||
141 | ret = drv_ampdu_action(local, IEEE80211_AMPDU_TX_STOP, | 141 | ret = drv_ampdu_action(local, &sta->sdata->vif, |
142 | IEEE80211_AMPDU_TX_STOP, | ||
142 | &sta->sta, tid, NULL); | 143 | &sta->sta, tid, NULL); |
143 | 144 | ||
144 | /* HW shall not deny going back to legacy */ | 145 | /* HW shall not deny going back to legacy */ |
@@ -196,11 +197,11 @@ static inline int ieee80211_ac_from_tid(int tid) | |||
196 | return ieee802_1d_to_ac[tid & 7]; | 197 | return ieee802_1d_to_ac[tid & 7]; |
197 | } | 198 | } |
198 | 199 | ||
199 | int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | 200 | int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid) |
200 | { | 201 | { |
201 | struct ieee80211_local *local = hw_to_local(hw); | 202 | struct sta_info *sta = container_of(pubsta, struct sta_info, sta); |
202 | struct sta_info *sta; | 203 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
203 | struct ieee80211_sub_if_data *sdata; | 204 | struct ieee80211_local *local = sdata->local; |
204 | u8 *state; | 205 | u8 *state; |
205 | int ret = 0; | 206 | int ret = 0; |
206 | u16 start_seq_num; | 207 | u16 start_seq_num; |
@@ -208,52 +209,37 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
208 | if (WARN_ON(!local->ops->ampdu_action)) | 209 | if (WARN_ON(!local->ops->ampdu_action)) |
209 | return -EINVAL; | 210 | return -EINVAL; |
210 | 211 | ||
211 | if ((tid >= STA_TID_NUM) || !(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION)) | 212 | if ((tid >= STA_TID_NUM) || |
213 | !(local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION)) | ||
212 | return -EINVAL; | 214 | return -EINVAL; |
213 | 215 | ||
214 | #ifdef CONFIG_MAC80211_HT_DEBUG | 216 | #ifdef CONFIG_MAC80211_HT_DEBUG |
215 | printk(KERN_DEBUG "Open BA session requested for %pM tid %u\n", | 217 | printk(KERN_DEBUG "Open BA session requested for %pM tid %u\n", |
216 | ra, tid); | 218 | pubsta->addr, tid); |
217 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 219 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
218 | 220 | ||
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 | /* | 221 | /* |
231 | * The aggregation code is not prepared to handle | 222 | * The aggregation code is not prepared to handle |
232 | * anything but STA/AP due to the BSSID handling. | 223 | * anything but STA/AP due to the BSSID handling. |
233 | * IBSS could work in the code but isn't supported | 224 | * IBSS could work in the code but isn't supported |
234 | * by drivers or the standard. | 225 | * by drivers or the standard. |
235 | */ | 226 | */ |
236 | if (sta->sdata->vif.type != NL80211_IFTYPE_STATION && | 227 | if (sdata->vif.type != NL80211_IFTYPE_STATION && |
237 | sta->sdata->vif.type != NL80211_IFTYPE_AP_VLAN && | 228 | sdata->vif.type != NL80211_IFTYPE_AP_VLAN && |
238 | sta->sdata->vif.type != NL80211_IFTYPE_AP) { | 229 | sdata->vif.type != NL80211_IFTYPE_AP) |
239 | ret = -EINVAL; | 230 | return -EINVAL; |
240 | goto unlock; | ||
241 | } | ||
242 | 231 | ||
243 | if (test_sta_flags(sta, WLAN_STA_SUSPEND)) { | 232 | if (test_sta_flags(sta, WLAN_STA_SUSPEND)) { |
244 | #ifdef CONFIG_MAC80211_HT_DEBUG | 233 | #ifdef CONFIG_MAC80211_HT_DEBUG |
245 | printk(KERN_DEBUG "Suspend in progress. " | 234 | printk(KERN_DEBUG "Suspend in progress. " |
246 | "Denying BA session request\n"); | 235 | "Denying BA session request\n"); |
247 | #endif | 236 | #endif |
248 | ret = -EINVAL; | 237 | return -EINVAL; |
249 | goto unlock; | ||
250 | } | 238 | } |
251 | 239 | ||
252 | spin_lock_bh(&sta->lock); | 240 | spin_lock_bh(&sta->lock); |
253 | spin_lock(&local->ampdu_lock); | 241 | spin_lock(&local->ampdu_lock); |
254 | 242 | ||
255 | sdata = sta->sdata; | ||
256 | |||
257 | /* we have tried too many times, receiver does not want A-MPDU */ | 243 | /* 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) { | 244 | if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) { |
259 | ret = -EBUSY; | 245 | ret = -EBUSY; |
@@ -310,8 +296,9 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
310 | 296 | ||
311 | start_seq_num = sta->tid_seq[tid]; | 297 | start_seq_num = sta->tid_seq[tid]; |
312 | 298 | ||
313 | ret = drv_ampdu_action(local, IEEE80211_AMPDU_TX_START, | 299 | ret = drv_ampdu_action(local, &sdata->vif, |
314 | &sta->sta, tid, &start_seq_num); | 300 | IEEE80211_AMPDU_TX_START, |
301 | pubsta, tid, &start_seq_num); | ||
315 | 302 | ||
316 | if (ret) { | 303 | if (ret) { |
317 | #ifdef CONFIG_MAC80211_HT_DEBUG | 304 | #ifdef CONFIG_MAC80211_HT_DEBUG |
@@ -336,7 +323,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
336 | sta->ampdu_mlme.dialog_token_allocator; | 323 | sta->ampdu_mlme.dialog_token_allocator; |
337 | sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num; | 324 | sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num; |
338 | 325 | ||
339 | ieee80211_send_addba_request(sta->sdata, ra, tid, | 326 | ieee80211_send_addba_request(sdata, pubsta->addr, tid, |
340 | sta->ampdu_mlme.tid_tx[tid]->dialog_token, | 327 | sta->ampdu_mlme.tid_tx[tid]->dialog_token, |
341 | sta->ampdu_mlme.tid_tx[tid]->ssn, | 328 | sta->ampdu_mlme.tid_tx[tid]->ssn, |
342 | 0x40, 5000); | 329 | 0x40, 5000); |
@@ -348,7 +335,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
348 | #ifdef CONFIG_MAC80211_HT_DEBUG | 335 | #ifdef CONFIG_MAC80211_HT_DEBUG |
349 | printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid); | 336 | printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid); |
350 | #endif | 337 | #endif |
351 | goto unlock; | 338 | return 0; |
352 | 339 | ||
353 | err_free: | 340 | err_free: |
354 | kfree(sta->ampdu_mlme.tid_tx[tid]); | 341 | kfree(sta->ampdu_mlme.tid_tx[tid]); |
@@ -360,8 +347,6 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
360 | err_unlock_sta: | 347 | err_unlock_sta: |
361 | spin_unlock(&local->ampdu_lock); | 348 | spin_unlock(&local->ampdu_lock); |
362 | spin_unlock_bh(&sta->lock); | 349 | spin_unlock_bh(&sta->lock); |
363 | unlock: | ||
364 | rcu_read_unlock(); | ||
365 | return ret; | 350 | return ret; |
366 | } | 351 | } |
367 | EXPORT_SYMBOL(ieee80211_start_tx_ba_session); | 352 | EXPORT_SYMBOL(ieee80211_start_tx_ba_session); |
@@ -428,13 +413,15 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local, | |||
428 | ieee80211_agg_splice_finish(local, sta, tid); | 413 | ieee80211_agg_splice_finish(local, sta, tid); |
429 | spin_unlock(&local->ampdu_lock); | 414 | spin_unlock(&local->ampdu_lock); |
430 | 415 | ||
431 | drv_ampdu_action(local, IEEE80211_AMPDU_TX_OPERATIONAL, | 416 | drv_ampdu_action(local, &sta->sdata->vif, |
417 | IEEE80211_AMPDU_TX_OPERATIONAL, | ||
432 | &sta->sta, tid, NULL); | 418 | &sta->sta, tid, NULL); |
433 | } | 419 | } |
434 | 420 | ||
435 | void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | 421 | void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid) |
436 | { | 422 | { |
437 | struct ieee80211_local *local = hw_to_local(hw); | 423 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
424 | struct ieee80211_local *local = sdata->local; | ||
438 | struct sta_info *sta; | 425 | struct sta_info *sta; |
439 | u8 *state; | 426 | u8 *state; |
440 | 427 | ||
@@ -483,10 +470,11 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
483 | } | 470 | } |
484 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); | 471 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); |
485 | 472 | ||
486 | void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, | 473 | void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, |
487 | const u8 *ra, u16 tid) | 474 | const u8 *ra, u16 tid) |
488 | { | 475 | { |
489 | struct ieee80211_local *local = hw_to_local(hw); | 476 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
477 | struct ieee80211_local *local = sdata->local; | ||
490 | struct ieee80211_ra_tid *ra_tid; | 478 | struct ieee80211_ra_tid *ra_tid; |
491 | struct sk_buff *skb = dev_alloc_skb(0); | 479 | struct sk_buff *skb = dev_alloc_skb(0); |
492 | 480 | ||
@@ -535,13 +523,12 @@ int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | |||
535 | return ret; | 523 | return ret; |
536 | } | 524 | } |
537 | 525 | ||
538 | int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | 526 | int ieee80211_stop_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, |
539 | u8 *ra, u16 tid, | ||
540 | enum ieee80211_back_parties initiator) | 527 | enum ieee80211_back_parties initiator) |
541 | { | 528 | { |
542 | struct ieee80211_local *local = hw_to_local(hw); | 529 | struct sta_info *sta = container_of(pubsta, struct sta_info, sta); |
543 | struct sta_info *sta; | 530 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
544 | int ret = 0; | 531 | struct ieee80211_local *local = sdata->local; |
545 | 532 | ||
546 | if (WARN_ON(!local->ops->ampdu_action)) | 533 | if (WARN_ON(!local->ops->ampdu_action)) |
547 | return -EINVAL; | 534 | return -EINVAL; |
@@ -549,22 +536,14 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | |||
549 | if (tid >= STA_TID_NUM) | 536 | if (tid >= STA_TID_NUM) |
550 | return -EINVAL; | 537 | return -EINVAL; |
551 | 538 | ||
552 | rcu_read_lock(); | 539 | 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 | } | 540 | } |
563 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_session); | 541 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_session); |
564 | 542 | ||
565 | void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | 543 | void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid) |
566 | { | 544 | { |
567 | struct ieee80211_local *local = hw_to_local(hw); | 545 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
546 | struct ieee80211_local *local = sdata->local; | ||
568 | struct sta_info *sta; | 547 | struct sta_info *sta; |
569 | u8 *state; | 548 | u8 *state; |
570 | 549 | ||
@@ -627,10 +606,11 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | |||
627 | } | 606 | } |
628 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb); | 607 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb); |
629 | 608 | ||
630 | void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, | 609 | void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, |
631 | const u8 *ra, u16 tid) | 610 | const u8 *ra, u16 tid) |
632 | { | 611 | { |
633 | struct ieee80211_local *local = hw_to_local(hw); | 612 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
613 | struct ieee80211_local *local = sdata->local; | ||
634 | struct ieee80211_ra_tid *ra_tid; | 614 | struct ieee80211_ra_tid *ra_tid; |
635 | struct sk_buff *skb = dev_alloc_skb(0); | 615 | struct sk_buff *skb = dev_alloc_skb(0); |
636 | 616 | ||