aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/mac80211/agg-rx.c24
-rw-r--r--net/mac80211/ht.c5
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/sta_info.h3
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
35static void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, 35void ___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,
76void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, 70void __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
104static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid, 100static 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
1099void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
1100 u16 initiator, u16 reason);
1099void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, 1101void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
1100 u16 initiator, u16 reason); 1102 u16 initiator, u16 reason);
1101void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta); 1103void 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 */
144struct sta_ampdu_mlme { 146struct 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];