wifi: ath12k: refactor multiple MSI vector implementation
authorKang Yang <quic_kangyang@quicinc.com>
Fri, 1 Dec 2023 16:09:47 +0000 (18:09 +0200)
committerKalle Valo <quic_kvalo@quicinc.com>
Tue, 5 Dec 2023 15:04:19 +0000 (17:04 +0200)
This is to prepare for one MSI vector support. IRQ enable and disable
of CE and DP are done only in case of multiple MSI vectors.

Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4

Signed-off-by: Kang Yang <quic_kangyang@quicinc.com>
Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://lore.kernel.org/r/20231121021304.12966-5-quic_kangyang@quicinc.com
drivers/net/wireless/ath/ath12k/pci.c
drivers/net/wireless/ath/ath12k/pci.h

index 9c8dfa002760f0dd9fe5c09eecc2c7065c308f06..30be938e168a77da8ec8d31fc741e2c6f63fdec4 100644 (file)
@@ -356,16 +356,30 @@ static void ath12k_pci_free_irq(struct ath12k_base *ab)
 
 static void ath12k_pci_ce_irq_enable(struct ath12k_base *ab, u16 ce_id)
 {
+       struct ath12k_pci *ab_pci = ath12k_pci_priv(ab);
        u32 irq_idx;
 
+       /* In case of one MSI vector, we handle irq enable/disable in a
+        * uniform way since we only have one irq
+        */
+       if (!test_bit(ATH12K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags))
+               return;
+
        irq_idx = ATH12K_PCI_IRQ_CE0_OFFSET + ce_id;
        enable_irq(ab->irq_num[irq_idx]);
 }
 
 static void ath12k_pci_ce_irq_disable(struct ath12k_base *ab, u16 ce_id)
 {
+       struct ath12k_pci *ab_pci = ath12k_pci_priv(ab);
        u32 irq_idx;
 
+       /* In case of one MSI vector, we handle irq enable/disable in a
+        * uniform way since we only have one irq
+        */
+       if (!test_bit(ATH12K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags))
+               return;
+
        irq_idx = ATH12K_PCI_IRQ_CE0_OFFSET + ce_id;
        disable_irq_nosync(ab->irq_num[irq_idx]);
 }
@@ -425,8 +439,15 @@ static irqreturn_t ath12k_pci_ce_interrupt_handler(int irq, void *arg)
 
 static void ath12k_pci_ext_grp_disable(struct ath12k_ext_irq_grp *irq_grp)
 {
+       struct ath12k_pci *ab_pci = ath12k_pci_priv(irq_grp->ab);
        int i;
 
+       /* In case of one MSI vector, we handle irq enable/disable
+        * in a uniform way since we only have one irq
+        */
+       if (!test_bit(ATH12K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags))
+               return;
+
        for (i = 0; i < irq_grp->num_irq; i++)
                disable_irq_nosync(irq_grp->ab->irq_num[irq_grp->irqs[i]]);
 }
@@ -449,8 +470,15 @@ static void __ath12k_pci_ext_irq_disable(struct ath12k_base *ab)
 
 static void ath12k_pci_ext_grp_enable(struct ath12k_ext_irq_grp *irq_grp)
 {
+       struct ath12k_pci *ab_pci = ath12k_pci_priv(irq_grp->ab);
        int i;
 
+       /* In case of one MSI vector, we handle irq enable/disable in a
+        * uniform way since we only have one irq
+        */
+       if (!test_bit(ATH12K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags))
+               return;
+
        for (i = 0; i < irq_grp->num_irq; i++)
                enable_irq(irq_grp->ab->irq_num[irq_grp->irqs[i]]);
 }
@@ -511,6 +539,7 @@ static irqreturn_t ath12k_pci_ext_interrupt_handler(int irq, void *arg)
 
 static int ath12k_pci_ext_irq_config(struct ath12k_base *ab)
 {
+       struct ath12k_pci *ab_pci = ath12k_pci_priv(ab);
        int i, j, ret, num_vectors = 0;
        u32 user_base_data = 0, base_vector = 0;
 
@@ -556,16 +585,15 @@ static int ath12k_pci_ext_irq_config(struct ath12k_base *ab)
 
                        irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY);
                        ret = request_irq(irq, ath12k_pci_ext_interrupt_handler,
-                                         IRQF_SHARED,
+                                         ab_pci->irq_flags,
                                          "DP_EXT_IRQ", irq_grp);
                        if (ret) {
                                ath12k_err(ab, "failed request irq %d: %d\n",
                                           vector, ret);
                                return ret;
                        }
-
-                       disable_irq_nosync(ab->irq_num[irq_idx]);
                }
+               ath12k_pci_ext_grp_disable(irq_grp);
        }
 
        return 0;
@@ -573,6 +601,7 @@ static int ath12k_pci_ext_irq_config(struct ath12k_base *ab)
 
 static int ath12k_pci_config_irq(struct ath12k_base *ab)
 {
+       struct ath12k_pci *ab_pci = ath12k_pci_priv(ab);
        struct ath12k_ce_pipe *ce_pipe;
        u32 msi_data_start;
        u32 msi_data_count, msi_data_idx;
@@ -601,7 +630,7 @@ static int ath12k_pci_config_irq(struct ath12k_base *ab)
                tasklet_setup(&ce_pipe->intr_tq, ath12k_pci_ce_tasklet);
 
                ret = request_irq(irq, ath12k_pci_ce_interrupt_handler,
-                                 IRQF_SHARED, irq_name[irq_idx],
+                                 ab_pci->irq_flags, irq_name[irq_idx],
                                  ce_pipe);
                if (ret) {
                        ath12k_err(ab, "failed to request irq %d: %d\n",
@@ -692,6 +721,9 @@ static int ath12k_pci_msi_alloc(struct ath12k_pci *ab_pci)
                        return -EINVAL;
                else
                        return num_vectors;
+       } else {
+               set_bit(ATH12K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags);
+               ab_pci->irq_flags = IRQF_SHARED;
        }
 
        ath12k_pci_msi_disable(ab_pci);
@@ -924,11 +956,11 @@ int ath12k_pci_get_user_msi_assignment(struct ath12k_base *ab, char *user_name,
        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;
+                       *base_vector =  msi_config->users[idx].base_vector;
+                       *user_base_data = *base_vector + ab_pci->msi_ep_base_data;
 
-                       ath12k_dbg(ab, ATH12K_DBG_PCI, "Assign MSI to user: %s, num_vectors: %d, user_base_data: %u, base_vector: %u\n",
+                       ath12k_dbg(ab, ATH12K_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);
 
index 9a17a7dcdd6a6ea6355da35a46f256fe0fb9d63d..b2edf32ada20a90f6296a80dd72c2ec5eea5da9f 100644 (file)
@@ -84,6 +84,7 @@ enum ath12k_pci_flags {
        ATH12K_PCI_FLAG_INIT_DONE,
        ATH12K_PCI_FLAG_IS_MSI_64,
        ATH12K_PCI_ASPM_RESTORE,
+       ATH12K_PCI_FLAG_MULTI_MSI_VECTORS,
 };
 
 struct ath12k_pci_ops {
@@ -108,6 +109,7 @@ struct ath12k_pci {
        /* enum ath12k_pci_flags */
        unsigned long flags;
        u16 link_ctl;
+       unsigned long irq_flags;
        const struct ath12k_pci_ops *pci_ops;
 };