wlan-ap-Telecominfraproject/feeds/wifi-ax/mac80211/patches/qca/197-ath11k-add-support-to-collect-q6mem-dump.patch
John Crispin 528a778e38 open-converged-wireless: Import 21.02 based uCentral tree
Signed-off-by: John Crispin <john@phrozen.org>
2021-03-25 12:19:47 +01:00

216 lines
7.4 KiB
Diff

From b3213496ab8688c6ef6f92be1dce0d1ed32ca9e3 Mon Sep 17 00:00:00 2001
From: Ramya Gnanasekar <rgnanase@codeaurora.org>
Date: Thu, 9 Jul 2020 10:48:15 +0530
Subject: [PATCH] ath11k: add support to collect q6mem dump
q6mem dump is not collected when fw crashes due to system restart.
Implemented a knob in debugfs to enable/disable fw recovery from
qsdk to collect q6mem dump .
root@OpenWrt:~# echo 1 > /sys/kernel/debug/ath11k/ipq6018_2/set_fw_recovery
root@OpenWrt:~# cat /sys/kernel/debug/ath11k/ipq6018_2/set_fw_recovery
1
Signed-off-by: Ramya Gnanasekar <rgnanase@codeaurora.org>
---
drivers/net/wireless/ath/ath11k/core.c | 3 ++-
drivers/net/wireless/ath/ath11k/core.h | 1 +
drivers/net/wireless/ath/ath11k/debug.c | 46 +++++++++++++++++++++++++++++++++
3 files changed, 49 insertions(+), 1 deletion(-)
--- a/drivers/net/wireless/ath/ath11k/core.c
+++ b/drivers/net/wireless/ath/ath11k/core.c
@@ -693,7 +693,8 @@ int ath11k_core_ssr_notifier_cb(struct n
/* TODO Add more driver stats */
/* Crash the system once all the stats are dumped */
- BUG_ON(1);
+ if(!qmi->ab->fw_recovery_support)
+ BUG_ON(1);
return 0;
}
--- a/drivers/net/wireless/ath/ath11k/core.h
+++ b/drivers/net/wireless/ath/ath11k/core.h
@@ -831,6 +831,7 @@ struct ath11k_base {
u32 num_db_cap;
u32 sw_pdev_id_map[MAX_RADIOS];
u32 hw_pdev_id_map[MAX_RADIOS];
+ bool fw_recovery_support;
/* must be last */
u8 drv_priv[0] __aligned(sizeof(void *));
};
@@ -990,6 +991,7 @@ void ath11k_core_free_bdf(struct ath11k_
void ath11k_core_halt(struct ath11k *ar);
+void ath11k_core_dump_bp_stats(struct ath11k_base *ab);
void ath11k_coredump_qdss_dump(struct ath11k_base *ab,
struct ath11k_qmi_event_qdss_trace_save_data *event_data);
const struct firmware *ath11k_core_firmware_request(struct ath11k_base *ab,
--- a/drivers/net/wireless/ath/ath11k/debug.c
+++ b/drivers/net/wireless/ath/ath11k/debug.c
@@ -1207,6 +1207,48 @@ static const struct file_operations fops
.llseek = default_llseek,
};
+static ssize_t ath11k_debug_write_fw_recovery(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath11k_base *ab = file->private_data;
+ bool enable;
+ int ret;
+
+ if (kstrtobool_from_user(user_buf, count, &enable))
+ return -EINVAL;
+
+ if (enable == ab->fw_recovery_support) {
+ ret = count;
+ goto exit;
+ }
+
+ ab->fw_recovery_support = enable;
+ ret = count;
+
+exit:
+ return ret;
+}
+
+static ssize_t ath11k_debug_read_fw_recovery(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath11k_base *ab = file->private_data;
+ char buf[32];
+ size_t len;
+
+ len = scnprintf(buf, sizeof(buf), "%u\n", ab->fw_recovery_support);
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static const struct file_operations fops_fw_recovery = {
+ .read = ath11k_debug_read_fw_recovery,
+ .write = ath11k_debug_write_fw_recovery,
+ .open = simple_open,
+};
+
int ath11k_debug_pdev_create(struct ath11k_base *ab)
{
if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags))
@@ -1221,6 +1263,10 @@ int ath11k_debug_pdev_create(struct ath1
debugfs_create_file("soc_dp_stats", 0600, ab->debugfs_soc, ab,
&fops_soc_dp_stats);
+ debugfs_create_file("set_fw_recovery", 0600, ab->debugfs_soc, ab,
+ &fops_fw_recovery);
+
+
return 0;
}
--- a/drivers/net/wireless/ath/ath11k/pci.c
+++ b/drivers/net/wireless/ath/ath11k/pci.c
@@ -982,6 +982,8 @@ static int ath11k_pci_probe(struct pci_d
ab_pci->pdev = pdev;
ab->hif.ops = &ath11k_pci_hif_ops;
pci_set_drvdata(pdev, ab);
+ ab->fw_recovery_support = false;
+
spin_lock_init(&ab_pci->window_lock);
switch (pci_dev->device) {
--- a/drivers/net/wireless/ath/ath11k/coredump.c
+++ b/drivers/net/wireless/ath/ath11k/coredump.c
@@ -162,13 +162,16 @@ void ath11k_coredump_download_rddm(struc
fw_img = mhi_ctrl->fbc_image;
for (i = 0; i < ab->qmi.mem_seg_count; i++) {
- if (ab->qmi.target_mem[i].type == HOST_DDR_REGION_TYPE)
+ if (ab->qmi.target_mem[i].type == HOST_DDR_REGION_TYPE ||
+ ab->qmi.target_mem[i].type == CALDB_MEM_REGION_TYPE ||
+ ab->qmi.target_mem[i].type == M3_DUMP_REGION_TYPE)
rem_seg_cnt++;
}
num_seg = fw_img->entries + rddm_img->entries + rem_seg_cnt;
if (ab->is_qdss_tracing)
num_seg += qdss_seg_cnt;
+
len = num_seg * sizeof(*segment);
seg_info = segment = (struct ath11k_dump_segment *)vzalloc(len);
@@ -195,31 +198,46 @@ void ath11k_coredump_download_rddm(struc
ath11k_info(ab, "seg vaddr is %px len is 0x%x type %d\n",
seg_info->vaddr, seg_info->len, seg_info->type);
seg_info->type = ATH11K_FW_CRASH_RDDM_DATA;
+ ath11k_info(ab, "seg vaddr is %px len is 0x%x type %d\n",
+ seg_info->vaddr, seg_info->len, seg_info->type);
seg_info++;
}
for (i = 0; i < ab->qmi.mem_seg_count; i++) {
- if (ab->qmi.target_mem[i].type != HOST_DDR_REGION_TYPE)
- continue;
- seg_info->len = ab->qmi.target_mem[i].size;
- seg_info->addr = ab->qmi.target_mem[i].paddr;
- seg_info->vaddr = ab->qmi.target_mem[i].vaddr;
- ath11k_info(ab, "seg vaddr is %px len is 0x%x type %d\n",
- seg_info->vaddr, seg_info->len, seg_info->type);
- seg_info->type = ATH11K_FW_REMOTE_MEM_DATA;
- seg_info++;
+ if (ab->qmi.target_mem[i].type == HOST_DDR_REGION_TYPE ||
+ ab->qmi.target_mem[i].type == M3_DUMP_REGION_TYPE) {
+ seg_info->len = ab->qmi.target_mem[i].size;
+ seg_info->addr = ab->qmi.target_mem[i].paddr;
+ seg_info->vaddr = ab->qmi.target_mem[i].vaddr;
+ seg_info->type = ATH11K_FW_REMOTE_MEM_DATA;
+ ath11k_info(ab, "seg vaddr is %px len is 0x%x type %d\n",
+ seg_info->vaddr, seg_info->len, seg_info->type);
+ seg_info++;
+ }
}
if (ab->is_qdss_tracing) {
seg_info->len = ab->qmi.qdss_mem[0].size;
seg_info->addr = ab->qmi.qdss_mem[0].paddr;
seg_info->vaddr = ab->qmi.qdss_mem[0].vaddr;
- ath11k_dbg(ab, ATH11K_DBG_QMI, "seg vaddr is %px len is 0x%x type %d\n",
- seg_info->vaddr, seg_info->len, seg_info->type);
- seg_info->type = ATH11K_FW_QDSS_DATA;
+ seg_info->type = ATH11K_FW_REMOTE_MEM_DATA;
+ ath11k_info(ab, "seg vaddr is %px len is 0x%x type %d\n",
+ seg_info->vaddr, seg_info->len, seg_info->type);
seg_info++;
}
+ for (i = 0; i < ab->qmi.mem_seg_count; i++) {
+ if (ab->qmi.target_mem[i].type == CALDB_MEM_REGION_TYPE) {
+ seg_info->len = ab->qmi.target_mem[i].size;
+ seg_info->addr = ab->qmi.target_mem[i].paddr;
+ seg_info->vaddr = ab->qmi.target_mem[i].vaddr;
+ seg_info->type = ATH11K_FW_REMOTE_MEM_DATA;
+ ath11k_info(ab, "seg vaddr is %px len is 0x%x type %d\n",
+ seg_info->vaddr, seg_info->len, seg_info->type);
+ seg_info++;
+ }
+ }
+
/* Crash the system once all the stats are dumped */
if(!ab->fw_recovery_support) {
ath11k_core_dump_bp_stats(ab);
--- a/drivers/net/wireless/ath/ath11k/qmi.c
+++ b/drivers/net/wireless/ath/ath11k/qmi.c
@@ -2413,6 +2413,10 @@ static int ath11k_qmi_assign_target_mem_
ab->qmi.target_mem[idx].paddr = ab->hw_params.m3_addr;
else
ab->qmi.target_mem[idx].paddr = (phys_addr_t)addr;
+
+ ab->qmi.target_mem[idx].vaddr =
+ ioremap(ab->qmi.target_mem[idx].paddr,
+ ab->qmi.target_mem[i].size);
idx++;
break;
default: