2021-10-26 07:03:26

by Baochen Qiang

[permalink] [raw]
Subject: [PATCH 4/7] ath11k: refactor multiple MSI vector implementation

From: Carl Huang <[email protected]>

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 <[email protected]>
Signed-off-by: Kalle Valo <[email protected]>
Signed-off-by: Baochen Qiang <[email protected]>
---
drivers/net/wireless/ath/ath11k/pci.c | 48 ++++++++++++++++++++++-----
drivers/net/wireless/ath/ath11k/pci.h | 3 ++
2 files changed, 43 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c
index ed610e56c160..c4d726f492dc 100644
--- a/drivers/net/wireless/ath/ath11k/pci.c
+++ b/drivers/net/wireless/ath/ath11k/pci.c
@@ -482,11 +482,11 @@ int ath11k_pci_get_user_msi_assignment(struct ath11k_pci *ab_pci, char *user_nam
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);

@@ -558,6 +558,13 @@ static void ath11k_pci_free_irq(struct ath11k_base *ab)
static void ath11k_pci_ce_irq_enable(struct ath11k_base *ab, u16 ce_id)
{
u32 irq_idx;
+ struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
+
+ /*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]);
@@ -566,6 +573,13 @@ static void ath11k_pci_ce_irq_enable(struct ath11k_base *ab, u16 ce_id)
static void ath11k_pci_ce_irq_disable(struct ath11k_base *ab, u16 ce_id)
{
u32 irq_idx;
+ struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
+
+ /*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]);
@@ -627,6 +641,13 @@ static irqreturn_t ath11k_pci_ce_interrupt_handler(int irq, void *arg)
static void ath11k_pci_ext_grp_disable(struct ath11k_ext_irq_grp *irq_grp)
{
int i;
+ struct ath11k_pci *ab_pci = ath11k_pci_priv(irq_grp->ab);
+
+ /*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]]);
@@ -651,6 +672,13 @@ 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)
{
int i;
+ struct ath11k_pci *ab_pci = ath11k_pci_priv(irq_grp->ab);
+
+ /*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]]);
@@ -732,6 +760,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, base_idx;

@@ -779,16 +808,15 @@ static int ath11k_pci_ext_irq_config(struct ath11k_base *ab)

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;
@@ -796,6 +824,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, msi_data_idx;
@@ -823,7 +852,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",
@@ -917,6 +946,9 @@ static int ath11k_pci_alloc_msi(struct ath11k_pci *ab_pci)
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);

diff --git a/drivers/net/wireless/ath/ath11k/pci.h b/drivers/net/wireless/ath/ath11k/pci.h
index f3e645891d19..61d67b20a0eb 100644
--- 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)
--
2.25.1


2021-11-19 12:43:35

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 4/7] ath11k: refactor multiple MSI vector implementation

Baochen Qiang <[email protected]> writes:

> From: Carl Huang <[email protected]>
>
> 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 <[email protected]>
> Signed-off-by: Kalle Valo <[email protected]>
> Signed-off-by: Baochen Qiang <[email protected]>

[...]

> @@ -558,6 +558,13 @@ static void ath11k_pci_free_irq(struct ath11k_base *ab)
> static void ath11k_pci_ce_irq_enable(struct ath11k_base *ab, u16 ce_id)
> {
> u32 irq_idx;
> + struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);

ab_pci should be before irq_idx to follow the reverse xmas tree style, I
fixed it in the pending branch.

> +
> + /*In case of one MSI vector, we handle irq enable/disable
> + *in a uniform way since we only have one irq
> + */

There should be a space after '*', fixed now.

> + 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]);
> @@ -566,6 +573,13 @@ static void ath11k_pci_ce_irq_enable(struct ath11k_base *ab, u16 ce_id)
> static void ath11k_pci_ce_irq_disable(struct ath11k_base *ab, u16 ce_id)
> {
> u32 irq_idx;
> + struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
> +
> + /*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;

Both style issues fixed here as well.

> static void ath11k_pci_ext_grp_disable(struct ath11k_ext_irq_grp *irq_grp)
> {
> int i;
> + struct ath11k_pci *ab_pci = ath11k_pci_priv(irq_grp->ab);
> +
> + /*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;

And here.

>
> for (i = 0; i < irq_grp->num_irq; i++)
> disable_irq_nosync(irq_grp->ab->irq_num[irq_grp->irqs[i]]);
> @@ -651,6 +672,13 @@ 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)
> {
> int i;
> + struct ath11k_pci *ab_pci = ath11k_pci_priv(irq_grp->ab);
> +
> + /*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;

And here.

--
https://patchwork.kernel.org/project/linux-wireless/list/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches