From: greearb@candelatech.com To: ath10k@lists.infradead.org Cc: linux-wireless@vger.kernel.org, Ben Greear <greearb@candelatech.com>, Kalle Valo <kvalo@qca.qualcomm.com> Subject: [PATCH 07/21] ath10k: save firmware RAM and ROM BSS sections on crash Date: Mon, 9 May 2016 16:11:01 -0700 [thread overview] Message-ID: <1462835475-11079-8-git-send-email-greearb@candelatech.com> (raw) In-Reply-To: <1462835475-11079-1-git-send-email-greearb@candelatech.com> From: Ben Greear <greearb@candelatech.com> This can be used to get a useful back trace out of a firmware crash that involves an interrupt handler. For instance, a null-pointer-exception would be this kind of trace. A user-space tool can read the debugfs file and decode things as wished. This requires a packaged firmware with a new IE to describe the BSS section starts and length. Signed-off-by: Ben Greear <greearb@candelatech.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com> --- drivers/net/wireless/ath/ath10k/core.c | 48 +++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath10k/core.h | 14 +++++++++ drivers/net/wireless/ath/ath10k/debug.c | 40 +++++++++++++++++++++++- drivers/net/wireless/ath/ath10k/hw.h | 2 ++ drivers/net/wireless/ath/ath10k/pci.c | 54 +++++++++++++++++++++++++++++++++ 5 files changed, 157 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index b7318b8..3f1786c 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -922,6 +922,13 @@ err: return ret; } +struct ath10k_bss_rom_ie { + __le32 ram_addr; + __le32 ram_len; + __le32 rom_addr; + __le32 rom_len; +} __packed; + static int ath10k_core_create_board_name(struct ath10k *ar, char *name, size_t name_len) { @@ -983,6 +990,7 @@ int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name, struct ath10k_fw_ie *hdr; const u8 *data; __le32 *timestamp, *version; + struct ath10k_bss_rom_ie *bss; /* first fetch the firmware file (firmware-*.bin) */ fw_file->firmware = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir, @@ -1100,6 +1108,12 @@ int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name, break; case ATH10K_FW_IE_WMI_OP_VERSION: + /* Upstream stole the ID CT firmware was using, so add + * hack-around to deal with backwards-compat. --Ben + */ + if (ie_len >= sizeof(*bss)) + goto fw_ie_bss_info_ct; + if (ie_len != sizeof(u32)) break; @@ -1128,6 +1142,40 @@ int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name, fw_file->codeswap_data = data; fw_file->codeswap_len = ie_len; break; + case ATH10K_FW_IE_BSS_INFO_CT: +fw_ie_bss_info_ct: + if (ie_len < sizeof(*bss)) { + ath10k_warn(ar, "invalid ie len for bss-info (%zd)\n", + ie_len); + break; + } + bss = (struct ath10k_bss_rom_ie *)(data); + + fw_file->ram_bss_addr = le32_to_cpu(bss->ram_addr); + fw_file->ram_bss_len = le32_to_cpu(bss->ram_len); + ath10k_dbg(ar, ATH10K_DBG_BOOT, + "found RAM BSS addr 0x%x length %d\n", + fw_file->ram_bss_addr, fw_file->ram_bss_len); + + if (fw_file->ram_bss_len > ATH10K_RAM_BSS_BUF_LEN) { + ath10k_warn(ar, "too long firmware RAM BSS length: %d\n", + fw_file->ram_bss_len); + fw_file->ram_bss_len = 0; + } + + fw_file->rom_bss_addr = le32_to_cpu(bss->rom_addr); + fw_file->rom_bss_len = le32_to_cpu(bss->rom_len); + ath10k_dbg(ar, ATH10K_DBG_BOOT, + "found ROM BSS addr 0x%x length %d\n", + fw_file->rom_bss_addr, fw_file->rom_bss_len); + + if (fw_file->rom_bss_len > ATH10K_ROM_BSS_BUF_LEN) { + ath10k_warn(ar, "too long firmware ROM BSS length: %d\n", + fw_file->rom_bss_len); + fw_file->rom_bss_len = 0; + } + + break; default: ath10k_warn(ar, "Unknown FW IE: %u\n", le32_to_cpu(hdr->id)); diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 644d077..6aa7a14 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -420,6 +420,10 @@ struct ath10k_dbglog_entry_storage { #define DBGLOG_NUM_ARGS_MASK 0xFC000000 /* Bit 26-31 */ #define DBGLOG_NUM_ARGS_MAX 5 /* firmware tool chain limit */ +/* estimated values, hopefully these are enough */ +#define ATH10K_ROM_BSS_BUF_LEN 30000 +#define ATH10K_RAM_BSS_BUF_LEN 10000 + /* used for crash-dump storage, protected by data-lock */ struct ath10k_fw_crash_data { bool crashed_since_read; @@ -431,6 +435,8 @@ struct ath10k_fw_crash_data { __le32 exc_stack_buf[ATH10K_FW_STACK_SIZE / sizeof(__le32)]; __le32 stack_addr; __le32 exc_stack_addr; + __le32 rom_bss_buf[ATH10K_ROM_BSS_BUF_LEN / sizeof(__le32)]; + __le32 ram_bss_buf[ATH10K_RAM_BSS_BUF_LEN / sizeof(__le32)]; }; struct ath10k_debug { @@ -666,6 +672,14 @@ struct ath10k_fw_file { const void *codeswap_data; size_t codeswap_len; + + /* These are written to only during first firmware load from user + * space so no need for any locking. + */ + u32 ram_bss_addr; + u32 ram_bss_len; + u32 rom_bss_addr; + u32 rom_bss_len; }; struct ath10k_fw_components { diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index 7bc3053..28e0c05 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -38,12 +38,16 @@ * @ATH10K_FW_ERROR_DUMP_DBGLOG: Recent firmware debug log entries * @ATH10K_FW_CRASH_DUMP_STACK: Stack memory contents. * @ATH10K_FW_CRASH_DUMP_EXC_STACK: Exception stack memory contents. + * @ATH10K_FW_CRASH_DUMP_RAM_BSS: BSS area for RAM code + * @ATH10K_FW_CRASH_DUMP_ROM_BSS: BSS area for ROM code */ enum ath10k_fw_crash_dump_type { ATH10K_FW_CRASH_DUMP_REGISTERS = 0, ATH10K_FW_CRASH_DUMP_DBGLOG = 1, ATH10K_FW_CRASH_DUMP_STACK = 2, ATH10K_FW_CRASH_DUMP_EXC_STACK = 3, + ATH10K_FW_CRASH_DUMP_RAM_BSS = 4, + ATH10K_FW_CRASH_DUMP_ROM_BSS = 5, ATH10K_FW_CRASH_DUMP_MAX, }; @@ -110,9 +114,11 @@ struct ath10k_dump_file_data { __le32 stack_addr; __le32 exc_stack_addr; + __le32 rom_bss_addr; + __le32 ram_bss_addr; /* room for growth w/out changing binary format */ - u8 unused[120]; + u8 unused[112]; /* struct ath10k_tlv_dump_data + more */ u8 data[0]; @@ -808,6 +814,14 @@ static struct ath10k_dump_file_data *ath10k_build_dump_file(struct ath10k *ar) len += sizeof(*dump_tlv) + sizeof(crash_data->stack_buf); len += sizeof(*dump_tlv) + sizeof(crash_data->exc_stack_buf); + if (ar->running_fw->fw_file.ram_bss_addr && + ar->running_fw->fw_file.ram_bss_len) + len += sizeof(*dump_tlv) + ar->running_fw->fw_file.ram_bss_len; + + if (ar->running_fw->fw_file.rom_bss_addr && + ar->running_fw->fw_file.rom_bss_len) + len += sizeof(*dump_tlv) + ar->running_fw->fw_file.rom_bss_len; + sofar += hdr_len; /* This is going to get big when we start dumping FW RAM and such, @@ -848,6 +862,10 @@ static struct ath10k_dump_file_data *ath10k_build_dump_file(struct ath10k *ar) dump_data->num_rf_chains = cpu_to_le32(ar->num_rf_chains); dump_data->stack_addr = cpu_to_le32(crash_data->stack_addr); dump_data->exc_stack_addr = cpu_to_le32(crash_data->exc_stack_addr); + dump_data->rom_bss_addr = + cpu_to_le32(ar->running_fw->fw_file.rom_bss_addr); + dump_data->ram_bss_addr = + cpu_to_le32(ar->running_fw->fw_file.ram_bss_addr); strlcpy(dump_data->fw_ver, ar->hw->wiphy->fw_version, sizeof(dump_data->fw_ver)); @@ -898,6 +916,26 @@ static struct ath10k_dump_file_data *ath10k_build_dump_file(struct ath10k *ar) memcpy(dump_tlv->tlv_data, crash_data->exc_stack_buf, tmp); sofar += sizeof(*dump_tlv) + tmp; + if (ar->running_fw->fw_file.ram_bss_addr && + ar->running_fw->fw_file.ram_bss_len) { + tmp = ar->running_fw->fw_file.ram_bss_len; + dump_tlv = (struct ath10k_tlv_dump_data *)(buf + sofar); + dump_tlv->type = cpu_to_le32(ATH10K_FW_CRASH_DUMP_RAM_BSS); + dump_tlv->tlv_len = cpu_to_le32(tmp); + memcpy(dump_tlv->tlv_data, crash_data->ram_bss_buf, tmp); + sofar += sizeof(*dump_tlv) + tmp; + } + + if (ar->running_fw->fw_file.rom_bss_addr && + ar->running_fw->fw_file.rom_bss_len) { + tmp = ar->running_fw->fw_file.rom_bss_len; + dump_tlv = (struct ath10k_tlv_dump_data *)(buf + sofar); + dump_tlv->type = cpu_to_le32(ATH10K_FW_CRASH_DUMP_ROM_BSS); + dump_tlv->tlv_len = cpu_to_le32(tmp); + memcpy(dump_tlv->tlv_data, crash_data->rom_bss_buf, tmp); + sofar += sizeof(*dump_tlv) + tmp; + } + ar->debug.fw_crash_data->crashed_since_read = false; WARN_ON(sofar != len); diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h index e86ebf0..7b80e29 100644 --- a/drivers/net/wireless/ath/ath10k/hw.h +++ b/drivers/net/wireless/ath/ath10k/hw.h @@ -149,6 +149,8 @@ enum ath10k_fw_ie_type { /* Code swap image for firmware binary */ ATH10K_FW_IE_FW_CODE_SWAP_IMAGE = 7, + + ATH10K_FW_IE_BSS_INFO_CT = 30, }; enum ath10k_fw_wmi_op_version { diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 62dd167..e6315ec 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -1424,6 +1424,58 @@ u16 ath10k_pci_hif_get_free_queue_number(struct ath10k *ar, u8 pipe) return ath10k_ce_num_free_src_entries(ar_pci->pipe_info[pipe].ce_hdl); } +static void ath10k_pci_dump_bss_ram(struct ath10k *ar, + struct ath10k_fw_crash_data *crash_data) +{ + int ret; + + if (!crash_data) + return; + + lockdep_assert_held(&ar->data_lock); + + if (!ar->running_fw->fw_file.ram_bss_addr) + return; + + if (!ar->running_fw->fw_file.ram_bss_len) + return; + + ret = ath10k_pci_diag_read_mem(ar, ar->running_fw->fw_file.ram_bss_addr, + crash_data->ram_bss_buf, + ar->running_fw->fw_file.ram_bss_len); + if (ret) + ath10k_warn(ar, + "failed to read firmware RAM BSS memory from %d (%d B): %d\n", + ar->running_fw->fw_file.ram_bss_addr, + ar->running_fw->fw_file.ram_bss_len, ret); +} + +static void ath10k_pci_dump_bss_rom(struct ath10k *ar, + struct ath10k_fw_crash_data *crash_data) +{ + int ret; + + if (!crash_data) + return; + + lockdep_assert_held(&ar->data_lock); + + if (!ar->running_fw->fw_file.rom_bss_addr) + return; + + if (!ar->running_fw->fw_file.rom_bss_len) + return; + + ret = ath10k_pci_diag_read_mem(ar, ar->running_fw->fw_file.rom_bss_addr, + crash_data->rom_bss_buf, + ar->running_fw->fw_file.rom_bss_len); + if (ret) + ath10k_warn(ar, + "failed to read firmware ROM BSS memory from %d (%d B): %d\n", + ar->running_fw->fw_file.rom_bss_addr, + ar->running_fw->fw_file.rom_bss_len, ret); +} + /* Save the main firmware stack */ static void ath10k_pci_dump_stack(struct ath10k *ar, struct ath10k_fw_crash_data *crash_data) @@ -1607,6 +1659,8 @@ static void ath10k_pci_fw_crashed_dump(struct ath10k *ar) ath10k_pci_dump_dbglog(ar); ath10k_pci_dump_stack(ar, crash_data); ath10k_pci_dump_exc_stack(ar, crash_data); + ath10k_pci_dump_bss_ram(ar, crash_data); + ath10k_pci_dump_bss_rom(ar, crash_data); if (crash_data) crash_data->crashed_since_read = true; -- 2.4.3
WARNING: multiple messages have this Message-ID (diff)
From: greearb@candelatech.com To: ath10k@lists.infradead.org Cc: Ben Greear <greearb@candelatech.com>, linux-wireless@vger.kernel.org, Kalle Valo <kvalo@qca.qualcomm.com> Subject: [PATCH 07/21] ath10k: save firmware RAM and ROM BSS sections on crash Date: Mon, 9 May 2016 16:11:01 -0700 [thread overview] Message-ID: <1462835475-11079-8-git-send-email-greearb@candelatech.com> (raw) In-Reply-To: <1462835475-11079-1-git-send-email-greearb@candelatech.com> From: Ben Greear <greearb@candelatech.com> This can be used to get a useful back trace out of a firmware crash that involves an interrupt handler. For instance, a null-pointer-exception would be this kind of trace. A user-space tool can read the debugfs file and decode things as wished. This requires a packaged firmware with a new IE to describe the BSS section starts and length. Signed-off-by: Ben Greear <greearb@candelatech.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com> --- drivers/net/wireless/ath/ath10k/core.c | 48 +++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath10k/core.h | 14 +++++++++ drivers/net/wireless/ath/ath10k/debug.c | 40 +++++++++++++++++++++++- drivers/net/wireless/ath/ath10k/hw.h | 2 ++ drivers/net/wireless/ath/ath10k/pci.c | 54 +++++++++++++++++++++++++++++++++ 5 files changed, 157 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index b7318b8..3f1786c 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -922,6 +922,13 @@ err: return ret; } +struct ath10k_bss_rom_ie { + __le32 ram_addr; + __le32 ram_len; + __le32 rom_addr; + __le32 rom_len; +} __packed; + static int ath10k_core_create_board_name(struct ath10k *ar, char *name, size_t name_len) { @@ -983,6 +990,7 @@ int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name, struct ath10k_fw_ie *hdr; const u8 *data; __le32 *timestamp, *version; + struct ath10k_bss_rom_ie *bss; /* first fetch the firmware file (firmware-*.bin) */ fw_file->firmware = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir, @@ -1100,6 +1108,12 @@ int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name, break; case ATH10K_FW_IE_WMI_OP_VERSION: + /* Upstream stole the ID CT firmware was using, so add + * hack-around to deal with backwards-compat. --Ben + */ + if (ie_len >= sizeof(*bss)) + goto fw_ie_bss_info_ct; + if (ie_len != sizeof(u32)) break; @@ -1128,6 +1142,40 @@ int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name, fw_file->codeswap_data = data; fw_file->codeswap_len = ie_len; break; + case ATH10K_FW_IE_BSS_INFO_CT: +fw_ie_bss_info_ct: + if (ie_len < sizeof(*bss)) { + ath10k_warn(ar, "invalid ie len for bss-info (%zd)\n", + ie_len); + break; + } + bss = (struct ath10k_bss_rom_ie *)(data); + + fw_file->ram_bss_addr = le32_to_cpu(bss->ram_addr); + fw_file->ram_bss_len = le32_to_cpu(bss->ram_len); + ath10k_dbg(ar, ATH10K_DBG_BOOT, + "found RAM BSS addr 0x%x length %d\n", + fw_file->ram_bss_addr, fw_file->ram_bss_len); + + if (fw_file->ram_bss_len > ATH10K_RAM_BSS_BUF_LEN) { + ath10k_warn(ar, "too long firmware RAM BSS length: %d\n", + fw_file->ram_bss_len); + fw_file->ram_bss_len = 0; + } + + fw_file->rom_bss_addr = le32_to_cpu(bss->rom_addr); + fw_file->rom_bss_len = le32_to_cpu(bss->rom_len); + ath10k_dbg(ar, ATH10K_DBG_BOOT, + "found ROM BSS addr 0x%x length %d\n", + fw_file->rom_bss_addr, fw_file->rom_bss_len); + + if (fw_file->rom_bss_len > ATH10K_ROM_BSS_BUF_LEN) { + ath10k_warn(ar, "too long firmware ROM BSS length: %d\n", + fw_file->rom_bss_len); + fw_file->rom_bss_len = 0; + } + + break; default: ath10k_warn(ar, "Unknown FW IE: %u\n", le32_to_cpu(hdr->id)); diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 644d077..6aa7a14 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -420,6 +420,10 @@ struct ath10k_dbglog_entry_storage { #define DBGLOG_NUM_ARGS_MASK 0xFC000000 /* Bit 26-31 */ #define DBGLOG_NUM_ARGS_MAX 5 /* firmware tool chain limit */ +/* estimated values, hopefully these are enough */ +#define ATH10K_ROM_BSS_BUF_LEN 30000 +#define ATH10K_RAM_BSS_BUF_LEN 10000 + /* used for crash-dump storage, protected by data-lock */ struct ath10k_fw_crash_data { bool crashed_since_read; @@ -431,6 +435,8 @@ struct ath10k_fw_crash_data { __le32 exc_stack_buf[ATH10K_FW_STACK_SIZE / sizeof(__le32)]; __le32 stack_addr; __le32 exc_stack_addr; + __le32 rom_bss_buf[ATH10K_ROM_BSS_BUF_LEN / sizeof(__le32)]; + __le32 ram_bss_buf[ATH10K_RAM_BSS_BUF_LEN / sizeof(__le32)]; }; struct ath10k_debug { @@ -666,6 +672,14 @@ struct ath10k_fw_file { const void *codeswap_data; size_t codeswap_len; + + /* These are written to only during first firmware load from user + * space so no need for any locking. + */ + u32 ram_bss_addr; + u32 ram_bss_len; + u32 rom_bss_addr; + u32 rom_bss_len; }; struct ath10k_fw_components { diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index 7bc3053..28e0c05 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -38,12 +38,16 @@ * @ATH10K_FW_ERROR_DUMP_DBGLOG: Recent firmware debug log entries * @ATH10K_FW_CRASH_DUMP_STACK: Stack memory contents. * @ATH10K_FW_CRASH_DUMP_EXC_STACK: Exception stack memory contents. + * @ATH10K_FW_CRASH_DUMP_RAM_BSS: BSS area for RAM code + * @ATH10K_FW_CRASH_DUMP_ROM_BSS: BSS area for ROM code */ enum ath10k_fw_crash_dump_type { ATH10K_FW_CRASH_DUMP_REGISTERS = 0, ATH10K_FW_CRASH_DUMP_DBGLOG = 1, ATH10K_FW_CRASH_DUMP_STACK = 2, ATH10K_FW_CRASH_DUMP_EXC_STACK = 3, + ATH10K_FW_CRASH_DUMP_RAM_BSS = 4, + ATH10K_FW_CRASH_DUMP_ROM_BSS = 5, ATH10K_FW_CRASH_DUMP_MAX, }; @@ -110,9 +114,11 @@ struct ath10k_dump_file_data { __le32 stack_addr; __le32 exc_stack_addr; + __le32 rom_bss_addr; + __le32 ram_bss_addr; /* room for growth w/out changing binary format */ - u8 unused[120]; + u8 unused[112]; /* struct ath10k_tlv_dump_data + more */ u8 data[0]; @@ -808,6 +814,14 @@ static struct ath10k_dump_file_data *ath10k_build_dump_file(struct ath10k *ar) len += sizeof(*dump_tlv) + sizeof(crash_data->stack_buf); len += sizeof(*dump_tlv) + sizeof(crash_data->exc_stack_buf); + if (ar->running_fw->fw_file.ram_bss_addr && + ar->running_fw->fw_file.ram_bss_len) + len += sizeof(*dump_tlv) + ar->running_fw->fw_file.ram_bss_len; + + if (ar->running_fw->fw_file.rom_bss_addr && + ar->running_fw->fw_file.rom_bss_len) + len += sizeof(*dump_tlv) + ar->running_fw->fw_file.rom_bss_len; + sofar += hdr_len; /* This is going to get big when we start dumping FW RAM and such, @@ -848,6 +862,10 @@ static struct ath10k_dump_file_data *ath10k_build_dump_file(struct ath10k *ar) dump_data->num_rf_chains = cpu_to_le32(ar->num_rf_chains); dump_data->stack_addr = cpu_to_le32(crash_data->stack_addr); dump_data->exc_stack_addr = cpu_to_le32(crash_data->exc_stack_addr); + dump_data->rom_bss_addr = + cpu_to_le32(ar->running_fw->fw_file.rom_bss_addr); + dump_data->ram_bss_addr = + cpu_to_le32(ar->running_fw->fw_file.ram_bss_addr); strlcpy(dump_data->fw_ver, ar->hw->wiphy->fw_version, sizeof(dump_data->fw_ver)); @@ -898,6 +916,26 @@ static struct ath10k_dump_file_data *ath10k_build_dump_file(struct ath10k *ar) memcpy(dump_tlv->tlv_data, crash_data->exc_stack_buf, tmp); sofar += sizeof(*dump_tlv) + tmp; + if (ar->running_fw->fw_file.ram_bss_addr && + ar->running_fw->fw_file.ram_bss_len) { + tmp = ar->running_fw->fw_file.ram_bss_len; + dump_tlv = (struct ath10k_tlv_dump_data *)(buf + sofar); + dump_tlv->type = cpu_to_le32(ATH10K_FW_CRASH_DUMP_RAM_BSS); + dump_tlv->tlv_len = cpu_to_le32(tmp); + memcpy(dump_tlv->tlv_data, crash_data->ram_bss_buf, tmp); + sofar += sizeof(*dump_tlv) + tmp; + } + + if (ar->running_fw->fw_file.rom_bss_addr && + ar->running_fw->fw_file.rom_bss_len) { + tmp = ar->running_fw->fw_file.rom_bss_len; + dump_tlv = (struct ath10k_tlv_dump_data *)(buf + sofar); + dump_tlv->type = cpu_to_le32(ATH10K_FW_CRASH_DUMP_ROM_BSS); + dump_tlv->tlv_len = cpu_to_le32(tmp); + memcpy(dump_tlv->tlv_data, crash_data->rom_bss_buf, tmp); + sofar += sizeof(*dump_tlv) + tmp; + } + ar->debug.fw_crash_data->crashed_since_read = false; WARN_ON(sofar != len); diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h index e86ebf0..7b80e29 100644 --- a/drivers/net/wireless/ath/ath10k/hw.h +++ b/drivers/net/wireless/ath/ath10k/hw.h @@ -149,6 +149,8 @@ enum ath10k_fw_ie_type { /* Code swap image for firmware binary */ ATH10K_FW_IE_FW_CODE_SWAP_IMAGE = 7, + + ATH10K_FW_IE_BSS_INFO_CT = 30, }; enum ath10k_fw_wmi_op_version { diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 62dd167..e6315ec 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -1424,6 +1424,58 @@ u16 ath10k_pci_hif_get_free_queue_number(struct ath10k *ar, u8 pipe) return ath10k_ce_num_free_src_entries(ar_pci->pipe_info[pipe].ce_hdl); } +static void ath10k_pci_dump_bss_ram(struct ath10k *ar, + struct ath10k_fw_crash_data *crash_data) +{ + int ret; + + if (!crash_data) + return; + + lockdep_assert_held(&ar->data_lock); + + if (!ar->running_fw->fw_file.ram_bss_addr) + return; + + if (!ar->running_fw->fw_file.ram_bss_len) + return; + + ret = ath10k_pci_diag_read_mem(ar, ar->running_fw->fw_file.ram_bss_addr, + crash_data->ram_bss_buf, + ar->running_fw->fw_file.ram_bss_len); + if (ret) + ath10k_warn(ar, + "failed to read firmware RAM BSS memory from %d (%d B): %d\n", + ar->running_fw->fw_file.ram_bss_addr, + ar->running_fw->fw_file.ram_bss_len, ret); +} + +static void ath10k_pci_dump_bss_rom(struct ath10k *ar, + struct ath10k_fw_crash_data *crash_data) +{ + int ret; + + if (!crash_data) + return; + + lockdep_assert_held(&ar->data_lock); + + if (!ar->running_fw->fw_file.rom_bss_addr) + return; + + if (!ar->running_fw->fw_file.rom_bss_len) + return; + + ret = ath10k_pci_diag_read_mem(ar, ar->running_fw->fw_file.rom_bss_addr, + crash_data->rom_bss_buf, + ar->running_fw->fw_file.rom_bss_len); + if (ret) + ath10k_warn(ar, + "failed to read firmware ROM BSS memory from %d (%d B): %d\n", + ar->running_fw->fw_file.rom_bss_addr, + ar->running_fw->fw_file.rom_bss_len, ret); +} + /* Save the main firmware stack */ static void ath10k_pci_dump_stack(struct ath10k *ar, struct ath10k_fw_crash_data *crash_data) @@ -1607,6 +1659,8 @@ static void ath10k_pci_fw_crashed_dump(struct ath10k *ar) ath10k_pci_dump_dbglog(ar); ath10k_pci_dump_stack(ar, crash_data); ath10k_pci_dump_exc_stack(ar, crash_data); + ath10k_pci_dump_bss_ram(ar, crash_data); + ath10k_pci_dump_bss_rom(ar, crash_data); if (crash_data) crash_data->crashed_since_read = true; -- 2.4.3 _______________________________________________ ath10k mailing list ath10k@lists.infradead.org http://lists.infradead.org/mailman/listinfo/ath10k
next prev parent reply other threads:[~2016-05-09 23:11 UTC|newest] Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top 2016-05-09 23:10 [PATCH 00/21] ath10k patches, generic and CT firmware related greearb 2016-05-09 23:10 ` greearb 2016-05-09 23:10 ` [PATCH 01/21] ath10k: Fix crash related to printing features greearb 2016-05-09 23:10 ` greearb 2016-05-09 23:10 ` [PATCH 02/21] ath10k: fix typo in logging message greearb 2016-05-09 23:10 ` greearb 2016-05-09 23:10 ` [PATCH 03/21] ath10k: Support setting debug mask from driver code greearb 2016-05-09 23:10 ` greearb 2016-05-11 10:40 ` Michal Kazior 2016-05-11 10:40 ` Michal Kazior 2016-05-11 15:10 ` Ben Greear 2016-05-11 15:10 ` Ben Greear 2016-05-09 23:10 ` [PATCH 04/21] ath10k: rate-limit packet tx errors greearb 2016-05-09 23:10 ` greearb 2016-05-09 23:10 ` [PATCH 05/21] ath10k: save firmware debug log messages greearb 2016-05-09 23:10 ` greearb 2016-05-09 23:11 ` [PATCH 06/21] ath10k: save firmware stacks upon firmware crash greearb 2016-05-09 23:11 ` greearb 2016-05-09 23:11 ` greearb [this message] 2016-05-09 23:11 ` [PATCH 07/21] ath10k: save firmware RAM and ROM BSS sections on crash greearb 2016-05-09 23:11 ` [PATCH 08/21] ath10k: make firmware text debug messages more verbose greearb 2016-05-09 23:11 ` greearb 2016-05-09 23:11 ` [PATCH 09/21] ath10k: print fw debug messages in hex greearb 2016-05-09 23:11 ` greearb 2016-05-09 23:11 ` [PATCH 10/21] ath10k: support logging ath10k_info as KERN_DEBUG greearb 2016-05-09 23:11 ` greearb 2016-05-09 23:11 ` [PATCH 11/21] ath10k: add fw-powerup-fail to ethtool stats greearb 2016-05-09 23:11 ` greearb 2016-05-09 23:11 ` [PATCH 12/21] ath10k: Support up to 64 vdevs greearb 2016-05-09 23:11 ` greearb 2016-05-09 23:11 ` [PATCH 13/21] ath10k: Document cycle count related counters greearb 2016-05-09 23:11 ` greearb 2016-05-11 10:24 ` Michal Kazior 2016-05-11 10:24 ` Michal Kazior 2016-05-09 23:11 ` [PATCH 14/21] ath10k: Add tx/rx bytes, cycle counters to ethtool stats greearb 2016-05-09 23:11 ` greearb 2016-05-09 23:11 ` [PATCH 15/21] ath10k: support CT firmware flag greearb 2016-05-09 23:11 ` greearb 2016-05-10 7:20 ` Mohammed Shafi Shajakhan 2016-05-10 7:20 ` Mohammed Shafi Shajakhan 2016-05-10 14:52 ` Ben Greear 2016-05-10 14:52 ` Ben Greear 2016-05-09 23:11 ` [PATCH 16/21] ath10k: Support 32+ stations greearb 2016-05-09 23:11 ` greearb 2016-05-09 23:11 ` [PATCH 17/21] ath10k: Enable detecting failure to install key in firmware (CT) greearb 2016-05-09 23:11 ` greearb 2016-05-09 23:11 ` [PATCH 18/21] ath10k: Note limitation on beaconing vdevs greearb 2016-05-09 23:11 ` greearb 2016-05-09 23:11 ` [PATCH 19/21] ath10k: Enable adhoc mode for CT firmware greearb 2016-05-09 23:11 ` greearb 2016-05-09 23:11 ` [PATCH 20/21] ath10k: read firmware crash over ioread32 if CE fails greearb 2016-05-09 23:11 ` greearb 2016-05-09 23:11 ` [PATCH 21/21] ath10k: Read dbglog buffers over register ping-pong greearb 2016-05-09 23:11 ` greearb
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1462835475-11079-8-git-send-email-greearb@candelatech.com \ --to=greearb@candelatech.com \ --cc=ath10k@lists.infradead.org \ --cc=kvalo@qca.qualcomm.com \ --cc=linux-wireless@vger.kernel.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.