[openwrt/openwrt] realtek: refactor net rx interrupt handler rtl83xx_net_irq()

LEDE Commits lede-commits at lists.infradead.org
Sun Jun 8 12:21:39 PDT 2025


hauke pushed a commit to openwrt/openwrt.git, branch openwrt-24.10:
https://git.openwrt.org/072fd4de3c689bf9740f93cc5a881fb67ba13d12

commit 072fd4de3c689bf9740f93cc5a881fb67ba13d12
Author: Markus Stockhausen <markus.stockhausen at gmx.de>
AuthorDate: Tue May 20 16:10:44 2025 -0400

    realtek: refactor net rx interrupt handler rtl83xx_net_irq()
    
    Cleanup the code of the RTL83xx packet receive interrupt handler. Not
    only for better readability but to avoid inconsistencies and stalls on
    the RTL839x targets.
    
    The current implementation seems to come from the GPL source code.
    Calling the existing cleanup() function inside the interrupt context
    without any locks conflicts with SMP & NAPI polling and makes things
    worse instead of giving any benefit. Simply ignore RX buffer overruns
    and let the device handle packet dropping itself.
    
    Signed-off-by: Markus Stockhausen <markus.stockhausen at gmx.de>
    Link: https://github.com/openwrt/openwrt/pull/18855
    Signed-off-by: Robert Marko <robimarko at gmail.com>
    (cherry picked from commit 8dde1e463884b3ac84d7ba9ca7ce557c4f6e117d)
    Link: https://github.com/openwrt/openwrt/pull/18755
    Signed-off-by: Hauke Mehrtens <hauke at hauke-m.de>
---
 .../files-6.6/drivers/net/ethernet/rtl838x_eth.c   | 43 ++++++----------------
 .../files-6.6/drivers/net/ethernet/rtl838x_eth.h   |  4 ++
 2 files changed, 15 insertions(+), 32 deletions(-)

diff --git a/target/linux/realtek/files-6.6/drivers/net/ethernet/rtl838x_eth.c b/target/linux/realtek/files-6.6/drivers/net/ethernet/rtl838x_eth.c
index 4b79090696..83b5462ec5 100644
--- a/target/linux/realtek/files-6.6/drivers/net/ethernet/rtl838x_eth.c
+++ b/target/linux/realtek/files-6.6/drivers/net/ethernet/rtl838x_eth.c
@@ -433,23 +433,19 @@ static void rtl839x_l2_notification_handler(struct rtl838x_eth_priv *priv)
 
 static irqreturn_t rtl83xx_net_irq(int irq, void *dev_id)
 {
-	struct net_device *dev = dev_id;
-	struct rtl838x_eth_priv *priv = netdev_priv(dev);
+	struct net_device *ndev = dev_id;
+	struct rtl838x_eth_priv *priv = netdev_priv(ndev);
 	u32 status = sw_r32(priv->r->dma_if_intr_sts);
 
-	pr_debug("IRQ: %08x\n", status);
+	netdev_dbg(ndev, "RX IRQ received: %08x\n", status);
 
-	/*  Ignore TX interrupt */
-	if ((status & 0xf0000)) {
-		/* Clear ISR */
-		sw_w32(0x000f0000, priv->r->dma_if_intr_sts);
-	}
+	if ((status & RTL83XX_DMA_IF_INTR_STS_RX_RUN_OUT_MASK) && net_ratelimit())
+		netdev_warn(ndev, "RX buffer overrun: status 0x%x, mask: 0x%x\n",
+			   status, sw_r32(priv->r->dma_if_intr_msk));
 
-	/* RX interrupt */
-	if (status & 0x0ff00) {
-		/* ACK and disable RX interrupt for this ring */
+	if (status & RTL83XX_DMA_IF_INTR_STS_RX_DONE_MASK) {
+		/* Disable rx interrupts */
 		sw_w32_mask(0xff00 & status, 0, priv->r->dma_if_intr_msk);
-		sw_w32(0x0000ff00 & status, priv->r->dma_if_intr_sts);
 		for (int i = 0; i < priv->rxrings; i++) {
 			if (status & BIT(i + 8)) {
 				pr_debug("Scheduling queue: %d\n", i);
@@ -458,28 +454,11 @@ static irqreturn_t rtl83xx_net_irq(int irq, void *dev_id)
 		}
 	}
 
-	/* RX buffer overrun */
-	if (status & 0x000ff) {
-		pr_debug("RX buffer overrun: status %x, mask: %x\n",
-			 status, sw_r32(priv->r->dma_if_intr_msk));
-		sw_w32(status, priv->r->dma_if_intr_sts);
-		rtl838x_rb_cleanup(priv, status & 0xff);
-	}
-
-	if (priv->family_id == RTL8390_FAMILY_ID && status & 0x00100000) {
-		sw_w32(0x00100000, priv->r->dma_if_intr_sts);
-		rtl839x_l2_notification_handler(priv);
-	}
-
-	if (priv->family_id == RTL8390_FAMILY_ID && status & 0x00200000) {
-		sw_w32(0x00200000, priv->r->dma_if_intr_sts);
+	if ((status & RTL83XX_DMA_IF_INTR_STS_NOTIFY_MASK) && priv->family_id == RTL8390_FAMILY_ID)
 		rtl839x_l2_notification_handler(priv);
-	}
 
-	if (priv->family_id == RTL8390_FAMILY_ID && status & 0x00400000) {
-		sw_w32(0x00400000, priv->r->dma_if_intr_sts);
-		rtl839x_l2_notification_handler(priv);
-	}
+	/* Acknowledge all interrupts */
+	sw_w32(status, priv->r->dma_if_intr_sts);
 
 	return IRQ_HANDLED;
 }
diff --git a/target/linux/realtek/files-6.6/drivers/net/ethernet/rtl838x_eth.h b/target/linux/realtek/files-6.6/drivers/net/ethernet/rtl838x_eth.h
index d6d88fc2ed..a87a8a5988 100644
--- a/target/linux/realtek/files-6.6/drivers/net/ethernet/rtl838x_eth.h
+++ b/target/linux/realtek/files-6.6/drivers/net/ethernet/rtl838x_eth.h
@@ -48,6 +48,10 @@
 #define RTL930X_MAC_FORCE_MODE_CTRL		(0xCA1C)
 #define RTL931X_MAC_FORCE_MODE_CTRL		(0x0ddc)
 
+#define RTL83XX_DMA_IF_INTR_STS_NOTIFY_MASK	GENMASK(22, 20)
+#define RTL83XX_DMA_IF_INTR_STS_RX_DONE_MASK	GENMASK(15, 8)
+#define RTL83XX_DMA_IF_INTR_STS_RX_RUN_OUT_MASK	GENMASK(7, 0)
+
 /* MAC address settings */
 #define RTL838X_MAC				(0xa9ec)
 #define RTL839X_MAC				(0x02b4)




More information about the lede-commits mailing list