|
@@ -78,6 +78,7 @@
|
|
|
#include "iwl-agn-hw.h"
|
|
|
#include "iwl-fw-error-dump.h"
|
|
|
#include "internal.h"
|
|
|
+#include "iwl-fh.h"
|
|
|
|
|
|
/* extended range in FW SRAM */
|
|
|
#define IWL_FW_MEM_EXTENDED_START 0x40000
|
|
@@ -665,14 +666,14 @@ static int iwl_pcie_load_section(struct iwl_trans *trans, u8 section_num,
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-static int iwl_pcie_load_cpu_secured_sections(struct iwl_trans *trans,
|
|
|
- const struct fw_img *image,
|
|
|
- int cpu,
|
|
|
- int *first_ucode_section)
|
|
|
+static int iwl_pcie_load_cpu_sections_8000b(struct iwl_trans *trans,
|
|
|
+ const struct fw_img *image,
|
|
|
+ int cpu,
|
|
|
+ int *first_ucode_section)
|
|
|
{
|
|
|
int shift_param;
|
|
|
- int i, ret = 0;
|
|
|
- u32 last_read_idx = 0;
|
|
|
+ int i, ret = 0, sec_num = 0x1;
|
|
|
+ u32 val, last_read_idx = 0;
|
|
|
|
|
|
if (cpu == 1) {
|
|
|
shift_param = 0;
|
|
@@ -693,21 +694,16 @@ static int iwl_pcie_load_cpu_secured_sections(struct iwl_trans *trans,
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- if (i == (*first_ucode_section) + 1)
|
|
|
- /* set CPU to started */
|
|
|
- iwl_set_bits_prph(trans,
|
|
|
- CSR_UCODE_LOAD_STATUS_ADDR,
|
|
|
- LMPM_CPU_HDRS_LOADING_COMPLETED
|
|
|
- << shift_param);
|
|
|
-
|
|
|
ret = iwl_pcie_load_section(trans, i, &image->sec[i]);
|
|
|
if (ret)
|
|
|
return ret;
|
|
|
+
|
|
|
+ /* Notify the ucode of the loaded section number and status */
|
|
|
+ val = iwl_read_direct32(trans, FH_UCODE_LOAD_STATUS);
|
|
|
+ val = val | (sec_num << shift_param);
|
|
|
+ iwl_write_direct32(trans, FH_UCODE_LOAD_STATUS, val);
|
|
|
+ sec_num = (sec_num << 1) | 0x1;
|
|
|
}
|
|
|
- /* image loading complete */
|
|
|
- iwl_set_bits_prph(trans,
|
|
|
- CSR_UCODE_LOAD_STATUS_ADDR,
|
|
|
- LMPM_CPU_UCODE_LOADING_COMPLETED << shift_param);
|
|
|
|
|
|
*first_ucode_section = last_read_idx;
|
|
|
|
|
@@ -760,46 +756,78 @@ static int iwl_pcie_load_cpu_sections(struct iwl_trans *trans,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
|
|
|
- const struct fw_img *image)
|
|
|
+static void iwl_pcie_apply_destination(struct iwl_trans *trans)
|
|
|
{
|
|
|
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
|
|
- int ret = 0;
|
|
|
- int first_ucode_section;
|
|
|
+ const struct iwl_fw_dbg_dest_tlv *dest = trans->dbg_dest_tlv;
|
|
|
+ int i;
|
|
|
|
|
|
- IWL_DEBUG_FW(trans,
|
|
|
- "working with %s CPU\n",
|
|
|
- image->is_dual_cpus ? "Dual" : "Single");
|
|
|
+ if (dest->version)
|
|
|
+ IWL_ERR(trans,
|
|
|
+ "DBG DEST version is %d - expect issues\n",
|
|
|
+ dest->version);
|
|
|
|
|
|
- /* configure the ucode to be ready to get the secured image */
|
|
|
- if (iwl_has_secure_boot(trans->hw_rev, trans->cfg->device_family)) {
|
|
|
- /* set secure boot inspector addresses */
|
|
|
- iwl_write_prph(trans,
|
|
|
- LMPM_SECURE_INSPECTOR_CODE_ADDR,
|
|
|
- LMPM_SECURE_INSPECTOR_CODE_MEM_SPACE);
|
|
|
+ IWL_INFO(trans, "Applying debug destination %s\n",
|
|
|
+ get_fw_dbg_mode_string(dest->monitor_mode));
|
|
|
|
|
|
- iwl_write_prph(trans,
|
|
|
- LMPM_SECURE_INSPECTOR_DATA_ADDR,
|
|
|
- LMPM_SECURE_INSPECTOR_DATA_MEM_SPACE);
|
|
|
+ if (dest->monitor_mode == EXTERNAL_MODE)
|
|
|
+ iwl_pcie_alloc_fw_monitor(trans);
|
|
|
+ else
|
|
|
+ IWL_WARN(trans, "PCI should have external buffer debug\n");
|
|
|
|
|
|
- /* set CPU1 header address */
|
|
|
- iwl_write_prph(trans,
|
|
|
- LMPM_SECURE_UCODE_LOAD_CPU1_HDR_ADDR,
|
|
|
- LMPM_SECURE_CPU1_HDR_MEM_SPACE);
|
|
|
+ for (i = 0; i < trans->dbg_dest_reg_num; i++) {
|
|
|
+ u32 addr = le32_to_cpu(dest->reg_ops[i].addr);
|
|
|
+ u32 val = le32_to_cpu(dest->reg_ops[i].val);
|
|
|
|
|
|
- /* load to FW the binary Secured sections of CPU1 */
|
|
|
- ret = iwl_pcie_load_cpu_secured_sections(trans, image, 1,
|
|
|
- &first_ucode_section);
|
|
|
- if (ret)
|
|
|
- return ret;
|
|
|
+ switch (dest->reg_ops[i].op) {
|
|
|
+ case CSR_ASSIGN:
|
|
|
+ iwl_write32(trans, addr, val);
|
|
|
+ break;
|
|
|
+ case CSR_SETBIT:
|
|
|
+ iwl_set_bit(trans, addr, BIT(val));
|
|
|
+ break;
|
|
|
+ case CSR_CLEARBIT:
|
|
|
+ iwl_clear_bit(trans, addr, BIT(val));
|
|
|
+ break;
|
|
|
+ case PRPH_ASSIGN:
|
|
|
+ iwl_write_prph(trans, addr, val);
|
|
|
+ break;
|
|
|
+ case PRPH_SETBIT:
|
|
|
+ iwl_set_bits_prph(trans, addr, BIT(val));
|
|
|
+ break;
|
|
|
+ case PRPH_CLEARBIT:
|
|
|
+ iwl_clear_bits_prph(trans, addr, BIT(val));
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ IWL_ERR(trans, "FW debug - unknown OP %d\n",
|
|
|
+ dest->reg_ops[i].op);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- } else {
|
|
|
- /* load to FW the binary Non secured sections of CPU1 */
|
|
|
- ret = iwl_pcie_load_cpu_sections(trans, image, 1,
|
|
|
- &first_ucode_section);
|
|
|
- if (ret)
|
|
|
- return ret;
|
|
|
+ if (dest->monitor_mode == EXTERNAL_MODE && trans_pcie->fw_mon_size) {
|
|
|
+ iwl_write_prph(trans, le32_to_cpu(dest->base_reg),
|
|
|
+ trans_pcie->fw_mon_phys >> dest->base_shift);
|
|
|
+ iwl_write_prph(trans, le32_to_cpu(dest->end_reg),
|
|
|
+ (trans_pcie->fw_mon_phys +
|
|
|
+ trans_pcie->fw_mon_size) >> dest->end_shift);
|
|
|
}
|
|
|
+}
|
|
|
+
|
|
|
+static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
|
|
|
+ const struct fw_img *image)
|
|
|
+{
|
|
|
+ struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
|
|
+ int ret = 0;
|
|
|
+ int first_ucode_section;
|
|
|
+
|
|
|
+ IWL_DEBUG_FW(trans, "working with %s CPU\n",
|
|
|
+ image->is_dual_cpus ? "Dual" : "Single");
|
|
|
+
|
|
|
+ /* load to FW the binary non secured sections of CPU1 */
|
|
|
+ ret = iwl_pcie_load_cpu_sections(trans, image, 1, &first_ucode_section);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
|
|
|
if (image->is_dual_cpus) {
|
|
|
/* set CPU2 header address */
|
|
@@ -808,14 +836,8 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
|
|
|
LMPM_SECURE_CPU2_HDR_MEM_SPACE);
|
|
|
|
|
|
/* load to FW the binary sections of CPU2 */
|
|
|
- if (iwl_has_secure_boot(trans->hw_rev,
|
|
|
- trans->cfg->device_family))
|
|
|
- ret = iwl_pcie_load_cpu_secured_sections(
|
|
|
- trans, image, 2,
|
|
|
- &first_ucode_section);
|
|
|
- else
|
|
|
- ret = iwl_pcie_load_cpu_sections(trans, image, 2,
|
|
|
- &first_ucode_section);
|
|
|
+ ret = iwl_pcie_load_cpu_sections(trans, image, 2,
|
|
|
+ &first_ucode_section);
|
|
|
if (ret)
|
|
|
return ret;
|
|
|
}
|
|
@@ -832,6 +854,8 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
|
|
|
(trans_pcie->fw_mon_phys +
|
|
|
trans_pcie->fw_mon_size) >> 4);
|
|
|
}
|
|
|
+ } else if (trans->dbg_dest_tlv) {
|
|
|
+ iwl_pcie_apply_destination(trans);
|
|
|
}
|
|
|
|
|
|
/* release CPU reset */
|
|
@@ -840,18 +864,50 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
|
|
|
else
|
|
|
iwl_write32(trans, CSR_RESET, 0);
|
|
|
|
|
|
- if (iwl_has_secure_boot(trans->hw_rev, trans->cfg->device_family)) {
|
|
|
- /* wait for image verification to complete */
|
|
|
- ret = iwl_poll_prph_bit(trans,
|
|
|
- LMPM_SECURE_BOOT_CPU1_STATUS_ADDR,
|
|
|
- LMPM_SECURE_BOOT_STATUS_SUCCESS,
|
|
|
- LMPM_SECURE_BOOT_STATUS_SUCCESS,
|
|
|
- LMPM_SECURE_TIME_OUT);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
|
|
|
- if (ret < 0) {
|
|
|
- IWL_ERR(trans, "Time out on secure boot process\n");
|
|
|
- return ret;
|
|
|
- }
|
|
|
+static int iwl_pcie_load_given_ucode_8000b(struct iwl_trans *trans,
|
|
|
+ const struct fw_img *image)
|
|
|
+{
|
|
|
+ int ret = 0;
|
|
|
+ int first_ucode_section;
|
|
|
+ u32 reg;
|
|
|
+
|
|
|
+ IWL_DEBUG_FW(trans, "working with %s CPU\n",
|
|
|
+ image->is_dual_cpus ? "Dual" : "Single");
|
|
|
+
|
|
|
+ /* configure the ucode to be ready to get the secured image */
|
|
|
+ /* release CPU reset */
|
|
|
+ iwl_write_prph(trans, RELEASE_CPU_RESET, RELEASE_CPU_RESET_BIT);
|
|
|
+
|
|
|
+ /* load to FW the binary Secured sections of CPU1 */
|
|
|
+ ret = iwl_pcie_load_cpu_sections_8000b(trans, image, 1,
|
|
|
+ &first_ucode_section);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ /* load to FW the binary sections of CPU2 */
|
|
|
+ ret = iwl_pcie_load_cpu_sections_8000b(trans, image, 2,
|
|
|
+ &first_ucode_section);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ /* Notify FW loading is done */
|
|
|
+ iwl_write_direct32(trans, FH_UCODE_LOAD_STATUS, 0xFFFFFFFF);
|
|
|
+
|
|
|
+ /* wait for image verification to complete */
|
|
|
+ ret = iwl_poll_prph_bit(trans, LMPM_SECURE_BOOT_CPU1_STATUS_ADDR_B0,
|
|
|
+ LMPM_SECURE_BOOT_STATUS_SUCCESS,
|
|
|
+ LMPM_SECURE_BOOT_STATUS_SUCCESS,
|
|
|
+ LMPM_SECURE_TIME_OUT);
|
|
|
+ if (ret < 0) {
|
|
|
+ reg = iwl_read_prph(trans,
|
|
|
+ LMPM_SECURE_BOOT_CPU1_STATUS_ADDR_B0);
|
|
|
+
|
|
|
+ IWL_ERR(trans, "Timeout on secure boot process, reg = %x\n",
|
|
|
+ reg);
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
@@ -903,7 +959,11 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
|
|
|
iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
|
|
|
|
|
|
/* Load the given image to the HW */
|
|
|
- return iwl_pcie_load_given_ucode(trans, fw);
|
|
|
+ if ((trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) &&
|
|
|
+ (CSR_HW_REV_STEP(trans->hw_rev) == SILICON_B_STEP))
|
|
|
+ return iwl_pcie_load_given_ucode_8000b(trans, fw);
|
|
|
+ else
|
|
|
+ return iwl_pcie_load_given_ucode(trans, fw);
|
|
|
}
|
|
|
|
|
|
static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans, u32 scd_addr)
|
|
@@ -994,6 +1054,9 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
|
|
|
clear_bit(STATUS_RFKILL, &trans->status);
|
|
|
if (hw_rfkill != was_hw_rfkill)
|
|
|
iwl_trans_pcie_rf_kill(trans, hw_rfkill);
|
|
|
+
|
|
|
+ /* re-take ownership to prevent other users from stealing the deivce */
|
|
|
+ iwl_pcie_prepare_card_hw(trans);
|
|
|
}
|
|
|
|
|
|
void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state)
|
|
@@ -1968,6 +2031,31 @@ static u32 iwl_trans_pcie_dump_csr(struct iwl_trans *trans,
|
|
|
return csr_len;
|
|
|
}
|
|
|
|
|
|
+static u32 iwl_trans_pcie_fh_regs_dump(struct iwl_trans *trans,
|
|
|
+ struct iwl_fw_error_dump_data **data)
|
|
|
+{
|
|
|
+ u32 fh_regs_len = FH_MEM_UPPER_BOUND - FH_MEM_LOWER_BOUND;
|
|
|
+ unsigned long flags;
|
|
|
+ __le32 *val;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ if (!iwl_trans_grab_nic_access(trans, false, &flags))
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ (*data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_FH_REGS);
|
|
|
+ (*data)->len = cpu_to_le32(fh_regs_len);
|
|
|
+ val = (void *)(*data)->data;
|
|
|
+
|
|
|
+ for (i = FH_MEM_LOWER_BOUND; i < FH_MEM_UPPER_BOUND; i += sizeof(u32))
|
|
|
+ *val++ = cpu_to_le32(iwl_trans_pcie_read32(trans, i));
|
|
|
+
|
|
|
+ iwl_trans_release_nic_access(trans, &flags);
|
|
|
+
|
|
|
+ *data = iwl_fw_error_next_data(*data);
|
|
|
+
|
|
|
+ return sizeof(**data) + fh_regs_len;
|
|
|
+}
|
|
|
+
|
|
|
static
|
|
|
struct iwl_trans_dump_data *iwl_trans_pcie_dump_data(struct iwl_trans *trans)
|
|
|
{
|
|
@@ -1977,6 +2065,7 @@ struct iwl_trans_dump_data *iwl_trans_pcie_dump_data(struct iwl_trans *trans)
|
|
|
struct iwl_fw_error_dump_txcmd *txcmd;
|
|
|
struct iwl_trans_dump_data *dump_data;
|
|
|
u32 len;
|
|
|
+ u32 monitor_len;
|
|
|
int i, ptr;
|
|
|
|
|
|
/* transport dump header */
|
|
@@ -1999,10 +2088,34 @@ struct iwl_trans_dump_data *iwl_trans_pcie_dump_data(struct iwl_trans *trans)
|
|
|
num_bytes_in_chunk;
|
|
|
}
|
|
|
|
|
|
+ /* FH registers */
|
|
|
+ len += sizeof(*data) + (FH_MEM_UPPER_BOUND - FH_MEM_LOWER_BOUND);
|
|
|
+
|
|
|
/* FW monitor */
|
|
|
- if (trans_pcie->fw_mon_page)
|
|
|
+ if (trans_pcie->fw_mon_page) {
|
|
|
len += sizeof(*data) + sizeof(struct iwl_fw_error_dump_fw_mon) +
|
|
|
- trans_pcie->fw_mon_size;
|
|
|
+ trans_pcie->fw_mon_size;
|
|
|
+ monitor_len = trans_pcie->fw_mon_size;
|
|
|
+ } else if (trans->dbg_dest_tlv) {
|
|
|
+ u32 base, end;
|
|
|
+
|
|
|
+ base = le32_to_cpu(trans->dbg_dest_tlv->base_reg);
|
|
|
+ end = le32_to_cpu(trans->dbg_dest_tlv->end_reg);
|
|
|
+
|
|
|
+ base = iwl_read_prph(trans, base) <<
|
|
|
+ trans->dbg_dest_tlv->base_shift;
|
|
|
+ end = iwl_read_prph(trans, end) <<
|
|
|
+ trans->dbg_dest_tlv->end_shift;
|
|
|
+
|
|
|
+ /* Make "end" point to the actual end */
|
|
|
+ if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
|
|
|
+ end += (1 << trans->dbg_dest_tlv->end_shift);
|
|
|
+ monitor_len = end - base;
|
|
|
+ len += sizeof(*data) + sizeof(struct iwl_fw_error_dump_fw_mon) +
|
|
|
+ monitor_len;
|
|
|
+ } else {
|
|
|
+ monitor_len = 0;
|
|
|
+ }
|
|
|
|
|
|
dump_data = vzalloc(len);
|
|
|
if (!dump_data)
|
|
@@ -2039,36 +2152,71 @@ struct iwl_trans_dump_data *iwl_trans_pcie_dump_data(struct iwl_trans *trans)
|
|
|
|
|
|
len += iwl_trans_pcie_dump_prph(trans, &data);
|
|
|
len += iwl_trans_pcie_dump_csr(trans, &data);
|
|
|
+ len += iwl_trans_pcie_fh_regs_dump(trans, &data);
|
|
|
/* data is already pointing to the next section */
|
|
|
|
|
|
- if (trans_pcie->fw_mon_page) {
|
|
|
+ if ((trans_pcie->fw_mon_page &&
|
|
|
+ trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) ||
|
|
|
+ trans->dbg_dest_tlv) {
|
|
|
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);
|
|
|
- data->len = cpu_to_le32(trans_pcie->fw_mon_size +
|
|
|
- sizeof(*fw_mon_data));
|
|
|
fw_mon_data = (void *)data->data;
|
|
|
fw_mon_data->fw_mon_wr_ptr =
|
|
|
- cpu_to_le32(iwl_read_prph(trans, MON_BUFF_WRPTR));
|
|
|
+ cpu_to_le32(iwl_read_prph(trans, write_ptr));
|
|
|
fw_mon_data->fw_mon_cycle_cnt =
|
|
|
- cpu_to_le32(iwl_read_prph(trans, MON_BUFF_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, MON_BUFF_BASE_ADDR));
|
|
|
-
|
|
|
- /*
|
|
|
- * The firmware is now asserted, it won't write anything to
|
|
|
- * the buffer. CPU can take ownership to fetch the data.
|
|
|
- * The buffer will be handed back to the device before the
|
|
|
- * firmware will be restarted.
|
|
|
- */
|
|
|
- dma_sync_single_for_cpu(trans->dev, trans_pcie->fw_mon_phys,
|
|
|
- trans_pcie->fw_mon_size,
|
|
|
- DMA_FROM_DEVICE);
|
|
|
- memcpy(fw_mon_data->data, page_address(trans_pcie->fw_mon_page),
|
|
|
- trans_pcie->fw_mon_size);
|
|
|
-
|
|
|
- len += sizeof(*data) + sizeof(*fw_mon_data) +
|
|
|
- trans_pcie->fw_mon_size;
|
|
|
+ cpu_to_le32(iwl_read_prph(trans, base));
|
|
|
+
|
|
|
+ len += sizeof(*data) + sizeof(*fw_mon_data);
|
|
|
+ if (trans_pcie->fw_mon_page) {
|
|
|
+ data->len = cpu_to_le32(trans_pcie->fw_mon_size +
|
|
|
+ sizeof(*fw_mon_data));
|
|
|
+
|
|
|
+ /*
|
|
|
+ * The firmware is now asserted, it won't write anything
|
|
|
+ * to the buffer. CPU can take ownership to fetch the
|
|
|
+ * data. The buffer will be handed back to the device
|
|
|
+ * before the firmware will be restarted.
|
|
|
+ */
|
|
|
+ dma_sync_single_for_cpu(trans->dev,
|
|
|
+ trans_pcie->fw_mon_phys,
|
|
|
+ trans_pcie->fw_mon_size,
|
|
|
+ DMA_FROM_DEVICE);
|
|
|
+ memcpy(fw_mon_data->data,
|
|
|
+ page_address(trans_pcie->fw_mon_page),
|
|
|
+ trans_pcie->fw_mon_size);
|
|
|
+
|
|
|
+ len += trans_pcie->fw_mon_size;
|
|
|
+ } else {
|
|
|
+ /* If we are here then the buffer is internal */
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Update pointers to reflect actual values after
|
|
|
+ * shifting
|
|
|
+ */
|
|
|
+ base = iwl_read_prph(trans, base) <<
|
|
|
+ trans->dbg_dest_tlv->base_shift;
|
|
|
+ iwl_trans_read_mem(trans, base, fw_mon_data->data,
|
|
|
+ monitor_len / sizeof(u32));
|
|
|
+ data->len = cpu_to_le32(sizeof(*fw_mon_data) +
|
|
|
+ monitor_len);
|
|
|
+ len += monitor_len;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
dump_data->len = len;
|