From 186e8421e08e2d000a71615714bcf1dfa9877863 Mon Sep 17 00:00:00 2001 From: Bing Sun Date: Fri, 21 Oct 2022 15:04:59 +0800 Subject: [PATCH] qcacmn: Support one MSI vector dynamically MSI vector number is defined in platform driver, so use platform driver API to check whether it is in one MSI mode or not. In case of one MSI vector, interrupt migration needs to be disabled. This is because when interrupt migration happens, the MSI data may change. However, MSI data is already programmed to rings during initial phase and there is no way to know that MSI data is changed during run time and reprogram again. If it is in one MSI mode, disable interrupt migration by adding IRQ flag IRQF_NOBALANCING. Change-Id: I54579dfe1e658c1a2c395be93875d013d6e6affd CRs-Fixed: 3290829 --- dp/wifi3.0/dp_main.c | 22 +++++++++++----------- hif/src/pcie/if_pci.c | 22 ++++++++++++++++------ 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index c19b9458a4..9d8655d21c 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -1225,24 +1225,22 @@ static int dp_srng_find_ring_in_mask(int ring_num, uint8_t *grp_mask) /** * dp_is_msi_group_number_invalid() - check msi_group_number valid or not + * @soc: dp_soc * @msi_group_number: MSI group number. * @msi_data_count: MSI data count. * * Return: true if msi_group_number is invalid. */ -#ifdef WLAN_ONE_MSI_VECTOR -static bool dp_is_msi_group_number_invalid(int msi_group_number, - int msi_data_count) -{ - return false; -} -#else -static bool dp_is_msi_group_number_invalid(int msi_group_number, +static bool dp_is_msi_group_number_invalid(struct dp_soc *soc, + int msi_group_number, int msi_data_count) { + if (soc && soc->osdev && soc->osdev->dev && + pld_is_one_msi(soc->osdev->dev)) + return false; + return msi_group_number > msi_data_count; } -#endif #ifdef WLAN_FEATURE_NEAR_FULL_IRQ /** @@ -1370,7 +1368,8 @@ dp_srng_msi2_setup(struct dp_soc *soc, return; } - if (dp_is_msi_group_number_invalid(nf_msi_grp_num, msi_data_count)) { + if (dp_is_msi_group_number_invalid(soc, nf_msi_grp_num, + msi_data_count)) { dp_init_warn("%pK: 2 msi_groups will share an msi for near full IRQ; msi_group_num %d", soc, nf_msi_grp_num); QDF_ASSERT(0); @@ -1681,7 +1680,8 @@ static void dp_srng_msi_setup(struct dp_soc *soc, struct hal_srng_params goto configure_msi2; } - if (dp_is_msi_group_number_invalid(reg_msi_grp_num, msi_data_count)) { + if (dp_is_msi_group_number_invalid(soc, reg_msi_grp_num, + msi_data_count)) { dp_init_warn("%pK: 2 msi_groups will share an msi; msi_group_num %d", soc, reg_msi_grp_num); QDF_ASSERT(0); diff --git a/hif/src/pcie/if_pci.c b/hif/src/pcie/if_pci.c index d091db28f2..7cf869ca4d 100644 --- a/hif/src/pcie/if_pci.c +++ b/hif/src/pcie/if_pci.c @@ -3020,6 +3020,7 @@ int hif_ce_msi_configure_irq_by_ceid(struct hif_softc *scn, int ce_id) struct HIF_CE_state *ce_sc = HIF_GET_CE_STATE(scn); struct hif_pci_softc *pci_sc = HIF_GET_PCI_SOFTC(scn); int pci_slot; + unsigned long irq_flags; if (ce_id >= CE_COUNT_MAX) return -EINVAL; @@ -3041,8 +3042,12 @@ int hif_ce_msi_configure_irq_by_ceid(struct hif_softc *scn, int ce_id) pci_slot = hif_get_pci_slot(scn); msi_data = irq_id + msi_irq_start; irq = pld_get_msi_irq(scn->qdf_dev->dev, msi_data); - hif_debug("%s: (ce_id %d, irq_id %d, msi_data %d, irq %d tasklet %pK)", - __func__, ce_id, irq_id, msi_data, irq, + if (pld_is_one_msi(scn->qdf_dev->dev)) + irq_flags = IRQF_SHARED | IRQF_NOBALANCING; + else + irq_flags = IRQF_SHARED; + hif_debug("%s: (ce_id %d, irq_id %d, msi_data %d, irq %d flag 0x%lx tasklet %pK)", + __func__, ce_id, irq_id, msi_data, irq, irq_flags, &ce_sc->tasklets[ce_id]); /* implies the ce is also initialized */ @@ -3056,7 +3061,7 @@ int hif_ce_msi_configure_irq_by_ceid(struct hif_softc *scn, int ce_id) pci_slot, ce_id); ret = pfrm_request_irq(scn->qdf_dev->dev, - irq, hif_ce_interrupt_handler, IRQF_SHARED, + irq, hif_ce_interrupt_handler, irq_flags, ce_irqname[pci_slot][ce_id], &ce_sc->tasklets[ce_id]); if (ret) @@ -3430,6 +3435,7 @@ int hif_pci_configure_grp_irq(struct hif_softc *scn, int irq = 0; int j; int pci_slot; + unsigned long irq_flags; if (pld_get_enable_intx(scn->qdf_dev->dev)) return hif_grp_configure_legacyirq(scn, hif_ext_group); @@ -3446,8 +3452,12 @@ int hif_pci_configure_grp_irq(struct hif_softc *scn, qdf_dev_set_irq_status_flags(irq, QDF_IRQ_DISABLE_UNLAZY); - hif_debug("request_irq = %d for grp %d", - irq, hif_ext_group->grp_id); + if (pld_is_one_msi(scn->qdf_dev->dev)) + irq_flags = IRQF_SHARED | IRQF_NOBALANCING; + else + irq_flags = IRQF_SHARED | IRQF_NO_SUSPEND; + hif_debug("request_irq = %d for grp %d irq_flags 0x%lx", + irq, hif_ext_group->grp_id, irq_flags); qdf_scnprintf(dp_irqname[pci_slot][hif_ext_group->grp_id], DP_IRQ_NAME_LEN, "pci%u_wlan_grp_dp_%u", @@ -3455,7 +3465,7 @@ int hif_pci_configure_grp_irq(struct hif_softc *scn, ret = pfrm_request_irq( scn->qdf_dev->dev, irq, hif_ext_group_interrupt_handler, - IRQF_SHARED | IRQF_NO_SUSPEND, + irq_flags, dp_irqname[pci_slot][hif_ext_group->grp_id], hif_ext_group); if (ret) {