iwlwifi: dbg: dump data according to the new ini TLVs
authorSara Sharon <sara.sharon@intel.com>
Wed, 13 Jun 2018 12:24:13 +0000 (15:24 +0300)
committerLuca Coelho <luciano.coelho@intel.com>
Fri, 14 Dec 2018 11:04:44 +0000 (13:04 +0200)
When ini TLVs are loaded, dump data according to the
stored configuration.

Signed-off-by: Sara Sharon <sara.sharon@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
drivers/net/wireless/intel/iwlwifi/fw/dbg.c
drivers/net/wireless/intel/iwlwifi/fw/dbg.h
drivers/net/wireless/intel/iwlwifi/fw/error-dump.h
drivers/net/wireless/intel/iwlwifi/iwl-prph.h
drivers/net/wireless/intel/iwlwifi/mvm/fw.c
drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c
drivers/net/wireless/intel/iwlwifi/pcie/internal.h
drivers/net/wireless/intel/iwlwifi/pcie/trans.c

index 76050cc3532aab27d77adc01314287f23515cb5c..58771e253396abca1b31626cb4b2a16c447e5c21 100644 (file)
@@ -605,6 +605,28 @@ static void iwl_fw_dump_mem(struct iwl_fw_runtime *fwrt,
        IWL_DEBUG_INFO(fwrt, "WRT memory dump. Type=%u\n", dump_mem->type);
 }
 
+static void iwl_fw_dump_named_mem(struct iwl_fw_runtime *fwrt,
+                                 struct iwl_fw_error_dump_data **dump_data,
+                                 u32 len, u32 ofs, u8 *name, u8 name_len)
+{
+       struct iwl_fw_error_dump_named_mem *dump_mem;
+
+       if (!len)
+               return;
+
+       (*dump_data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM);
+       (*dump_data)->len = cpu_to_le32(len + sizeof(*dump_mem));
+       dump_mem = (void *)(*dump_data)->data;
+       dump_mem->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM_NAMED_MEM);
+       dump_mem->offset = cpu_to_le32(ofs);
+       dump_mem->name_len = name_len;
+       memcpy(dump_mem->name, name, name_len);
+       iwl_trans_read_mem_bytes(fwrt->trans, ofs, dump_mem->data, len);
+       *dump_data = iwl_fw_error_next_data(*dump_data);
+
+       IWL_DEBUG_INFO(fwrt, "WRT memory dump. Type=%u\n", dump_mem->type);
+}
+
 #define ADD_LEN(len, item_len, const_len) \
        do {size_t item = item_len; len += (!!item) * const_len + item; } \
        while (0)
@@ -928,6 +950,238 @@ out:
        return dump_file;
 }
 
