diff options
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 29 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-sta.c | 31 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-sta.h | 2 |
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 | ||
3428 | static void iwl_mac_sta_notify(struct ieee80211_hw *hw, | 3427 | static 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 | */ |
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 | ||
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); |
74 | int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 74 | int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
75 | struct ieee80211_sta *sta); | 75 | struct ieee80211_sta *sta); |
76 | void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid); | 76 | int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid); |
77 | int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, | 77 | int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, |
78 | int tid, u16 ssn); | 78 | int tid, u16 ssn); |
79 | int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, | 79 | int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, |