[RFC PATCH 2/3] wifi: ath11k: make external IRQ control idempotent
Mark Ruvald Pedersen
wabsie at gmail.com
Sun Jul 19 14:58:16 PDT 2026
ath11k tracks each external IRQ group's NAPI lifecycle with napi_enabled,
but calls the physical IRQ enable and disable helpers outside the state
guards. Repeating a lifecycle disable therefore increments Linux's IRQ
disable depth on AHB and multi-MSI PCI even when NAPI is already
disabled. One later enable leaves the IRQ masked.
Move each physical group transition inside the matching NAPI state
transition. Preserve the ordering: mask IRQs before synchronizing and
disabling NAPI, then enable NAPI before unmasking IRQs. The outer
synchronize_irq() calls remain unchanged.
This makes sequential lifecycle transitions idempotent. It does not
change the temporary disable/enable pairing in interrupt handlers and
NAPI poll completion.
Fixes: d943fdad7589 ("ath11k: Fix napi related hang")
Fixes: bbfdc5a751a6 ("ath11k: Refactor PCI code to support WCN6750")
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.9.0.1-02146-QCAHKSWPL_SILICONZ-1
Signed-off-by: Mark Ruvald Pedersen <wabsie at gmail.com>
---
diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c
index 1e1dea485..1f1562ff3 100644
--- a/drivers/net/wireless/ath/ath11k/ahb.c
+++ b/drivers/net/wireless/ath/ath11k/ahb.c
@@ -235,9 +235,9 @@ static void __ath11k_ahb_ext_irq_disable(struct ath11k_base *ab)
for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
- ath11k_ahb_ext_grp_disable(irq_grp);
-
if (irq_grp->napi_enabled) {
+ ath11k_ahb_ext_grp_disable(irq_grp);
+
napi_synchronize(&irq_grp->napi);
napi_disable(&irq_grp->napi);
irq_grp->napi_enabled = false;
@@ -380,8 +380,8 @@ static void ath11k_ahb_ext_irq_enable(struct ath11k_base *ab)
if (!irq_grp->napi_enabled) {
napi_enable(&irq_grp->napi);
irq_grp->napi_enabled = true;
+ ath11k_ahb_ext_grp_enable(irq_grp);
}
- ath11k_ahb_ext_grp_enable(irq_grp);
}
}
diff --git a/drivers/net/wireless/ath/ath11k/pcic.c b/drivers/net/wireless/ath/ath11k/pcic.c
index 2259adc3b..bf367f60b 100644
--- a/drivers/net/wireless/ath/ath11k/pcic.c
+++ b/drivers/net/wireless/ath/ath11k/pcic.c
@@ -455,9 +455,9 @@ static void __ath11k_pcic_ext_irq_disable(struct ath11k_base *ab)
for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
- ath11k_pcic_ext_grp_disable(irq_grp);
-
if (irq_grp->napi_enabled) {
+ ath11k_pcic_ext_grp_disable(irq_grp);
+
napi_synchronize(&irq_grp->napi);
napi_disable(&irq_grp->napi);
irq_grp->napi_enabled = false;
@@ -490,8 +490,8 @@ void ath11k_pcic_ext_irq_enable(struct ath11k_base *ab)
if (!irq_grp->napi_enabled) {
napi_enable(&irq_grp->napi);
irq_grp->napi_enabled = true;
+ ath11k_pcic_ext_grp_enable(irq_grp);
}
- ath11k_pcic_ext_grp_enable(irq_grp);
}
set_bit(ATH11K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags);
More information about the ath11k
mailing list