Commit 3f14b73c authored by Govind Singh's avatar Govind Singh Committed by Kalle Valo

ath10k: Enable MSA region dump support for WCN3990

MSA memory region caries the hw descriptors information.
Dump MSA region in core dump as this is very helpful in debugging
hw issues.

Testing: Tested on WCN3990 HW
Tested FW: WLAN.HL.3.1-00959-QCAHLSWMTPLZ-1
Signed-off-by: default avatarGovind Singh <govinds@codeaurora.org>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 75f545e8
......@@ -951,6 +951,19 @@ static const struct ath10k_mem_region qca4019_hw10_mem_regions[] = {
},
};
static const struct ath10k_mem_region wcn399x_hw10_mem_regions[] = {
{
/* MSA region start is not fixed, hence it is assigned at runtime */
.type = ATH10K_MEM_REGION_TYPE_MSA,
.len = 0x100000,
.name = "DRAM",
.section_table = {
.sections = NULL,
.size = 0,
},
},
};
static const struct ath10k_hw_mem_layout hw_mem_layouts[] = {
{
.hw_id = QCA6174_HW_1_0_VERSION,
......@@ -1048,6 +1061,14 @@ static const struct ath10k_hw_mem_layout hw_mem_layouts[] = {
.size = ARRAY_SIZE(qca4019_hw10_mem_regions),
},
},
{
.hw_id = WCN3990_HW_1_0_DEV_VERSION,
.hw_rev = ATH10K_HW_WCN3990,
.region_table = {
.regions = wcn399x_hw10_mem_regions,
.size = ARRAY_SIZE(wcn399x_hw10_mem_regions),
},
},
};
static u32 ath10k_coredump_get_ramdump_size(struct ath10k *ar)
......
......@@ -115,6 +115,7 @@ enum ath10k_mem_region_type {
ATH10K_MEM_REGION_TYPE_IRAM2 = 5,
ATH10K_MEM_REGION_TYPE_IOSRAM = 6,
ATH10K_MEM_REGION_TYPE_IOREG = 7,
ATH10K_MEM_REGION_TYPE_MSA = 8,
};
/* Define a section of the region which should be copied. As not all parts
......
......@@ -829,9 +829,13 @@ ath10k_qmi_driver_event_post(struct ath10k_qmi *qmi,
static void ath10k_qmi_event_server_exit(struct ath10k_qmi *qmi)
{
struct ath10k *ar = qmi->ar;
struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
ath10k_qmi_remove_msa_permission(qmi);
ath10k_core_free_board_files(ar);
if (!test_bit(ATH10K_SNOC_FLAG_UNREGISTERING, &ar_snoc->flags))
ath10k_snoc_fw_crashed_dump(ar);
ath10k_snoc_fw_indication(ar, ATH10K_QMI_EVENT_FW_DOWN_IND);
ath10k_dbg(ar, ATH10K_DBG_QMI, "wifi fw qmi service disconnected\n");
}
......
......@@ -13,6 +13,7 @@
#include <linux/regulator/consumer.h>
#include "ce.h"
#include "coredump.h"
#include "debug.h"
#include "hif.h"
#include "htc.h"
......@@ -1389,6 +1390,71 @@ static int ath10k_hw_power_off(struct ath10k *ar)
return regulator_bulk_disable(ar_snoc->num_vregs, ar_snoc->vregs);
}
static void ath10k_msa_dump_memory(struct ath10k *ar,
struct ath10k_fw_crash_data *crash_data)
{
struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
const struct ath10k_hw_mem_layout *mem_layout;
const struct ath10k_mem_region *current_region;
struct ath10k_dump_ram_data_hdr *hdr;
size_t buf_len;
u8 *buf;
if (!crash_data && !crash_data->ramdump_buf)
return;
mem_layout = ath10k_coredump_get_mem_layout(ar);
if (!mem_layout)
return;
current_region = &mem_layout->region_table.regions[0];
buf = crash_data->ramdump_buf;
buf_len = crash_data->ramdump_buf_len;
memset(buf, 0, buf_len);
/* Reserve space for the header. */
hdr = (void *)buf;
buf += sizeof(*hdr);
buf_len -= sizeof(*hdr);
hdr->region_type = cpu_to_le32(current_region->type);
hdr->start = cpu_to_le32((unsigned long)ar_snoc->qmi->msa_va);
hdr->length = cpu_to_le32(ar_snoc->qmi->msa_mem_size);
if (current_region->len < ar_snoc->qmi->msa_mem_size) {
memcpy(buf, ar_snoc->qmi->msa_va, current_region->len);
ath10k_warn(ar, "msa dump length is less than msa size %x, %x\n",
current_region->len, ar_snoc->qmi->msa_mem_size);
} else {
memcpy(buf, ar_snoc->qmi->msa_va, ar_snoc->qmi->msa_mem_size);
}
}
void ath10k_snoc_fw_crashed_dump(struct ath10k *ar)
{
struct ath10k_fw_crash_data *crash_data;
char guid[UUID_STRING_LEN + 1];
mutex_lock(&ar->dump_mutex);
spin_lock_bh(&ar->data_lock);
ar->stats.fw_crash_counter++;
spin_unlock_bh(&ar->data_lock);
crash_data = ath10k_coredump_new(ar);
if (crash_data)
scnprintf(guid, sizeof(guid), "%pUl", &crash_data->guid);
else
scnprintf(guid, sizeof(guid), "n/a");
ath10k_err(ar, "firmware crashed! (guid %s)\n", guid);
ath10k_print_driver_info(ar);
ath10k_msa_dump_memory(ar, crash_data);
mutex_unlock(&ar->dump_mutex);
}
static const struct of_device_id ath10k_snoc_dt_match[] = {
{ .compatible = "qcom,wcn3990-wifi",
.data = &drv_priv,
......
......@@ -79,5 +79,6 @@ static inline struct ath10k_snoc *ath10k_snoc_priv(struct ath10k *ar)
}
int ath10k_snoc_fw_indication(struct ath10k *ar, u64 type);
void ath10k_snoc_fw_crashed_dump(struct ath10k *ar);
#endif /* _SNOC_H_ */
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