diff mbox series

[4/6] ath11k: refactor mulitple msi vector implementation

Message ID 20201223030225.2345-5-cjhuang@codeaurora.org
State Changes Requested
Delegated to: Kalle Valo
Headers show
Series ath11k: support one MSI vector | expand

Commit Message

Carl Huang Dec. 23, 2020, 3:02 a.m. UTC
This is to prepare for one msi vector support.
Irq enable and disable functions of ce and dp are wrapped.

Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1

Signed-off-by: Carl Huang <cjhuang@codeaurora.org>
---
 drivers/net/wireless/ath/ath11k/pci.c | 86 +++++++++++++++++++++++++++--------
 drivers/net/wireless/ath/ath11k/pci.h |  8 ++++
 2 files changed, 75 insertions(+), 19 deletions(-)
diff mbox series

Patch

diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c
index 7ec2209..5fdfc72 100644
--- a/drivers/net/wireless/ath/ath11k/pci.c
+++ b/drivers/net/wireless/ath/ath11k/pci.c
@@ -406,17 +406,18 @@  int ath11k_pci_get_user_msi_assignment(struct ath11k_pci *ab_pci, char *user_nam
 				       int *num_vectors, u32 *user_base_data,
 				       u32 *base_vector)
 {
+	const struct ath11k_msi_config *msi_config = ab_pci->msi_config;
 	struct ath11k_base *ab = ab_pci->ab;
 	int idx;
 
-	for (idx = 0; idx < msi_config.total_users; idx++) {
-		if (strcmp(user_name, msi_config.users[idx].name) == 0) {
-			*num_vectors = msi_config.users[idx].num_vectors;
-			*user_base_data = msi_config.users[idx].base_vector
-				+ ab_pci->msi_ep_base_data;
-			*base_vector = msi_config.users[idx].base_vector;
+	for (idx = 0; idx < msi_config->total_users; idx++) {
+		if (strcmp(user_name, msi_config->users[idx].name) == 0) {
+			*num_vectors = msi_config->users[idx].num_vectors;
+			*base_vector =  msi_config->users[idx].base_vector;
+			*user_base_data = *base_vector + ab_pci->msi_ep_base_data;
 
-			ath11k_dbg(ab, ATH11K_DBG_PCI, "Assign MSI to user: %s, num_vectors: %d, user_base_data: %u, base_vector: %u\n",
+			ath11k_dbg(ab, ATH11K_DBG_PCI,
+				   "Assign MSI to user: %s, num_vectors: %d, user_base_data: %u, base_vector: %u\n",
 				   user_name, *num_vectors, *user_base_data,
 				   *base_vector);
 
@@ -468,7 +469,7 @@  static void ath11k_pci_free_irq(struct ath11k_base *ab)
 	ath11k_pci_free_ext_irq(ab);
 }
 
-static void ath11k_pci_ce_irq_enable(struct ath11k_base *ab, u16 ce_id)
+static void ath11k_pci_ce_irq_enable_multiple_msi(struct ath11k_base *ab, u16 ce_id)
 {
 	u32 irq_idx;
 
@@ -476,7 +477,15 @@  static void ath11k_pci_ce_irq_enable(struct ath11k_base *ab, u16 ce_id)
 	enable_irq(ab->irq_num[irq_idx]);
 }
 
-static void ath11k_pci_ce_irq_disable(struct ath11k_base *ab, u16 ce_id)
+static void ath11k_pci_ce_irq_enable(struct ath11k_base *ab, u16 ce_id)
+{
+	struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
+
+	if (ab_pci->ce_irq_enable)
+		ab_pci->ce_irq_enable(ab, ce_id);
+}
+
+static void ath11k_pci_ce_irq_disable_multiple_msi(struct ath11k_base *ab, u16 ce_id)
 {
 	u32 irq_idx;
 
@@ -484,12 +493,19 @@  static void ath11k_pci_ce_irq_disable(struct ath11k_base *ab, u16 ce_id)
 	disable_irq_nosync(ab->irq_num[irq_idx]);
 }
 
+static void ath11k_pci_ce_irq_disable(struct ath11k_base *ab, u16 ce_id)
+{
+	struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
+
+	if (ab_pci->ce_irq_disable)
+		ab_pci->ce_irq_disable(ab, ce_id);
+}
+
 static void ath11k_pci_ce_irqs_disable(struct ath11k_base *ab)
 {
 	int i;
 
 	ab->ce_irq_enabled_flag = false;
-
 	for (i = 0; i < ab->hw_params.ce_count; i++) {
 		if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR)
 			continue;
@@ -523,6 +539,7 @@  static void ath11k_pci_ce_tasklet(struct tasklet_struct *t)
 static irqreturn_t ath11k_pci_ce_interrupt_handler(int irq, void *arg)
 {
 	struct ath11k_ce_pipe *ce_pipe = arg;
+	struct ath11k_base *ab = ce_pipe->ab;
 
 	if (!ab->ce_irq_enabled_flag)
 		return IRQ_HANDLED;
@@ -533,7 +550,7 @@  static irqreturn_t ath11k_pci_ce_interrupt_handler(int irq, void *arg)
 	return IRQ_HANDLED;
 }
 
-static void ath11k_pci_ext_grp_disable(struct ath11k_ext_irq_grp *irq_grp)
+static void ath11k_pci_ext_grp_disable_multiple_msi(struct ath11k_ext_irq_grp *irq_grp)
 {
 	int i;
 
@@ -541,14 +558,21 @@  static void ath11k_pci_ext_grp_disable(struct ath11k_ext_irq_grp *irq_grp)
 		disable_irq_nosync(irq_grp->ab->irq_num[irq_grp->irqs[i]]);
 }
 
-static void __ath11k_pci_ext_irq_disable(struct ath11k_base *sc)
+static void ath11k_pci_ext_grp_disable(struct ath11k_ext_irq_grp *irq_grp)
+{
+	struct ath11k_pci *ab_pci = ath11k_pci_priv(irq_grp->ab);
+
+	if (ab_pci->ext_grp_disable)
+		ab_pci->ext_grp_disable(irq_grp);
+}
+
+static void __ath11k_pci_ext_irq_disable(struct ath11k_base *ab)
 {
 	int i;
 
 	ab->ext_irq_enabled_flag = false;
-
 	for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
-		struct ath11k_ext_irq_grp *irq_grp = &sc->ext_irq_grp[i];
+		struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
 
 		ath11k_pci_ext_grp_disable(irq_grp);
 
@@ -557,7 +581,7 @@  static void __ath11k_pci_ext_irq_disable(struct ath11k_base *sc)
 	}
 }
 
-static void ath11k_pci_ext_grp_enable(struct ath11k_ext_irq_grp *irq_grp)
+static void ath11k_pci_ext_grp_enable_multiple_msi(struct ath11k_ext_irq_grp *irq_grp)
 {
 	int i;
 
@@ -565,6 +589,14 @@  static void ath11k_pci_ext_grp_enable(struct ath11k_ext_irq_grp *irq_grp)
 		enable_irq(irq_grp->ab->irq_num[irq_grp->irqs[i]]);
 }
 
+static void ath11k_pci_ext_grp_enable(struct ath11k_ext_irq_grp *irq_grp)
+{
+	struct ath11k_pci *ab_pci = ath11k_pci_priv(irq_grp->ab);
+
+	if (ab_pci->ext_grp_enable)
+		ab_pci->ext_grp_enable(irq_grp);
+}
+
 static void ath11k_pci_ext_irq_enable(struct ath11k_base *ab)
 {
 	int i;
@@ -637,6 +669,7 @@  static irqreturn_t ath11k_pci_ext_interrupt_handler(int irq, void *arg)
 
 static int ath11k_pci_ext_irq_config(struct ath11k_base *ab)
 {
+	struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
 	int i, j, ret, num_vectors = 0;
 	u32 user_base_data = 0, base_vector = 0;
 
@@ -681,16 +714,15 @@  static int ath11k_pci_ext_irq_config(struct ath11k_base *ab)
 			ath11k_dbg(ab, ATH11K_DBG_PCI,
 				   "irq:%d group:%d\n", irq, i);
 			ret = request_irq(irq, ath11k_pci_ext_interrupt_handler,
-					  IRQF_SHARED,
+					  ab_pci->irq_flags,
 					  "DP_EXT_IRQ", irq_grp);
 			if (ret) {
 				ath11k_err(ab, "failed request irq %d: %d\n",
 					   vector, ret);
 				return ret;
 			}
-
-			disable_irq_nosync(ab->irq_num[irq_idx]);
 		}
+		ath11k_pci_ext_grp_disable(irq_grp);
 	}
 
 	return 0;
@@ -698,6 +730,7 @@  static int ath11k_pci_ext_irq_config(struct ath11k_base *ab)
 
 static int ath11k_pci_config_irq(struct ath11k_base *ab)
 {
+	struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
 	struct ath11k_ce_pipe *ce_pipe;
 	u32 msi_data_start;
 	u32 msi_data_count;
@@ -725,7 +758,7 @@  static int ath11k_pci_config_irq(struct ath11k_base *ab)
 		tasklet_setup(&ce_pipe->intr_tq, ath11k_pci_ce_tasklet);
 
 		ret = request_irq(irq, ath11k_pci_ce_interrupt_handler,
-				  IRQF_SHARED, irq_name[irq_idx],
+				  ab_pci->irq_flags, irq_name[irq_idx],
 				  ce_pipe);
 		if (ret) {
 			ath11k_err(ab, "failed to request irq %d: %d\n",
@@ -770,6 +803,19 @@  static void ath11k_pci_ce_irqs_enable(struct ath11k_base *ab)
 	}
 }
 
+static void ath11k_pci_init_irq_handlers(struct ath11k_pci *ab_pci, bool multiple_msi)
+{
+	if (multiple_msi) {
+		ab_pci->vectors_32_capability = true;
+		ab_pci->ext_grp_enable = ath11k_pci_ext_grp_enable_multiple_msi;
+		ab_pci->ext_grp_disable = ath11k_pci_ext_grp_disable_multiple_msi;
+		ab_pci->ce_irq_enable = ath11k_pci_ce_irq_enable_multiple_msi;
+		ab_pci->ce_irq_disable = ath11k_pci_ce_irq_disable_multiple_msi;
+		ab_pci->msi_config = &msi_config;
+		ab_pci->irq_flags = IRQF_SHARED;
+	}
+}
+
 static int ath11k_pci_enable_msi(struct ath11k_pci *ab_pci)
 {
 	struct ath11k_base *ab = ab_pci->ab;
@@ -789,6 +835,8 @@  static int ath11k_pci_enable_msi(struct ath11k_pci *ab_pci)
 			return -EINVAL;
 		else
 			return num_vectors;
+	} else {
+		ath11k_pci_init_irq_handlers(ab_pci, true);
 	}
 
 	msi_desc = irq_get_msi_desc(ab_pci->pdev->irq);
diff --git a/drivers/net/wireless/ath/ath11k/pci.h b/drivers/net/wireless/ath/ath11k/pci.h
index fe44d0d..2097466 100644
--- a/drivers/net/wireless/ath/ath11k/pci.h
+++ b/drivers/net/wireless/ath/ath11k/pci.h
@@ -72,6 +72,7 @@  struct ath11k_pci {
 	u16 dev_id;
 	char amss_path[100];
 	u32 msi_ep_base_data;
+	bool vectors_32_capability;
 	struct mhi_controller *mhi_ctrl;
 	unsigned long mhi_state;
 	u32 register_window;
@@ -82,6 +83,13 @@  struct ath11k_pci {
 	/* enum ath11k_pci_flags */
 	unsigned long flags;
 	u16 link_ctl;
+
+	const struct ath11k_msi_config *msi_config;
+	unsigned long irq_flags;
+	void (*ext_grp_disable)(struct ath11k_ext_irq_grp *irq_grp);
+	void (*ext_grp_enable)(struct ath11k_ext_irq_grp *irq_grp);
+	void (*ce_irq_enable)(struct ath11k_base *ab, u16 ce_id);
+	void (*ce_irq_disable)(struct ath11k_base *ab, u16 ce_id);
 };
 
 static inline struct ath11k_pci *ath11k_pci_priv(struct ath11k_base *ab)