From: Markus Stockhausen Date: Mon, 23 Feb 2026 17:44:25 +0000 (+0100) Subject: realtek: eth: be defensive in rteth_confirm_and_disable_irqs() X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=0eac896cc7697a2a522a2da417dd3cbea8937db7;p=thirdparty%2Fopenwrt.git 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 --- 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 1e43cefbff4..779aa6fac6b 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);