diff options
author | Mordechay Goodstein <mordechay.goodstein@intel.com> | 2021-11-10 15:01:59 +0200 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2021-11-22 20:38:17 +0200 |
commit | 5283dd677e52af9db6fe6ad11b2f12220d519d0c (patch) | |
tree | 0a1b0126b5642853f9bb00a0ef71f4386e898c57 /drivers/net/wireless/intel/iwlwifi/iwl-drv.c | |
parent | iwlwifi: Fix missing error code in iwl_pci_probe() (diff) | |
download | linux-5283dd677e52af9db6fe6ad11b2f12220d519d0c.tar.xz linux-5283dd677e52af9db6fe6ad11b2f12220d519d0c.zip |
iwlwifi: mvm: retry init flow if failed
In some very rare cases the init flow may fail. In many cases, this is
recoverable, so we can retry. Implement a loop to retry two more times
after the first attempt failed.
This can happen in two different situations, namely during probe and
during mac80211 start. For the first case, a simple loop is enough.
For the second case, we need to add a flag to prevent mac80211 from
trying to restart it as well, leaving full control with the driver.
Cc: <stable@vger.kernel.org>
Signed-off-by: Mordechay Goodstein <mordechay.goodstein@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/iwlwifi.20211110150132.57514296ecab.I52a0411774b700bdc7dedb124d8b59bf99456eb2@changeid
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/iwl-drv.c')
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index 36196e07b1a0..5cec467b995b 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c @@ -1313,23 +1313,31 @@ _iwl_op_mode_start(struct iwl_drv *drv, struct iwlwifi_opmode_table *op) const struct iwl_op_mode_ops *ops = op->ops; struct dentry *dbgfs_dir = NULL; struct iwl_op_mode *op_mode = NULL; + int retry, max_retry = !!iwlwifi_mod_params.fw_restart * IWL_MAX_INIT_RETRY; + + for (retry = 0; retry <= max_retry; retry++) { #ifdef CONFIG_IWLWIFI_DEBUGFS - drv->dbgfs_op_mode = debugfs_create_dir(op->name, - drv->dbgfs_drv); - dbgfs_dir = drv->dbgfs_op_mode; + drv->dbgfs_op_mode = debugfs_create_dir(op->name, + drv->dbgfs_drv); + dbgfs_dir = drv->dbgfs_op_mode; #endif - op_mode = ops->start(drv->trans, drv->trans->cfg, &drv->fw, dbgfs_dir); + op_mode = ops->start(drv->trans, drv->trans->cfg, + &drv->fw, dbgfs_dir); + + if (op_mode) + return op_mode; + + IWL_ERR(drv, "retry init count %d\n", retry); #ifdef CONFIG_IWLWIFI_DEBUGFS - if (!op_mode) { debugfs_remove_recursive(drv->dbgfs_op_mode); drv->dbgfs_op_mode = NULL; - } #endif + } - return op_mode; + return NULL; } static void _iwl_op_mode_stop(struct iwl_drv *drv) |