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@xxxxxxxxxxx> --- drivers/net/wireless/ath/ath12k/pci.c | 48 ++++++++++++++++++++++----- drivers/net/wireless/ath/ath12k/pci.h | 2 ++ 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c index 4b872eff087c..3bb2d622dc52 100644 --- a/drivers/net/wireless/ath/ath12k/pci.c +++ b/drivers/net/wireless/ath/ath12k/pci.c @@ -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); diff --git a/drivers/net/wireless/ath/ath12k/pci.h b/drivers/net/wireless/ath/ath12k/pci.h index 0f24fd9395cd..db32676fec50 100644 --- a/drivers/net/wireless/ath/ath12k/pci.h +++ b/drivers/net/wireless/ath/ath12k/pci.h @@ -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; }; -- 2.34.1