wlan-ap-Telecominfraproject/feeds/wifi-ax/mac80211/patches/qca/031-ath11k-print-stats-on-crash.patch
John Crispin 8cd26b4b50 ipq807x: update to 11.4-CS
Signed-off-by: John Crispin <john@phrozen.org>
2021-09-14 09:16:23 +02:00

171 lines
4.8 KiB
Diff

--- a/drivers/net/wireless/ath/ath11k/core.c
+++ b/drivers/net/wireless/ath/ath11k/core.c
@@ -30,6 +30,8 @@ module_param_named(frame_mode, ath11k_fr
MODULE_PARM_DESC(frame_mode,
"Datapath frame mode (0: raw, 1: native wifi (default), 2: ethernet)");
+struct ath11k_base *ath11k_soc;
+
static const struct ath11k_hw_params ath11k_hw_params[] = {
{
.hw_rev = ATH11K_HW_IPQ8074,
@@ -803,6 +805,62 @@ err_firmware_stop:
return ret;
}
+void ath11k_core_dump_bp_stats(struct ath11k_base *ab)
+{
+ int len = 0;
+ const int size = 4096;
+ char *buf;
+
+ buf = kzalloc(size, GFP_KERNEL);
+ if (!buf)
+ return;
+
+ len = ath11k_debugfs_dump_soc_ring_bp_stats(ab, buf, size - 1);
+
+ buf[len] = '\0';
+
+ ath11k_info(ab, "ATH11K Driver Stats\n%s\n", buf);
+
+ kfree(buf);
+}
+
+#ifdef CONFIG_QCOM_QMI_HELPERS
+
+/* Print the driver stats and crash the system on receving this notification */
+int ath11k_core_ssr_notifier_cb(struct notifier_block *nb, unsigned long event,
+ void *data)
+{
+ struct ath11k_qmi *qmi = container_of(nb, struct ath11k_qmi, ssr_nb);
+ struct ath11k_base *ab = qmi->ab;
+ struct device *dev = ab->dev;
+ bool multi_pd_arch = false;
+ const char *name;
+
+ if (test_bit(ATH11K_FLAG_FW_RESTART_FOR_HOST, &qmi->ab->dev_flags)) {
+ return 0;
+ }
+
+ /* Print the stats only if notification is received for expected PD*/
+ multi_pd_arch = of_property_read_bool(dev->of_node, "qcom,multipd_arch");
+ if (multi_pd_arch) {
+ if (of_property_read_string(dev->of_node, "qcom,userpd-subsys-name", &name))
+ return 0;
+
+ if (strcmp((char*)data, name) != 0)
+ return 0;
+ }
+
+ ath11k_core_dump_bp_stats(qmi->ab);
+ ath11k_hal_dump_srng_stats(qmi->ab);
+ /* TODO Add more driver stats */
+
+ /* Crash the system once all the stats are dumped */
+ BUG_ON(1);
+
+ return 0;
+}
+#endif
+
int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab)
{
int ret;
@@ -848,6 +906,16 @@ int ath11k_core_qmi_firmware_ready(struc
ath11k_err(ab, "failed to create pdev core: %d\n", ret);
goto err_core_stop;
}
+
+#ifdef CONFIG_QCOM_QMI_HELPERS
+ /* Register a notifier after mac registration
+ * to be called on fw crash
+ */
+ if (ab->hif.bus == ATH11K_BUS_AHB) {
+ ab->qmi.ssr_nb.notifier_call = ath11k_core_ssr_notifier_cb;
+ qcom_register_ssr_notifier(&ab->qmi.ssr_nb);
+ }
+#endif
ath11k_hif_irq_enable(ab);
mutex_unlock(&ab->core_lock);
@@ -1061,6 +1129,13 @@ void ath11k_core_deinit(struct ath11k_ba
{
mutex_lock(&ab->core_lock);
+#ifdef CONFIG_QCOM_QMI_HELPERS
+ /* Unregister the ssr notifier as we are not intersted
+ * in receving these notifications after mac is unregistered.
+ */
+ if (ab->hif.bus == ATH11K_BUS_AHB)
+ qcom_unregister_ssr_notifier(&ab->qmi.ssr_nb);
+#endif
ath11k_core_pdev_destroy(ab);
ath11k_core_stop(ab);
@@ -1109,6 +1184,7 @@ struct ath11k_base *ath11k_core_alloc(st
ab->dev = dev;
ab->bus_params = *bus_params;
ab->hif.bus = bus;
+ ath11k_soc = ab;
return ab;
--- a/drivers/net/wireless/ath/ath11k/debugfs.c
+++ b/drivers/net/wireless/ath/ath11k/debugfs.c
@@ -706,8 +706,8 @@ static int ath11k_fill_bp_stats(struct a
return len;
}
-static ssize_t ath11k_debugfs_dump_soc_ring_bp_stats(struct ath11k_base *ab,
- char *buf, int size)
+ssize_t ath11k_debugfs_dump_soc_ring_bp_stats(struct ath11k_base *ab,
+ char *buf, int size)
{
struct ath11k_bp_stats *bp_stats;
bool stats_rxd = false;
--- a/drivers/net/wireless/ath/ath11k/debugfs.h
+++ b/drivers/net/wireless/ath/ath11k/debugfs.h
@@ -113,6 +113,8 @@ void ath11k_debugfs_unregister(struct at
void ath11k_debugfs_fw_stats_process(struct ath11k_base *ab, struct sk_buff *skb);
void ath11k_debugfs_fw_stats_init(struct ath11k *ar);
+ssize_t ath11k_debugfs_dump_soc_ring_bp_stats(struct ath11k_base *ab,
+ char *buf, int size);
static inline bool ath11k_debugfs_is_pktlog_lite_mode_enabled(struct ath11k *ar)
{
@@ -146,6 +148,12 @@ static inline int ath11k_debugfs_rx_filt
}
#else
+ssize_t ath11k_debugfs_dump_soc_ring_bp_stats(struct ath11k_base *ab,
+ char *buf, int size)
+{
+ return 0;
+}
+
static inline int ath11k_debugfs_soc_create(struct ath11k_base *ab)
{
return 0;
--- a/drivers/net/wireless/ath/ath11k/qmi.h
+++ b/drivers/net/wireless/ath/ath11k/qmi.h
@@ -7,7 +7,9 @@
#define ATH11K_QMI_H
#include <linux/mutex.h>
+#include <linux/notifier.h>
#include <linux/soc/qcom/qmi.h>
+#include <linux/remoteproc/qcom_rproc.h>
#define ATH11K_HOST_VERSION_STRING "WIN"
#define ATH11K_QMI_WLANFW_TIMEOUT_MS 5000
@@ -123,6 +125,7 @@ struct ath11k_qmi {
struct workqueue_struct *event_wq;
struct list_head event_list;
spinlock_t event_lock; /* spinlock for qmi event list */
+ struct notifier_block ssr_nb;
struct ath11k_qmi_ce_cfg ce_cfg;
struct target_mem_chunk target_mem[ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01];
u32 mem_seg_count;