From 41363c3109235a96d90d5946bbc01d1cc8dad47e Mon Sep 17 00:00:00 2001
From: Anilkumar Kolli <akolli@codeaurora.org>
Date: Sun, 6 Sep 2020 11:01:38 +0530
Subject: [PATCH] ath11k: update debugfs support for mupltiple radios in PCI
bus

debugfs_ath11k struct is moved to ath11k_core, since its common
for both pci and ahb.

Current ath11k_pci insmod fails if there are multiple PCI rdaios,
debugfs directory is created with soc_name and bus_id to allow
creating debugfs directory for second PCI radio.

with this Debugfs entries looks like,
 # ls -l /sys/kernel/debug/ath11k/
 ipq8074 hw2.0 qcn9000 hw1.0_0000:01:00.0 qcn9000 hw1.0_0001:01:00.0

 # ls -l /sys/kernel/debug/ath11k/ipq8074 hw2.0/
   mac0  mac1 simulate_fw_crash soc_dp_stats

 # ls -l /sys/kernel/debug/ath11k/qcn9000 hw1.0_0000:01:00.0
   mac0 simulate_fw_crash soc_dp_stats

 # /sys/kernel/debug/ath11k/qcn9000 hw1.0_0001:01:00.0:
   mac0  simulate_fw_crash soc_dp_stats

Signed-off-by: Anilkumar Kolli <akolli@codeaurora.org>
---
 drivers/net/wireless/ath/ath11k/core.c     | 12 +++++++
 drivers/net/wireless/ath/ath11k/core.h     |  1 -
 drivers/net/wireless/ath/ath11k/debugfs.c  | 57 ++++++++++++++++++++++++------
 drivers/net/wireless/ath/ath11k/debugfs.h  | 11 ++++++
 5 files changed, 72 insertions(+), 13 deletions(-)

--- a/drivers/net/wireless/ath/ath11k/core.c
+++ b/drivers/net/wireless/ath/ath11k/core.c
@@ -1201,5 +1201,17 @@ err_sc_free:
 }
 EXPORT_SYMBOL(ath11k_core_alloc);
 
+int ath11k_init(void)
+{
+	return ath11k_debugfs_create();
+}
+module_init(ath11k_init);
+
+void ath11k_exit(void)
+{
+	ath11k_debugfs_destroy();
+}
+module_exit(ath11k_exit);
+
 MODULE_DESCRIPTION("Core module for Qualcomm Atheros 802.11ax wireless LAN cards.");
 MODULE_LICENSE("Dual BSD/GPL");
--- a/drivers/net/wireless/ath/ath11k/core.h
+++ b/drivers/net/wireless/ath/ath11k/core.h
@@ -811,7 +811,6 @@ struct ath11k_base {
 	enum ath11k_dfs_region dfs_region;
 #ifdef CPTCFG_ATH11K_DEBUGFS
 	struct dentry *debugfs_soc;
-	struct dentry *debugfs_ath11k;
 #endif
 	struct ath11k_soc_dp_stats soc_stats;
 
--- a/drivers/net/wireless/ath/ath11k/debugfs.c
+++ b/drivers/net/wireless/ath/ath11k/debugfs.c
@@ -14,6 +14,8 @@
 #include "peer.h"
 #include "pktlog.h"
 
+struct dentry *debugfs_ath11k;
+
 static const char *htt_bp_umac_ring[HTT_SW_UMAC_RING_IDX_MAX] = {
 	"REO2SW1_RING",
 	"REO2SW2_RING",
@@ -1040,10 +1042,6 @@ int ath11k_debugfs_pdev_create(struct at
 	if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags))
 		return 0;
 
-	ab->debugfs_soc = debugfs_create_dir(ab->hw_params.name, ab->debugfs_ath11k);
-	if (IS_ERR(ab->debugfs_soc))
-		return PTR_ERR(ab->debugfs_soc);
-
 	debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab,
 			    &fops_simulate_fw_crash);
 
@@ -1055,24 +1053,58 @@ int ath11k_debugfs_pdev_create(struct at
 
 void ath11k_debugfs_pdev_destroy(struct ath11k_base *ab)
 {
-	debugfs_remove_recursive(ab->debugfs_soc);
-	ab->debugfs_soc = NULL;
 }
 
 int ath11k_debugfs_soc_create(struct ath11k_base *ab)
 {
-	ab->debugfs_ath11k = debugfs_create_dir("ath11k", NULL);
+	struct device *dev = ab->dev;
+	char soc_name[64] = {0};
+
+	if (!(IS_ERR_OR_NULL(ab->debugfs_soc)))
+		return 0;
+
+	if (ab->hif.bus == ATH11K_BUS_AHB) {
+		snprintf(soc_name, sizeof(soc_name), "%s", ab->hw_params.name);
+	} else {
+		snprintf(soc_name, sizeof(soc_name), "%s_%s",
+			 ab->hw_params.name, dev_name(dev));
+	}
 
-	return PTR_ERR_OR_ZERO(ab->debugfs_ath11k);
+	ab->debugfs_soc = debugfs_create_dir(soc_name, debugfs_ath11k);
+	if (IS_ERR_OR_NULL(ab->debugfs_soc)) {
+		if (IS_ERR(ab->debugfs_soc))
+			return PTR_ERR(ab->debugfs_soc);
+		return -ENOMEM;
+	}
+
+	return 0;
 }
 
 void ath11k_debugfs_soc_destroy(struct ath11k_base *ab)
 {
-	debugfs_remove_recursive(ab->debugfs_ath11k);
-	ab->debugfs_ath11k = NULL;
+	debugfs_remove_recursive(ab->debugfs_soc);
+	ab->debugfs_soc = NULL;
 }
 EXPORT_SYMBOL(ath11k_debugfs_soc_destroy);
 
+int ath11k_debugfs_create()
+{
+	debugfs_ath11k = debugfs_create_dir("ath11k", NULL);
+	if (IS_ERR_OR_NULL(debugfs_ath11k)) {
+		if (IS_ERR(debugfs_ath11k))
+			return PTR_ERR(debugfs_ath11k);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+void ath11k_debugfs_destroy()
+{
+	debugfs_remove_recursive(debugfs_ath11k);
+	debugfs_ath11k = NULL;
+}
+
 void ath11k_debugfs_fw_stats_init(struct ath11k *ar)
 {
 	struct dentry *fwstats_dir = debugfs_create_dir("fw_stats",
@@ -1653,6 +1685,9 @@ int ath11k_debugfs_register(struct ath11
 	char pdev_name[5];
 	char buf[100] = {0};
 
+	if (!(IS_ERR_OR_NULL(ar->debug.debugfs_pdev)))
+		return 0;
+
 	snprintf(pdev_name, sizeof(pdev_name), "%s%d", "mac", ar->pdev_idx);
 
 	ar->debug.debugfs_pdev = debugfs_create_dir(pdev_name, ab->debugfs_soc);
@@ -1708,4 +1743,6 @@ int ath11k_debugfs_register(struct ath11
 void ath11k_debugfs_unregister(struct ath11k *ar)
 {
 	ath11k_deinit_pktlog(ar);
+	debugfs_remove_recursive(ar->debug.debugfs_pdev);
+	ar->debug.debugfs_pdev = NULL;
 }
--- a/drivers/net/wireless/ath/ath11k/debugfs.h
+++ b/drivers/net/wireless/ath/ath11k/debugfs.h
@@ -117,6 +117,8 @@ static inline void ath11k_debugfs_twt(st
 #endif
 
 #ifdef CPTCFG_ATH11K_DEBUGFS
+int ath11k_debugfs_create(void);
+void ath11k_debugfs_destroy(void);
 int ath11k_debugfs_soc_create(struct ath11k_base *ab);
 void ath11k_debugfs_soc_destroy(struct ath11k_base *ab);
 int ath11k_debugfs_pdev_create(struct ath11k_base *ab);
@@ -161,7 +163,16 @@ static inline int ath11k_debugfs_rx_filt
 }
 
 #else
-ssize_t ath11k_debugfs_dump_soc_ring_bp_stats(struct ath11k_base *ab,
+static inline int ath11k_debugfs_create(void)
+{
+	return 0;
+}
+
+static inline void ath11k_debugfs_destroy(void)
+{
+}
+
+static inline ssize_t ath11k_debugfs_dump_soc_ring_bp_stats(struct ath11k_base *ab,
 					      char *buf, int size)
 {
 	return 0;
