diff options
-rw-r--r-- | net/mac80211/agg-rx.c | 24 | ||||
-rw-r--r-- | net/mac80211/ht.c | 5 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 2 | ||||
-rw-r--r-- | net/mac80211/sta_info.h | 3 |
4 files changed, 20 insertions, 14 deletions
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index bbf36d980232..1c4320b01e3c 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c | |||
@@ -32,21 +32,18 @@ static void ieee80211_free_tid_rx(struct rcu_head *h) | |||
32 | kfree(tid_rx); | 32 | kfree(tid_rx); |
33 | } | 33 | } |
34 | 34 | ||
35 | static void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, | 35 | void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, |
36 | u16 initiator, u16 reason, | 36 | u16 initiator, u16 reason) |
37 | bool from_timer) | ||
38 | { | 37 | { |
39 | struct ieee80211_local *local = sta->local; | 38 | struct ieee80211_local *local = sta->local; |
40 | struct tid_ampdu_rx *tid_rx; | 39 | struct tid_ampdu_rx *tid_rx; |
41 | 40 | ||
42 | spin_lock_bh(&sta->lock); | 41 | lockdep_assert_held(&sta->lock); |
43 | 42 | ||
44 | tid_rx = sta->ampdu_mlme.tid_rx[tid]; | 43 | tid_rx = sta->ampdu_mlme.tid_rx[tid]; |
45 | 44 | ||
46 | if (!tid_rx) { | 45 | if (!tid_rx) |
47 | spin_unlock_bh(&sta->lock); | ||
48 | return; | 46 | return; |
49 | } | ||
50 | 47 | ||
51 | rcu_assign_pointer(sta->ampdu_mlme.tid_rx[tid], NULL); | 48 | rcu_assign_pointer(sta->ampdu_mlme.tid_rx[tid], NULL); |
52 | 49 | ||
@@ -65,10 +62,7 @@ static void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, | |||
65 | ieee80211_send_delba(sta->sdata, sta->sta.addr, | 62 | ieee80211_send_delba(sta->sdata, sta->sta.addr, |
66 | tid, 0, reason); | 63 | tid, 0, reason); |
67 | 64 | ||
68 | spin_unlock_bh(&sta->lock); | 65 | del_timer_sync(&tid_rx->session_timer); |
69 | |||
70 | if (!from_timer) | ||
71 | del_timer_sync(&tid_rx->session_timer); | ||
72 | 66 | ||
73 | call_rcu(&tid_rx->rcu_head, ieee80211_free_tid_rx); | 67 | call_rcu(&tid_rx->rcu_head, ieee80211_free_tid_rx); |
74 | } | 68 | } |
@@ -76,7 +70,9 @@ static void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, | |||
76 | void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, | 70 | void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, |
77 | u16 initiator, u16 reason) | 71 | u16 initiator, u16 reason) |
78 | { | 72 | { |
79 | ___ieee80211_stop_rx_ba_session(sta, tid, initiator, reason, false); | 73 | spin_lock_bh(&sta->lock); |
74 | ___ieee80211_stop_rx_ba_session(sta, tid, initiator, reason); | ||
75 | spin_unlock_bh(&sta->lock); | ||
80 | } | 76 | } |
81 | 77 | ||
82 | /* | 78 | /* |
@@ -97,8 +93,8 @@ static void sta_rx_agg_session_timer_expired(unsigned long data) | |||
97 | #ifdef CONFIG_MAC80211_HT_DEBUG | 93 | #ifdef CONFIG_MAC80211_HT_DEBUG |
98 | printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid); | 94 | printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid); |
99 | #endif | 95 | #endif |
100 | ___ieee80211_stop_rx_ba_session(sta, *ptid, WLAN_BACK_RECIPIENT, | 96 | set_bit(*ptid, sta->ampdu_mlme.tid_rx_timer_expired); |
101 | WLAN_REASON_QSTA_TIMEOUT, true); | 97 | ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work); |
102 | } | 98 | } |
103 | 99 | ||
104 | static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid, | 100 | static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid, |
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 531a19d358df..730f8089678e 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
@@ -132,6 +132,11 @@ void ieee80211_ba_session_work(struct work_struct *work) | |||
132 | 132 | ||
133 | spin_lock_bh(&sta->lock); | 133 | spin_lock_bh(&sta->lock); |
134 | for (tid = 0; tid < STA_TID_NUM; tid++) { | 134 | for (tid = 0; tid < STA_TID_NUM; tid++) { |
135 | if (test_and_clear_bit(tid, sta->ampdu_mlme.tid_rx_timer_expired)) | ||
136 | ___ieee80211_stop_rx_ba_session( | ||
137 | sta, tid, WLAN_BACK_RECIPIENT, | ||
138 | WLAN_REASON_QSTA_TIMEOUT); | ||
139 | |||
135 | tid_tx = sta->ampdu_mlme.tid_tx[tid]; | 140 | tid_tx = sta->ampdu_mlme.tid_tx[tid]; |
136 | if (!tid_tx) | 141 | if (!tid_tx) |
137 | continue; | 142 | continue; |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 628a53db9f7e..9d753a02a2e4 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -1096,6 +1096,8 @@ int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, | |||
1096 | enum ieee80211_smps_mode smps, const u8 *da, | 1096 | enum ieee80211_smps_mode smps, const u8 *da, |
1097 | const u8 *bssid); | 1097 | const u8 *bssid); |
1098 | 1098 | ||
1099 | void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, | ||
1100 | u16 initiator, u16 reason); | ||
1099 | void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, | 1101 | void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, |
1100 | u16 initiator, u16 reason); | 1102 | u16 initiator, u16 reason); |
1101 | void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta); | 1103 | void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta); |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 040cbb0ac3af..500bafe0a0bb 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -140,10 +140,13 @@ struct tid_ampdu_rx { | |||
140 | * @addba_req_num: number of times addBA request has been sent. | 140 | * @addba_req_num: number of times addBA request has been sent. |
141 | * @dialog_token_allocator: dialog token enumerator for each new session; | 141 | * @dialog_token_allocator: dialog token enumerator for each new session; |
142 | * @work: work struct for starting/stopping aggregation | 142 | * @work: work struct for starting/stopping aggregation |
143 | * @tid_rx_timer_expired: bitmap indicating on which TIDs the | ||
144 | * RX timer expired until the work for it runs | ||
143 | */ | 145 | */ |
144 | struct sta_ampdu_mlme { | 146 | struct sta_ampdu_mlme { |
145 | /* rx */ | 147 | /* rx */ |
146 | struct tid_ampdu_rx *tid_rx[STA_TID_NUM]; | 148 | struct tid_ampdu_rx *tid_rx[STA_TID_NUM]; |
149 | unsigned long tid_rx_timer_expired[BITS_TO_LONGS(STA_TID_NUM)]; | ||
147 | /* tx */ | 150 | /* tx */ |
148 | struct work_struct work; | 151 | struct work_struct work; |
149 | struct tid_ampdu_tx *tid_tx[STA_TID_NUM]; | 152 | struct tid_ampdu_tx *tid_tx[STA_TID_NUM]; |