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>
This commit is contained in:
parent
ff776cecec
commit
9d39e5bad7
|
@ -2363,12 +2363,21 @@ void iwlagn_stop_device(struct iwl_priv *priv)
|
|||
/* device going down, Stop using ICT table */
|
||||
iwl_disable_ict(priv);
|
||||
|
||||
iwlagn_txq_ctx_stop(priv);
|
||||
iwlagn_rxq_stop(priv);
|
||||
/*
|
||||
* If a HW restart happens during firmware loading,
|
||||
* then the firmware loading might call this function
|
||||
* and later it might be called again due to the
|
||||
* restart. So don't process again if the device is
|
||||
* already dead.
|
||||
*/
|
||||
if (test_bit(STATUS_DEVICE_ENABLED, &priv->status)) {
|
||||
iwlagn_txq_ctx_stop(priv);
|
||||
iwlagn_rxq_stop(priv);
|
||||
|
||||
/* Power-down device's busmaster DMA clocks */
|
||||
iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
|
||||
udelay(5);
|
||||
/* Power-down device's busmaster DMA clocks */
|
||||
iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
|
||||
udelay(5);
|
||||
}
|
||||
|
||||
/* Make sure (redundant) we've released our request to stay awake */
|
||||
iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
|
||||
|
|
|
@ -995,6 +995,8 @@ void iwl_apm_stop(struct iwl_priv *priv)
|
|||
{
|
||||
IWL_DEBUG_INFO(priv, "Stop card, put in low power state\n");
|
||||
|
||||
clear_bit(STATUS_DEVICE_ENABLED, &priv->status);
|
||||
|
||||
/* Stop device's DMA activity */
|
||||
iwl_apm_stop_master(priv);
|
||||
|
||||
|
@ -1109,6 +1111,8 @@ int iwl_apm_init(struct iwl_priv *priv)
|
|||
iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
|
||||
APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
|
||||
|
||||
set_bit(STATUS_DEVICE_ENABLED, &priv->status);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -592,6 +592,7 @@ void iwlcore_free_geos(struct iwl_priv *priv);
|
|||
#define STATUS_SCAN_HW 15
|
||||
#define STATUS_POWER_PMI 16
|
||||
#define STATUS_FW_ERROR 17
|
||||
#define STATUS_DEVICE_ENABLED 18
|
||||
|
||||
|
||||
static inline int iwl_is_ready(struct iwl_priv *priv)
|
||||
|
|
Loading…
Reference in New Issue