aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
authorWey-Yi Guy <wey-yi.w.guy@intel.com>2011-02-09 12:37:46 -0500
committerWey-Yi Guy <wey-yi.w.guy@intel.com>2011-02-21 13:08:15 -0500
commit491bc292766330473eac4569be5d57f9aeb80112 (patch)
tree4642fd4973e736e1e69b486e91ebf17350157771 /drivers/net/wireless/iwlwifi
parentb67afe7f43afd2f5cd98798993561920c1684c12 (diff)
iwlwifi: Limit number of firmware reload
If device has serious problem and cause firmware can not recover itself. Keep reloading firmware will not help, it can only fill up the syslog and lock up the system because busy reloading. Introduce the limit reload counter, if the reload reach the maximum within the pre-defined duration;stop the reload operation. Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c22
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h9
2 files changed, 31 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 4ad89389a0a9..977ddfb8c24c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -948,6 +948,9 @@ EXPORT_SYMBOL(iwl_print_rx_config_cmd);
948 */ 948 */
949void iwl_irq_handle_error(struct iwl_priv *priv) 949void iwl_irq_handle_error(struct iwl_priv *priv)
950{ 950{
951 unsigned int reload_msec;
952 unsigned long reload_jiffies;
953
951 /* Set the FW error flag -- cleared on iwl_down */ 954 /* Set the FW error flag -- cleared on iwl_down */
952 set_bit(STATUS_FW_ERROR, &priv->status); 955 set_bit(STATUS_FW_ERROR, &priv->status);
953 956
@@ -991,6 +994,25 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
991 * commands by clearing the INIT status bit */ 994 * commands by clearing the INIT status bit */
992 clear_bit(STATUS_READY, &priv->status); 995 clear_bit(STATUS_READY, &priv->status);
993 996
997 /*
998 * If firmware keep reloading, then it indicate something
999 * serious wrong and firmware having problem to recover
1000 * from it. Instead of keep trying which will fill the syslog
1001 * and hang the system, let's just stop it
1002 */
1003 reload_jiffies = jiffies;
1004 reload_msec = jiffies_to_msecs((long) reload_jiffies -
1005 (long) priv->reload_jiffies);
1006 priv->reload_jiffies = reload_jiffies;
1007 if (reload_msec <= IWL_MIN_RELOAD_DURATION) {
1008 priv->reload_count++;
1009 if (priv->reload_count >= IWL_MAX_CONTINUE_RELOAD_CNT) {
1010 IWL_ERR(priv, "BUG_ON, Stop restarting\n");
1011 return;
1012 }
1013 } else
1014 priv->reload_count = 0;
1015
994 if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) { 1016 if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
995 IWL_DEBUG(priv, IWL_DL_FW_ERRORS, 1017 IWL_DEBUG(priv, IWL_DL_FW_ERRORS,
996 "Restarting adapter due to uCode error.\n"); 1018 "Restarting adapter due to uCode error.\n");
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index ecfbef402781..065615ee040a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1110,6 +1110,11 @@ struct iwl_event_log {
1110/* BT Antenna Coupling Threshold (dB) */ 1110/* BT Antenna Coupling Threshold (dB) */
1111#define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35) 1111#define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35)
1112 1112
1113/* Firmware reload counter and Timestamp */
1114#define IWL_MIN_RELOAD_DURATION 1000 /* 1000 ms */
1115#define IWL_MAX_CONTINUE_RELOAD_CNT 4
1116
1117
1113enum iwl_reset { 1118enum iwl_reset {
1114 IWL_RF_RESET = 0, 1119 IWL_RF_RESET = 0,
1115 IWL_FW_RESET, 1120 IWL_FW_RESET,
@@ -1262,6 +1267,10 @@ struct iwl_priv {
1262 /* force reset */ 1267 /* force reset */
1263 struct iwl_force_reset force_reset[IWL_MAX_FORCE_RESET]; 1268 struct iwl_force_reset force_reset[IWL_MAX_FORCE_RESET];
1264 1269
1270 /* firmware reload counter and timestamp */
1271 unsigned long reload_jiffies;
1272 int reload_count;
1273
1265 /* we allocate array of iwl_channel_info for NIC's valid channels. 1274 /* we allocate array of iwl_channel_info for NIC's valid channels.
1266 * Access via channel # using indirect index array */ 1275 * Access via channel # using indirect index array */
1267 struct iwl_channel_info *channel_info; /* channel info array */ 1276 struct iwl_channel_info *channel_info; /* channel info array */