diff options
author | Johannes Berg <johannes.berg@intel.com> | 2010-06-16 06:30:27 -0400 |
---|---|---|
committer | Reinette Chatre <reinette.chatre@intel.com> | 2010-06-21 13:46:21 -0400 |
commit | 4620fefa59d8aeae400b21d60d9a86aa11ebffa7 (patch) | |
tree | de4e8f3b4526ca9c8b87c27737c47065e3630494 /drivers/net/wireless/iwlwifi/iwl-sta.c | |
parent | 543708be320d7df692d24b349ca01a947b340764 (diff) |
iwlagn: use mutex for aggregation
Now that the ampdu_action callback can sleep,
we can use the mutex to properly protect the
aggregation data, and return useful errors if
they should happen.
Also, add some sleep and mutex debugging so
we won't call any of the functions that now
require being able to sleep and/or the mutex
to be held in an invalid context.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Acked-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-sta.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-sta.c | 31 |
1 files changed, 22 insertions, 9 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index d57df6c02db3..a62a03236ebb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <net/mac80211.h> | 30 | #include <net/mac80211.h> |
31 | #include <linux/etherdevice.h> | 31 | #include <linux/etherdevice.h> |
32 | #include <linux/sched.h> | 32 | #include <linux/sched.h> |
33 | #include <linux/lockdep.h> | ||
33 | 34 | ||
34 | #include "iwl-dev.h" | 35 | #include "iwl-dev.h" |
35 | #include "iwl-core.h" | 36 | #include "iwl-core.h" |
@@ -145,8 +146,10 @@ int iwl_send_add_sta(struct iwl_priv *priv, | |||
145 | 146 | ||
146 | if (flags & CMD_ASYNC) | 147 | if (flags & CMD_ASYNC) |
147 | cmd.callback = iwl_add_sta_callback; | 148 | cmd.callback = iwl_add_sta_callback; |
148 | else | 149 | else { |
149 | cmd.flags |= CMD_WANT_SKB; | 150 | cmd.flags |= CMD_WANT_SKB; |
151 | might_sleep(); | ||
152 | } | ||
150 | 153 | ||
151 | cmd.len = priv->cfg->ops->utils->build_addsta_hcmd(sta, data); | 154 | cmd.len = priv->cfg->ops->utils->build_addsta_hcmd(sta, data); |
152 | ret = iwl_send_cmd(priv, &cmd); | 155 | ret = iwl_send_cmd(priv, &cmd); |
@@ -1268,17 +1271,22 @@ EXPORT_SYMBOL_GPL(iwl_dealloc_bcast_station); | |||
1268 | /** | 1271 | /** |
1269 | * iwl_sta_tx_modify_enable_tid - Enable Tx for this TID in station table | 1272 | * iwl_sta_tx_modify_enable_tid - Enable Tx for this TID in station table |
1270 | */ | 1273 | */ |
1271 | void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid) | 1274 | int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid) |
1272 | { | 1275 | { |
1273 | unsigned long flags; | 1276 | unsigned long flags; |
1277 | struct iwl_addsta_cmd sta_cmd; | ||
1278 | |||
1279 | lockdep_assert_held(&priv->mutex); | ||
1274 | 1280 | ||
1275 | /* Remove "disable" flag, to enable Tx for this TID */ | 1281 | /* Remove "disable" flag, to enable Tx for this TID */ |
1276 | spin_lock_irqsave(&priv->sta_lock, flags); | 1282 | spin_lock_irqsave(&priv->sta_lock, flags); |
1277 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX; | 1283 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX; |
1278 | priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid)); | 1284 | priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid)); |
1279 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | 1285 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; |
1280 | iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); | 1286 | memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); |
1281 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 1287 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
1288 | |||
1289 | return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); | ||
1282 | } | 1290 | } |
1283 | EXPORT_SYMBOL(iwl_sta_tx_modify_enable_tid); | 1291 | EXPORT_SYMBOL(iwl_sta_tx_modify_enable_tid); |
1284 | 1292 | ||
@@ -1287,6 +1295,9 @@ int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, | |||
1287 | { | 1295 | { |
1288 | unsigned long flags; | 1296 | unsigned long flags; |
1289 | int sta_id; | 1297 | int sta_id; |
1298 | struct iwl_addsta_cmd sta_cmd; | ||
1299 | |||
1300 | lockdep_assert_held(&priv->mutex); | ||
1290 | 1301 | ||
1291 | sta_id = iwl_sta_id(sta); | 1302 | sta_id = iwl_sta_id(sta); |
1292 | if (sta_id == IWL_INVALID_STATION) | 1303 | if (sta_id == IWL_INVALID_STATION) |
@@ -1298,10 +1309,10 @@ int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, | |||
1298 | priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid; | 1309 | priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid; |
1299 | priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn); | 1310 | priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn); |
1300 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | 1311 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; |
1312 | memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); | ||
1301 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 1313 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
1302 | 1314 | ||
1303 | return iwl_send_add_sta(priv, &priv->stations[sta_id].sta, | 1315 | return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); |
1304 | CMD_ASYNC); | ||
1305 | } | 1316 | } |
1306 | EXPORT_SYMBOL(iwl_sta_rx_agg_start); | 1317 | EXPORT_SYMBOL(iwl_sta_rx_agg_start); |
1307 | 1318 | ||
@@ -1309,7 +1320,10 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, | |||
1309 | int tid) | 1320 | int tid) |
1310 | { | 1321 | { |
1311 | unsigned long flags; | 1322 | unsigned long flags; |
1312 | int sta_id, ret; | 1323 | int sta_id; |
1324 | struct iwl_addsta_cmd sta_cmd; | ||
1325 | |||
1326 | lockdep_assert_held(&priv->mutex); | ||
1313 | 1327 | ||
1314 | sta_id = iwl_sta_id(sta); | 1328 | sta_id = iwl_sta_id(sta); |
1315 | if (sta_id == IWL_INVALID_STATION) { | 1329 | if (sta_id == IWL_INVALID_STATION) { |
@@ -1322,11 +1336,10 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, | |||
1322 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK; | 1336 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK; |
1323 | priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid; | 1337 | priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid; |
1324 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | 1338 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; |
1325 | ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); | 1339 | memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); |
1326 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 1340 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
1327 | 1341 | ||
1328 | return ret; | 1342 | return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); |
1329 | |||
1330 | } | 1343 | } |
1331 | EXPORT_SYMBOL(iwl_sta_rx_agg_stop); | 1344 | EXPORT_SYMBOL(iwl_sta_rx_agg_stop); |
1332 | 1345 | ||