aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-core.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c87
1 files changed, 63 insertions, 24 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 885167f8168d..4653deada05b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -41,6 +41,7 @@
41#include "iwl-power.h" 41#include "iwl-power.h"
42#include "iwl-sta.h" 42#include "iwl-sta.h"
43#include "iwl-helpers.h" 43#include "iwl-helpers.h"
44#include "iwl-agn.h"
44 45
45 46
46/* 47/*
@@ -94,7 +95,7 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
94 max_bit_rate = MAX_BIT_RATE_40_MHZ; 95 max_bit_rate = MAX_BIT_RATE_40_MHZ;
95 } 96 }
96 97
97 if (priv->cfg->mod_params->amsdu_size_8K) 98 if (iwlagn_mod_params.amsdu_size_8K)
98 ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; 99 ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU;
99 100
100 ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF; 101 ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF;
@@ -135,6 +136,7 @@ int iwlcore_init_geos(struct iwl_priv *priv)
135 struct ieee80211_channel *geo_ch; 136 struct ieee80211_channel *geo_ch;
136 struct ieee80211_rate *rates; 137 struct ieee80211_rate *rates;
137 int i = 0; 138 int i = 0;
139 s8 max_tx_power = IWLAGN_TX_POWER_TARGET_POWER_MIN;
138 140
139 if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates || 141 if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates ||
140 priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) { 142 priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) {
@@ -208,8 +210,8 @@ int iwlcore_init_geos(struct iwl_priv *priv)
208 210
209 geo_ch->flags |= ch->ht40_extension_channel; 211 geo_ch->flags |= ch->ht40_extension_channel;
210 212
211 if (ch->max_power_avg > priv->tx_power_device_lmt) 213 if (ch->max_power_avg > max_tx_power)
212 priv->tx_power_device_lmt = ch->max_power_avg; 214 max_tx_power = ch->max_power_avg;
213 } else { 215 } else {
214 geo_ch->flags |= IEEE80211_CHAN_DISABLED; 216 geo_ch->flags |= IEEE80211_CHAN_DISABLED;
215 } 217 }
@@ -222,6 +224,10 @@ int iwlcore_init_geos(struct iwl_priv *priv)
222 geo_ch->flags); 224 geo_ch->flags);
223 } 225 }
224 226
227 priv->tx_power_device_lmt = max_tx_power;
228 priv->tx_power_user_lmt = max_tx_power;
229 priv->tx_power_next = max_tx_power;
230
225 if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && 231 if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
226 priv->cfg->sku & IWL_SKU_A) { 232 priv->cfg->sku & IWL_SKU_A) {
227 IWL_INFO(priv, "Incorrectly detected BG card as ABG. " 233 IWL_INFO(priv, "Incorrectly detected BG card as ABG. "
@@ -410,72 +416,72 @@ void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
410int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx) 416int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
411{ 417{
412 struct iwl_rxon_cmd *rxon = &ctx->staging; 418 struct iwl_rxon_cmd *rxon = &ctx->staging;
413 bool error = false; 419 u32 errors = 0;
414 420
415 if (rxon->flags & RXON_FLG_BAND_24G_MSK) { 421 if (rxon->flags & RXON_FLG_BAND_24G_MSK) {
416 if (rxon->flags & RXON_FLG_TGJ_NARROW_BAND_MSK) { 422 if (rxon->flags & RXON_FLG_TGJ_NARROW_BAND_MSK) {
417 IWL_WARN(priv, "check 2.4G: wrong narrow\n"); 423 IWL_WARN(priv, "check 2.4G: wrong narrow\n");
418 error = true; 424 errors |= BIT(0);
419 } 425 }
420 if (rxon->flags & RXON_FLG_RADAR_DETECT_MSK) { 426 if (rxon->flags & RXON_FLG_RADAR_DETECT_MSK) {
421 IWL_WARN(priv, "check 2.4G: wrong radar\n"); 427 IWL_WARN(priv, "check 2.4G: wrong radar\n");
422 error = true; 428 errors |= BIT(1);
423 } 429 }
424 } else { 430 } else {
425 if (!(rxon->flags & RXON_FLG_SHORT_SLOT_MSK)) { 431 if (!(rxon->flags & RXON_FLG_SHORT_SLOT_MSK)) {
426 IWL_WARN(priv, "check 5.2G: not short slot!\n"); 432 IWL_WARN(priv, "check 5.2G: not short slot!\n");
427 error = true; 433 errors |= BIT(2);
428 } 434 }
429 if (rxon->flags & RXON_FLG_CCK_MSK) { 435 if (rxon->flags & RXON_FLG_CCK_MSK) {
430 IWL_WARN(priv, "check 5.2G: CCK!\n"); 436 IWL_WARN(priv, "check 5.2G: CCK!\n");
431 error = true; 437 errors |= BIT(3);
432 } 438 }
433 } 439 }
434 if ((rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1) { 440 if ((rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1) {
435 IWL_WARN(priv, "mac/bssid mcast!\n"); 441 IWL_WARN(priv, "mac/bssid mcast!\n");
436 error = true; 442 errors |= BIT(4);
437 } 443 }
438 444
439 /* make sure basic rates 6Mbps and 1Mbps are supported */ 445 /* make sure basic rates 6Mbps and 1Mbps are supported */
440 if ((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0 && 446 if ((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0 &&
441 (rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0) { 447 (rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0) {
442 IWL_WARN(priv, "neither 1 nor 6 are basic\n"); 448 IWL_WARN(priv, "neither 1 nor 6 are basic\n");
443 error = true; 449 errors |= BIT(5);
444 } 450 }
445 451
446 if (le16_to_cpu(rxon->assoc_id) > 2007) { 452 if (le16_to_cpu(rxon->assoc_id) > 2007) {
447 IWL_WARN(priv, "aid > 2007\n"); 453 IWL_WARN(priv, "aid > 2007\n");
448 error = true; 454 errors |= BIT(6);
449 } 455 }
450 456
451 if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) 457 if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK))
452 == (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) { 458 == (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) {
453 IWL_WARN(priv, "CCK and short slot\n"); 459 IWL_WARN(priv, "CCK and short slot\n");
454 error = true; 460 errors |= BIT(7);
455 } 461 }
456 462
457 if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) 463 if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK))
458 == (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) { 464 == (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) {
459 IWL_WARN(priv, "CCK and auto detect"); 465 IWL_WARN(priv, "CCK and auto detect");
460 error = true; 466 errors |= BIT(8);
461 } 467 }
462 468
463 if ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK | 469 if ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK |
464 RXON_FLG_TGG_PROTECT_MSK)) == 470 RXON_FLG_TGG_PROTECT_MSK)) ==
465 RXON_FLG_TGG_PROTECT_MSK) { 471 RXON_FLG_TGG_PROTECT_MSK) {
466 IWL_WARN(priv, "TGg but no auto-detect\n"); 472 IWL_WARN(priv, "TGg but no auto-detect\n");
467 error = true; 473 errors |= BIT(9);
468 } 474 }
469 475
470 if (error) 476 if (rxon->channel == 0) {
471 IWL_WARN(priv, "Tuning to channel %d\n", 477 IWL_WARN(priv, "zero channel is invalid\n");
472 le16_to_cpu(rxon->channel)); 478 errors |= BIT(10);
473
474 if (error) {
475 IWL_ERR(priv, "Invalid RXON\n");
476 return -EINVAL;
477 } 479 }
478 return 0; 480
481 WARN(errors, "Invalid RXON (%#x), channel %d",
482 errors, le16_to_cpu(rxon->channel));
483
484 return errors ? -EINVAL : 0;
479} 485}
480 486
481/** 487/**
@@ -867,6 +873,19 @@ void iwl_print_rx_config_cmd(struct iwl_priv *priv,
867} 873}
868#endif 874#endif
869 875
876static void iwlagn_abort_notification_waits(struct iwl_priv *priv)
877{
878 unsigned long flags;
879 struct iwl_notification_wait *wait_entry;
880
881 spin_lock_irqsave(&priv->_agn.notif_wait_lock, flags);
882 list_for_each_entry(wait_entry, &priv->_agn.notif_waits, list)
883 wait_entry->aborted = true;
884 spin_unlock_irqrestore(&priv->_agn.notif_wait_lock, flags);
885
886 wake_up_all(&priv->_agn.notif_waitq);
887}
888
870void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) 889void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
871{ 890{
872 unsigned int reload_msec; 891 unsigned int reload_msec;
@@ -878,6 +897,8 @@ void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
878 /* Cancel currently queued command. */ 897 /* Cancel currently queued command. */
879 clear_bit(STATUS_HCMD_ACTIVE, &priv->status); 898 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
880 899
900 iwlagn_abort_notification_waits(priv);
901
881 /* Keep the restart process from trying to send host 902 /* Keep the restart process from trying to send host
882 * commands by clearing the ready bit */ 903 * commands by clearing the ready bit */
883 clear_bit(STATUS_READY, &priv->status); 904 clear_bit(STATUS_READY, &priv->status);
@@ -906,7 +927,7 @@ void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
906 } 927 }
907 928
908 if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) { 929 if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
909 if (priv->cfg->mod_params->restart_fw) { 930 if (iwlagn_mod_params.restart_fw) {
910 IWL_DEBUG(priv, IWL_DL_FW_ERRORS, 931 IWL_DEBUG(priv, IWL_DL_FW_ERRORS,
911 "Restarting adapter due to uCode error.\n"); 932 "Restarting adapter due to uCode error.\n");
912 queue_work(priv->workqueue, &priv->restart); 933 queue_work(priv->workqueue, &priv->restart);
@@ -975,6 +996,8 @@ void iwl_apm_stop(struct iwl_priv *priv)
975{ 996{
976 IWL_DEBUG_INFO(priv, "Stop card, put in low power state\n"); 997 IWL_DEBUG_INFO(priv, "Stop card, put in low power state\n");
977 998
999 clear_bit(STATUS_DEVICE_ENABLED, &priv->status);
1000
978 /* Stop device's DMA activity */ 1001 /* Stop device's DMA activity */
979 iwl_apm_stop_master(priv); 1002 iwl_apm_stop_master(priv);
980 1003
@@ -1089,6 +1112,8 @@ int iwl_apm_init(struct iwl_priv *priv)
1089 iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG, 1112 iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
1090 APMG_PCIDEV_STT_VAL_L1_ACT_DIS); 1113 APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
1091 1114
1115 set_bit(STATUS_DEVICE_ENABLED, &priv->status);
1116
1092out: 1117out:
1093 return ret; 1118 return ret;
1094} 1119}
@@ -1723,7 +1748,7 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external)
1723 * detect failure), then fw_restart module parameter 1748 * detect failure), then fw_restart module parameter
1724 * need to be check before performing firmware reload 1749 * need to be check before performing firmware reload
1725 */ 1750 */
1726 if (!external && !priv->cfg->mod_params->restart_fw) { 1751 if (!external && !iwlagn_mod_params.restart_fw) {
1727 IWL_DEBUG_INFO(priv, "Cancel firmware reload based on " 1752 IWL_DEBUG_INFO(priv, "Cancel firmware reload based on "
1728 "module parameter setting\n"); 1753 "module parameter setting\n");
1729 break; 1754 break;
@@ -1740,6 +1765,7 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1740{ 1765{
1741 struct iwl_priv *priv = hw->priv; 1766 struct iwl_priv *priv = hw->priv;
1742 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); 1767 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
1768 struct iwl_rxon_context *bss_ctx = &priv->contexts[IWL_RXON_CTX_BSS];
1743 struct iwl_rxon_context *tmp; 1769 struct iwl_rxon_context *tmp;
1744 u32 interface_modes; 1770 u32 interface_modes;
1745 int err; 1771 int err;
@@ -1764,6 +1790,19 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1764 goto out; 1790 goto out;
1765 } 1791 }
1766 1792
1793 /*
1794 * Refuse a change that should be done by moving from the PAN
1795 * context to the BSS context instead, if the BSS context is
1796 * available and can support the new interface type.
1797 */
1798 if (ctx->ctxid == IWL_RXON_CTX_PAN && !bss_ctx->vif &&
1799 (bss_ctx->interface_modes & BIT(newtype) ||
1800 bss_ctx->exclusive_interface_modes & BIT(newtype))) {
1801 BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
1802 err = -EBUSY;
1803 goto out;
1804 }
1805
1767 if (ctx->exclusive_interface_modes & BIT(newtype)) { 1806 if (ctx->exclusive_interface_modes & BIT(newtype)) {
1768 for_each_context(priv, tmp) { 1807 for_each_context(priv, tmp) {
1769 if (ctx == tmp) 1808 if (ctx == tmp)