diff options
Diffstat (limited to 'net/mac80211/agg-rx.c')
-rw-r--r-- | net/mac80211/agg-rx.c | 48 |
1 files changed, 21 insertions, 27 deletions
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index 7d87f446f030..53233ab50f65 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c | |||
@@ -22,19 +22,20 @@ void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, | |||
22 | u16 initiator, u16 reason) | 22 | u16 initiator, u16 reason) |
23 | { | 23 | { |
24 | struct ieee80211_local *local = sta->local; | 24 | struct ieee80211_local *local = sta->local; |
25 | struct tid_ampdu_rx *tid_rx; | ||
25 | int i; | 26 | int i; |
26 | 27 | ||
27 | /* check if TID is in operational state */ | ||
28 | spin_lock_bh(&sta->lock); | 28 | spin_lock_bh(&sta->lock); |
29 | if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_OPERATIONAL) { | 29 | |
30 | /* check if TID is in operational state */ | ||
31 | if (!sta->ampdu_mlme.tid_active_rx[tid]) { | ||
30 | spin_unlock_bh(&sta->lock); | 32 | spin_unlock_bh(&sta->lock); |
31 | return; | 33 | return; |
32 | } | 34 | } |
33 | 35 | ||
34 | sta->ampdu_mlme.tid_state_rx[tid] = | 36 | sta->ampdu_mlme.tid_active_rx[tid] = false; |
35 | HT_AGG_STATE_REQ_STOP_BA_MSK | | 37 | |
36 | (initiator << HT_AGG_STATE_INITIATOR_SHIFT); | 38 | tid_rx = sta->ampdu_mlme.tid_rx[tid]; |
37 | spin_unlock_bh(&sta->lock); | ||
38 | 39 | ||
39 | #ifdef CONFIG_MAC80211_HT_DEBUG | 40 | #ifdef CONFIG_MAC80211_HT_DEBUG |
40 | printk(KERN_DEBUG "Rx BA session stop requested for %pM tid %u\n", | 41 | printk(KERN_DEBUG "Rx BA session stop requested for %pM tid %u\n", |
@@ -46,37 +47,30 @@ void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, | |||
46 | printk(KERN_DEBUG "HW problem - can not stop rx " | 47 | printk(KERN_DEBUG "HW problem - can not stop rx " |
47 | "aggregation for tid %d\n", tid); | 48 | "aggregation for tid %d\n", tid); |
48 | 49 | ||
49 | /* shutdown timer has not expired */ | ||
50 | if (initiator != WLAN_BACK_TIMER) | ||
51 | del_timer_sync(&sta->ampdu_mlme.tid_rx[tid]->session_timer); | ||
52 | |||
53 | /* check if this is a self generated aggregation halt */ | 50 | /* check if this is a self generated aggregation halt */ |
54 | if (initiator == WLAN_BACK_RECIPIENT || initiator == WLAN_BACK_TIMER) | 51 | if (initiator == WLAN_BACK_RECIPIENT) |
55 | ieee80211_send_delba(sta->sdata, sta->sta.addr, | 52 | ieee80211_send_delba(sta->sdata, sta->sta.addr, |
56 | tid, 0, reason); | 53 | tid, 0, reason); |
57 | 54 | ||
58 | /* free the reordering buffer */ | 55 | /* free the reordering buffer */ |
59 | for (i = 0; i < sta->ampdu_mlme.tid_rx[tid]->buf_size; i++) { | 56 | for (i = 0; i < tid_rx->buf_size; i++) { |
60 | if (sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]) { | 57 | if (tid_rx->reorder_buf[i]) { |
61 | /* release the reordered frames */ | 58 | /* release the reordered frames */ |
62 | dev_kfree_skb(sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]); | 59 | dev_kfree_skb(tid_rx->reorder_buf[i]); |
63 | sta->ampdu_mlme.tid_rx[tid]->stored_mpdu_num--; | 60 | tid_rx->stored_mpdu_num--; |
64 | sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i] = NULL; | 61 | tid_rx->reorder_buf[i] = NULL; |
65 | } | 62 | } |
66 | } | 63 | } |
67 | 64 | ||
68 | spin_lock_bh(&sta->lock); | ||
69 | /* free resources */ | 65 | /* free resources */ |
70 | kfree(sta->ampdu_mlme.tid_rx[tid]->reorder_buf); | 66 | kfree(tid_rx->reorder_buf); |
71 | kfree(sta->ampdu_mlme.tid_rx[tid]->reorder_time); | 67 | kfree(tid_rx->reorder_time); |
72 | 68 | sta->ampdu_mlme.tid_rx[tid] = NULL; | |
73 | if (!sta->ampdu_mlme.tid_rx[tid]->shutdown) { | ||
74 | kfree(sta->ampdu_mlme.tid_rx[tid]); | ||
75 | sta->ampdu_mlme.tid_rx[tid] = NULL; | ||
76 | } | ||
77 | 69 | ||
78 | sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_IDLE; | ||
79 | spin_unlock_bh(&sta->lock); | 70 | spin_unlock_bh(&sta->lock); |
71 | |||
72 | del_timer_sync(&tid_rx->session_timer); | ||
73 | kfree(tid_rx); | ||
80 | } | 74 | } |
81 | 75 | ||
82 | /* | 76 | /* |
@@ -211,7 +205,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
211 | /* examine state machine */ | 205 | /* examine state machine */ |
212 | spin_lock_bh(&sta->lock); | 206 | spin_lock_bh(&sta->lock); |
213 | 207 | ||
214 | if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_IDLE) { | 208 | if (sta->ampdu_mlme.tid_active_rx[tid]) { |
215 | #ifdef CONFIG_MAC80211_HT_DEBUG | 209 | #ifdef CONFIG_MAC80211_HT_DEBUG |
216 | if (net_ratelimit()) | 210 | if (net_ratelimit()) |
217 | printk(KERN_DEBUG "unexpected AddBA Req from " | 211 | printk(KERN_DEBUG "unexpected AddBA Req from " |
@@ -273,7 +267,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
273 | } | 267 | } |
274 | 268 | ||
275 | /* change state and send addba resp */ | 269 | /* change state and send addba resp */ |
276 | sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_OPERATIONAL; | 270 | sta->ampdu_mlme.tid_active_rx[tid] = true; |
277 | tid_agg_rx->dialog_token = dialog_token; | 271 | tid_agg_rx->dialog_token = dialog_token; |
278 | tid_agg_rx->ssn = start_seq_num; | 272 | tid_agg_rx->ssn = start_seq_num; |
279 | tid_agg_rx->head_seq_num = start_seq_num; | 273 | tid_agg_rx->head_seq_num = start_seq_num; |