mirror of
https://github.com/torvalds/linux.git
synced 2024-12-25 20:32:22 +00:00
iwlwifi: dbg_ini: implement paging memory dump
Implement paging memory dump in the new dump mechanism. To support this change, moved iwl_self_init_dram strcut from trans_pcie to trans so that it will accessible via fw_runtime. Signed-off-by: Shahar S Matityahu <shahar.s.matityahu@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
This commit is contained in:
parent
6e9f8f9924
commit
505a00c071
@ -1095,6 +1095,43 @@ static int iwl_dump_ini_dev_mem_iter(struct iwl_fw_runtime *fwrt,
|
|||||||
return le32_to_cpu(range->range_data_size);
|
return le32_to_cpu(range->range_data_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
iwl_dump_ini_paging_gen2_iter(struct iwl_fw_runtime *fwrt,
|
||||||
|
struct iwl_fw_ini_error_dump_range *range,
|
||||||
|
struct iwl_fw_ini_region_cfg *reg,
|
||||||
|
int idx)
|
||||||
|
{
|
||||||
|
u32 page_size = fwrt->trans->init_dram.paging[idx].size;
|
||||||
|
|
||||||
|
range->start_addr = cpu_to_le32(idx);
|
||||||
|
range->range_data_size = cpu_to_le32(page_size);
|
||||||
|
memcpy(range->data, fwrt->trans->init_dram.paging[idx].block,
|
||||||
|
page_size);
|
||||||
|
return le32_to_cpu(range->range_data_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int iwl_dump_ini_paging_iter(struct iwl_fw_runtime *fwrt,
|
||||||
|
struct iwl_fw_ini_error_dump_range *range,
|
||||||
|
struct iwl_fw_ini_region_cfg *reg,
|
||||||
|
int idx)
|
||||||
|
{
|
||||||
|
/* increase idx by 1 since the pages are from 1 to
|
||||||
|
* fwrt->num_of_paging_blk + 1
|
||||||
|
*/
|
||||||
|
struct page *page = fwrt->fw_paging_db[++idx].fw_paging_block;
|
||||||
|
dma_addr_t addr = fwrt->fw_paging_db[idx].fw_paging_phys;
|
||||||
|
u32 page_size = fwrt->fw_paging_db[idx].fw_paging_size;
|
||||||
|
|
||||||
|
range->start_addr = cpu_to_le32(idx);
|
||||||
|
range->range_data_size = cpu_to_le32(page_size);
|
||||||
|
dma_sync_single_for_cpu(fwrt->trans->dev, addr, page_size,
|
||||||
|
DMA_BIDIRECTIONAL);
|
||||||
|
memcpy(range->data, page_address(page), page_size);
|
||||||
|
dma_sync_single_for_device(fwrt->trans->dev, addr, page_size,
|
||||||
|
DMA_BIDIRECTIONAL);
|
||||||
|
return le32_to_cpu(range->range_data_size);
|
||||||
|
}
|
||||||
|
|
||||||
static struct iwl_fw_ini_error_dump_range
|
static struct iwl_fw_ini_error_dump_range
|
||||||
*iwl_dump_ini_mem_fill_header(struct iwl_fw_runtime *fwrt, void *data)
|
*iwl_dump_ini_mem_fill_header(struct iwl_fw_runtime *fwrt, void *data)
|
||||||
{
|
{
|
||||||
@ -1110,12 +1147,46 @@ static u32 iwl_dump_ini_mem_get_size(struct iwl_fw_runtime *fwrt,
|
|||||||
le32_to_cpu(reg->internal.range_data_size);
|
le32_to_cpu(reg->internal.range_data_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u32 iwl_dump_ini_paging_gen2_get_size(struct iwl_fw_runtime *fwrt,
|
||||||
|
struct iwl_fw_ini_region_cfg *reg)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
u32 size = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < fwrt->trans->init_dram.paging_cnt; i++)
|
||||||
|
size += fwrt->trans->init_dram.paging[i].size;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 iwl_dump_ini_paging_get_size(struct iwl_fw_runtime *fwrt,
|
||||||
|
struct iwl_fw_ini_region_cfg *reg)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
u32 size = 0;
|
||||||
|
|
||||||
|
for (i = 1; i <= fwrt->num_of_paging_blk; i++)
|
||||||
|
size += fwrt->fw_paging_db[i].fw_paging_size;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
static u32 iwl_dump_ini_mem_ranges(struct iwl_fw_runtime *fwrt,
|
static u32 iwl_dump_ini_mem_ranges(struct iwl_fw_runtime *fwrt,
|
||||||
struct iwl_fw_ini_region_cfg *reg)
|
struct iwl_fw_ini_region_cfg *reg)
|
||||||
{
|
{
|
||||||
return le32_to_cpu(reg->internal.num_of_ranges);
|
return le32_to_cpu(reg->internal.num_of_ranges);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u32 iwl_dump_ini_paging_gen2_ranges(struct iwl_fw_runtime *fwrt,
|
||||||
|
struct iwl_fw_ini_region_cfg *reg)
|
||||||
|
{
|
||||||
|
return fwrt->trans->init_dram.paging_cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 iwl_dump_ini_paging_ranges(struct iwl_fw_runtime *fwrt,
|
||||||
|
struct iwl_fw_ini_region_cfg *reg)
|
||||||
|
{
|
||||||
|
return fwrt->num_of_paging_blk;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct iwl_dump_ini_mem_ops - ini memory dump operations
|
* struct iwl_dump_ini_mem_ops - ini memory dump operations
|
||||||
* @get_num_of_ranges: returns the number of memory ranges in the region.
|
* @get_num_of_ranges: returns the number of memory ranges in the region.
|
||||||
@ -1224,14 +1295,21 @@ static int iwl_fw_ini_get_trigger_len(struct iwl_fw_runtime *fwrt,
|
|||||||
case IWL_FW_INI_REGION_RXF:
|
case IWL_FW_INI_REGION_RXF:
|
||||||
size += iwl_fw_rxf_len(fwrt, &fwrt->smem_cfg);
|
size += iwl_fw_rxf_len(fwrt, &fwrt->smem_cfg);
|
||||||
break;
|
break;
|
||||||
case IWL_FW_INI_REGION_PAGING:
|
case IWL_FW_INI_REGION_PAGING: {
|
||||||
if (!iwl_fw_dbg_is_paging_enabled(fwrt))
|
size += hdr_len + dump_header_len;
|
||||||
break;
|
if (iwl_fw_dbg_is_paging_enabled(fwrt)) {
|
||||||
size += fwrt->num_of_paging_blk *
|
size += range_header_len *
|
||||||
(hdr_len +
|
iwl_dump_ini_paging_ranges(fwrt, reg) +
|
||||||
sizeof(struct iwl_fw_error_dump_paging) +
|
iwl_dump_ini_paging_get_size(fwrt, reg);
|
||||||
PAGING_BLOCK_SIZE);
|
} else {
|
||||||
|
size += range_header_len *
|
||||||
|
iwl_dump_ini_paging_gen2_ranges(fwrt,
|
||||||
|
reg) +
|
||||||
|
iwl_dump_ini_paging_gen2_get_size(fwrt,
|
||||||
|
reg);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case IWL_FW_INI_REGION_DRAM_BUFFER:
|
case IWL_FW_INI_REGION_DRAM_BUFFER:
|
||||||
/* Transport takes care of DRAM dumping */
|
/* Transport takes care of DRAM dumping */
|
||||||
case IWL_FW_INI_REGION_INTERNAL_BUFFER:
|
case IWL_FW_INI_REGION_INTERNAL_BUFFER:
|
||||||
@ -1286,12 +1364,24 @@ static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt,
|
|||||||
case IWL_FW_INI_REGION_DRAM_BUFFER:
|
case IWL_FW_INI_REGION_DRAM_BUFFER:
|
||||||
*dump_mask |= BIT(IWL_FW_ERROR_DUMP_FW_MONITOR);
|
*dump_mask |= BIT(IWL_FW_ERROR_DUMP_FW_MONITOR);
|
||||||
break;
|
break;
|
||||||
case IWL_FW_INI_REGION_PAGING:
|
case IWL_FW_INI_REGION_PAGING: {
|
||||||
if (iwl_fw_dbg_is_paging_enabled(fwrt))
|
ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header;
|
||||||
iwl_dump_paging(fwrt, data);
|
if (iwl_fw_dbg_is_paging_enabled(fwrt)) {
|
||||||
else
|
ops.get_num_of_ranges =
|
||||||
*dump_mask |= BIT(IWL_FW_ERROR_DUMP_PAGING);
|
iwl_dump_ini_paging_ranges;
|
||||||
|
ops.get_size = iwl_dump_ini_paging_get_size;
|
||||||
|
ops.fill_range = iwl_dump_ini_paging_iter;
|
||||||
|
} else {
|
||||||
|
ops.get_num_of_ranges =
|
||||||
|
iwl_dump_ini_paging_gen2_ranges;
|
||||||
|
ops.get_size =
|
||||||
|
iwl_dump_ini_paging_gen2_get_size;
|
||||||
|
ops.fill_range = iwl_dump_ini_paging_gen2_iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
iwl_dump_ini_mem(fwrt, type, data, reg, &ops);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case IWL_FW_INI_REGION_TXF:
|
case IWL_FW_INI_REGION_TXF:
|
||||||
iwl_fw_dump_txf(fwrt, data);
|
iwl_fw_dump_txf(fwrt, data);
|
||||||
break;
|
break;
|
||||||
|
@ -700,6 +700,20 @@ struct iwl_dram_data {
|
|||||||
int size;
|
int size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct iwl_self_init_dram - dram data used by self init process
|
||||||
|
* @fw: lmac and umac dram data
|
||||||
|
* @fw_cnt: total number of items in array
|
||||||
|
* @paging: paging dram data
|
||||||
|
* @paging_cnt: total number of items in array
|
||||||
|
*/
|
||||||
|
struct iwl_self_init_dram {
|
||||||
|
struct iwl_dram_data *fw;
|
||||||
|
int fw_cnt;
|
||||||
|
struct iwl_dram_data *paging;
|
||||||
|
int paging_cnt;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct iwl_trans - transport common data
|
* struct iwl_trans - transport common data
|
||||||
*
|
*
|
||||||
@ -794,6 +808,7 @@ struct iwl_trans {
|
|||||||
u8 dbg_n_dest_reg;
|
u8 dbg_n_dest_reg;
|
||||||
int num_blocks;
|
int num_blocks;
|
||||||
struct iwl_dram_data fw_mon[IWL_FW_INI_APPLY_NUM];
|
struct iwl_dram_data fw_mon[IWL_FW_INI_APPLY_NUM];
|
||||||
|
struct iwl_self_init_dram init_dram;
|
||||||
|
|
||||||
enum iwl_plat_pm_mode system_pm_mode;
|
enum iwl_plat_pm_mode system_pm_mode;
|
||||||
enum iwl_plat_pm_mode runtime_pm_mode;
|
enum iwl_plat_pm_mode runtime_pm_mode;
|
||||||
|
@ -59,8 +59,7 @@
|
|||||||
|
|
||||||
void iwl_pcie_ctxt_info_free_paging(struct iwl_trans *trans)
|
void iwl_pcie_ctxt_info_free_paging(struct iwl_trans *trans)
|
||||||
{
|
{
|
||||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
struct iwl_self_init_dram *dram = &trans->init_dram;
|
||||||
struct iwl_self_init_dram *dram = &trans_pcie->init_dram;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!dram->paging) {
|
if (!dram->paging) {
|
||||||
@ -83,8 +82,7 @@ int iwl_pcie_init_fw_sec(struct iwl_trans *trans,
|
|||||||
const struct fw_img *fw,
|
const struct fw_img *fw,
|
||||||
struct iwl_context_info_dram *ctxt_dram)
|
struct iwl_context_info_dram *ctxt_dram)
|
||||||
{
|
{
|
||||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
struct iwl_self_init_dram *dram = &trans->init_dram;
|
||||||
struct iwl_self_init_dram *dram = &trans_pcie->init_dram;
|
|
||||||
int i, ret, lmac_cnt, umac_cnt, paging_cnt;
|
int i, ret, lmac_cnt, umac_cnt, paging_cnt;
|
||||||
|
|
||||||
if (WARN(dram->paging,
|
if (WARN(dram->paging,
|
||||||
|
@ -453,20 +453,6 @@ enum iwl_image_response_code {
|
|||||||
IWL_IMAGE_RESP_FAIL = 2,
|
IWL_IMAGE_RESP_FAIL = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* struct iwl_self_init_dram - dram data used by self init process
|
|
||||||
* @fw: lmac and umac dram data
|
|
||||||
* @fw_cnt: total number of items in array
|
|
||||||
* @paging: paging dram data
|
|
||||||
* @paging_cnt: total number of items in array
|
|
||||||
*/
|
|
||||||
struct iwl_self_init_dram {
|
|
||||||
struct iwl_dram_data *fw;
|
|
||||||
int fw_cnt;
|
|
||||||
struct iwl_dram_data *paging;
|
|
||||||
int paging_cnt;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct cont_rec: continuous recording data structure
|
* struct cont_rec: continuous recording data structure
|
||||||
* @prev_wr_ptr: the last address that was read in monitor_data
|
* @prev_wr_ptr: the last address that was read in monitor_data
|
||||||
@ -554,7 +540,6 @@ struct iwl_trans_pcie {
|
|||||||
dma_addr_t prph_info_dma_addr;
|
dma_addr_t prph_info_dma_addr;
|
||||||
dma_addr_t prph_scratch_dma_addr;
|
dma_addr_t prph_scratch_dma_addr;
|
||||||
dma_addr_t iml_dma_addr;
|
dma_addr_t iml_dma_addr;
|
||||||
struct iwl_self_init_dram init_dram;
|
|
||||||
struct iwl_trans *trans;
|
struct iwl_trans *trans;
|
||||||
|
|
||||||
struct net_device napi_dev;
|
struct net_device napi_dev;
|
||||||
@ -813,8 +798,7 @@ static inline int iwl_pcie_ctxt_info_alloc_dma(struct iwl_trans *trans,
|
|||||||
|
|
||||||
static inline void iwl_pcie_ctxt_info_free_fw_img(struct iwl_trans *trans)
|
static inline void iwl_pcie_ctxt_info_free_fw_img(struct iwl_trans *trans)
|
||||||
{
|
{
|
||||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
struct iwl_self_init_dram *dram = &trans->init_dram;
|
||||||
struct iwl_self_init_dram *dram = &trans_pcie->init_dram;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!dram->fw) {
|
if (!dram->fw) {
|
||||||
|
@ -3220,10 +3220,10 @@ static struct iwl_trans_dump_data
|
|||||||
|
|
||||||
/* Paged memory for gen2 HW */
|
/* Paged memory for gen2 HW */
|
||||||
if (trans->cfg->gen2 && dump_mask & BIT(IWL_FW_ERROR_DUMP_PAGING))
|
if (trans->cfg->gen2 && dump_mask & BIT(IWL_FW_ERROR_DUMP_PAGING))
|
||||||
for (i = 0; i < trans_pcie->init_dram.paging_cnt; i++)
|
for (i = 0; i < trans->init_dram.paging_cnt; i++)
|
||||||
len += sizeof(*data) +
|
len += sizeof(*data) +
|
||||||
sizeof(struct iwl_fw_error_dump_paging) +
|
sizeof(struct iwl_fw_error_dump_paging) +
|
||||||
trans_pcie->init_dram.paging[i].size;
|
trans->init_dram.paging[i].size;
|
||||||
|
|
||||||
dump_data = vzalloc(len);
|
dump_data = vzalloc(len);
|
||||||
if (!dump_data)
|
if (!dump_data)
|
||||||
@ -3275,16 +3275,16 @@ static struct iwl_trans_dump_data
|
|||||||
|
|
||||||
/* Paged memory for gen2 HW */
|
/* Paged memory for gen2 HW */
|
||||||
if (trans->cfg->gen2 && dump_mask & BIT(IWL_FW_ERROR_DUMP_PAGING)) {
|
if (trans->cfg->gen2 && dump_mask & BIT(IWL_FW_ERROR_DUMP_PAGING)) {
|
||||||
for (i = 0; i < trans_pcie->init_dram.paging_cnt; i++) {
|
for (i = 0; i < trans->init_dram.paging_cnt; i++) {
|
||||||
struct iwl_fw_error_dump_paging *paging;
|
struct iwl_fw_error_dump_paging *paging;
|
||||||
u32 page_len = trans_pcie->init_dram.paging[i].size;
|
u32 page_len = trans->init_dram.paging[i].size;
|
||||||
|
|
||||||
data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_PAGING);
|
data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_PAGING);
|
||||||
data->len = cpu_to_le32(sizeof(*paging) + page_len);
|
data->len = cpu_to_le32(sizeof(*paging) + page_len);
|
||||||
paging = (void *)data->data;
|
paging = (void *)data->data;
|
||||||
paging->index = cpu_to_le32(i);
|
paging->index = cpu_to_le32(i);
|
||||||
memcpy(paging->data,
|
memcpy(paging->data,
|
||||||
trans_pcie->init_dram.paging[i].block, page_len);
|
trans->init_dram.paging[i].block, page_len);
|
||||||
data = iwl_fw_error_next_data(data);
|
data = iwl_fw_error_next_data(data);
|
||||||
|
|
||||||
len += sizeof(*data) + sizeof(*paging) + page_len;
|
len += sizeof(*data) + sizeof(*paging) + page_len;
|
||||||
|
Loading…
Reference in New Issue
Block a user