wifi: iwlwifi: dbg: print pc register data once fw dump occurred
authorMukesh Sisodiya <mukesh.sisodiya@intel.com>
Thu, 13 Apr 2023 18:40:21 +0000 (21:40 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 14 Apr 2023 11:14:49 +0000 (13:14 +0200)
Add debug print for different FW program counter details of
different CPU. Program counter pc details will be read from
TLV during init.

Signed-off-by: Mukesh Sisodiya <mukesh.sisodiya@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20230413213309.862790d336a9.I34e2ea05a79e8b2552f7f221bacf3af0166cb9c0@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/intel/iwlwifi/fw/dump.c
drivers/net/wireless/intel/iwlwifi/fw/file.h
drivers/net/wireless/intel/iwlwifi/iwl-drv.c
drivers/net/wireless/intel/iwlwifi/iwl-trans.h
drivers/net/wireless/intel/iwlwifi/mvm/fw.c

index 59ed321..f86f7b4 100644 (file)
@@ -484,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");
@@ -502,6 +505,14 @@ void iwl_fwrt_dump_error_logs(struct iwl_fw_runtime *fwrt)
                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);
index f2eefca..a0260a1 100644 (file)
@@ -101,6 +101,7 @@ enum iwl_ucode_tlv_type {
 
        IWL_UCODE_TLV_SEC_TABLE_ADDR            = 66,
        IWL_UCODE_TLV_D3_KEK_KCK_ADDR           = 67,
+       IWL_UCODE_TLV_CURRENT_PC                = 68,
 
        IWL_UCODE_TLV_FW_NUM_STATIONS           = IWL_UCODE_TLV_CONST_BASE + 0,
 
index 4c977ba..75d52e6 100644 (file)
@@ -127,6 +127,7 @@ static void iwl_dealloc_ucode(struct iwl_drv *drv)
        kfree(drv->fw.iml);
        kfree(drv->fw.ucode_capa.cmd_versions);
        kfree(drv->fw.phy_integration_ver);
+       kfree(drv->trans->dbg.pc_data);
 
        for (i = 0; i < IWL_UCODE_TYPE_MAX; i++)
                iwl_free_fw_img(drv, drv->fw.img + i);
@@ -1232,6 +1233,14 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
                        iwl_drv_set_dump_exclude(drv, tlv_type,
                                                 tlv_data, tlv_len);
                        break;
+               case IWL_UCODE_TLV_CURRENT_PC:
+                       if (tlv_len < sizeof(struct iwl_pc_data))
+                               goto invalid_tlv_len;
+                       drv->trans->dbg.num_pc =
+                               tlv_len / sizeof(struct iwl_pc_data);
+                       drv->trans->dbg.pc_data =
+                               kmemdup(tlv_data, tlv_len, GFP_KERNEL);
+                       break;
                default:
                        IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type);
                        break;
index dd277a4..74ff478 100644 (file)
@@ -748,6 +748,18 @@ struct iwl_imr_data {
        __le64 imr_base_addr;
 };
 
+#define IWL_TRANS_CURRENT_PC_NAME_MAX_BYTES      32
+
+/**
+ * struct iwl_pc_data - program counter details
+ * @pc_name: cpu name
+ * @pc_address: cpu program counter
+ */
+struct iwl_pc_data {
+       u8  pc_name[IWL_TRANS_CURRENT_PC_NAME_MAX_BYTES];
+       u32 pc_address;
+};
+
 /**
  * struct iwl_trans_debug - transport debug related data
  *
@@ -777,6 +789,8 @@ struct iwl_imr_data {
  * @ucode_preset: preset based on ucode
  * @dump_file_name_ext: dump file name extension
  * @dump_file_name_ext_valid: dump file name extension if valid or not
+ * @num_pc: number of program counter for cpu
+ * @pc_data: details of the program counter
  */
 struct iwl_trans_debug {
        u8 n_dest_reg;
@@ -817,6 +831,8 @@ struct iwl_trans_debug {
        struct iwl_imr_data imr_data;
        u8 dump_file_name_ext[IWL_FW_INI_MAX_NAME];
        bool dump_file_name_ext_valid;
+       u32 num_pc;
+       struct iwl_pc_data *pc_data;
 };
 
 struct iwl_dma_ptr {
index 521eded..3f5cc6b 100644 (file)
@@ -321,6 +321,8 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
        static const u16 alive_cmd[] = { UCODE_ALIVE_NTFY };
        bool run_in_rfkill =
                ucode_type == IWL_UCODE_INIT || iwl_mvm_has_unified_ucode(mvm);
+       u8 count;
+       struct iwl_pc_data *pc_data;
 
        if (ucode_type == IWL_UCODE_REGULAR &&
            iwl_fw_dbg_conf_usniffer(mvm->fw, FW_DBG_START_FROM_ALIVE) &&
@@ -393,6 +395,14 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
 
                /* LMAC/UMAC PC info */
                if (trans->trans_cfg->device_family >=
+                                       IWL_DEVICE_FAMILY_22000) {
+                       pc_data = trans->dbg.pc_data;
+                       for (count = 0; count < trans->dbg.num_pc;
+                            count++, pc_data++)
+                               IWL_ERR(mvm, "%s: 0x%x\n",
+                                       pc_data->pc_name,
+                                       pc_data->pc_address);
+               } else if (trans->trans_cfg->device_family >=
                                        IWL_DEVICE_FAMILY_9000) {
                        IWL_ERR(mvm, "UMAC PC: 0x%x\n",
                                iwl_read_umac_prph(trans,