diff options
Diffstat (limited to 'net/mac80211/agg-rx.c')
| -rw-r--r-- | net/mac80211/agg-rx.c | 72 |
1 files changed, 23 insertions, 49 deletions
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index f9516a27e233..9598fdb4ad01 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c | |||
| @@ -23,19 +23,20 @@ void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, | |||
| 23 | u16 initiator, u16 reason) | 23 | u16 initiator, u16 reason) |
| 24 | { | 24 | { |
| 25 | struct ieee80211_local *local = sta->local; | 25 | struct ieee80211_local *local = sta->local; |
| 26 | struct tid_ampdu_rx *tid_rx; | ||
| 26 | int i; | 27 | int i; |
| 27 | 28 | ||
| 28 | /* check if TID is in operational state */ | ||
| 29 | spin_lock_bh(&sta->lock); | 29 | spin_lock_bh(&sta->lock); |
| 30 | if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_OPERATIONAL) { | 30 | |
| 31 | /* check if TID is in operational state */ | ||
| 32 | if (!sta->ampdu_mlme.tid_active_rx[tid]) { | ||
| 31 | spin_unlock_bh(&sta->lock); | 33 | spin_unlock_bh(&sta->lock); |
| 32 | return; | 34 | return; |
| 33 | } | 35 | } |
| 34 | 36 | ||
| 35 | sta->ampdu_mlme.tid_state_rx[tid] = | 37 | sta->ampdu_mlme.tid_active_rx[tid] = false; |
| 36 | HT_AGG_STATE_REQ_STOP_BA_MSK | | 38 | |
| 37 | (initiator << HT_AGG_STATE_INITIATOR_SHIFT); | 39 | tid_rx = sta->ampdu_mlme.tid_rx[tid]; |
| 38 | spin_unlock_bh(&sta->lock); | ||
| 39 | 40 | ||
| 40 | #ifdef CONFIG_MAC80211_HT_DEBUG | 41 | #ifdef CONFIG_MAC80211_HT_DEBUG |
| 41 | printk(KERN_DEBUG "Rx BA session stop requested for %pM tid %u\n", | 42 | printk(KERN_DEBUG "Rx BA session stop requested for %pM tid %u\n", |
| @@ -47,61 +48,35 @@ void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, | |||
| 47 | printk(KERN_DEBUG "HW problem - can not stop rx " | 48 | printk(KERN_DEBUG "HW problem - can not stop rx " |
| 48 | "aggregation for tid %d\n", tid); | 49 | "aggregation for tid %d\n", tid); |
| 49 | 50 | ||
| 50 | /* shutdown timer has not expired */ | ||
| 51 | if (initiator != WLAN_BACK_TIMER) | ||
| 52 | del_timer_sync(&sta->ampdu_mlme.tid_rx[tid]->session_timer); | ||
| 53 | |||
| 54 | /* check if this is a self generated aggregation halt */ | 51 | /* check if this is a self generated aggregation halt */ |
| 55 | if (initiator == WLAN_BACK_RECIPIENT || initiator == WLAN_BACK_TIMER) | 52 | if (initiator == WLAN_BACK_RECIPIENT) |
| 56 | ieee80211_send_delba(sta->sdata, sta->sta.addr, | 53 | ieee80211_send_delba(sta->sdata, sta->sta.addr, |
| 57 | tid, 0, reason); | 54 | tid, 0, reason); |
| 58 | 55 | ||
| 59 | /* free the reordering buffer */ | 56 | /* free the reordering buffer */ |
| 60 | for (i = 0; i < sta->ampdu_mlme.tid_rx[tid]->buf_size; i++) { | 57 | for (i = 0; i < tid_rx->buf_size; i++) { |
| 61 | if (sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]) { | 58 | if (tid_rx->reorder_buf[i]) { |
| 62 | /* release the reordered frames */ | 59 | /* release the reordered frames */ |
| 63 | dev_kfree_skb(sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]); | 60 | dev_kfree_skb(tid_rx->reorder_buf[i]); |
| 64 | sta->ampdu_mlme.tid_rx[tid]->stored_mpdu_num--; | 61 | tid_rx->stored_mpdu_num--; |
| 65 | sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i] = NULL; | 62 | tid_rx->reorder_buf[i] = NULL; |
| 66 | } | 63 | } |
| 67 | } | 64 | } |
| 68 | 65 | ||
| 69 | spin_lock_bh(&sta->lock); | ||
| 70 | /* free resources */ | 66 | /* free resources */ |
| 71 | kfree(sta->ampdu_mlme.tid_rx[tid]->reorder_buf); | 67 | kfree(tid_rx->reorder_buf); |
| 72 | kfree(sta->ampdu_mlme.tid_rx[tid]->reorder_time); | 68 | kfree(tid_rx->reorder_time); |
| 69 | sta->ampdu_mlme.tid_rx[tid] = NULL; | ||
| 73 | 70 | ||
| 74 | if (!sta->ampdu_mlme.tid_rx[tid]->shutdown) { | ||
| 75 | kfree(sta->ampdu_mlme.tid_rx[tid]); | ||
| 76 | sta->ampdu_mlme.tid_rx[tid] = NULL; | ||
| 77 | } | ||
| 78 | |||
| 79 | sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_IDLE; | ||
| 80 | spin_unlock_bh(&sta->lock); | 71 | spin_unlock_bh(&sta->lock); |
| 81 | } | ||
| 82 | |||
| 83 | void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, | ||
| 84 | u16 initiator, u16 reason) | ||
| 85 | { | ||
| 86 | struct sta_info *sta; | ||
| 87 | |||
| 88 | rcu_read_lock(); | ||
| 89 | |||
| 90 | sta = sta_info_get(sdata, ra); | ||
| 91 | if (!sta) { | ||
| 92 | rcu_read_unlock(); | ||
| 93 | return; | ||
| 94 | } | ||
| 95 | |||
| 96 | __ieee80211_stop_rx_ba_session(sta, tid, initiator, reason); | ||
| 97 | 72 | ||
| 98 | rcu_read_unlock(); | 73 | del_timer_sync(&tid_rx->session_timer); |
| 74 | kfree(tid_rx); | ||
| 99 | } | 75 | } |
| 100 | 76 | ||
| 101 | /* | 77 | /* |
| 102 | * After accepting the AddBA Request we activated a timer, | 78 | * After accepting the AddBA Request we activated a timer, |
| 103 | * resetting it after each frame that arrives from the originator. | 79 | * resetting it after each frame that arrives from the originator. |
| 104 | * if this timer expires ieee80211_sta_stop_rx_ba_session will be executed. | ||
| 105 | */ | 80 | */ |
| 106 | static void sta_rx_agg_session_timer_expired(unsigned long data) | 81 | static void sta_rx_agg_session_timer_expired(unsigned long data) |
| 107 | { | 82 | { |
| @@ -117,9 +92,8 @@ static void sta_rx_agg_session_timer_expired(unsigned long data) | |||
| 117 | #ifdef CONFIG_MAC80211_HT_DEBUG | 92 | #ifdef CONFIG_MAC80211_HT_DEBUG |
| 118 | printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid); | 93 | printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid); |
| 119 | #endif | 94 | #endif |
| 120 | ieee80211_sta_stop_rx_ba_session(sta->sdata, sta->sta.addr, | 95 | __ieee80211_stop_rx_ba_session(sta, *ptid, WLAN_BACK_RECIPIENT, |
| 121 | (u16)*ptid, WLAN_BACK_TIMER, | 96 | WLAN_REASON_QSTA_TIMEOUT); |
| 122 | WLAN_REASON_QSTA_TIMEOUT); | ||
| 123 | } | 97 | } |
| 124 | 98 | ||
| 125 | static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid, | 99 | static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid, |
| @@ -194,7 +168,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
| 194 | 168 | ||
| 195 | status = WLAN_STATUS_REQUEST_DECLINED; | 169 | status = WLAN_STATUS_REQUEST_DECLINED; |
| 196 | 170 | ||
| 197 | if (test_sta_flags(sta, WLAN_STA_SUSPEND)) { | 171 | if (test_sta_flags(sta, WLAN_STA_BLOCK_BA)) { |
| 198 | #ifdef CONFIG_MAC80211_HT_DEBUG | 172 | #ifdef CONFIG_MAC80211_HT_DEBUG |
| 199 | printk(KERN_DEBUG "Suspend in progress. " | 173 | printk(KERN_DEBUG "Suspend in progress. " |
| 200 | "Denying ADDBA request\n"); | 174 | "Denying ADDBA request\n"); |
| @@ -232,7 +206,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
| 232 | /* examine state machine */ | 206 | /* examine state machine */ |
| 233 | spin_lock_bh(&sta->lock); | 207 | spin_lock_bh(&sta->lock); |
| 234 | 208 | ||
| 235 | if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_IDLE) { | 209 | if (sta->ampdu_mlme.tid_active_rx[tid]) { |
| 236 | #ifdef CONFIG_MAC80211_HT_DEBUG | 210 | #ifdef CONFIG_MAC80211_HT_DEBUG |
| 237 | if (net_ratelimit()) | 211 | if (net_ratelimit()) |
| 238 | printk(KERN_DEBUG "unexpected AddBA Req from " | 212 | printk(KERN_DEBUG "unexpected AddBA Req from " |
| @@ -294,7 +268,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
| 294 | } | 268 | } |
| 295 | 269 | ||
| 296 | /* change state and send addba resp */ | 270 | /* change state and send addba resp */ |
| 297 | sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_OPERATIONAL; | 271 | sta->ampdu_mlme.tid_active_rx[tid] = true; |
| 298 | tid_agg_rx->dialog_token = dialog_token; | 272 | tid_agg_rx->dialog_token = dialog_token; |
| 299 | tid_agg_rx->ssn = start_seq_num; | 273 | tid_agg_rx->ssn = start_seq_num; |
| 300 | tid_agg_rx->head_seq_num = start_seq_num; | 274 | tid_agg_rx->head_seq_num = start_seq_num; |
