Skip to content

Commit

Permalink
iwlwifi: Limit number of firmware reload
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Wey-Yi Guy committed Feb 21, 2011
1 parent b67afe7 commit 491bc29
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 0 deletions.
22 changes: 22 additions & 0 deletions drivers/net/wireless/iwlwifi/iwl-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -948,6 +948,9 @@ EXPORT_SYMBOL(iwl_print_rx_config_cmd);
*/
void iwl_irq_handle_error(struct iwl_priv *priv)
{
unsigned int reload_msec;
unsigned long reload_jiffies;

/* Set the FW error flag -- cleared on iwl_down */
set_bit(STATUS_FW_ERROR, &priv->status);

Expand Down Expand Up @@ -991,6 +994,25 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
* commands by clearing the INIT status bit */
clear_bit(STATUS_READY, &priv->status);

/*
* If firmware keep reloading, then it indicate something
* serious wrong and firmware having problem to recover
* from it. Instead of keep trying which will fill the syslog
* and hang the system, let's just stop it
*/
reload_jiffies = jiffies;
reload_msec = jiffies_to_msecs((long) reload_jiffies -
(long) priv->reload_jiffies);
priv->reload_jiffies = reload_jiffies;
if (reload_msec <= IWL_MIN_RELOAD_DURATION) {
priv->reload_count++;
if (priv->reload_count >= IWL_MAX_CONTINUE_RELOAD_CNT) {
IWL_ERR(priv, "BUG_ON, Stop restarting\n");
return;
}
} else
priv->reload_count = 0;

if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
IWL_DEBUG(priv, IWL_DL_FW_ERRORS,
"Restarting adapter due to uCode error.\n");
Expand Down
9 changes: 9 additions & 0 deletions drivers/net/wireless/iwlwifi/iwl-dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -1110,6 +1110,11 @@ struct iwl_event_log {
/* BT Antenna Coupling Threshold (dB) */
#define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35)

/* Firmware reload counter and Timestamp */
#define IWL_MIN_RELOAD_DURATION 1000 /* 1000 ms */
#define IWL_MAX_CONTINUE_RELOAD_CNT 4


enum iwl_reset {
IWL_RF_RESET = 0,
IWL_FW_RESET,
Expand Down Expand Up @@ -1262,6 +1267,10 @@ struct iwl_priv {
/* force reset */
struct iwl_force_reset force_reset[IWL_MAX_FORCE_RESET];

/* firmware reload counter and timestamp */
unsigned long reload_jiffies;
int reload_count;

/* we allocate array of iwl_channel_info for NIC's valid channels.
* Access via channel # using indirect index array */
struct iwl_channel_info *channel_info; /* channel info array */
Expand Down

0 comments on commit 491bc29

Please sign in to comment.