diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index 05720352e49f..43fb5cf85f05 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -281,7 +281,7 @@ static const struct iwl_ht_params iwl_gl_a_ht_params = { .trans.gen2 = true, \ .nvm_type = IWL_NVM_EXT, \ .dbgc_supported = true, \ - .min_umac_error_event_table = 0x400000, \ + .min_umac_error_event_table = 0xD0000, \ .d3_debug_data_base_addr = 0x401000, \ .d3_debug_data_length = 60 * 1024, \ .mon_smem_regs = { \ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dump.c b/drivers/net/wireless/intel/iwlwifi/fw/dump.c index 792f7fee1840..59ed321bcc27 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); @@ -444,8 +496,10 @@ 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); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h index d3cb1ae68a96..a59cf4d9567c 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h @@ -24,6 +24,8 @@ struct iwl_fw_runtime_ops { }; #define MAX_NUM_LMAC 2 +#define MAX_NUM_TCM 2 +#define MAX_NUM_RCM 2 struct iwl_fwrt_shared_mem_cfg { int num_lmacs; int num_txfifo_entries; @@ -129,6 +131,8 @@ struct iwl_fw_runtime { unsigned long non_collect_ts_start[IWL_FW_INI_TIME_POINT_NUM]; u32 *d3_debug_data; u32 lmac_err_id[MAX_NUM_LMAC]; + u32 tcm_err_id[MAX_NUM_TCM]; + u32 rcm_err_id[MAX_NUM_RCM]; u32 umac_err_id; struct iwl_txf_iter_data txf_iter_data; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 45981e22b2db..3e9e9f13506b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -122,8 +122,6 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait, u32 version = iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP, UCODE_ALIVE_NTFY, 0); u32 i; - struct iwl_trans *trans = mvm->trans; - enum iwl_device_family device_family = trans->trans_cfg->device_family; if (version == 6) { @@ -233,8 +231,7 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait, if (umac_error_table) { if (umac_error_table >= - mvm->trans->cfg->min_umac_error_event_table || - device_family >= IWL_DEVICE_FAMILY_BZ) { + mvm->trans->cfg->min_umac_error_event_table) { iwl_fw_umac_set_alive_err_table(mvm->trans, umac_error_table); } else { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c index 114c96ba39ee..422550e31bc6 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c @@ -430,6 +430,36 @@ static void iwl_mvm_mac_ctxt_set_ht_flags(struct iwl_mvm *mvm, } } +static int iwl_mvm_get_mac_type(struct ieee80211_vif *vif) +{ + u32 mac_type = FW_MAC_TYPE_BSS_STA; + + switch (vif->type) { + case NL80211_IFTYPE_STATION: + if (vif->p2p) + mac_type = FW_MAC_TYPE_P2P_STA; + else + mac_type = FW_MAC_TYPE_BSS_STA; + break; + case NL80211_IFTYPE_AP: + mac_type = FW_MAC_TYPE_GO; + break; + case NL80211_IFTYPE_MONITOR: + mac_type = FW_MAC_TYPE_LISTENER; + break; + case NL80211_IFTYPE_P2P_DEVICE: + mac_type = FW_MAC_TYPE_P2P_DEVICE; + break; + case NL80211_IFTYPE_ADHOC: + mac_type = FW_MAC_TYPE_IBSS; + break; + default: + WARN_ON_ONCE(1); + } + + return mac_type; +} + static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct iwl_mac_ctx_cmd *cmd, @@ -447,29 +477,7 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm, cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color)); cmd->action = cpu_to_le32(action); - - switch (vif->type) { - case NL80211_IFTYPE_STATION: - if (vif->p2p) - cmd->mac_type = cpu_to_le32(FW_MAC_TYPE_P2P_STA); - else - cmd->mac_type = cpu_to_le32(FW_MAC_TYPE_BSS_STA); - break; - case NL80211_IFTYPE_AP: - cmd->mac_type = cpu_to_le32(FW_MAC_TYPE_GO); - break; - case NL80211_IFTYPE_MONITOR: - cmd->mac_type = cpu_to_le32(FW_MAC_TYPE_LISTENER); - break; - case NL80211_IFTYPE_P2P_DEVICE: - cmd->mac_type = cpu_to_le32(FW_MAC_TYPE_P2P_DEVICE); - break; - case NL80211_IFTYPE_ADHOC: - cmd->mac_type = cpu_to_le32(FW_MAC_TYPE_IBSS); - break; - default: - WARN_ON_ONCE(1); - } + cmd->mac_type = cpu_to_le32(iwl_mvm_get_mac_type(vif)); cmd->tsf_id = cpu_to_le32(mvmvif->tsf_id); @@ -1428,6 +1436,7 @@ void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm, struct ieee80211_vif *vif; u32 id = le32_to_cpu(mb->mac_id); union iwl_dbg_tlv_tp_data tp_data = { .fw_pkt = pkt }; + u32 mac_type; IWL_DEBUG_INFO(mvm, "missed bcn mac_id=%u, consecutive=%u (%u, %u, %u)\n", @@ -1443,6 +1452,14 @@ void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm, if (!vif) goto out; + mac_type = iwl_mvm_get_mac_type(vif); + + IWL_DEBUG_INFO(mvm, "missed beacon mac_type=%u,\n", mac_type); + + mvm->trans->dbg.dump_file_name_ext_valid = true; + snprintf(mvm->trans->dbg.dump_file_name_ext, IWL_FW_INI_MAX_NAME, + "MacId_%d_MacType_%d", id, mac_type); + rx_missed_bcon = le32_to_cpu(mb->consec_missed_beacons); rx_missed_bcon_since_rx = le32_to_cpu(mb->consec_missed_beacons_since_last_rx);