The AHB external IRQ helpers change the hardware IRQ state even when NAPI is already in the requested state. PCI has a device-wide enabled bit guard, but also changes each group's IRQ state outside its NAPI state check. Tie each group's hardware IRQ transition to its NAPI state transition. Mask IRQs before disabling NAPI and enable NAPI before unmasking IRQs. This permits an extra IRQ disable before crash-recovery RXDMA teardown without increasing the IRQ disable depth. Based on Mark Ruvald Pedersen's ath11k IRQ lifecycle fix. Link: https://lore.kernel.org/linux-wireless/20260719215817.2468580-3-wabsie@gmail.com/ Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01243-QCAHKSWPL_SILICONZ-1 Signed-off-by: Nikolai Semendiaev --- drivers/net/wireless/ath/ath12k/ahb.c | 4 ++-- drivers/net/wireless/ath/ath12k/pci.c | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c index 85360365a..a5eaf5bf5 100644 --- a/drivers/net/wireless/ath/ath12k/ahb.c +++ b/drivers/net/wireless/ath/ath12k/ahb.c @@ -182,8 +182,8 @@ static void __ath12k_ahb_ext_irq_disable(struct ath12k_base *ab) for (i = 0; i < ATH12K_EXT_IRQ_GRP_NUM_MAX; i++) { struct ath12k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; - ath12k_ahb_ext_grp_disable(irq_grp); if (irq_grp->napi_enabled) { + ath12k_ahb_ext_grp_disable(irq_grp); napi_synchronize(&irq_grp->napi); napi_disable(&irq_grp->napi); irq_grp->napi_enabled = false; @@ -326,8 +326,8 @@ static void ath12k_ahb_ext_irq_enable(struct ath12k_base *ab) if (!irq_grp->napi_enabled) { napi_enable(&irq_grp->napi); irq_grp->napi_enabled = true; + ath12k_ahb_ext_grp_enable(irq_grp); } - ath12k_ahb_ext_grp_enable(irq_grp); } } diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c index af0e882fd..d2a7b6719 100644 --- a/drivers/net/wireless/ath/ath12k/pci.c +++ b/drivers/net/wireless/ath/ath12k/pci.c @@ -458,9 +458,8 @@ static void __ath12k_pci_ext_irq_disable(struct ath12k_base *ab) for (i = 0; i < ATH12K_EXT_IRQ_GRP_NUM_MAX; i++) { struct ath12k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; - ath12k_pci_ext_grp_disable(irq_grp); - if (irq_grp->napi_enabled) { + ath12k_pci_ext_grp_disable(irq_grp); napi_synchronize(&irq_grp->napi); napi_disable(&irq_grp->napi); irq_grp->napi_enabled = false; @@ -1108,9 +1107,8 @@ void ath12k_pci_ext_irq_enable(struct ath12k_base *ab) if (!irq_grp->napi_enabled) { napi_enable(&irq_grp->napi); irq_grp->napi_enabled = true; + ath12k_pci_ext_grp_enable(irq_grp); } - - ath12k_pci_ext_grp_enable(irq_grp); } set_bit(ATH12K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags); -- 2.43.0