6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kang Yang quic_kangyang@quicinc.com
[ Upstream commit 604308a34487eaa382c50fcdb4396c435030b4fa ]
Add two flags to indicate whether IRQ handler for CE and DP can be called. This is because in one MSI vector case, interrupt is not disabled in hif_stop and hif_irq_disable. So if interrupt is disabled, MHI interrupt is disabled too.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4
Signed-off-by: Kang Yang quic_kangyang@quicinc.com Acked-by: Jeff Johnson quic_jjohnson@quicinc.com Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20231121021304.12966-3-quic_kangyang@quicinc.com Stable-dep-of: a47f3320bb4b ("wifi: ath12k: fix soft lockup on suspend") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath12k/core.h | 2 ++ drivers/net/wireless/ath/ath12k/pci.c | 16 ++++++++++++++++ 2 files changed, 18 insertions(+)
diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index c926952c956ef..33f4706af880d 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -181,6 +181,8 @@ enum ath12k_dev_flags { ATH12K_FLAG_REGISTERED, ATH12K_FLAG_QMI_FAIL, ATH12K_FLAG_HTC_SUSPEND_COMPLETE, + ATH12K_FLAG_CE_IRQ_ENABLED, + ATH12K_FLAG_EXT_IRQ_ENABLED, };
enum ath12k_monitor_flags { diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c index a6a5f9bcffbd6..f27b93c20a349 100644 --- a/drivers/net/wireless/ath/ath12k/pci.c +++ b/drivers/net/wireless/ath/ath12k/pci.c @@ -373,6 +373,8 @@ static void ath12k_pci_ce_irqs_disable(struct ath12k_base *ab) { int i;
+ clear_bit(ATH12K_FLAG_CE_IRQ_ENABLED, &ab->dev_flags); + for (i = 0; i < ab->hw_params->ce_count; i++) { if (ath12k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR) continue; @@ -406,6 +408,10 @@ static void ath12k_pci_ce_tasklet(struct tasklet_struct *t) static irqreturn_t ath12k_pci_ce_interrupt_handler(int irq, void *arg) { struct ath12k_ce_pipe *ce_pipe = arg; + struct ath12k_base *ab = ce_pipe->ab; + + if (!test_bit(ATH12K_FLAG_CE_IRQ_ENABLED, &ab->dev_flags)) + return IRQ_HANDLED;
/* last interrupt received for this CE */ ce_pipe->timestamp = jiffies; @@ -428,6 +434,8 @@ static void __ath12k_pci_ext_irq_disable(struct ath12k_base *ab) { int i;
+ clear_bit(ATH12K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags); + for (i = 0; i < ATH12K_EXT_IRQ_GRP_NUM_MAX; i++) { struct ath12k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
@@ -483,6 +491,10 @@ static int ath12k_pci_ext_grp_napi_poll(struct napi_struct *napi, int budget) static irqreturn_t ath12k_pci_ext_interrupt_handler(int irq, void *arg) { struct ath12k_ext_irq_grp *irq_grp = arg; + struct ath12k_base *ab = irq_grp->ab; + + if (!test_bit(ATH12K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags)) + return IRQ_HANDLED;
ath12k_dbg(irq_grp->ab, ATH12K_DBG_PCI, "ext irq:%d\n", irq);
@@ -626,6 +638,8 @@ static void ath12k_pci_ce_irqs_enable(struct ath12k_base *ab) { int i;
+ set_bit(ATH12K_FLAG_CE_IRQ_ENABLED, &ab->dev_flags); + for (i = 0; i < ab->hw_params->ce_count; i++) { if (ath12k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR) continue; @@ -956,6 +970,8 @@ void ath12k_pci_ext_irq_enable(struct ath12k_base *ab) { int i;
+ set_bit(ATH12K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags); + for (i = 0; i < ATH12K_EXT_IRQ_GRP_NUM_MAX; i++) { struct ath12k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];