diff options
| author | Dmitry Torokhov <[email protected]> | 2023-08-30 16:06:38 -0700 | 
|---|---|---|
| committer | Dmitry Torokhov <[email protected]> | 2023-08-30 16:06:38 -0700 | 
| commit | 1ac731c529cd4d6adbce134754b51ff7d822b145 (patch) | |
| tree | 143ab3f35ca5f3b69f583c84e6964b17139c2ec1 /drivers/net/wireless/intel/iwlwifi/fw/dump.c | |
| parent | 07b4c950f27bef0362dc6ad7ee713aab61d58149 (diff) | |
| parent | 54116d442e001e1b6bd482122043b1870998a1f3 (diff) | |
Merge branch 'next' into for-linus
Prepare input updates for 6.6 merge window.
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/fw/dump.c')
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/fw/dump.c | 69 | 
1 files changed, 67 insertions, 2 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dump.c b/drivers/net/wireless/intel/iwlwifi/fw/dump.c index 792f7fee1840..f86f7b4baa18 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dump.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dump.c @@ -14,6 +14,13 @@  #include "iwl-csr.h"  #include "pnvm.h" +#define FW_ASSERT_LMAC_FATAL			0x70 +#define FW_ASSERT_LMAC2_FATAL			0x72 +#define FW_ASSERT_UMAC_FATAL			0x71 +#define UMAC_RT_NMI_LMAC2_FATAL			0x72 +#define RT_NMI_INTERRUPT_OTHER_LMAC_FATAL	0x73 +#define FW_ASSERT_NMI_UNKNOWN			0x84 +  /*   * Note: This structure is read from the device with IO accesses,   * and the reading already does the endian conversion. As it is @@ -96,6 +103,17 @@ struct iwl_umac_error_event_table {  #define ERROR_START_OFFSET  (1 * sizeof(u32))  #define ERROR_ELEM_SIZE     (7 * sizeof(u32)) +static bool iwl_fwrt_if_errorid_other_cpu(u32 err_id) +{ +	err_id &= 0xFF; + +	if ((err_id >= FW_ASSERT_LMAC_FATAL && +	     err_id <= RT_NMI_INTERRUPT_OTHER_LMAC_FATAL) || +	    err_id == FW_ASSERT_NMI_UNKNOWN) +		return  true; +	return false; +} +  static void iwl_fwrt_dump_umac_error_log(struct iwl_fw_runtime *fwrt)  {  	struct iwl_trans *trans = fwrt->trans; @@ -113,6 +131,13 @@ static void iwl_fwrt_dump_umac_error_log(struct iwl_fw_runtime *fwrt)  	if (table.valid)  		fwrt->dump.umac_err_id = table.error_id; +	if (!iwl_fwrt_if_errorid_other_cpu(fwrt->dump.umac_err_id) && +	    !fwrt->trans->dbg.dump_file_name_ext_valid) { +		fwrt->trans->dbg.dump_file_name_ext_valid = true; +		snprintf(fwrt->trans->dbg.dump_file_name_ext, IWL_FW_INI_MAX_NAME, +			 "0x%x", fwrt->dump.umac_err_id); +	} +  	if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) {  		IWL_ERR(trans, "Start IWL Error Log Dump:\n");  		IWL_ERR(trans, "Transport status: 0x%08lX, valid: %d\n", @@ -189,6 +214,13 @@ static void iwl_fwrt_dump_lmac_error_log(struct iwl_fw_runtime *fwrt, u8 lmac_nu  	if (table.valid)  		fwrt->dump.lmac_err_id[lmac_num] = table.error_id; +	if (!iwl_fwrt_if_errorid_other_cpu(fwrt->dump.lmac_err_id[lmac_num]) && +	    !fwrt->trans->dbg.dump_file_name_ext_valid) { +		fwrt->trans->dbg.dump_file_name_ext_valid = true; +		snprintf(fwrt->trans->dbg.dump_file_name_ext, IWL_FW_INI_MAX_NAME, +			 "0x%x", fwrt->dump.lmac_err_id[lmac_num]); +	} +  	if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) {  		IWL_ERR(trans, "Start IWL Error Log Dump:\n");  		IWL_ERR(trans, "Transport status: 0x%08lX, valid: %d\n", @@ -274,6 +306,16 @@ static void iwl_fwrt_dump_tcm_error_log(struct iwl_fw_runtime *fwrt, int idx)  	iwl_trans_read_mem_bytes(trans, base, &table, sizeof(table)); +	if (table.valid) +		fwrt->dump.tcm_err_id[idx] = table.error_id; + +	if (!iwl_fwrt_if_errorid_other_cpu(fwrt->dump.tcm_err_id[idx]) && +	    !fwrt->trans->dbg.dump_file_name_ext_valid) { +		fwrt->trans->dbg.dump_file_name_ext_valid = true; +		snprintf(fwrt->trans->dbg.dump_file_name_ext, IWL_FW_INI_MAX_NAME, +			 "0x%x", fwrt->dump.tcm_err_id[idx]); +	} +  	IWL_ERR(fwrt, "TCM%d status:\n", idx + 1);  	IWL_ERR(fwrt, "0x%08X | error ID\n", table.error_id);  	IWL_ERR(fwrt, "0x%08X | tcm branchlink2\n", table.blink2); @@ -337,6 +379,16 @@ static void iwl_fwrt_dump_rcm_error_log(struct iwl_fw_runtime *fwrt, int idx)  	iwl_trans_read_mem_bytes(trans, base, &table, sizeof(table)); +	if (table.valid) +		fwrt->dump.rcm_err_id[idx] = table.error_id; + +	if (!iwl_fwrt_if_errorid_other_cpu(fwrt->dump.rcm_err_id[idx]) && +	    !fwrt->trans->dbg.dump_file_name_ext_valid) { +		fwrt->trans->dbg.dump_file_name_ext_valid = true; +		snprintf(fwrt->trans->dbg.dump_file_name_ext, IWL_FW_INI_MAX_NAME, +			 "0x%x", fwrt->dump.rcm_err_id[idx]); +	} +  	IWL_ERR(fwrt, "RCM%d status:\n", idx + 1);  	IWL_ERR(fwrt, "0x%08X | error ID\n", table.error_id);  	IWL_ERR(fwrt, "0x%08X | rcm branchlink2\n", table.blink2); @@ -432,6 +484,9 @@ static void iwl_fwrt_dump_fseq_regs(struct iwl_fw_runtime *fwrt)  void iwl_fwrt_dump_error_logs(struct iwl_fw_runtime *fwrt)  { +	struct iwl_pc_data *pc_data; +	u8 count; +  	if (!test_bit(STATUS_DEVICE_ENABLED, &fwrt->trans->status)) {  		IWL_ERR(fwrt,  			"DEVICE_ENABLED bit is not set. Aborting dump.\n"); @@ -444,10 +499,20 @@ void iwl_fwrt_dump_error_logs(struct iwl_fw_runtime *fwrt)  	iwl_fwrt_dump_umac_error_log(fwrt);  	iwl_fwrt_dump_tcm_error_log(fwrt, 0);  	iwl_fwrt_dump_rcm_error_log(fwrt, 0); -	iwl_fwrt_dump_tcm_error_log(fwrt, 1); -	iwl_fwrt_dump_rcm_error_log(fwrt, 1); +	if (fwrt->trans->dbg.tcm_error_event_table[1]) +		iwl_fwrt_dump_tcm_error_log(fwrt, 1); +	if (fwrt->trans->dbg.rcm_error_event_table[1]) +		iwl_fwrt_dump_rcm_error_log(fwrt, 1);  	iwl_fwrt_dump_iml_error_log(fwrt);  	iwl_fwrt_dump_fseq_regs(fwrt); +	if (fwrt->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000) { +		pc_data = fwrt->trans->dbg.pc_data; +		for (count = 0; count < fwrt->trans->dbg.num_pc; +		     count++, pc_data++) +			IWL_ERR(fwrt, "%s: 0x%x\n", +				pc_data->pc_name, +				pc_data->pc_address); +	}  	if (fwrt->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) {  		u32 scratch = iwl_read32(fwrt->trans, CSR_FUNC_SCRATCH);  |