diff mbox series

ath12k: add module param to control MSI mode and address width

Message ID 20250624165031.58616-1-govind.sk85@gmail.com
State New
Headers show
Series ath12k: add module param to control MSI mode and address width | expand

Commit Message

Govind Singh June 24, 2025, 4:50 p.m. UTC
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@gmail.com>
---
 drivers/net/wireless/ath/ath12k/pci.c | 25 +++++++++++++++++++++----
 drivers/net/wireless/ath/ath12k/pci.h |  5 +++++
 2 files changed, 26 insertions(+), 4 deletions(-)
diff mbox series

Patch

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);