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 d815356c9d8..91577ac7668 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 @@ -452,28 +452,25 @@ static irqreturn_t rtl83xx_net_irq(int irq, void *dev_id) struct net_device *ndev = dev_id; struct rtl838x_eth_priv *priv = netdev_priv(ndev); u32 status = sw_r32(priv->r->dma_if_intr_sts); + unsigned long ring, rings; - netdev_dbg(ndev, "RX IRQ received: %08x\n", status); + netdev_dbg(ndev, "rx interrupt received, status %08x\n", status); - 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)); + if (status & RTL83XX_DMA_IF_INTR_RX_RUN_OUT_MASK) + if (net_ratelimit()) + netdev_warn(ndev, "rx ring overrun, status 0x%08x, mask 0x%08x\n", + status, sw_r32(priv->r->dma_if_intr_msk)); - 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); - for (int i = 0; i < priv->rxrings; i++) { - if (status & BIT(i + 8)) { - pr_debug("Scheduling queue: %d\n", i); - napi_schedule(&priv->rx_qs[i].napi); - } - } + rings = FIELD_GET(RTL83XX_DMA_IF_INTR_RX_DONE_MASK, status); + for_each_set_bit(ring, &rings, priv->rxrings) { + netdev_dbg(ndev, "schedule rx ring %lu\n", ring); + sw_w32_mask(RTL83XX_DMA_IF_INTR_RX_MASK(ring), 0, priv->r->dma_if_intr_msk); + napi_schedule(&priv->rx_qs[ring].napi); } - if ((status & RTL83XX_DMA_IF_INTR_STS_NOTIFY_MASK) && priv->family_id == RTL8390_FAMILY_ID) + if (status & RTL839X_DMA_IF_INTR_NOTIFY_MASK) rtl839x_l2_notification_handler(priv); - /* Acknowledge all interrupts */ sw_w32(status, priv->r->dma_if_intr_sts); return IRQ_HANDLED; @@ -1353,25 +1350,22 @@ static int rtl838x_poll_rx(struct napi_struct *napi, int budget) { struct rtl838x_rx_q *rx_q = container_of(napi, struct rtl838x_rx_q, napi); struct rtl838x_eth_priv *priv = rx_q->priv; + int ring = rx_q->id; int work_done = 0; - int r = rx_q->id; - int work; while (work_done < budget) { - work = rtl838x_hw_receive(priv->netdev, r, budget - work_done); + int work = rtl838x_hw_receive(priv->netdev, ring, budget - work_done); if (!work) break; work_done += work; } - if (work_done < budget) { - napi_complete_done(napi, work_done); - - /* Enable RX interrupt */ + if (work_done < budget && napi_complete_done(napi, work_done)) { + /* Re-enable rx interrupts */ if (priv->family_id == RTL9300_FAMILY_ID || priv->family_id == RTL9310_FAMILY_ID) sw_w32(0xffffffff, priv->r->dma_if_intr_rx_done_msk); else - sw_w32_mask(0, 0xf00ff | BIT(r + 8), priv->r->dma_if_intr_msk); + sw_w32_mask(0, RTL83XX_DMA_IF_INTR_RX_MASK(ring), priv->r->dma_if_intr_msk); } return work_done; diff --git a/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.h b/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.h index 8d138cabb9d..e899467d133 100644 --- a/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.h +++ b/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.h @@ -48,9 +48,10 @@ #define RTL930X_MAC_FORCE_MODE_CTRL (0xCA1C) #define RTL931X_MAC_FORCE_MODE_CTRL (0x0dcc) -#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) +#define RTL839X_DMA_IF_INTR_NOTIFY_MASK GENMASK(22, 20) +#define RTL83XX_DMA_IF_INTR_RX_DONE_MASK GENMASK(15, 8) +#define RTL83XX_DMA_IF_INTR_RX_RUN_OUT_MASK GENMASK(7, 0) +#define RTL83XX_DMA_IF_INTR_RX_MASK(ring) (BIT(ring) | BIT(ring + 8)) /* MAC address settings */ #define RTL838X_MAC (0xa9ec)