+static void iwl_dump_prph_ini(struct iwl_trans *trans,
+                             struct iwl_fw_error_dump_data **data,
+                             struct iwl_fw_ini_region_cfg *reg)
+{
+       struct iwl_fw_error_dump_prph *prph;
+       unsigned long flags;
+       u32 i, size = le32_to_cpu(reg->num_regions);
+
+       IWL_DEBUG_INFO(trans, "WRT PRPH dump\n");
+
+       if (!iwl_trans_grab_nic_access(trans, &flags))
+               return;
+
+       for (i = 0; i < size; i++) {
+               (*data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_PRPH);
+               (*data)->len = cpu_to_le32(le32_to_cpu(reg->size) +
+                                          sizeof(*prph));
+               prph = (void *)(*data)->data;
+               prph->prph_start = reg->start_addr[i];
+               prph->data[0] = cpu_to_le32(iwl_read_prph_no_grab(trans,
+                                                                 le32_to_cpu(prph->prph_start)));
+               *data = iwl_fw_error_next_data(*data);
+       }
+       iwl_trans_release_nic_access(trans, &flags);
+}
+
+static void iwl_dump_csr_ini(struct iwl_trans *trans,
+                            struct iwl_fw_error_dump_data **data,
+                            struct iwl_fw_ini_region_cfg *reg)
+{
+       int i, num = le32_to_cpu(reg->num_regions);
+       u32 size = le32_to_cpu(reg->size);
+
+       IWL_DEBUG_INFO(trans, "WRT CSR dump\n");
+
+       for (i = 0; i < num; i++) {
+               u32 add = le32_to_cpu(reg->start_addr[i]);
+               __le32 *val;
+               int j;
+
+               (*data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_CSR);
+               (*data)->len = cpu_to_le32(size);
+               val = (void *)(*data)->data;
+
+               for (j = 0; j < size; j += 4)
+                       *val++ = cpu_to_le32(iwl_trans_read32(trans, j + add));
+
+               *data = iwl_fw_error_next_data(*data);
+       }
+}
+
+static int iwl_fw_ini_get_trigger_len(struct iwl_fw_runtime *fwrt,
+                                     struct iwl_fw_ini_trigger *trigger)
+{
+       int i, num, size = 0, hdr_len = sizeof(struct iwl_fw_error_dump_data);
+
+       if (!trigger || !trigger->num_regions)
+               return 0;
+
+       num = le32_to_cpu(trigger->num_regions);
+       for (i = 0; i < num; i++) {
+               u32 reg_id = le32_to_cpu(trigger->data[i]);
+               struct iwl_fw_ini_region_cfg *reg;
+               enum iwl_fw_ini_region_type type;
+               u32 num_entries;
+
+               if (WARN_ON(reg_id >= ARRAY_SIZE(fwrt->dump.active_regs)))
+                       continue;
+
+               reg = fwrt->dump.active_regs[reg_id].reg;
+               if (WARN(!reg, "Unassigned region %d\n", reg_id))
+                       continue;
+
+               type = le32_to_cpu(reg->region_type);
+               num_entries = le32_to_cpu(reg->num_regions);
+
+               switch (type) {
+               case IWL_FW_INI_REGION_DEVICE_MEMORY:
+                       size += hdr_len +
+                               sizeof(struct iwl_fw_error_dump_named_mem) +
+                               le32_to_cpu(reg->size);
+                       break;
+               case IWL_FW_INI_REGION_PERIPHERY_MAC:
+               case IWL_FW_INI_REGION_PERIPHERY_PHY:
+               case IWL_FW_INI_REGION_PERIPHERY_AUX:
+                       size += num_entries *
+                               (hdr_len +
+                                sizeof(struct iwl_fw_error_dump_prph) +
+                                sizeof(u32));
+                       break;
+               case IWL_FW_INI_REGION_TXF:
+                       size += iwl_fw_txf_len(fwrt, &fwrt->smem_cfg);
+                       break;
+               case IWL_FW_INI_REGION_RXF:
+                       size += iwl_fw_rxf_len(fwrt, &fwrt->smem_cfg);
+                       break;
+               case IWL_FW_INI_REGION_PAGING:
+                       if (!iwl_fw_dbg_is_paging_enabled(fwrt))
+                               break;
+                       size += fwrt->num_of_paging_blk *
+                               (hdr_len +
+                                sizeof(struct iwl_fw_error_dump_paging) +
+                                PAGING_BLOCK_SIZE);
+                       break;
+               case IWL_FW_INI_REGION_CSR:
+                       size += num_entries *
+                               (hdr_len + le32_to_cpu(reg->size));
+                       break;
+               case IWL_FW_INI_REGION_DRAM_BUFFER:
+                       /* Transport takes care of DRAM dumping */
+               case IWL_FW_INI_REGION_INTERNAL_BUFFER:
+               case IWL_FW_INI_REGION_DRAM_IMR:
+                       /* Undefined yet */
+               default:
+                       break;
+               }
+       }
+       return size;
+}
+
+static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt,
+                                   struct iwl_fw_ini_trigger *trigger,
+                                   struct iwl_fw_error_dump_data **data,
+                                   u32 *dump_mask)
+{
+       int i, num = le32_to_cpu(trigger->num_regions);
+
+       for (i = 0; i < num; i++) {
+               u32 reg_id = le32_to_cpu(trigger->data[i]);
+               enum iwl_fw_ini_region_type type;
+               struct iwl_fw_ini_region_cfg *reg;
+
+               if (reg_id >= ARRAY_SIZE(fwrt->dump.active_regs))
+                       continue;
+
+               reg = fwrt->dump.active_regs[reg_id].reg;
+               /* Don't warn, get_trigger_len already warned */
+               if (!reg)
+                       continue;
+
+               type = le32_to_cpu(reg->region_type);
+               switch (type) {
+               case IWL_FW_INI_REGION_DEVICE_MEMORY:
+                       if (WARN_ON(le32_to_cpu(reg->num_regions) > 1))
+                               continue;
+                       iwl_fw_dump_named_mem(fwrt, data,
+                                             le32_to_cpu(reg->size),
+                                             le32_to_cpu(reg->start_addr[0]),
+                                             reg->name,
+                                             le32_to_cpu(reg->name_len));
+                       break;
+               case IWL_FW_INI_REGION_PERIPHERY_MAC:
+               case IWL_FW_INI_REGION_PERIPHERY_PHY:
+               case IWL_FW_INI_REGION_PERIPHERY_AUX:
+                       iwl_dump_prph_ini(fwrt->trans, data, reg);
+                       break;
+               case IWL_FW_INI_REGION_DRAM_BUFFER:
+                       *dump_mask |= IWL_FW_ERROR_DUMP_FW_MONITOR;
+                       break;
+               case IWL_FW_INI_REGION_PAGING:
+                       if (iwl_fw_dbg_is_paging_enabled(fwrt))
+                               iwl_dump_paging(fwrt, data);
+                       else
+                               *dump_mask |= IWL_FW_ERROR_DUMP_PAGING;
+                       break;
+               case IWL_FW_INI_REGION_TXF:
+                       iwl_fw_dump_txf(fwrt, data);
+                       break;
+               case IWL_FW_INI_REGION_RXF:
+                       iwl_fw_dump_rxf(fwrt, data);
+                       break;
+               case IWL_FW_INI_REGION_CSR:
+                       iwl_dump_csr_ini(fwrt->trans, data, reg);
+                       break;
+               case IWL_FW_INI_REGION_DRAM_IMR:
+               case IWL_FW_INI_REGION_INTERNAL_BUFFER:
+                       /* This is undefined yet */
+               default:
+                       break;
+               }
+       }
+}
+
+static struct iwl_fw_error_dump_file *
+_iwl_fw_error_ini_dump(struct iwl_fw_runtime *fwrt,
+                      struct iwl_fw_dump_ptrs *fw_error_dump,
+                      u32 *dump_mask)
+{
+       int size, id = le32_to_cpu(fwrt->dump.desc->trig_desc.type);
+       struct iwl_fw_error_dump_data *dump_data;
+       struct iwl_fw_error_dump_file *dump_file;
+       struct iwl_fw_ini_trigger *trigger, *ext;
+
+       if (id == FW_DBG_TRIGGER_FW_ASSERT)
+               id = IWL_FW_TRIGGER_ID_FW_ASSERT;
+       else if (id == FW_DBG_TRIGGER_USER)
+               id = IWL_FW_TRIGGER_ID_USER_TRIGGER;
+       else if (id < FW_DBG_TRIGGER_MAX)
+               return NULL;
+
+       if (WARN_ON(id >= ARRAY_SIZE(fwrt->dump.active_trigs)))
+               return NULL;
+
+       trigger = fwrt->dump.active_trigs[id].conf;
+       ext = fwrt->dump.active_trigs[id].conf_ext;
+
+       size = sizeof(*dump_file);
+       size += iwl_fw_ini_get_trigger_len(fwrt, trigger);
+       size += iwl_fw_ini_get_trigger_len(fwrt, ext);
+
+       if (!size)
+               return NULL;
+
+       dump_file = vzalloc(size);
+       if (!dump_file)
+               return NULL;
+
+       fw_error_dump->fwrt_ptr = dump_file;
+
+       dump_file->barker = cpu_to_le32(IWL_FW_ERROR_DUMP_BARKER);
+       dump_data = (void *)dump_file->data;
+       dump_file->file_len = cpu_to_le32(size);
+
+       *dump_mask = 0;
+       if (trigger)
+               iwl_fw_ini_dump_trigger(fwrt, trigger, &dump_data, dump_mask);
+       if (ext)
+               iwl_fw_ini_dump_trigger(fwrt, ext, &dump_data, dump_mask);
+
+       return dump_file;
+}
+
 void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
 {
        struct iwl_fw_dump_ptrs *fw_error_dump;
@@ -948,13 +1202,18 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
        if (!fw_error_dump)
                goto out;
 
-       dump_file = _iwl_fw_error_dump(fwrt, fw_error_dump);
+       if (fwrt->trans->ini_valid)
+               dump_file = _iwl_fw_error_ini_dump(fwrt, fw_error_dump,
+                                                  &dump_mask);
+       else
+               dump_file = _iwl_fw_error_dump(fwrt, fw_error_dump);
+
        if (!dump_file) {
                kfree(fw_error_dump);
                goto out;
        }
 
-       if (fwrt->dump.monitor_only)
+       if (!fwrt->trans->ini_valid && fwrt->dump.monitor_only)
                dump_mask &= IWL_FW_ERROR_DUMP_FW_MONITOR;
 
        fw_error_dump->trans_ptr = iwl_trans_dump_data(fwrt->trans, dump_mask);
index ab81ea8b636fdfa4b9773f26f5711d0e4b7c5e24..324ee063224dbc03f5fe83f5e50842468f0e0908 100644 (file)
@@ -329,7 +329,7 @@ void iwl_fw_error_dump_wk(struct work_struct *work);
 
 static inline bool iwl_fw_dbg_type_on(struct iwl_fw_runtime *fwrt, u32 type)
 {
-       return (fwrt->fw->dbg.dump_mask & BIT(type));
+       return (fwrt->fw->dbg.dump_mask & BIT(type) || fwrt->trans->ini_valid);
 }
 
 static inline bool iwl_fw_dbg_is_d3_debug_enabled(struct iwl_fw_runtime *fwrt)
index 6fede174c6649cd6395927ad8b2d43373144d882..cefafc9a082f6ef7d007c16a67e0dcb871e0c8f9 100644 (file)
@@ -249,6 +249,7 @@ struct iwl_fw_error_dump_prph {
 enum iwl_fw_error_dump_mem_type {
        IWL_FW_ERROR_DUMP_MEM_SRAM,
        IWL_FW_ERROR_DUMP_MEM_SMEM,
+       IWL_FW_ERROR_DUMP_MEM_NAMED_MEM = 10,
 };
 
 /**
@@ -263,6 +264,22 @@ struct iwl_fw_error_dump_mem {
        u8 data[];
 };
 
+/**
+ * struct iwl_fw_error_dump_named_mem - chunk of memory
+ * @type: &enum iwl_fw_error_dump_mem_type
+ * @offset: the offset from which the memory was read
+ * @name_len: name length
+ * @name: file name
+ * @data: the content of the memory
+ */
+struct iwl_fw_error_dump_named_mem {
+       __le32 type;
+       __le32 offset;
+       u8 name_len;
+       u8 name[32];
+       u8 data[];
+};
+
 /**
  * struct iwl_fw_error_dump_rb - content of an Receive Buffer
  * @index: the index of the Receive Buffer in the Rx queue
index 2084c63dc670a89537a2a6dc6a6ab69ff73d0c0d..9d89b7d7f9fa3fe3660dcd70e695b88229e31c0f 100644 (file)
 #define MON_BUFF_END_ADDR              (0xa03c40)
 #define MON_BUFF_WRPTR                 (0xa03c44)
 #define MON_BUFF_CYCLE_CNT             (0xa03c48)
+/* FW monitor family 8000 and on */
+#define MON_BUFF_BASE_ADDR_VER2                (0xa03c3c)
+#define MON_BUFF_END_ADDR_VER2         (0xa03c20)
+#define MON_BUFF_WRPTR_VER2            (0xa03c24)
+#define MON_BUFF_CYCLE_CNT_VER2                (0xa03c28)
+#define MON_BUFF_SHIFT_VER2            (0x8)
 
 #define MON_DMARB_RD_CTL_ADDR          (0xa03c60)
 #define MON_DMARB_RD_DATA_ADDR         (0xa03c5c)
index c5168abe107c480adabfd23e1fbece319204b720..443a7df684bd8d533576864db335418b526f4f03 100644 (file)
@@ -1050,11 +1050,13 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
        if (ret)
                IWL_ERR(mvm, "Failed to initialize Smart Fifo\n");
 
-       mvm->fwrt.dump.conf = FW_DBG_INVALID;
-       /* if we have a destination, assume EARLY START */
-       if (mvm->fw->dbg.dest_tlv)
-               mvm->fwrt.dump.conf = FW_DBG_START_FROM_ALIVE;
-       iwl_fw_start_dbg_conf(&mvm->fwrt, FW_DBG_START_FROM_ALIVE);
+       if (!mvm->trans->ini_valid) {
+               mvm->fwrt.dump.conf = FW_DBG_INVALID;
+               /* if we have a destination, assume EARLY START */
+               if (mvm->fw->dbg.dest_tlv)
+                       mvm->fwrt.dump.conf = FW_DBG_START_FROM_ALIVE;
+               iwl_fw_start_dbg_conf(&mvm->fwrt, FW_DBG_START_FROM_ALIVE);
+       }
 
        ret = iwl_send_tx_ant_cfg(mvm, iwl_mvm_get_valid_tx_ant(mvm));
        if (ret)
index 05ed4fb88e0c2c740a99b43426cf7ce334ea478c..ceb3aa03d5618a749dd46be305c47c0f6a37590c 100644 (file)
@@ -94,11 +94,14 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
                cpu_to_le64(trans_pcie->rxq->bd_dma);
 
        /* Configure debug, for integration */
-       iwl_pcie_alloc_fw_monitor(trans, 0);
-       prph_sc_ctrl->hwm_cfg.hwm_base_addr =
-               cpu_to_le64(trans->fw_mon[0].physical);
-       prph_sc_ctrl->hwm_cfg.hwm_size =
-               cpu_to_le32(trans->fw_mon[0].size);
+       if (!trans->ini_valid)
+               iwl_pcie_alloc_fw_monitor(trans, 0);
+       if (trans->num_blocks) {
+               prph_sc_ctrl->hwm_cfg.hwm_base_addr =
+                       cpu_to_le64(trans->fw_mon[0].physical);
+               prph_sc_ctrl->hwm_cfg.hwm_size =
+                       cpu_to_le32(trans->fw_mon[0].size);
+       }
 
        /* allocate ucode sections in dram and set addresses */
        ret = iwl_pcie_init_fw_sec(trans, fw, &prph_scratch->dram);
index 6f45a0303ddd62561efafe942b4be32cac56d635..7f4aaa810ea17450ef2c3e1320e220478ba0082f 100644 (file)
@@ -227,7 +227,7 @@ int iwl_pcie_ctxt_info_init(struct iwl_trans *trans,
        iwl_enable_interrupts(trans);
 
        /* Configure debug, if exists */
-       if (trans->dbg_dest_tlv)
+       if (iwl_pcie_dbg_on(trans))
                iwl_pcie_apply_destination(trans);
 
        /* kick FW self load */
index 0f816761ca45858668bff83b1a85eaec6401205c..d6fc6ce73e0a087f1f43165732606603cec3f366 100644 (file)
@@ -1009,6 +1009,11 @@ static inline void __iwl_trans_pcie_set_bit(struct iwl_trans *trans,
        __iwl_trans_pcie_set_bits_mask(trans, reg, mask, mask);
 }
 
+static inline bool iwl_pcie_dbg_on(struct iwl_trans *trans)
+{
+       return (trans->dbg_dest_tlv || trans->ini_valid);
+}
+
 void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state);
 void iwl_trans_pcie_dump_regs(struct iwl_trans *trans);
 
index 166bacc5ea543a1383835a9101c1ed74b397cbea..f97aea5ffc44e4398754d020ef347238d387a3fb 100644 (file)
@@ -924,6 +924,20 @@ void iwl_pcie_apply_destination(struct iwl_trans *trans)
        const struct iwl_fw_dbg_dest_tlv_v1 *dest = trans->dbg_dest_tlv;
        int i;
 
+       if (trans->ini_valid) {
+               if (!trans->num_blocks)
+                       return;
+
+               iwl_write_prph(trans, MON_BUFF_BASE_ADDR_VER2,
+                              trans->fw_mon[0].physical >>
+                              MON_BUFF_SHIFT_VER2);
+               iwl_write_prph(trans, MON_BUFF_END_ADDR_VER2,
+                              (trans->fw_mon[0].physical +
+                               trans->fw_mon[0].size - 256) >>
+                              MON_BUFF_SHIFT_VER2);
+               return;
+       }
+
        IWL_INFO(trans, "Applying debug destination %s\n",
                 get_fw_dbg_mode_string(dest->monitor_mode));
 
@@ -1026,7 +1040,7 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
                                       (trans->fw_mon[0].physical +
                                        trans->fw_mon[0].size) >> 4);
                }
