diff options
Diffstat (limited to 'net/mac80211/agg-tx.c')
-rw-r--r-- | net/mac80211/agg-tx.c | 133 |
1 files changed, 62 insertions, 71 deletions
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 89e238b001de..87782a4bb541 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
@@ -14,6 +14,7 @@ | |||
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/ieee80211.h> | 16 | #include <linux/ieee80211.h> |
17 | #include <linux/slab.h> | ||
17 | #include <net/mac80211.h> | 18 | #include <net/mac80211.h> |
18 | #include "ieee80211_i.h" | 19 | #include "ieee80211_i.h" |
19 | #include "driver-ops.h" | 20 | #include "driver-ops.h" |
@@ -58,17 +59,17 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata, | |||
58 | 59 | ||
59 | if (!skb) { | 60 | if (!skb) { |
60 | printk(KERN_ERR "%s: failed to allocate buffer " | 61 | printk(KERN_ERR "%s: failed to allocate buffer " |
61 | "for addba request frame\n", sdata->dev->name); | 62 | "for addba request frame\n", sdata->name); |
62 | return; | 63 | return; |
63 | } | 64 | } |
64 | skb_reserve(skb, local->hw.extra_tx_headroom); | 65 | skb_reserve(skb, local->hw.extra_tx_headroom); |
65 | mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); | 66 | mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); |
66 | memset(mgmt, 0, 24); | 67 | memset(mgmt, 0, 24); |
67 | memcpy(mgmt->da, da, ETH_ALEN); | 68 | memcpy(mgmt->da, da, ETH_ALEN); |
68 | memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); | 69 | memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); |
69 | if (sdata->vif.type == NL80211_IFTYPE_AP || | 70 | if (sdata->vif.type == NL80211_IFTYPE_AP || |
70 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | 71 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) |
71 | memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN); | 72 | memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); |
72 | else if (sdata->vif.type == NL80211_IFTYPE_STATION) | 73 | else if (sdata->vif.type == NL80211_IFTYPE_STATION) |
73 | memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN); | 74 | memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN); |
74 | 75 | ||
@@ -91,7 +92,7 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata, | |||
91 | mgmt->u.action.u.addba_req.start_seq_num = | 92 | mgmt->u.action.u.addba_req.start_seq_num = |
92 | cpu_to_le16(start_seq_num << 4); | 93 | cpu_to_le16(start_seq_num << 4); |
93 | 94 | ||
94 | ieee80211_tx_skb(sdata, skb, 1); | 95 | ieee80211_tx_skb(sdata, skb); |
95 | } | 96 | } |
96 | 97 | ||
97 | void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn) | 98 | void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn) |
@@ -104,7 +105,7 @@ void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u1 | |||
104 | skb = dev_alloc_skb(sizeof(*bar) + local->hw.extra_tx_headroom); | 105 | skb = dev_alloc_skb(sizeof(*bar) + local->hw.extra_tx_headroom); |
105 | if (!skb) { | 106 | if (!skb) { |
106 | printk(KERN_ERR "%s: failed to allocate buffer for " | 107 | printk(KERN_ERR "%s: failed to allocate buffer for " |
107 | "bar frame\n", sdata->dev->name); | 108 | "bar frame\n", sdata->name); |
108 | return; | 109 | return; |
109 | } | 110 | } |
110 | skb_reserve(skb, local->hw.extra_tx_headroom); | 111 | skb_reserve(skb, local->hw.extra_tx_headroom); |
@@ -113,14 +114,15 @@ void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u1 | |||
113 | bar->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL | | 114 | bar->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL | |
114 | IEEE80211_STYPE_BACK_REQ); | 115 | IEEE80211_STYPE_BACK_REQ); |
115 | memcpy(bar->ra, ra, ETH_ALEN); | 116 | memcpy(bar->ra, ra, ETH_ALEN); |
116 | memcpy(bar->ta, sdata->dev->dev_addr, ETH_ALEN); | 117 | memcpy(bar->ta, sdata->vif.addr, ETH_ALEN); |
117 | bar_control |= (u16)IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL; | 118 | bar_control |= (u16)IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL; |
118 | bar_control |= (u16)IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA; | 119 | bar_control |= (u16)IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA; |
119 | bar_control |= (u16)(tid << 12); | 120 | bar_control |= (u16)(tid << 12); |
120 | bar->control = cpu_to_le16(bar_control); | 121 | bar->control = cpu_to_le16(bar_control); |
121 | bar->start_seq_num = cpu_to_le16(ssn); | 122 | bar->start_seq_num = cpu_to_le16(ssn); |
122 | 123 | ||
123 | ieee80211_tx_skb(sdata, skb, 0); | 124 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; |
125 | ieee80211_tx_skb(sdata, skb); | ||
124 | } | 126 | } |
125 | 127 | ||
126 | int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | 128 | int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, |
@@ -143,7 +145,8 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | |||
143 | *state = HT_AGG_STATE_REQ_STOP_BA_MSK | | 145 | *state = HT_AGG_STATE_REQ_STOP_BA_MSK | |
144 | (initiator << HT_AGG_STATE_INITIATOR_SHIFT); | 146 | (initiator << HT_AGG_STATE_INITIATOR_SHIFT); |
145 | 147 | ||
146 | ret = drv_ampdu_action(local, IEEE80211_AMPDU_TX_STOP, | 148 | ret = drv_ampdu_action(local, sta->sdata, |
149 | IEEE80211_AMPDU_TX_STOP, | ||
147 | &sta->sta, tid, NULL); | 150 | &sta->sta, tid, NULL); |
148 | 151 | ||
149 | /* HW shall not deny going back to legacy */ | 152 | /* HW shall not deny going back to legacy */ |
@@ -177,10 +180,10 @@ static void sta_addba_resp_timer_expired(unsigned long data) | |||
177 | 180 | ||
178 | /* check if the TID waits for addBA response */ | 181 | /* check if the TID waits for addBA response */ |
179 | spin_lock_bh(&sta->lock); | 182 | spin_lock_bh(&sta->lock); |
180 | if ((*state & (HT_ADDBA_REQUESTED_MSK | HT_ADDBA_RECEIVED_MSK)) != | 183 | if ((*state & (HT_ADDBA_REQUESTED_MSK | HT_ADDBA_RECEIVED_MSK | |
184 | HT_AGG_STATE_REQ_STOP_BA_MSK)) != | ||
181 | HT_ADDBA_REQUESTED_MSK) { | 185 | HT_ADDBA_REQUESTED_MSK) { |
182 | spin_unlock_bh(&sta->lock); | 186 | spin_unlock_bh(&sta->lock); |
183 | *state = HT_AGG_STATE_IDLE; | ||
184 | #ifdef CONFIG_MAC80211_HT_DEBUG | 187 | #ifdef CONFIG_MAC80211_HT_DEBUG |
185 | printk(KERN_DEBUG "timer expired on tid %d but we are not " | 188 | printk(KERN_DEBUG "timer expired on tid %d but we are not " |
186 | "(or no longer) expecting addBA response there", | 189 | "(or no longer) expecting addBA response there", |
@@ -202,11 +205,11 @@ static inline int ieee80211_ac_from_tid(int tid) | |||
202 | return ieee802_1d_to_ac[tid & 7]; | 205 | return ieee802_1d_to_ac[tid & 7]; |
203 | } | 206 | } |
204 | 207 | ||
205 | int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | 208 | int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid) |
206 | { | 209 | { |
207 | struct ieee80211_local *local = hw_to_local(hw); | 210 | struct sta_info *sta = container_of(pubsta, struct sta_info, sta); |
208 | struct sta_info *sta; | 211 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
209 | struct ieee80211_sub_if_data *sdata; | 212 | struct ieee80211_local *local = sdata->local; |
210 | u8 *state; | 213 | u8 *state; |
211 | int ret = 0; | 214 | int ret = 0; |
212 | u16 start_seq_num; | 215 | u16 start_seq_num; |
@@ -214,36 +217,32 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
214 | if (WARN_ON(!local->ops->ampdu_action)) | 217 | if (WARN_ON(!local->ops->ampdu_action)) |
215 | return -EINVAL; | 218 | return -EINVAL; |
216 | 219 | ||
217 | if ((tid >= STA_TID_NUM) || !(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION)) | 220 | if ((tid >= STA_TID_NUM) || |
221 | !(local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION)) | ||
218 | return -EINVAL; | 222 | return -EINVAL; |
219 | 223 | ||
220 | #ifdef CONFIG_MAC80211_HT_DEBUG | 224 | #ifdef CONFIG_MAC80211_HT_DEBUG |
221 | printk(KERN_DEBUG "Open BA session requested for %pM tid %u\n", | 225 | printk(KERN_DEBUG "Open BA session requested for %pM tid %u\n", |
222 | ra, tid); | 226 | pubsta->addr, tid); |
223 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 227 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
224 | 228 | ||
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 | /* | 229 | /* |
237 | * The aggregation code is not prepared to handle | 230 | * The aggregation code is not prepared to handle |
238 | * anything but STA/AP due to the BSSID handling. | 231 | * anything but STA/AP due to the BSSID handling. |
239 | * IBSS could work in the code but isn't supported | 232 | * IBSS could work in the code but isn't supported |
240 | * by drivers or the standard. | 233 | * by drivers or the standard. |
241 | */ | 234 | */ |
242 | if (sta->sdata->vif.type != NL80211_IFTYPE_STATION && | 235 | if (sdata->vif.type != NL80211_IFTYPE_STATION && |
243 | sta->sdata->vif.type != NL80211_IFTYPE_AP_VLAN && | 236 | sdata->vif.type != NL80211_IFTYPE_AP_VLAN && |
244 | sta->sdata->vif.type != NL80211_IFTYPE_AP) { | 237 | sdata->vif.type != NL80211_IFTYPE_AP) |
245 | ret = -EINVAL; | 238 | return -EINVAL; |
246 | goto unlock; | 239 | |
240 | if (test_sta_flags(sta, WLAN_STA_DISASSOC)) { | ||
241 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
242 | printk(KERN_DEBUG "Disassociation is in progress. " | ||
243 | "Denying BA session request\n"); | ||
244 | #endif | ||
245 | return -EINVAL; | ||
247 | } | 246 | } |
248 | 247 | ||
249 | if (test_sta_flags(sta, WLAN_STA_SUSPEND)) { | 248 | if (test_sta_flags(sta, WLAN_STA_SUSPEND)) { |
@@ -251,15 +250,12 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
251 | printk(KERN_DEBUG "Suspend in progress. " | 250 | printk(KERN_DEBUG "Suspend in progress. " |
252 | "Denying BA session request\n"); | 251 | "Denying BA session request\n"); |
253 | #endif | 252 | #endif |
254 | ret = -EINVAL; | 253 | return -EINVAL; |
255 | goto unlock; | ||
256 | } | 254 | } |
257 | 255 | ||
258 | spin_lock_bh(&sta->lock); | 256 | spin_lock_bh(&sta->lock); |
259 | spin_lock(&local->ampdu_lock); | 257 | spin_lock(&local->ampdu_lock); |
260 | 258 | ||
261 | sdata = sta->sdata; | ||
262 | |||
263 | /* we have tried too many times, receiver does not want A-MPDU */ | 259 | /* 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) { | 260 | if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) { |
265 | ret = -EBUSY; | 261 | ret = -EBUSY; |
@@ -314,10 +310,10 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
314 | * call back right away, it must see that the flow has begun */ | 310 | * call back right away, it must see that the flow has begun */ |
315 | *state |= HT_ADDBA_REQUESTED_MSK; | 311 | *state |= HT_ADDBA_REQUESTED_MSK; |
316 | 312 | ||
317 | start_seq_num = sta->tid_seq[tid]; | 313 | start_seq_num = sta->tid_seq[tid] >> 4; |
318 | 314 | ||
319 | ret = drv_ampdu_action(local, IEEE80211_AMPDU_TX_START, | 315 | ret = drv_ampdu_action(local, sdata, IEEE80211_AMPDU_TX_START, |
320 | &sta->sta, tid, &start_seq_num); | 316 | pubsta, tid, &start_seq_num); |
321 | 317 | ||
322 | if (ret) { | 318 | if (ret) { |
323 | #ifdef CONFIG_MAC80211_HT_DEBUG | 319 | #ifdef CONFIG_MAC80211_HT_DEBUG |
@@ -342,7 +338,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
342 | sta->ampdu_mlme.dialog_token_allocator; | 338 | sta->ampdu_mlme.dialog_token_allocator; |
343 | sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num; | 339 | sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num; |
344 | 340 | ||
345 | ieee80211_send_addba_request(sta->sdata, ra, tid, | 341 | ieee80211_send_addba_request(sdata, pubsta->addr, tid, |
346 | sta->ampdu_mlme.tid_tx[tid]->dialog_token, | 342 | sta->ampdu_mlme.tid_tx[tid]->dialog_token, |
347 | sta->ampdu_mlme.tid_tx[tid]->ssn, | 343 | sta->ampdu_mlme.tid_tx[tid]->ssn, |
348 | 0x40, 5000); | 344 | 0x40, 5000); |
@@ -354,7 +350,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
354 | #ifdef CONFIG_MAC80211_HT_DEBUG | 350 | #ifdef CONFIG_MAC80211_HT_DEBUG |
355 | printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid); | 351 | printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid); |
356 | #endif | 352 | #endif |
357 | goto unlock; | 353 | return 0; |
358 | 354 | ||
359 | err_free: | 355 | err_free: |
360 | kfree(sta->ampdu_mlme.tid_tx[tid]); | 356 | kfree(sta->ampdu_mlme.tid_tx[tid]); |
@@ -366,8 +362,6 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
366 | err_unlock_sta: | 362 | err_unlock_sta: |
367 | spin_unlock(&local->ampdu_lock); | 363 | spin_unlock(&local->ampdu_lock); |
368 | spin_unlock_bh(&sta->lock); | 364 | spin_unlock_bh(&sta->lock); |
369 | unlock: | ||
370 | rcu_read_unlock(); | ||
371 | return ret; | 365 | return ret; |
372 | } | 366 | } |
373 | EXPORT_SYMBOL(ieee80211_start_tx_ba_session); | 367 | EXPORT_SYMBOL(ieee80211_start_tx_ba_session); |
@@ -434,13 +428,15 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local, | |||
434 | ieee80211_agg_splice_finish(local, sta, tid); | 428 | ieee80211_agg_splice_finish(local, sta, tid); |
435 | spin_unlock(&local->ampdu_lock); | 429 | spin_unlock(&local->ampdu_lock); |
436 | 430 | ||
437 | drv_ampdu_action(local, IEEE80211_AMPDU_TX_OPERATIONAL, | 431 | drv_ampdu_action(local, sta->sdata, |
432 | IEEE80211_AMPDU_TX_OPERATIONAL, | ||
438 | &sta->sta, tid, NULL); | 433 | &sta->sta, tid, NULL); |
439 | } | 434 | } |
440 | 435 | ||
441 | void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | 436 | void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid) |
442 | { | 437 | { |
443 | struct ieee80211_local *local = hw_to_local(hw); | 438 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
439 | struct ieee80211_local *local = sdata->local; | ||
444 | struct sta_info *sta; | 440 | struct sta_info *sta; |
445 | u8 *state; | 441 | u8 *state; |
446 | 442 | ||
@@ -453,7 +449,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
453 | } | 449 | } |
454 | 450 | ||
455 | rcu_read_lock(); | 451 | rcu_read_lock(); |
456 | sta = sta_info_get(local, ra); | 452 | sta = sta_info_get(sdata, ra); |
457 | if (!sta) { | 453 | if (!sta) { |
458 | rcu_read_unlock(); | 454 | rcu_read_unlock(); |
459 | #ifdef CONFIG_MAC80211_HT_DEBUG | 455 | #ifdef CONFIG_MAC80211_HT_DEBUG |
@@ -489,10 +485,11 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
489 | } | 485 | } |
490 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); | 486 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); |
491 | 487 | ||
492 | void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, | 488 | void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, |
493 | const u8 *ra, u16 tid) | 489 | const u8 *ra, u16 tid) |
494 | { | 490 | { |
495 | struct ieee80211_local *local = hw_to_local(hw); | 491 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
492 | struct ieee80211_local *local = sdata->local; | ||
496 | struct ieee80211_ra_tid *ra_tid; | 493 | struct ieee80211_ra_tid *ra_tid; |
497 | struct sk_buff *skb = dev_alloc_skb(0); | 494 | struct sk_buff *skb = dev_alloc_skb(0); |
498 | 495 | ||
@@ -500,13 +497,14 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, | |||
500 | #ifdef CONFIG_MAC80211_HT_DEBUG | 497 | #ifdef CONFIG_MAC80211_HT_DEBUG |
501 | if (net_ratelimit()) | 498 | if (net_ratelimit()) |
502 | printk(KERN_WARNING "%s: Not enough memory, " | 499 | printk(KERN_WARNING "%s: Not enough memory, " |
503 | "dropping start BA session", skb->dev->name); | 500 | "dropping start BA session", sdata->name); |
504 | #endif | 501 | #endif |
505 | return; | 502 | return; |
506 | } | 503 | } |
507 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | 504 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; |
508 | memcpy(&ra_tid->ra, ra, ETH_ALEN); | 505 | memcpy(&ra_tid->ra, ra, ETH_ALEN); |
509 | ra_tid->tid = tid; | 506 | ra_tid->tid = tid; |
507 | ra_tid->vif = vif; | ||
510 | 508 | ||
511 | skb->pkt_type = IEEE80211_ADDBA_MSG; | 509 | skb->pkt_type = IEEE80211_ADDBA_MSG; |
512 | skb_queue_tail(&local->skb_queue, skb); | 510 | skb_queue_tail(&local->skb_queue, skb); |
@@ -536,13 +534,12 @@ int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | |||
536 | return ret; | 534 | return ret; |
537 | } | 535 | } |
538 | 536 | ||
539 | int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | 537 | int ieee80211_stop_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, |
540 | u8 *ra, u16 tid, | ||
541 | enum ieee80211_back_parties initiator) | 538 | enum ieee80211_back_parties initiator) |
542 | { | 539 | { |
543 | struct ieee80211_local *local = hw_to_local(hw); | 540 | struct sta_info *sta = container_of(pubsta, struct sta_info, sta); |
544 | struct sta_info *sta; | 541 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
545 | int ret = 0; | 542 | struct ieee80211_local *local = sdata->local; |
546 | 543 | ||
547 | if (!local->ops->ampdu_action) | 544 | if (!local->ops->ampdu_action) |
548 | return -EINVAL; | 545 | return -EINVAL; |
@@ -550,22 +547,14 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | |||
550 | if (tid >= STA_TID_NUM) | 547 | if (tid >= STA_TID_NUM) |
551 | return -EINVAL; | 548 | return -EINVAL; |
552 | 549 | ||
553 | rcu_read_lock(); | 550 | 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 | } | 551 | } |
564 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_session); | 552 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_session); |
565 | 553 | ||
566 | void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | 554 | void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid) |
567 | { | 555 | { |
568 | struct ieee80211_local *local = hw_to_local(hw); | 556 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
557 | struct ieee80211_local *local = sdata->local; | ||
569 | struct sta_info *sta; | 558 | struct sta_info *sta; |
570 | u8 *state; | 559 | u8 *state; |
571 | 560 | ||
@@ -583,7 +572,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | |||
583 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 572 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
584 | 573 | ||
585 | rcu_read_lock(); | 574 | rcu_read_lock(); |
586 | sta = sta_info_get(local, ra); | 575 | sta = sta_info_get(sdata, ra); |
587 | if (!sta) { | 576 | if (!sta) { |
588 | #ifdef CONFIG_MAC80211_HT_DEBUG | 577 | #ifdef CONFIG_MAC80211_HT_DEBUG |
589 | printk(KERN_DEBUG "Could not find station: %pM\n", ra); | 578 | printk(KERN_DEBUG "Could not find station: %pM\n", ra); |
@@ -628,10 +617,11 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | |||
628 | } | 617 | } |
629 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb); | 618 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb); |
630 | 619 | ||
631 | void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, | 620 | void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, |
632 | const u8 *ra, u16 tid) | 621 | const u8 *ra, u16 tid) |
633 | { | 622 | { |
634 | struct ieee80211_local *local = hw_to_local(hw); | 623 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
624 | struct ieee80211_local *local = sdata->local; | ||
635 | struct ieee80211_ra_tid *ra_tid; | 625 | struct ieee80211_ra_tid *ra_tid; |
636 | struct sk_buff *skb = dev_alloc_skb(0); | 626 | struct sk_buff *skb = dev_alloc_skb(0); |
637 | 627 | ||
@@ -639,13 +629,14 @@ void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, | |||
639 | #ifdef CONFIG_MAC80211_HT_DEBUG | 629 | #ifdef CONFIG_MAC80211_HT_DEBUG |
640 | if (net_ratelimit()) | 630 | if (net_ratelimit()) |
641 | printk(KERN_WARNING "%s: Not enough memory, " | 631 | printk(KERN_WARNING "%s: Not enough memory, " |
642 | "dropping stop BA session", skb->dev->name); | 632 | "dropping stop BA session", sdata->name); |
643 | #endif | 633 | #endif |
644 | return; | 634 | return; |
645 | } | 635 | } |
646 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | 636 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; |
647 | memcpy(&ra_tid->ra, ra, ETH_ALEN); | 637 | memcpy(&ra_tid->ra, ra, ETH_ALEN); |
648 | ra_tid->tid = tid; | 638 | ra_tid->tid = tid; |
639 | ra_tid->vif = vif; | ||
649 | 640 | ||
650 | skb->pkt_type = IEEE80211_DELBA_MSG; | 641 | skb->pkt_type = IEEE80211_DELBA_MSG; |
651 | skb_queue_tail(&local->skb_queue, skb); | 642 | skb_queue_tail(&local->skb_queue, skb); |