diff options
author | Luca Coelho <luciano.coelho@intel.com> | 2019-11-01 15:31:02 +0200 |
---|---|---|
committer | Luca Coelho <luciano.coelho@intel.com> | 2020-03-27 08:12:47 +0200 |
commit | f696a7ee254f7e4e96bd1a21addd1315169b8a8a (patch) | |
tree | 403c7393cee7e0ba30b59ce2ccacad715e344b49 /drivers/net/wireless/intel/iwlwifi/fw | |
parent | cceb45078a62cda3ebdb97bd96916c3f8d811e7c (diff) |
iwlwifi: yoyo: add PCI config space region type
Add a new region type that allows us to dump the PCI config space.
This is mostly the same as dumping a memory region, but reading from
the device's config space instead.
In order to make this generic and independent of the trans type, we
make a function called iwl_dump_ini_config_iter() that calls a new op
in the transport to read its config space.
Change-Id: I15151bddf589f13b0e0a45c28b96bbcd73bcfdeb
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/fw')
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 91df1ee25dd0..d5dda93c3953 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -1108,6 +1108,38 @@ static int iwl_dump_ini_csr_iter(struct iwl_fw_runtime *fwrt, return sizeof(*range) + le32_to_cpu(range->range_data_size); } +static int iwl_dump_ini_config_iter(struct iwl_fw_runtime *fwrt, + struct iwl_dump_ini_region_data *reg_data, + void *range_ptr, int idx) +{ + struct iwl_trans *trans = fwrt->trans; + struct iwl_fw_ini_region_tlv *reg = (void *)reg_data->reg_tlv->data; + struct iwl_fw_ini_error_dump_range *range = range_ptr; + __le32 *val = range->data; + u32 addr = le32_to_cpu(reg->addrs[idx]) + + le32_to_cpu(reg->dev_addr.offset); + int i; + + /* we shouldn't get here if the trans doesn't have read_config32 */ + if (WARN_ON_ONCE(!trans->ops->read_config32)) + return -EOPNOTSUPP; + + range->internal_base_addr = cpu_to_le32(addr); + range->range_data_size = reg->dev_addr.size; + for (i = 0; i < le32_to_cpu(reg->dev_addr.size); i += 4) { + int ret; + u32 tmp; + + ret = trans->ops->read_config32(trans, addr + i, &tmp); + if (ret < 0) + return ret; + + *val++ = cpu_to_le32(tmp); + } + + return sizeof(*range) + le32_to_cpu(range->range_data_size); +} + static int iwl_dump_ini_dev_mem_iter(struct iwl_fw_runtime *fwrt, struct iwl_dump_ini_region_data *reg_data, void *range_ptr, int idx) @@ -2052,7 +2084,12 @@ static const struct iwl_dump_ini_mem_ops iwl_dump_ini_region_ops[] = { .fill_range = iwl_dump_ini_csr_iter, }, [IWL_FW_INI_REGION_DRAM_IMR] = {}, - [IWL_FW_INI_REGION_PCI_IOSF_CONFIG] = {}, + [IWL_FW_INI_REGION_PCI_IOSF_CONFIG] = { + .get_num_of_ranges = iwl_dump_ini_mem_ranges, + .get_size = iwl_dump_ini_mem_get_size, + .fill_mem_hdr = iwl_dump_ini_mem_fill_header, + .fill_range = iwl_dump_ini_config_iter, + }, }; static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt, |