On 6/25/2025 12:50 AM, Govind Singh wrote: > This patch adds two module parameters to the ath12k PCI driver. > > - ath12k_msi_mode: Allows selecting the MSI allocation mode. > * 0 = multi-vector MSI (default) > * 1 = single-vector MSI > > - ath12k_32bit_msi: Forces the use of 32-bit MSI addressing > by setting pdev->no_64bit_msi = 1 before IRQ vector allocation. > > These options are useful for working around hardware or platform > limitations(ex: i.MX 8M Plus) where 64-bit MSI or multi-vector MSI > allocations fails or cause stability issues. > > The original MSI allocation logic remains unchanged unless the > parameters are explicitly set via modprobe or kernel boot options. > > Tested-on: QCN9274 hw2.0 WLAN.WBE.1.4.1-00103-QCAHKSWPL_SILICONZ-1 with > i.MX 8M Plus SOC > Signed-off-by: Govind Singh <govind.sk85@xxxxxxxxx> Like I commented in the Bugzilla, this is not a ath12k issue. Fix/workarounds need to go to the PCIe controller driver, not its users. > --- > drivers/net/wireless/ath/ath12k/pci.c | 25 +++++++++++++++++++++---- > drivers/net/wireless/ath/ath12k/pci.h | 5 +++++ > 2 files changed, 26 insertions(+), 4 deletions(-) > > diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c > index 1f3cfd9b89fd..4f58cb1e03f6 100644 > --- a/drivers/net/wireless/ath/ath12k/pci.c > +++ b/drivers/net/wireless/ath/ath12k/pci.c > @@ -45,6 +45,14 @@ > #define DOMAIN_NUMBER_MASK GENMASK(7, 4) > #define BUS_NUMBER_MASK GENMASK(3, 0) > > +int ath12k_msi_mode; > +module_param(ath12k_msi_mode, int, 0644); > +MODULE_PARM_DESC(ath12k_msi_mode, "MSI mode: 0 = multi-vector (default), 1 = single-vector"); > + > +bool ath12k_32bit_msi; > +module_param(ath12k_32bit_msi, bool, 0644); > +MODULE_PARM_DESC(ath12k_32bit_msi, "Force 32-bit MSI addressing"); > + > static const struct pci_device_id ath12k_pci_id_table[] = { > { PCI_VDEVICE(QCOM, QCN9274_DEVICE_ID) }, > { PCI_VDEVICE(QCOM, WCN7850_DEVICE_ID) }, > @@ -773,10 +781,19 @@ static int ath12k_pci_msi_alloc(struct ath12k_pci *ab_pci) > int num_vectors; > int ret; > > - num_vectors = pci_alloc_irq_vectors(ab_pci->pdev, > - msi_config->total_vectors, > - msi_config->total_vectors, > - PCI_IRQ_MSI); > + /* Set 32-bit MSI flag early if requested */ > + if (ath12k_32bit_msi) > + ab_pci->pdev->no_64bit_msi = 1; > + > + /* Force single MSI mode if requested */ > + if (ath12k_msi_mode == ATH12K_MSI_VEC_SINGLE) { > + num_vectors = -EINVAL; /* Force fallback path */ > + } else { > + num_vectors = pci_alloc_irq_vectors(ab_pci->pdev, > + msi_config->total_vectors, > + msi_config->total_vectors, > + PCI_IRQ_MSI); > + } > > if (num_vectors == msi_config->total_vectors) { > set_bit(ATH12K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags); > diff --git a/drivers/net/wireless/ath/ath12k/pci.h b/drivers/net/wireless/ath/ath12k/pci.h > index d1ec8aad7f6c..4fa8bb619cd9 100644 > --- a/drivers/net/wireless/ath/ath12k/pci.h > +++ b/drivers/net/wireless/ath/ath12k/pci.h > @@ -92,6 +92,11 @@ enum ath12k_pci_flags { > ATH12K_PCI_FLAG_MULTI_MSI_VECTORS, > }; > > +enum ath12k_msi_mode { > + ATH12K_MSI_VEC_AUTO = 0, > + ATH12K_MSI_VEC_SINGLE = 1, > +}; > + > struct ath12k_pci_ops { > int (*wakeup)(struct ath12k_base *ab); > void (*release)(struct ath12k_base *ab);