Commit ce27f005 authored by Golan Ben-Ami's avatar Golan Ben-Ami Committed by Luca Coelho

iwlwifi: dump smem configuration when firmware crashes

Add the smem configuration to the fw data dump, once
the firmware crashes. This is useful mainly for later
parsing of the smem.
Signed-off-by: default avatarGolan Ben-Ami <golan.ben.ami@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
parent 36ae4f3a
...@@ -545,11 +545,13 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt) ...@@ -545,11 +545,13 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
struct iwl_fw_error_dump_data *dump_data; struct iwl_fw_error_dump_data *dump_data;
struct iwl_fw_error_dump_info *dump_info; struct iwl_fw_error_dump_info *dump_info;
struct iwl_fw_error_dump_mem *dump_mem; struct iwl_fw_error_dump_mem *dump_mem;
struct iwl_fw_error_dump_smem_cfg *dump_smem_cfg;
struct iwl_fw_error_dump_trigger_desc *dump_trig; struct iwl_fw_error_dump_trigger_desc *dump_trig;
struct iwl_fw_dump_ptrs *fw_error_dump; struct iwl_fw_dump_ptrs *fw_error_dump;
struct scatterlist *sg_dump_data; struct scatterlist *sg_dump_data;
u32 sram_len, sram_ofs; u32 sram_len, sram_ofs;
const struct iwl_fw_dbg_mem_seg_tlv *fw_dbg_mem = fwrt->fw->dbg_mem_tlv; const struct iwl_fw_dbg_mem_seg_tlv *fw_dbg_mem = fwrt->fw->dbg_mem_tlv;
struct iwl_fwrt_shared_mem_cfg *mem_cfg = &fwrt->smem_cfg;
u32 file_len, fifo_data_len = 0, prph_len = 0, radio_len = 0; u32 file_len, fifo_data_len = 0, prph_len = 0, radio_len = 0;
u32 smem_len = fwrt->fw->n_dbg_mem_tlv ? 0 : fwrt->trans->cfg->smem_len; u32 smem_len = fwrt->fw->n_dbg_mem_tlv ? 0 : fwrt->trans->cfg->smem_len;
u32 sram2_len = fwrt->fw->n_dbg_mem_tlv ? u32 sram2_len = fwrt->fw->n_dbg_mem_tlv ?
...@@ -585,8 +587,6 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt) ...@@ -585,8 +587,6 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
/* reading RXF/TXF sizes */ /* reading RXF/TXF sizes */
if (test_bit(STATUS_FW_ERROR, &fwrt->trans->status)) { if (test_bit(STATUS_FW_ERROR, &fwrt->trans->status)) {
struct iwl_fwrt_shared_mem_cfg *mem_cfg = &fwrt->smem_cfg;
fifo_data_len = 0; fifo_data_len = 0;
/* Count RXF2 size */ /* Count RXF2 size */
...@@ -675,7 +675,8 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt) ...@@ -675,7 +675,8 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
} }
file_len = sizeof(*dump_file) + file_len = sizeof(*dump_file) +
sizeof(*dump_data) * 2 + sizeof(*dump_data) * 3 +
sizeof(*dump_smem_cfg) +
fifo_data_len + fifo_data_len +
prph_len + prph_len +
radio_len + radio_len +
...@@ -706,8 +707,8 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt) ...@@ -706,8 +707,8 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
/* If we only want a monitor dump, reset the file length */ /* If we only want a monitor dump, reset the file length */
if (monitor_dump_only) { if (monitor_dump_only) {
file_len = sizeof(*dump_file) + sizeof(*dump_data) + file_len = sizeof(*dump_file) + sizeof(*dump_data) * 2 +
sizeof(*dump_info); sizeof(*dump_info) + sizeof(*dump_smem_cfg);
} }
if (fwrt->dump.desc) if (fwrt->dump.desc)
...@@ -744,6 +745,33 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt) ...@@ -744,6 +745,33 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
sizeof(dump_info->bus_human_readable)); sizeof(dump_info->bus_human_readable));
dump_data = iwl_fw_error_next_data(dump_data); 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]);
}
dump_data = iwl_fw_error_next_data(dump_data);
/* We only dump the FIFOs if the FW is in error state */ /* We only dump the FIFOs if the FW is in error state */
if (test_bit(STATUS_FW_ERROR, &fwrt->trans->status)) { if (test_bit(STATUS_FW_ERROR, &fwrt->trans->status)) {
iwl_fw_dump_fifos(fwrt, &dump_data); iwl_fw_dump_fifos(fwrt, &dump_data);
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
* *
* Copyright(c) 2014 Intel Corporation. All rights reserved. * Copyright(c) 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2014 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2014 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as * it under the terms of version 2 of the GNU General Public License as
...@@ -33,6 +34,7 @@ ...@@ -33,6 +34,7 @@
* *
* Copyright(c) 2014 Intel Corporation. All rights reserved. * Copyright(c) 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2014 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2014 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -92,6 +94,9 @@ ...@@ -92,6 +94,9 @@
* @IWL_FW_ERROR_DUMP_EXTERNAL: used only by external code utilities, and * @IWL_FW_ERROR_DUMP_EXTERNAL: used only by external code utilities, and
* for that reason is not in use in any other place in the Linux Wi-Fi * for that reason is not in use in any other place in the Linux Wi-Fi
* stack. * stack.
* @IWL_FW_ERROR_DUMP_MEM_CFG: the addresses and sizes of fifos in the smem,
* which we get from the fw after ALIVE. The content is structured as
* &struct iwl_fw_error_dump_smem_cfg.
*/ */
enum iwl_fw_error_dump_type { enum iwl_fw_error_dump_type {
/* 0 is deprecated */ /* 0 is deprecated */
...@@ -110,6 +115,7 @@ enum iwl_fw_error_dump_type { ...@@ -110,6 +115,7 @@ enum iwl_fw_error_dump_type {
IWL_FW_ERROR_DUMP_RADIO_REG = 13, IWL_FW_ERROR_DUMP_RADIO_REG = 13,
IWL_FW_ERROR_DUMP_INTERNAL_TXF = 14, IWL_FW_ERROR_DUMP_INTERNAL_TXF = 14,
IWL_FW_ERROR_DUMP_EXTERNAL = 15, /* Do not move */ IWL_FW_ERROR_DUMP_EXTERNAL = 15, /* Do not move */
IWL_FW_ERROR_DUMP_MEM_CFG = 16,
IWL_FW_ERROR_DUMP_MAX, IWL_FW_ERROR_DUMP_MAX,
}; };
...@@ -208,6 +214,30 @@ struct iwl_fw_error_dump_fw_mon { ...@@ -208,6 +214,30 @@ struct iwl_fw_error_dump_fw_mon {
u8 data[]; u8 data[];
} __packed; } __packed;
#define MAX_NUM_LMAC 2
#define TX_FIFO_INTERNAL_MAX_NUM 6
#define TX_FIFO_MAX_NUM 15
/**
* struct iwl_fw_error_dump_smem_cfg - Dump SMEM configuration
* This must follow &struct iwl_fwrt_shared_mem_cfg.
* @num_lmacs: number of lmacs
* @num_txfifo_entries: number of tx fifos
* @lmac: sizes of lmacs txfifos and rxfifo1
* @rxfifo2_size: size of rxfifo2
* @internal_txfifo_addr: address of internal tx fifo
* @internal_txfifo_size: size of internal tx fifo
*/
struct iwl_fw_error_dump_smem_cfg {
__le32 num_lmacs;
__le32 num_txfifo_entries;
struct {
__le32 txfifo_size[TX_FIFO_MAX_NUM];
__le32 rxfifo1_size;
} lmac[MAX_NUM_LMAC];
__le32 rxfifo2_size;
__le32 internal_txfifo_addr;
__le32 internal_txfifo_size[TX_FIFO_INTERNAL_MAX_NUM];
} __packed;
/** /**
* struct iwl_fw_error_dump_prph - periphery registers data * struct iwl_fw_error_dump_prph - periphery registers data
* @prph_start: address of the first register in this chunk * @prph_start: address of the first register in this chunk
......
...@@ -113,6 +113,9 @@ static void iwl_parse_shared_mem(struct iwl_fw_runtime *fwrt, ...@@ -113,6 +113,9 @@ static void iwl_parse_shared_mem(struct iwl_fw_runtime *fwrt,
BUILD_BUG_ON(sizeof(fwrt->smem_cfg.internal_txfifo_size) != BUILD_BUG_ON(sizeof(fwrt->smem_cfg.internal_txfifo_size) !=
sizeof(mem_cfg->internal_txfifo_size)); sizeof(mem_cfg->internal_txfifo_size));
fwrt->smem_cfg.internal_txfifo_addr =
le32_to_cpu(mem_cfg->internal_txfifo_addr);
for (i = 0; for (i = 0;
i < ARRAY_SIZE(fwrt->smem_cfg.internal_txfifo_size); i < ARRAY_SIZE(fwrt->smem_cfg.internal_txfifo_size);
i++) i++)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment