mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-04-16 04:13:31 +00:00
174 lines
5.7 KiB
Diff
174 lines
5.7 KiB
Diff
From c41a6700b276ddf6ef93dcb43baca51ea0c4c7c1 Mon Sep 17 00:00:00 2001
|
|
From: Carl Huang <cjhuang@codeaurora.org>
|
|
Date: Fri, 19 Nov 2021 15:36:26 +0200
|
|
Subject: [PATCH 107/120] ath11k: refactor multiple MSI vector implementation
|
|
|
|
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: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1
|
|
|
|
Signed-off-by: Carl Huang <cjhuang@codeaurora.org>
|
|
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
|
Signed-off-by: Baochen Qiang <bqiang@codeaurora.org>
|
|
Link: https://lore.kernel.org/r/20211026041705.5167-1-bqiang@codeaurora.org
|
|
---
|
|
drivers/net/wireless/ath/ath11k/pci.c | 48 ++++++++++++++++++++++-----
|
|
drivers/net/wireless/ath/ath11k/pci.h | 3 ++
|
|
2 files changed, 43 insertions(+), 8 deletions(-)
|
|
|
|
--- a/drivers/net/wireless/ath/ath11k/pci.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/pci.c
|
|
@@ -486,11 +486,11 @@ int ath11k_pci_get_user_msi_assignment(s
|
|
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;
|
|
|
|
- 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);
|
|
|
|
@@ -561,16 +561,30 @@ static void ath11k_pci_free_irq(struct a
|
|
|
|
static void ath11k_pci_ce_irq_enable(struct ath11k_base *ab, u16 ce_id)
|
|
{
|
|
+ struct ath11k_pci *ab_pci = ath11k_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(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags))
|
|
+ return;
|
|
+
|
|
irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + ce_id;
|
|
enable_irq(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);
|
|
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(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags))
|
|
+ return;
|
|
+
|
|
irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + ce_id;
|
|
disable_irq_nosync(ab->irq_num[irq_idx]);
|
|
}
|
|
@@ -630,8 +644,15 @@ static irqreturn_t ath11k_pci_ce_interru
|
|
|
|
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);
|
|
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(ATH11K_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]]);
|
|
}
|
|
@@ -654,8 +675,15 @@ static void __ath11k_pci_ext_irq_disable
|
|
|
|
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);
|
|
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(ATH11K_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]]);
|
|
}
|
|
@@ -736,6 +764,7 @@ static irqreturn_t ath11k_pci_ext_interr
|
|
|
|
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;
|
|
|
|
@@ -782,16 +811,15 @@ static int ath11k_pci_ext_irq_config(str
|
|
|
|
irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY);
|
|
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;
|
|
@@ -799,6 +827,7 @@ static int ath11k_pci_ext_irq_config(str
|
|
|
|
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, msi_data_idx;
|
|
@@ -826,7 +855,7 @@ static int ath11k_pci_config_irq(struct
|
|
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",
|
|
@@ -920,6 +949,9 @@ static int ath11k_pci_alloc_msi(struct a
|
|
return -EINVAL;
|
|
else
|
|
return num_vectors;
|
|
+ } else {
|
|
+ set_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags);
|
|
+ ab_pci->irq_flags = IRQF_SHARED;
|
|
}
|
|
ath11k_pci_msi_disable(ab_pci);
|
|
|
|
--- a/drivers/net/wireless/ath/ath11k/pci.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/pci.h
|
|
@@ -68,6 +68,7 @@ enum ath11k_pci_flags {
|
|
ATH11K_PCI_FLAG_INIT_DONE,
|
|
ATH11K_PCI_FLAG_IS_MSI_64,
|
|
ATH11K_PCI_ASPM_RESTORE,
|
|
+ ATH11K_PCI_FLAG_MULTI_MSI_VECTORS,
|
|
};
|
|
|
|
struct ath11k_pci {
|
|
@@ -87,6 +88,8 @@ struct ath11k_pci {
|
|
/* enum ath11k_pci_flags */
|
|
unsigned long flags;
|
|
u16 link_ctl;
|
|
+
|
|
+ unsigned long irq_flags;
|
|
};
|
|
|
|
static inline struct ath11k_pci *ath11k_pci_priv(struct ath11k_base *ab)
|