From 5a9c554ff86d7f3750d95ce72ad0666e02e37b92 Mon Sep 17 00:00:00 2001 From: Runyu Xiao Date: Sun, 31 May 2026 22:54:35 +0800 Subject: [PATCH] wifi: qtnfmac: topaz: defer IRQ enabling until IPC init qtnf_pcie_topaz_probe() currently calls devm_request_irq() and only then disable_irq(). request_irq() installs the action in the irq core immediately, so qtnf_pcie_topaz_interrupt() can run before the Topaz private IRQ consumers are initialized, if the hardware misbehaves. This window is reachable on a running system as soon as probe has successfully registered pdev->irq but before qtnf_pcie_init_shm_ipc() sets shm_ipc_ep_in/out.irq_handler. If an interrupt is delivered in this interval, qtnf_pcie_topaz_interrupt() calls qtnf_shm_ipc_irq_handler() for shm_ipc_ep_in/out while their irq_handler callbacks are still unset, so the driver can observe an early IRQ before its IPC consumer state is ready. The issue was found on Linux v6.18.21 by our static analysis tool while scanning request_irq()/disable_irq() registration-order bugs in wireless PCIe drivers, and then manually reviewed. Request the IRQ with IRQF_NO_AUTOEN instead and keep the existing enable_irq() in qtnf_post_init_ep() as the point where interrupts become visible. This closes the early-IRQ window while preserving the intended bring-up order. Signed-off-by: Runyu Xiao Link: https://patch.msgid.link/20260531145435.701703-1-runyu.xiao@seu.edu.cn Signed-off-by: Johannes Berg --- drivers/net/wireless/quantenna/qtnfmac/pcie/topaz_pcie.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/topaz_pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/topaz_pcie.c index ef5c069542d4..a3a285f17dca 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/pcie/topaz_pcie.c +++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/topaz_pcie.c @@ -1132,9 +1132,9 @@ static int qtnf_pcie_topaz_probe(struct qtnf_bus *bus, /* assign host msi irq before card init */ if (ts->base.msi_enabled) - irqflags = IRQF_NOBALANCING; + irqflags = IRQF_NOBALANCING | IRQF_NO_AUTOEN; else - irqflags = IRQF_NOBALANCING | IRQF_SHARED; + irqflags = IRQF_NOBALANCING | IRQF_SHARED | IRQF_NO_AUTOEN; ret = devm_request_irq(&pdev->dev, pdev->irq, &qtnf_pcie_topaz_interrupt, @@ -1144,8 +1144,6 @@ static int qtnf_pcie_topaz_probe(struct qtnf_bus *bus, return ret; } - disable_irq(pdev->irq); - ret = qtnf_pre_init_ep(bus); if (ret) { pr_err("failed to init card\n");