aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-04-19 10:38:23 -0400
committerWey-Yi Guy <wey-yi.w.guy@intel.com>2011-04-30 11:39:12 -0400
commit9d39e5bad76a8830a8fa0c03cadc1e36ce2ec2ef (patch)
tree1bb63011eea553fdf20ef7e6bfcc52f3d5bd19fc
parentff776cecec92fe7cac4a9ce1919576ad6e737e08 (diff)
iwlagn: avoid hangs when restarting device
If a device error happens while the uCode is being loaded or initialised, we will attempt to restart the device (which will likely fail again, but that's not the issue here). During this new restart, we turn off the device, but as the uCode failed to initialise it already is turned off. As a consequence, grabbing NIC access will fail and cause excessive messages and hangs. To fix this issue, introduce a new status bit and only attempt to reprogram the device when it isn't already disabled. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c21
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h1
3 files changed, 20 insertions, 6 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index e202a40cbcb..75e1035330b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -2363,12 +2363,21 @@ void iwlagn_stop_device(struct iwl_priv *priv)
2363 /* device going down, Stop using ICT table */ 2363 /* device going down, Stop using ICT table */
2364 iwl_disable_ict(priv); 2364 iwl_disable_ict(priv);
2365 2365
2366 iwlagn_txq_ctx_stop(priv); 2366 /*
2367 iwlagn_rxq_stop(priv); 2367 * If a HW restart happens during firmware loading,
2368 2368 * then the firmware loading might call this function
2369 /* Power-down device's busmaster DMA clocks */ 2369 * and later it might be called again due to the
2370 iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT); 2370 * restart. So don't process again if the device is
2371 udelay(5); 2371 * already dead.
2372 */
2373 if (test_bit(STATUS_DEVICE_ENABLED, &priv->status)) {
2374 iwlagn_txq_ctx_stop(priv);
2375 iwlagn_rxq_stop(priv);
2376
2377 /* Power-down device's busmaster DMA clocks */
2378 iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
2379 udelay(5);
2380 }
2372 2381
2373 /* Make sure (redundant) we've released our request to stay awake */ 2382 /* Make sure (redundant) we've released our request to stay awake */
2374 iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 2383 iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index af72fd51ea7..66da1dec982 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -995,6 +995,8 @@ void iwl_apm_stop(struct iwl_priv *priv)
995{ 995{
996 IWL_DEBUG_INFO(priv, "Stop card, put in low power state\n"); 996 IWL_DEBUG_INFO(priv, "Stop card, put in low power state\n");
997 997
998 clear_bit(STATUS_DEVICE_ENABLED, &priv->status);
999
998 /* Stop device's DMA activity */ 1000 /* Stop device's DMA activity */
999 iwl_apm_stop_master(priv); 1001 iwl_apm_stop_master(priv);
1000 1002
@@ -1109,6 +1111,8 @@ int iwl_apm_init(struct iwl_priv *priv)
1109 iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG, 1111 iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
1110 APMG_PCIDEV_STT_VAL_L1_ACT_DIS); 1112 APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
1111 1113
1114 set_bit(STATUS_DEVICE_ENABLED, &priv->status);
1115
1112out: 1116out:
1113 return ret; 1117 return ret;
1114} 1118}
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 32a990ff09a..6226e3d9f10 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -592,6 +592,7 @@ void iwlcore_free_geos(struct iwl_priv *priv);
592#define STATUS_SCAN_HW 15 592#define STATUS_SCAN_HW 15
593#define STATUS_POWER_PMI 16 593#define STATUS_POWER_PMI 16
594#define STATUS_FW_ERROR 17 594#define STATUS_FW_ERROR 17
595#define STATUS_DEVICE_ENABLED 18
595 596
596 597
597static inline int iwl_is_ready(struct iwl_priv *priv) 598static inline int iwl_is_ready(struct iwl_priv *priv)