diff options
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c')
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 72 |
1 files changed, 47 insertions, 25 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c index c73672d61356..866a33f49915 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2018-2021 Intel Corporation + * Copyright (C) 2018-2022 Intel Corporation */ #include <linux/firmware.h> #include "iwl-drv.h" @@ -74,7 +74,8 @@ static int iwl_dbg_tlv_add(const struct iwl_ucode_tlv *tlv, if (!node) return -ENOMEM; - memcpy(&node->tlv, tlv, sizeof(node->tlv) + len); + memcpy(&node->tlv, tlv, sizeof(node->tlv)); + memcpy(node->tlv.data, tlv->data, len); list_add_tail(&node->list, list); return 0; @@ -181,11 +182,11 @@ static int iwl_dbg_tlv_alloc_region(struct iwl_trans *trans, u32 tlv_len = sizeof(*tlv) + le32_to_cpu(tlv->length); /* - * The higher part of the ID in from version 2 is irrelevant for - * us, so mask it out. + * The higher part of the ID from version 2 is debug policy. + * The id will be only lsb 16 bits, so mask it out. */ if (le32_to_cpu(reg->hdr.version) >= 2) - id &= IWL_FW_INI_REGION_V2_MASK; + id &= IWL_FW_INI_REGION_ID_MASK; if (le32_to_cpu(tlv->length) < sizeof(*reg)) return -EINVAL; @@ -211,6 +212,14 @@ static int iwl_dbg_tlv_alloc_region(struct iwl_trans *trans, return -EOPNOTSUPP; } + if (type == IWL_FW_INI_REGION_INTERNAL_BUFFER) { + trans->dbg.imr_data.sram_addr = + le32_to_cpu(reg->internal_buffer.base_addr); + trans->dbg.imr_data.sram_size = + le32_to_cpu(reg->internal_buffer.size); + } + + active_reg = &trans->dbg.active_regions[id]; if (*active_reg) { IWL_WARN(trans, "WRT: Overriding region id %u\n", id); @@ -271,7 +280,7 @@ static int iwl_dbg_tlv_alloc_trigger(struct iwl_trans *trans, static int iwl_dbg_tlv_config_set(struct iwl_trans *trans, const struct iwl_ucode_tlv *tlv) { - struct iwl_fw_ini_conf_set_tlv *conf_set = (void *)tlv->data; + const struct iwl_fw_ini_conf_set_tlv *conf_set = (const void *)tlv->data; u32 tp = le32_to_cpu(conf_set->time_point); u32 type = le32_to_cpu(conf_set->set_type); @@ -460,7 +469,7 @@ static int iwl_dbg_tlv_parse_bin(struct iwl_trans *trans, const u8 *data, while (len >= sizeof(*tlv)) { len -= sizeof(*tlv); - tlv = (void *)data; + tlv = (const void *)data; tlv_len = le32_to_cpu(tlv->length); @@ -577,8 +586,7 @@ static int iwl_dbg_tlv_alloc_fragments(struct iwl_fw_runtime *fwrt, return 0; num_frags = le32_to_cpu(fw_mon_cfg->max_frags_num); - if (!fw_has_capa(&fwrt->fw->ucode_capa, - IWL_UCODE_TLV_CAPA_DBG_BUF_ALLOC_CMD_SUPP)) { + if (fwrt->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210) { if (alloc_id != IWL_FW_INI_ALLOCATION_ID_DBGC1) return -EIO; num_frags = 1; @@ -762,33 +770,40 @@ static int iwl_dbg_tlv_update_dram(struct iwl_fw_runtime *fwrt, static void iwl_dbg_tlv_update_drams(struct iwl_fw_runtime *fwrt) { - int ret, i, dram_alloc = 0; - struct iwl_dram_info dram_info; + int ret, i; + bool dram_alloc = false; struct iwl_dram_data *frags = &fwrt->trans->dbg.fw_mon_ini[IWL_FW_INI_ALLOCATION_ID_DBGC1].frags[0]; + struct iwl_dram_info *dram_info; + + if (!frags || !frags->block) + return; + + dram_info = frags->block; if (!fw_has_capa(&fwrt->fw->ucode_capa, IWL_UCODE_TLV_CAPA_DRAM_FRAG_SUPPORT)) return; - dram_info.first_word = cpu_to_le32(DRAM_INFO_FIRST_MAGIC_WORD); - dram_info.second_word = cpu_to_le32(DRAM_INFO_SECOND_MAGIC_WORD); + dram_info->first_word = cpu_to_le32(DRAM_INFO_FIRST_MAGIC_WORD); + dram_info->second_word = cpu_to_le32(DRAM_INFO_SECOND_MAGIC_WORD); for (i = IWL_FW_INI_ALLOCATION_ID_DBGC1; i <= IWL_FW_INI_ALLOCATION_ID_DBGC3; i++) { - ret = iwl_dbg_tlv_update_dram(fwrt, i, &dram_info); + ret = iwl_dbg_tlv_update_dram(fwrt, i, dram_info); if (!ret) - dram_alloc++; + dram_alloc = true; else IWL_WARN(fwrt, "WRT: Failed to set DRAM buffer for alloc id %d, ret=%d\n", i, ret); } - if (dram_alloc) { - memcpy(frags->block, &dram_info, sizeof(dram_info)); - IWL_DEBUG_FW(fwrt, "block data after %016x\n", - *((int *)fwrt->trans->dbg.fw_mon_ini[1].frags[0].block)); - } + + if (dram_alloc) + IWL_DEBUG_FW(fwrt, "block data after %08x\n", + dram_info->first_word); + else + memset(frags->block, 0, sizeof(*dram_info)); } static void iwl_dbg_tlv_send_hcmds(struct iwl_fw_runtime *fwrt, @@ -811,11 +826,11 @@ static void iwl_dbg_tlv_send_hcmds(struct iwl_fw_runtime *fwrt, } static void iwl_dbg_tlv_apply_config(struct iwl_fw_runtime *fwrt, - struct list_head *config_list) + struct list_head *conf_list) { struct iwl_dbg_tlv_node *node; - list_for_each_entry(node, config_list, list) { + list_for_each_entry(node, conf_list, list) { struct iwl_fw_ini_conf_set_tlv *config_list = (void *)node->tlv.data; u32 count, address, value; u32 len = (le32_to_cpu(node->tlv.length) - sizeof(*config_list)) / 8; @@ -861,11 +876,18 @@ static void iwl_dbg_tlv_apply_config(struct iwl_fw_runtime *fwrt, case IWL_FW_INI_CONFIG_SET_TYPE_DBGC_DRAM_ADDR: { struct iwl_dbgc1_info dram_info = {}; struct iwl_dram_data *frags = &fwrt->trans->dbg.fw_mon_ini[1].frags[0]; - __le64 dram_base_addr = cpu_to_le64(frags->physical); - __le32 dram_size = cpu_to_le32(frags->size); - u64 dram_addr = le64_to_cpu(dram_base_addr); + __le64 dram_base_addr; + __le32 dram_size; + u64 dram_addr; u32 ret; + if (!frags) + break; + + dram_base_addr = cpu_to_le64(frags->physical); + dram_size = cpu_to_le32(frags->size); + dram_addr = le64_to_cpu(dram_base_addr); + IWL_DEBUG_FW(fwrt, "WRT: dram_base_addr 0x%016llx, dram_size 0x%x\n", dram_base_addr, dram_size); IWL_DEBUG_FW(fwrt, "WRT: config_list->addr_offset: %u\n", |