diff options
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/fw/dbg.c')
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 284 |
1 files changed, 165 insertions, 119 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index fa283285fcbe..a31a42e673c4 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -243,39 +243,47 @@ static void iwl_fw_dump_fifos(struct iwl_fw_runtime *fwrt, if (!iwl_trans_grab_nic_access(fwrt->trans, &flags)) return; - /* Pull RXF1 */ - iwl_fwrt_dump_rxf(fwrt, dump_data, cfg->lmac[0].rxfifo1_size, 0, 0); - /* Pull RXF2 */ - iwl_fwrt_dump_rxf(fwrt, dump_data, cfg->rxfifo2_size, - RXF_DIFF_FROM_PREV, 1); - /* Pull LMAC2 RXF1 */ - if (fwrt->smem_cfg.num_lmacs > 1) - iwl_fwrt_dump_rxf(fwrt, dump_data, cfg->lmac[1].rxfifo1_size, - LMAC2_PRPH_OFFSET, 2); - - /* Pull TXF data from LMAC1 */ - for (i = 0; i < fwrt->smem_cfg.num_txfifo_entries; i++) { - /* Mark the number of TXF we're pulling now */ - iwl_trans_write_prph(fwrt->trans, TXF_LARC_NUM, i); - iwl_fwrt_dump_txf(fwrt, dump_data, cfg->lmac[0].txfifo_size[i], - 0, i); + if (fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_RXF)) { + /* Pull RXF1 */ + iwl_fwrt_dump_rxf(fwrt, dump_data, + cfg->lmac[0].rxfifo1_size, 0, 0); + /* Pull RXF2 */ + iwl_fwrt_dump_rxf(fwrt, dump_data, cfg->rxfifo2_size, + RXF_DIFF_FROM_PREV, 1); + /* Pull LMAC2 RXF1 */ + if (fwrt->smem_cfg.num_lmacs > 1) + iwl_fwrt_dump_rxf(fwrt, dump_data, + cfg->lmac[1].rxfifo1_size, + LMAC2_PRPH_OFFSET, 2); } - /* Pull TXF data from LMAC2 */ - if (fwrt->smem_cfg.num_lmacs > 1) { + if (fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_TXF)) { + /* Pull TXF data from LMAC1 */ for (i = 0; i < fwrt->smem_cfg.num_txfifo_entries; i++) { /* Mark the number of TXF we're pulling now */ - iwl_trans_write_prph(fwrt->trans, - TXF_LARC_NUM + LMAC2_PRPH_OFFSET, - i); + iwl_trans_write_prph(fwrt->trans, TXF_LARC_NUM, i); iwl_fwrt_dump_txf(fwrt, dump_data, - cfg->lmac[1].txfifo_size[i], - LMAC2_PRPH_OFFSET, - i + cfg->num_txfifo_entries); + cfg->lmac[0].txfifo_size[i], 0, i); + } + + /* Pull TXF data from LMAC2 */ + if (fwrt->smem_cfg.num_lmacs > 1) { + for (i = 0; i < fwrt->smem_cfg.num_txfifo_entries; + i++) { + /* Mark the number of TXF we're pulling now */ + iwl_trans_write_prph(fwrt->trans, + TXF_LARC_NUM + + LMAC2_PRPH_OFFSET, i); + iwl_fwrt_dump_txf(fwrt, dump_data, + cfg->lmac[1].txfifo_size[i], + LMAC2_PRPH_OFFSET, + i + cfg->num_txfifo_entries); + } } } - if (fw_has_capa(&fwrt->fw->ucode_capa, + if (fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_INTERNAL_TXF) && + fw_has_capa(&fwrt->fw->ucode_capa, IWL_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG)) { /* Pull UMAC internal TXF data from all TXFs */ for (i = 0; @@ -600,42 +608,54 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt) if (test_bit(STATUS_FW_ERROR, &fwrt->trans->status)) { fifo_data_len = 0; - /* Count RXF2 size */ - if (mem_cfg->rxfifo2_size) { - /* Add header info */ - fifo_data_len += mem_cfg->rxfifo2_size + - sizeof(*dump_data) + - sizeof(struct iwl_fw_error_dump_fifo); - } - - /* Count RXF1 sizes */ - for (i = 0; i < mem_cfg->num_lmacs; i++) { - if (!mem_cfg->lmac[i].rxfifo1_size) - continue; - - /* Add header info */ - fifo_data_len += mem_cfg->lmac[i].rxfifo1_size + - sizeof(*dump_data) + - sizeof(struct iwl_fw_error_dump_fifo); - } + if (fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_RXF)) { - /* Count TXF sizes */ - for (i = 0; i < mem_cfg->num_lmacs; i++) { - int j; + /* Count RXF2 size */ + if (mem_cfg->rxfifo2_size) { + /* Add header info */ + fifo_data_len += + mem_cfg->rxfifo2_size + + sizeof(*dump_data) + + sizeof(struct iwl_fw_error_dump_fifo); + } - for (j = 0; j < mem_cfg->num_txfifo_entries; j++) { - if (!mem_cfg->lmac[i].txfifo_size[j]) + /* Count RXF1 sizes */ + for (i = 0; i < mem_cfg->num_lmacs; i++) { + if (!mem_cfg->lmac[i].rxfifo1_size) continue; /* Add header info */ fifo_data_len += - mem_cfg->lmac[i].txfifo_size[j] + + mem_cfg->lmac[i].rxfifo1_size + sizeof(*dump_data) + sizeof(struct iwl_fw_error_dump_fifo); } } - if (fw_has_capa(&fwrt->fw->ucode_capa, + if (fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_TXF)) { + size_t fifo_const_len = sizeof(*dump_data) + + sizeof(struct iwl_fw_error_dump_fifo); + + /* Count TXF sizes */ + for (i = 0; i < mem_cfg->num_lmacs; i++) { + int j; + + for (j = 0; j < mem_cfg->num_txfifo_entries; + j++) { + if (!mem_cfg->lmac[i].txfifo_size[j]) + continue; + + /* Add header info */ + fifo_data_len += + fifo_const_len + + mem_cfg->lmac[i].txfifo_size[j]; + } + } + } + + if ((fwrt->fw->dbg_dump_mask & + BIT(IWL_FW_ERROR_DUMP_INTERNAL_TXF)) && + fw_has_capa(&fwrt->fw->ucode_capa, IWL_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG)) { for (i = 0; i < ARRAY_SIZE(mem_cfg->internal_txfifo_size); @@ -652,7 +672,8 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt) } /* Make room for PRPH registers */ - if (!fwrt->trans->cfg->gen2) { + if (!fwrt->trans->cfg->gen2 && + fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_PRPH)) { for (i = 0; i < ARRAY_SIZE(iwl_prph_dump_addr_comm); i++) { /* The range includes both boundaries */ @@ -667,7 +688,8 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt) } if (!fwrt->trans->cfg->gen2 && - fwrt->trans->cfg->mq_rx_supported) { + fwrt->trans->cfg->mq_rx_supported && + fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_PRPH)) { for (i = 0; i < ARRAY_SIZE(iwl_prph_dump_addr_9000); i++) { /* The range includes both boundaries */ @@ -681,34 +703,42 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt) } } - if (fwrt->trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) + if (fwrt->trans->cfg->device_family == IWL_DEVICE_FAMILY_7000 && + fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_RADIO_REG)) radio_len = sizeof(*dump_data) + RADIO_REG_MAX_READ; } file_len = sizeof(*dump_file) + - sizeof(*dump_data) * 3 + - sizeof(*dump_smem_cfg) + fifo_data_len + prph_len + - radio_len + - sizeof(*dump_info); - - /* Make room for the SMEM, if it exists */ - if (smem_len) - file_len += sizeof(*dump_data) + sizeof(*dump_mem) + smem_len; - - /* Make room for the secondary SRAM, if it exists */ - if (sram2_len) - file_len += sizeof(*dump_data) + sizeof(*dump_mem) + sram2_len; - - /* Make room for MEM segments */ - for (i = 0; i < fwrt->fw->n_dbg_mem_tlv; i++) { - file_len += sizeof(*dump_data) + sizeof(*dump_mem) + - le32_to_cpu(fw_dbg_mem[i].len); + radio_len; + + if (fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_DEV_FW_INFO)) + file_len += sizeof(*dump_data) + sizeof(*dump_info); + if (fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_MEM_CFG)) + file_len += sizeof(*dump_data) + sizeof(*dump_smem_cfg); + + if (fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_MEM)) { + /* Make room for the SMEM, if it exists */ + if (smem_len) + file_len += sizeof(*dump_data) + sizeof(*dump_mem) + + smem_len; + + /* Make room for the secondary SRAM, if it exists */ + if (sram2_len) + file_len += sizeof(*dump_data) + sizeof(*dump_mem) + + sram2_len; + + /* Make room for MEM segments */ + for (i = 0; i < fwrt->fw->n_dbg_mem_tlv; i++) { + file_len += sizeof(*dump_data) + sizeof(*dump_mem) + + le32_to_cpu(fw_dbg_mem[i].len); + } } /* Make room for fw's virtual image pages, if it exists */ - if (!fwrt->trans->cfg->gen2 && + if (fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_PAGING) && + !fwrt->trans->cfg->gen2 && fwrt->fw->img[fwrt->cur_fw_img].paging_mem_size && fwrt->fw_paging_db[0].fw_paging_block) file_len += fwrt->num_of_paging_blk * @@ -722,12 +752,14 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt) sizeof(*dump_info) + sizeof(*dump_smem_cfg); } - if (fwrt->dump.desc) + if (fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_ERROR_INFO) && + fwrt->dump.desc) file_len += sizeof(*dump_data) + sizeof(*dump_trig) + fwrt->dump.desc->len; - if (!fwrt->fw->n_dbg_mem_tlv) - file_len += sram_len + sizeof(*dump_mem); + if (fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_MEM) && + !fwrt->fw->n_dbg_mem_tlv) + file_len += sizeof(*dump_data) + sram_len + sizeof(*dump_mem); dump_file = vzalloc(file_len); if (!dump_file) { @@ -740,48 +772,56 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt) dump_file->barker = cpu_to_le32(IWL_FW_ERROR_DUMP_BARKER); dump_data = (void *)dump_file->data; - dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_DEV_FW_INFO); - dump_data->len = cpu_to_le32(sizeof(*dump_info)); - dump_info = (void *)dump_data->data; - dump_info->device_family = - fwrt->trans->cfg->device_family == IWL_DEVICE_FAMILY_7000 ? - cpu_to_le32(IWL_FW_ERROR_DUMP_FAMILY_7) : - cpu_to_le32(IWL_FW_ERROR_DUMP_FAMILY_8); - dump_info->hw_step = cpu_to_le32(CSR_HW_REV_STEP(fwrt->trans->hw_rev)); - memcpy(dump_info->fw_human_readable, fwrt->fw->human_readable, - sizeof(dump_info->fw_human_readable)); - strncpy(dump_info->dev_human_readable, fwrt->trans->cfg->name, - sizeof(dump_info->dev_human_readable)); - strncpy(dump_info->bus_human_readable, fwrt->dev->bus->name, - sizeof(dump_info->bus_human_readable)); - - dump_data = iwl_fw_error_next_data(dump_data); - - /* Dump shared memory configuration */ - dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM_CFG); - dump_data->len = cpu_to_le32(sizeof(*dump_smem_cfg)); - dump_smem_cfg = (void *)dump_data->data; - dump_smem_cfg->num_lmacs = cpu_to_le32(mem_cfg->num_lmacs); - dump_smem_cfg->num_txfifo_entries = - cpu_to_le32(mem_cfg->num_txfifo_entries); - for (i = 0; i < MAX_NUM_LMAC; i++) { - int j; - - for (j = 0; j < TX_FIFO_MAX_NUM; j++) - dump_smem_cfg->lmac[i].txfifo_size[j] = - cpu_to_le32(mem_cfg->lmac[i].txfifo_size[j]); - dump_smem_cfg->lmac[i].rxfifo1_size = - cpu_to_le32(mem_cfg->lmac[i].rxfifo1_size); - } - dump_smem_cfg->rxfifo2_size = cpu_to_le32(mem_cfg->rxfifo2_size); - dump_smem_cfg->internal_txfifo_addr = - cpu_to_le32(mem_cfg->internal_txfifo_addr); - for (i = 0; i < TX_FIFO_INTERNAL_MAX_NUM; i++) { - dump_smem_cfg->internal_txfifo_size[i] = - cpu_to_le32(mem_cfg->internal_txfifo_size[i]); + if (fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_DEV_FW_INFO)) { + dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_DEV_FW_INFO); + dump_data->len = cpu_to_le32(sizeof(*dump_info)); + dump_info = (void *)dump_data->data; + dump_info->device_family = + fwrt->trans->cfg->device_family == + IWL_DEVICE_FAMILY_7000 ? + cpu_to_le32(IWL_FW_ERROR_DUMP_FAMILY_7) : + cpu_to_le32(IWL_FW_ERROR_DUMP_FAMILY_8); + dump_info->hw_step = + cpu_to_le32(CSR_HW_REV_STEP(fwrt->trans->hw_rev)); + memcpy(dump_info->fw_human_readable, fwrt->fw->human_readable, + sizeof(dump_info->fw_human_readable)); + strncpy(dump_info->dev_human_readable, fwrt->trans->cfg->name, + sizeof(dump_info->dev_human_readable) - 1); + strncpy(dump_info->bus_human_readable, fwrt->dev->bus->name, + sizeof(dump_info->bus_human_readable) - 1); + + dump_data = iwl_fw_error_next_data(dump_data); } - dump_data = iwl_fw_error_next_data(dump_data); + if (fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_MEM_CFG)) { + /* Dump shared memory configuration */ + dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM_CFG); + dump_data->len = cpu_to_le32(sizeof(*dump_smem_cfg)); + dump_smem_cfg = (void *)dump_data->data; + dump_smem_cfg->num_lmacs = cpu_to_le32(mem_cfg->num_lmacs); + dump_smem_cfg->num_txfifo_entries = + cpu_to_le32(mem_cfg->num_txfifo_entries); + for (i = 0; i < MAX_NUM_LMAC; i++) { + int j; + u32 *txf_size = mem_cfg->lmac[i].txfifo_size; + + for (j = 0; j < TX_FIFO_MAX_NUM; j++) + dump_smem_cfg->lmac[i].txfifo_size[j] = + cpu_to_le32(txf_size[j]); + dump_smem_cfg->lmac[i].rxfifo1_size = + cpu_to_le32(mem_cfg->lmac[i].rxfifo1_size); + } + dump_smem_cfg->rxfifo2_size = + cpu_to_le32(mem_cfg->rxfifo2_size); + dump_smem_cfg->internal_txfifo_addr = + cpu_to_le32(mem_cfg->internal_txfifo_addr); + for (i = 0; i < TX_FIFO_INTERNAL_MAX_NUM; i++) { + dump_smem_cfg->internal_txfifo_size[i] = + cpu_to_le32(mem_cfg->internal_txfifo_size[i]); + } + + dump_data = iwl_fw_error_next_data(dump_data); + } /* We only dump the FIFOs if the FW is in error state */ if (test_bit(STATUS_FW_ERROR, &fwrt->trans->status)) { @@ -790,7 +830,8 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt) iwl_read_radio_regs(fwrt, &dump_data); } - if (fwrt->dump.desc) { + if (fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_ERROR_INFO) && + fwrt->dump.desc) { dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_ERROR_INFO); dump_data->len = cpu_to_le32(sizeof(*dump_trig) + fwrt->dump.desc->len); @@ -805,7 +846,8 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt) if (monitor_dump_only) goto dump_trans_data; - if (!fwrt->fw->n_dbg_mem_tlv) { + if (!fwrt->fw->n_dbg_mem_tlv && + fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_MEM)) { dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM); dump_data->len = cpu_to_le32(sram_len + sizeof(*dump_mem)); dump_mem = (void *)dump_data->data; @@ -821,6 +863,9 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt) u32 ofs = le32_to_cpu(fw_dbg_mem[i].ofs); bool success; + if (!(fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_MEM))) + break; + 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; @@ -854,7 +899,7 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt) dump_data = iwl_fw_error_next_data(dump_data); } - if (smem_len) { + if (smem_len && fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_MEM)) { IWL_DEBUG_INFO(fwrt, "WRT SMEM dump\n"); dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM); dump_data->len = cpu_to_le32(smem_len + sizeof(*dump_mem)); @@ -867,7 +912,7 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt) dump_data = iwl_fw_error_next_data(dump_data); } - if (sram2_len) { + if (sram2_len && fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_MEM)) { IWL_DEBUG_INFO(fwrt, "WRT SRAM dump\n"); dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM); dump_data->len = cpu_to_le32(sram2_len + sizeof(*dump_mem)); @@ -881,7 +926,8 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt) } /* Dump fw's virtual image */ - if (!fwrt->trans->cfg->gen2 && + if (fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_PAGING) && + !fwrt->trans->cfg->gen2 && fwrt->fw->img[fwrt->cur_fw_img].paging_mem_size && fwrt->fw_paging_db[0].fw_paging_block) { IWL_DEBUG_INFO(fwrt, "WRT paging dump\n"); |