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