From 7bf29145d7a9564162c6b18f8d23760e141e2d15 Mon Sep 17 00:00:00 2001 From: Jiawen Wu Date: Tue, 18 Aug 2026 10:30:26 +0800 Subject: [PATCH] net: txgbe: fix MISC interrupt unmasking in non-MSI-X mode and device shutdown In txgbe_misc_irq_thread_fn(), the driver unmasks the miscellaneous interrupt at the end of the handler using TXGBE_INTR_MISC(wx) (which resolves to BIT(wx->num_q_vectors)). While this is correct for MSI-X mode, it is incorrect for legacy INTx or single MSI modes. Due to hardware behavior, the WX_PX_MISC_IVAR register is completely ignored by the hardware when MSI-X is disabled. In non-MSI-X mode, the hardware forcibly merges all interrupt causes (both Queue and MISC) into a single bit: BIT(0) of the interrupt register. Unconditionally unmasking TXGBE_INTR_MISC(wx) (e.g., BIT(1)) in non-MSI-X mode means the actual MISC interrupt bit (BIT(0)) is not unmasked promptly at the end of the MISC thread. Instead, it remains masked until NAPI completes its polling and unmasks the shared BIT(0). This delays the assertion of subsequent MISC interrupts, preventing timely handling of events like link state changes. Fix this by explicitly checking `pdev->msix_enabled` and falling back to BIT(0) as the interrupt mask for the MISC cause when MSI-X is disabled. Additionally, unconditionally unmasking the interrupt at the end of the thread introduces a race condition during device teardown. Guarding the wx_intr_enable() call with a check for the WX_STATE_DOWN bit, to prevent re-arming the interrupt during device shutdown. Fixes: e37546ad1f9b ("net: wangxun: revert the adjustment of the IRQ vector sequence") Signed-off-by: Jiawen Wu Reviewed-by: Simon Horman Link: https://patch.msgid.link/56A53978B83EEDE9+20260818023026.6631-1-jiawenwu@trustnetic.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/wangxun/txgbe/txgbe_irq.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_irq.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_irq.c index 8746318ad3bc..5ad1ff7c3ce9 100644 --- a/drivers/net/ethernet/wangxun/txgbe/txgbe_irq.c +++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_irq.c @@ -164,6 +164,7 @@ static irqreturn_t txgbe_misc_irq_thread_fn(int irq, void *data) struct wx *wx = txgbe->wx; unsigned int nhandled = 0; unsigned int sub_irq; + u64 misc_mask; u32 eicr; eicr = txgbe->eicr; @@ -183,7 +184,9 @@ static irqreturn_t txgbe_misc_irq_thread_fn(int irq, void *data) nhandled++; } - wx_intr_enable(wx, TXGBE_INTR_MISC(wx)); + misc_mask = wx->pdev->msix_enabled ? TXGBE_INTR_MISC(wx) : BIT(0); + if (!test_bit(WX_STATE_DOWN, wx->state)) + wx_intr_enable(wx, misc_mask); return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE); }