aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-sta.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-06-16 06:30:27 -0400
committerReinette Chatre <reinette.chatre@intel.com>2010-06-21 13:46:21 -0400
commit4620fefa59d8aeae400b21d60d9a86aa11ebffa7 (patch)
treede4e8f3b4526ca9c8b87c27737c47065e3630494 /drivers/net/wireless/iwlwifi/iwl-sta.c
parent543708be320d7df692d24b349ca01a947b340764 (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.c31
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 */
1271void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid) 1274int 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}
1283EXPORT_SYMBOL(iwl_sta_tx_modify_enable_tid); 1291EXPORT_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}
1306EXPORT_SYMBOL(iwl_sta_rx_agg_start); 1317EXPORT_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}
1331EXPORT_SYMBOL(iwl_sta_rx_agg_stop); 1344EXPORT_SYMBOL(iwl_sta_rx_agg_stop);
1332 1345