diff options
author | Mordechay Goodstein <mordechay.goodstein@intel.com> | 2018-12-13 16:04:51 -0500 |
---|---|---|
committer | Luca Coelho <luciano.coelho@intel.com> | 2019-02-14 04:29:45 -0500 |
commit | f130bb75d8817c560b48c4d1a0e5279968a0859d (patch) | |
tree | d3f34bd761be323cd1c3382783e90aa8e198a7a8 /drivers/net/wireless/intel/iwlwifi/mvm/ops.c | |
parent | ff911dcaa2e46627f5fc6a22802f72a8bfce4ab5 (diff) |
iwlwifi: add FW recovery flow
Add new API and TLV for the ability to send commands in the beginning
and end of reset flow.
The full flow of recovery is:
1. While loading FW, get address (from the TLV) of target buffer
to read in case of reset
2. If an error/assert happens read the address data from step 1.
3. Reset the HW and load the FW.
4. Send the data read in step 2.
5. Add station keys
6. Send notification to FW that reset flow is done.
The main use of the recovery flow is for support in PN/SN recovery
when offloaded
Signed-off-by: Mordechay Goodstein <mordechay.goodstein@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/ops.c')
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 0c276124bf0f..f8a5a7074dc1 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c | |||
@@ -422,6 +422,7 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = { | |||
422 | static const struct iwl_hcmd_names iwl_mvm_system_names[] = { | 422 | static const struct iwl_hcmd_names iwl_mvm_system_names[] = { |
423 | HCMD_NAME(SHARED_MEM_CFG_CMD), | 423 | HCMD_NAME(SHARED_MEM_CFG_CMD), |
424 | HCMD_NAME(INIT_EXTENDED_CFG_CMD), | 424 | HCMD_NAME(INIT_EXTENDED_CFG_CMD), |
425 | HCMD_NAME(FW_ERROR_RECOVERY_CMD), | ||
425 | }; | 426 | }; |
426 | 427 | ||
427 | /* Please keep this array *SORTED* by hex value. | 428 | /* Please keep this array *SORTED* by hex value. |
@@ -921,6 +922,9 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode) | |||
921 | kfree(mvm->mcast_filter_cmd); | 922 | kfree(mvm->mcast_filter_cmd); |
922 | mvm->mcast_filter_cmd = NULL; | 923 | mvm->mcast_filter_cmd = NULL; |
923 | 924 | ||
925 | kfree(mvm->error_recovery_buf); | ||
926 | mvm->error_recovery_buf = NULL; | ||
927 | |||
924 | #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_IWLWIFI_DEBUGFS) | 928 | #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_IWLWIFI_DEBUGFS) |
925 | kfree(mvm->d3_resume_sram); | 929 | kfree(mvm->d3_resume_sram); |
926 | #endif | 930 | #endif |
@@ -1301,6 +1305,20 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error) | |||
1301 | /* don't let the transport/FW power down */ | 1305 | /* don't let the transport/FW power down */ |
1302 | iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); | 1306 | iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); |
1303 | 1307 | ||
1308 | if (mvm->fw->ucode_capa.error_log_size) { | ||
1309 | u32 src_size = mvm->fw->ucode_capa.error_log_size; | ||
1310 | u32 src_addr = mvm->fw->ucode_capa.error_log_addr; | ||
1311 | u8 *recover_buf = kzalloc(src_size, GFP_ATOMIC); | ||
1312 | |||
1313 | if (recover_buf) { | ||
1314 | mvm->error_recovery_buf = recover_buf; | ||
1315 | iwl_trans_read_mem_bytes(mvm->trans, | ||
1316 | src_addr, | ||
1317 | recover_buf, | ||
1318 | src_size); | ||
1319 | } | ||
1320 | } | ||
1321 | |||
1304 | if (fw_error && mvm->fw_restart > 0) | 1322 | if (fw_error && mvm->fw_restart > 0) |
1305 | mvm->fw_restart--; | 1323 | mvm->fw_restart--; |
1306 | set_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status); | 1324 | set_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status); |