]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
realtek: refactor net rx interrupt handler rtl83xx_net_irq() 18855/head
authorMarkus Stockhausen <markus.stockhausen@gmx.de>
Tue, 20 May 2025 20:10:44 +0000 (16:10 -0400)
committerRobert Marko <robimarko@gmail.com>
Wed, 21 May 2025 11:54:06 +0000 (13:54 +0200)
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@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/18855
Signed-off-by: Robert Marko <robimarko@gmail.com>
target/linux/realtek/files-6.6/drivers/net/ethernet/rtl838x_eth.c
target/linux/realtek/files-6.6/drivers/net/ethernet/rtl838x_eth.h

index dbed9d70756baca1ec1a97a0c63dc6112f7ab3a6..d6647b280668db3e81832c37b3120ac63321b928 100644 (file)
@@ -434,23 +434,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);
@@ -459,28 +455,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;
 }
index 47ed286aa44731746bd922010850002d6a6bb024..692c1d69a0271912c97d5fe87682c80efcedcdb7 100644 (file)
 #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)