Commit 5c9d0a20 authored by Kalle Valo's avatar Kalle Valo

ath10k: add coredump_mask module parameter

For memory dump support (it consumes quite a lot of memory) we need to control
what is exactly stored to the crash dump. Add a module parameter call
coredump_mask to do that. It's a bit mask of these values:

enum ath10k_fw_crash_dump_type {
	ATH10K_FW_CRASH_DUMP_REGISTERS = 0,
	ATH10K_FW_CRASH_DUMP_CE_DATA = 1,

	ATH10K_FW_CRASH_DUMP_MAX,
};

For example, if we only want to store CE_DATA we would enable bit 2:

modprobe ath10k_core coredump_mask=0x2
Signed-off-by: default avatarKalle Valo <kvalo@qca.qualcomm.com>
parent e2fcf60c
......@@ -40,17 +40,25 @@ static bool uart_print;
static bool skip_otp;
static bool rawmode;
/* Enable ATH10K_FW_CRASH_DUMP_REGISTERS and ATH10K_FW_CRASH_DUMP_CE_DATA
* by default.
*/
unsigned long ath10k_coredump_mask = 0x3;
/* FIXME: most of these should be readonly */
module_param_named(debug_mask, ath10k_debug_mask, uint, 0644);
module_param_named(cryptmode, ath10k_cryptmode_param, uint, 0644);
module_param(uart_print, bool, 0644);
module_param(skip_otp, bool, 0644);
module_param(rawmode, bool, 0644);
module_param_named(coredump_mask, ath10k_coredump_mask, ulong, 0444);
MODULE_PARM_DESC(debug_mask, "Debugging mask");
MODULE_PARM_DESC(uart_print, "Uart target debugging");
MODULE_PARM_DESC(skip_otp, "Skip otp failure for calibration in testmode");
MODULE_PARM_DESC(cryptmode, "Crypto mode: 0-hardware, 1-software");
MODULE_PARM_DESC(rawmode, "Use raw 802.11 frame datapath");
MODULE_PARM_DESC(coredump_mask, "Bitfield of what to include in firmware crash file");
static const struct ath10k_hw_params ath10k_hw_params_list[] = {
{
......
......@@ -1027,6 +1027,8 @@ static inline bool ath10k_peer_stats_enabled(struct ath10k *ar)
return false;
}
extern unsigned long ath10k_coredump_mask;
struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
enum ath10k_bus bus,
enum ath10k_hw_rev hw_rev,
......
......@@ -27,6 +27,10 @@ struct ath10k_fw_crash_data *ath10k_coredump_new(struct ath10k *ar)
lockdep_assert_held(&ar->data_lock);
if (ath10k_coredump_mask == 0)
/* coredump disabled */
return NULL;
guid_gen(&crash_data->guid);
ktime_get_real_ts64(&crash_data->timestamp);
......@@ -45,9 +49,13 @@ static struct ath10k_dump_file_data *ath10k_coredump_build(struct ath10k *ar)
unsigned char *buf;
len = hdr_len;
len += sizeof(*dump_tlv) + sizeof(crash_data->registers);
len += sizeof(*dump_tlv) + sizeof(*ce_hdr) +
CE_COUNT * sizeof(ce_hdr->entries[0]);
if (test_bit(ATH10K_FW_CRASH_DUMP_REGISTERS, &ath10k_coredump_mask))
len += sizeof(*dump_tlv) + sizeof(crash_data->registers);
if (test_bit(ATH10K_FW_CRASH_DUMP_CE_DATA, &ath10k_coredump_mask))
len += sizeof(*dump_tlv) + sizeof(*ce_hdr) +
CE_COUNT * sizeof(ce_hdr->entries[0]);
sofar += hdr_len;
......@@ -92,25 +100,28 @@ static struct ath10k_dump_file_data *ath10k_coredump_build(struct ath10k *ar)
dump_data->tv_sec = cpu_to_le64(crash_data->timestamp.tv_sec);
dump_data->tv_nsec = cpu_to_le64(crash_data->timestamp.tv_nsec);
/* Gather crash-dump */
dump_tlv = (struct ath10k_tlv_dump_data *)(buf + sofar);
dump_tlv->type = cpu_to_le32(ATH10K_FW_CRASH_DUMP_REGISTERS);
dump_tlv->tlv_len = cpu_to_le32(sizeof(crash_data->registers));
memcpy(dump_tlv->tlv_data, &crash_data->registers,
sizeof(crash_data->registers));
sofar += sizeof(*dump_tlv) + sizeof(crash_data->registers);
dump_tlv = (struct ath10k_tlv_dump_data *)(buf + sofar);
dump_tlv->type = cpu_to_le32(ATH10K_FW_CRASH_DUMP_CE_DATA);
dump_tlv->tlv_len = cpu_to_le32(sizeof(*ce_hdr) +
CE_COUNT * sizeof(ce_hdr->entries[0]));
ce_hdr = (struct ath10k_ce_crash_hdr *)(dump_tlv->tlv_data);
ce_hdr->ce_count = cpu_to_le32(CE_COUNT);
memset(ce_hdr->reserved, 0, sizeof(ce_hdr->reserved));
memcpy(ce_hdr->entries, crash_data->ce_crash_data,
CE_COUNT * sizeof(ce_hdr->entries[0]));
sofar += sizeof(*dump_tlv) + sizeof(*ce_hdr) +
CE_COUNT * sizeof(ce_hdr->entries[0]);
if (test_bit(ATH10K_FW_CRASH_DUMP_REGISTERS, &ath10k_coredump_mask)) {
dump_tlv = (struct ath10k_tlv_dump_data *)(buf + sofar);
dump_tlv->type = cpu_to_le32(ATH10K_FW_CRASH_DUMP_REGISTERS);
dump_tlv->tlv_len = cpu_to_le32(sizeof(crash_data->registers));
memcpy(dump_tlv->tlv_data, &crash_data->registers,
sizeof(crash_data->registers));
sofar += sizeof(*dump_tlv) + sizeof(crash_data->registers);
}
if (test_bit(ATH10K_FW_CRASH_DUMP_CE_DATA, &ath10k_coredump_mask)) {
dump_tlv = (struct ath10k_tlv_dump_data *)(buf + sofar);
dump_tlv->type = cpu_to_le32(ATH10K_FW_CRASH_DUMP_CE_DATA);
dump_tlv->tlv_len = cpu_to_le32(sizeof(*ce_hdr) +
CE_COUNT * sizeof(ce_hdr->entries[0]));
ce_hdr = (struct ath10k_ce_crash_hdr *)(dump_tlv->tlv_data);
ce_hdr->ce_count = cpu_to_le32(CE_COUNT);
memset(ce_hdr->reserved, 0, sizeof(ce_hdr->reserved));
memcpy(ce_hdr->entries, crash_data->ce_crash_data,
CE_COUNT * sizeof(ce_hdr->entries[0]));
sofar += sizeof(*dump_tlv) + sizeof(*ce_hdr) +
CE_COUNT * sizeof(ce_hdr->entries[0]);
}
spin_unlock_bh(&ar->data_lock);
......@@ -121,6 +132,10 @@ int ath10k_coredump_submit(struct ath10k *ar)
{
struct ath10k_dump_file_data *dump;
if (ath10k_coredump_mask == 0)
/* coredump disabled */
return 0;
dump = ath10k_coredump_build(ar);
if (!dump) {
ath10k_warn(ar, "no crash dump data found for devcoredump");
......@@ -134,6 +149,10 @@ int ath10k_coredump_submit(struct ath10k *ar)
int ath10k_coredump_create(struct ath10k *ar)
{
if (ath10k_coredump_mask == 0)
/* coredump disabled */
return 0;
ar->coredump.fw_crash_data = vzalloc(sizeof(*ar->coredump.fw_crash_data));
if (!ar->coredump.fw_crash_data)
return -ENOMEM;
......
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