aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/util.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-06-10 04:21:29 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-06-14 15:38:16 -0400
commit2a419056c15478d2df3f3e9d4fa64e34eb1faa7d (patch)
tree680342d6b883c18eec9003f2b93abd8ffd1e6ae6 /net/mac80211/util.c
parent9d38d85de0270e3927bffab94973a9c78d1dc800 (diff)
mac80211: simplify station/aggregation code
A number of places use RCU locking for accessing the station list, even though they do not need to. Use mutex locking instead to prepare for the locking changes I want to make. The mlme code is also using a WLAN_STA_DISASSOC flag that has the same meaning as WLAN_STA_BLOCK_BA, so use that. While doing so, combine places where we loop over stations twice, and optimise away some of the loops by checking if the hardware supports aggregation at all first. Also fix a more theoretical race condition: right now we could resume, set up an aggregation session, and right after tear it down again due to the code that is needed for hardware reconfiguration here. Also mark add a comment to that code marking it as a workaround. Finally, remove a pointless aggregation disabling loop when an interface is stopped, directly after that we remove all stations from it which will also disable all aggregation sessions that may still be active, and does so in a race-free way unlike the current loop that doesn't block new sessions. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r--net/mac80211/util.c31
1 files changed, 16 insertions, 15 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 5b79d552780a..a54cf146ed50 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1138,18 +1138,6 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1138 } 1138 }
1139 mutex_unlock(&local->sta_mtx); 1139 mutex_unlock(&local->sta_mtx);
1140 1140
1141 /* Clear Suspend state so that ADDBA requests can be processed */
1142
1143 rcu_read_lock();
1144
1145 if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
1146 list_for_each_entry_rcu(sta, &local->sta_list, list) {
1147 clear_sta_flags(sta, WLAN_STA_BLOCK_BA);
1148 }
1149 }
1150
1151 rcu_read_unlock();
1152
1153 /* setup RTS threshold */ 1141 /* setup RTS threshold */
1154 drv_set_rts_threshold(local, hw->wiphy->rts_threshold); 1142 drv_set_rts_threshold(local, hw->wiphy->rts_threshold);
1155 1143
@@ -1202,13 +1190,26 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1202 } 1190 }
1203 } 1191 }
1204 1192
1205 rcu_read_lock(); 1193 /*
1194 * Clear the WLAN_STA_BLOCK_BA flag so new aggregation
1195 * sessions can be established after a resume.
1196 *
1197 * Also tear down aggregation sessions since reconfiguring
1198 * them in a hardware restart scenario is not easily done
1199 * right now, and the hardware will have lost information
1200 * about the sessions, but we and the AP still think they
1201 * are active. This is really a workaround though.
1202 */
1206 if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { 1203 if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
1207 list_for_each_entry_rcu(sta, &local->sta_list, list) { 1204 mutex_lock(&local->sta_mtx);
1205
1206 list_for_each_entry(sta, &local->sta_list, list) {
1208 ieee80211_sta_tear_down_BA_sessions(sta); 1207 ieee80211_sta_tear_down_BA_sessions(sta);
1208 clear_sta_flags(sta, WLAN_STA_BLOCK_BA);
1209 } 1209 }
1210
1211 mutex_unlock(&local->sta_mtx);
1210 } 1212 }
1211 rcu_read_unlock();
1212 1213
1213 /* add back keys */ 1214 /* add back keys */
1214 list_for_each_entry(sdata, &local->interfaces, list) 1215 list_for_each_entry(sdata, &local->interfaces, list)