aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c29
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c31
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h2
5 files changed, 45 insertions, 27 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 83e6a42ca2da..fee276bc36fe 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -1785,6 +1785,7 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id,
1785{ 1785{
1786 unsigned long flags; 1786 unsigned long flags;
1787 u16 ra_tid; 1787 u16 ra_tid;
1788 int ret;
1788 1789
1789 if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) || 1790 if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) ||
1790 (IWL49_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues 1791 (IWL49_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues
@@ -1800,7 +1801,9 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id,
1800 ra_tid = BUILD_RAxTID(sta_id, tid); 1801 ra_tid = BUILD_RAxTID(sta_id, tid);
1801 1802
1802 /* Modify device's station table to Tx this TID */ 1803 /* Modify device's station table to Tx this TID */
1803 iwl_sta_tx_modify_enable_tid(priv, sta_id, tid); 1804 ret = iwl_sta_tx_modify_enable_tid(priv, sta_id, tid);
1805 if (ret)
1806 return ret;
1804 1807
1805 spin_lock_irqsave(&priv->lock, flags); 1808 spin_lock_irqsave(&priv->lock, flags);
1806 1809
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 84df7fca750d..2573234e4db1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -233,6 +233,7 @@ int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
233{ 233{
234 unsigned long flags; 234 unsigned long flags;
235 u16 ra_tid; 235 u16 ra_tid;
236 int ret;
236 237
237 if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) || 238 if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) ||
238 (IWLAGN_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues 239 (IWLAGN_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues
@@ -248,7 +249,9 @@ int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
248 ra_tid = BUILD_RAxTID(sta_id, tid); 249 ra_tid = BUILD_RAxTID(sta_id, tid);
249 250
250 /* Modify device's station table to Tx this TID */ 251 /* Modify device's station table to Tx this TID */
251 iwl_sta_tx_modify_enable_tid(priv, sta_id, tid); 252 ret = iwl_sta_tx_modify_enable_tid(priv, sta_id, tid);
253 if (ret)
254 return ret;
252 255
253 spin_lock_irqsave(&priv->lock, flags); 256 spin_lock_irqsave(&priv->lock, flags);
254 257
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index d857f8496f69..294b7ed3c16a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -3374,7 +3374,7 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
3374 struct ieee80211_sta *sta, u16 tid, u16 *ssn) 3374 struct ieee80211_sta *sta, u16 tid, u16 *ssn)
3375{ 3375{
3376 struct iwl_priv *priv = hw->priv; 3376 struct iwl_priv *priv = hw->priv;
3377 int ret; 3377 int ret = -EINVAL;
3378 3378
3379 IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n", 3379 IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n",
3380 sta->addr, tid); 3380 sta->addr, tid);
@@ -3382,17 +3382,19 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
3382 if (!(priv->cfg->sku & IWL_SKU_N)) 3382 if (!(priv->cfg->sku & IWL_SKU_N))
3383 return -EACCES; 3383 return -EACCES;
3384 3384
3385 mutex_lock(&priv->mutex);
3386
3385 switch (action) { 3387 switch (action) {
3386 case IEEE80211_AMPDU_RX_START: 3388 case IEEE80211_AMPDU_RX_START:
3387 IWL_DEBUG_HT(priv, "start Rx\n"); 3389 IWL_DEBUG_HT(priv, "start Rx\n");
3388 return iwl_sta_rx_agg_start(priv, sta, tid, *ssn); 3390 ret = iwl_sta_rx_agg_start(priv, sta, tid, *ssn);
3391 break;
3389 case IEEE80211_AMPDU_RX_STOP: 3392 case IEEE80211_AMPDU_RX_STOP:
3390 IWL_DEBUG_HT(priv, "stop Rx\n"); 3393 IWL_DEBUG_HT(priv, "stop Rx\n");
3391 ret = iwl_sta_rx_agg_stop(priv, sta, tid); 3394 ret = iwl_sta_rx_agg_stop(priv, sta, tid);
3392 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 3395 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3393 return 0; 3396 ret = 0;
3394 else 3397 break;
3395 return ret;
3396 case IEEE80211_AMPDU_TX_START: 3398 case IEEE80211_AMPDU_TX_START:
3397 IWL_DEBUG_HT(priv, "start Tx\n"); 3399 IWL_DEBUG_HT(priv, "start Tx\n");
3398 ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn); 3400 ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn);
@@ -3401,7 +3403,7 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
3401 IWL_DEBUG_HT(priv, "priv->_agn.agg_tids_count = %u\n", 3403 IWL_DEBUG_HT(priv, "priv->_agn.agg_tids_count = %u\n",
3402 priv->_agn.agg_tids_count); 3404 priv->_agn.agg_tids_count);
3403 } 3405 }
3404 return ret; 3406 break;
3405 case IEEE80211_AMPDU_TX_STOP: 3407 case IEEE80211_AMPDU_TX_STOP:
3406 IWL_DEBUG_HT(priv, "stop Tx\n"); 3408 IWL_DEBUG_HT(priv, "stop Tx\n");
3407 ret = iwlagn_tx_agg_stop(priv, vif, sta, tid); 3409 ret = iwlagn_tx_agg_stop(priv, vif, sta, tid);
@@ -3411,18 +3413,15 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
3411 priv->_agn.agg_tids_count); 3413 priv->_agn.agg_tids_count);
3412 } 3414 }
3413 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 3415 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3414 return 0; 3416 ret = 0;
3415 else 3417 break;
3416 return ret;
3417 case IEEE80211_AMPDU_TX_OPERATIONAL: 3418 case IEEE80211_AMPDU_TX_OPERATIONAL:
3418 /* do nothing */ 3419 /* do nothing, return value ignored */
3419 return -EOPNOTSUPP;
3420 default:
3421 IWL_DEBUG_HT(priv, "unknown\n");
3422 return -EINVAL;
3423 break; 3420 break;
3424 } 3421 }
3425 return 0; 3422 mutex_unlock(&priv->mutex);
3423
3424 return ret;
3426} 3425}
3427 3426
3428static void iwl_mac_sta_notify(struct ieee80211_hw *hw, 3427static void iwl_mac_sta_notify(struct ieee80211_hw *hw,
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
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 5b1b1e461eb6..619bb99d85cf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -73,7 +73,7 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
73 const u8 *addr); 73 const u8 *addr);
74int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 74int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
75 struct ieee80211_sta *sta); 75 struct ieee80211_sta *sta);
76void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid); 76int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid);
77int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, 77int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta,
78 int tid, u16 ssn); 78 int tid, u16 ssn);
79int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, 79int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,