-       } else if (trans->dbg_dest_tlv) {
+       } else if (iwl_pcie_dbg_on(trans)) {
                iwl_pcie_apply_destination(trans);
        }
 
@@ -1047,7 +1061,7 @@ static int iwl_pcie_load_given_ucode_8000(struct iwl_trans *trans,
        IWL_DEBUG_FW(trans, "working with %s CPU\n",
                     image->is_dual_cpus ? "Dual" : "Single");
 
-       if (trans->dbg_dest_tlv)
+       if (iwl_pcie_dbg_on(trans))
                iwl_pcie_apply_destination(trans);
 
        IWL_DEBUG_POWER(trans, "Original WFPM value = 0x%08X\n",
@@ -3015,6 +3029,34 @@ iwl_trans_pci_dump_marbh_monitor(struct iwl_trans *trans,
        return monitor_len;
 }
 
+static void
+iwl_trans_pcie_dump_pointers(struct iwl_trans *trans,
+                            struct iwl_fw_error_dump_fw_mon *fw_mon_data)
+{
+       u32 base, write_ptr, wrap_cnt;
+
+       /* If there was a dest TLV - use the values from there */
+       if (trans->ini_valid) {
+               base = MON_BUFF_BASE_ADDR_VER2;
+               write_ptr = MON_BUFF_WRPTR_VER2;
+               wrap_cnt = MON_BUFF_CYCLE_CNT_VER2;
+       } else if (trans->dbg_dest_tlv) {
+               write_ptr = le32_to_cpu(trans->dbg_dest_tlv->write_ptr_reg);
+               wrap_cnt = le32_to_cpu(trans->dbg_dest_tlv->wrap_count);
+               base = le32_to_cpu(trans->dbg_dest_tlv->base_reg);
+       } else {
+               base = MON_BUFF_BASE_ADDR;
+               write_ptr = MON_BUFF_WRPTR;
+               wrap_cnt = MON_BUFF_CYCLE_CNT;
+       }
+       fw_mon_data->fw_mon_wr_ptr =
+               cpu_to_le32(iwl_read_prph(trans, write_ptr));
+       fw_mon_data->fw_mon_cycle_cnt =
+               cpu_to_le32(iwl_read_prph(trans, wrap_cnt));
+       fw_mon_data->fw_mon_base_ptr =
+               cpu_to_le32(iwl_read_prph(trans, base));
+}
+
 static u32
 iwl_trans_pcie_dump_monitor(struct iwl_trans *trans,
                            struct iwl_fw_error_dump_data **data,
@@ -3024,30 +3066,14 @@ iwl_trans_pcie_dump_monitor(struct iwl_trans *trans,
 
        if ((trans->num_blocks &&
             trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) ||
-           trans->dbg_dest_tlv) {
+            (trans->dbg_dest_tlv && !trans->ini_valid) ||
+            (trans->ini_valid && trans->num_blocks)) {
                struct iwl_fw_error_dump_fw_mon *fw_mon_data;
-               u32 base, write_ptr, wrap_cnt;
-
-               /* If there was a dest TLV - use the values from there */
-               if (trans->dbg_dest_tlv) {
-                       write_ptr =
-                               le32_to_cpu(trans->dbg_dest_tlv->write_ptr_reg);
-                       wrap_cnt = le32_to_cpu(trans->dbg_dest_tlv->wrap_count);
-                       base = le32_to_cpu(trans->dbg_dest_tlv->base_reg);
-               } else {
-                       base = MON_BUFF_BASE_ADDR;
-                       write_ptr = MON_BUFF_WRPTR;
-                       wrap_cnt = MON_BUFF_CYCLE_CNT;
-               }
 
                (*data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_FW_MONITOR);
                fw_mon_data = (void *)(*data)->data;
-               fw_mon_data->fw_mon_wr_ptr =
-                       cpu_to_le32(iwl_read_prph(trans, write_ptr));
-               fw_mon_data->fw_mon_cycle_cnt =
-                       cpu_to_le32(iwl_read_prph(trans, wrap_cnt));
-               fw_mon_data->fw_mon_base_ptr =
-                       cpu_to_le32(iwl_read_prph(trans, base));
+
+               iwl_trans_pcie_dump_pointers(trans, fw_mon_data);
 
                len += sizeof(**data) + sizeof(*fw_mon_data);
                if (trans->num_blocks) {
@@ -3057,6 +3083,7 @@ iwl_trans_pcie_dump_monitor(struct iwl_trans *trans,
 
                        monitor_len = trans->fw_mon[0].size;
                } else if (trans->dbg_dest_tlv->monitor_mode == SMEM_MODE) {
+                       u32 base = le32_to_cpu(fw_mon_data->fw_mon_base_ptr);
                        /*
                         * Update pointers to reflect actual values after
                         * shifting