From 0eac896cc7697a2a522a2da417dd3cbea8937db7 Mon Sep 17 00:00:00 2001 From: Markus Stockhausen Date: Mon, 23 Feb 2026 18:44:25 +0100 Subject: [PATCH] realtek: eth: be defensive in rteth_confirm_and_disable_irqs() With latest refactoring irq activation and deactivation is side-by-side in the code. This makes it easier to align these functions. Current assumption is, that the ethernet irq is only called on one cpu and napi handling does not interfere. So it should be totally fine to run irq disabling (called from interrupt handler) without locks. Nevertheless be defensive and add a lock(). So in the case the ethernet irq is fired twice on two cpus (e.g. RTL931x) the code is on the safe side. Signed-off-by: Markus Stockhausen Link: https://github.com/openwrt/openwrt/pull/22156 Signed-off-by: Robert Marko --- .../realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.c b/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.c index 1e43cefbff..779aa6fac6 100644 --- a/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.c +++ b/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.c @@ -211,12 +211,15 @@ static inline void rteth_confirm_and_disable_irqs(struct rteth_ctrl *ctrl, u32 mask = GENMASK(ctrl->r->rx_rings - 1, 0); u32 shift = ctrl->r->rx_rings % 32; u32 reg = ctrl->r->rx_rings / 32; + unsigned long flags; u32 active; /* get all irqs, disable only rx (on RTL839x this keeps L2), confirm all */ + spin_lock_irqsave(&ctrl->lock, flags); active = sw_r32(ctrl->r->dma_if_intr_sts + reg * 4); sw_w32_mask(active & (mask << shift), 0, ctrl->r->dma_if_intr_msk + reg * 4); sw_w32(active, ctrl->r->dma_if_intr_sts + reg * 4); + spin_unlock_irqrestore(&ctrl->lock, flags); /* ~mask filters out RTL93xx devices */ *l2 = !!(active & ~mask & RTL839X_DMA_IF_INTR_NOTIFY_MASK);