diff options
| author | Wei Fang <wei.fang@nxp.com> | 2026-02-05 16:57:29 +0800 |
|---|---|---|
| committer | Paolo Abeni <pabeni@redhat.com> | 2026-02-10 10:58:19 +0100 |
| commit | ff306e9a1963ffd5c8b800eb86213f88fac8dd3b (patch) | |
| tree | b078042aa97059eef337fca42df35811d24db20f | |
| parent | c8d4ad91765c451ba6bdbd08d71b6639b42c3b3e (diff) | |
net: fec: add fec_rx_error_check() to check RX errors
Extract fec_rx_error_check() from fec_enet_rx_queue(), this helper is
used to check RX errors. And it will be used in XDP and XDP zero copy
paths in subsequent patches.
Signed-off-by: Wei Fang <wei.fang@nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260205085742.2685134-3-wei.fang@nxp.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
| -rw-r--r-- | drivers/net/ethernet/freescale/fec_main.c | 58 |
1 files changed, 36 insertions, 22 deletions
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index ce433af02ad2..ee4a20d8c438 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -1747,6 +1747,41 @@ static void fec_enet_rx_vlan(const struct net_device *ndev, struct sk_buff *skb) } } +static int fec_rx_error_check(struct net_device *ndev, u16 status) +{ + if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO | + BD_ENET_RX_CR | BD_ENET_RX_OV | BD_ENET_RX_LAST | + BD_ENET_RX_CL)) { + ndev->stats.rx_errors++; + + if (status & BD_ENET_RX_OV) { + /* FIFO overrun */ + ndev->stats.rx_fifo_errors++; + return -EIO; + } + + if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | + BD_ENET_RX_LAST)) { + /* Frame too long or too short. */ + ndev->stats.rx_length_errors++; + if ((status & BD_ENET_RX_LAST) && net_ratelimit()) + netdev_err(ndev, "rcv is not +last\n"); + } + + /* CRC Error */ + if (status & BD_ENET_RX_CR) + ndev->stats.rx_crc_errors++; + + /* Report late collisions as a frame error. */ + if (status & (BD_ENET_RX_NO | BD_ENET_RX_CL)) + ndev->stats.rx_frame_errors++; + + return -EIO; + } + + return 0; +} + /* During a receive, the bd_rx.cur points to the current incoming buffer. * When we update through the ring, if the next incoming buffer has * not been given to the system, we just set the empty indicator, @@ -1807,29 +1842,8 @@ fec_enet_rx_queue(struct net_device *ndev, u16 queue_id, int budget) /* Check for errors. */ status ^= BD_ENET_RX_LAST; - if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO | - BD_ENET_RX_CR | BD_ENET_RX_OV | BD_ENET_RX_LAST | - BD_ENET_RX_CL)) { - ndev->stats.rx_errors++; - if (status & BD_ENET_RX_OV) { - /* FIFO overrun */ - ndev->stats.rx_fifo_errors++; - goto rx_processing_done; - } - if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH - | BD_ENET_RX_LAST)) { - /* Frame too long or too short. */ - ndev->stats.rx_length_errors++; - if (status & BD_ENET_RX_LAST) - netdev_err(ndev, "rcv is not +last\n"); - } - if (status & BD_ENET_RX_CR) /* CRC Error */ - ndev->stats.rx_crc_errors++; - /* Report late collisions as a frame error. */ - if (status & (BD_ENET_RX_NO | BD_ENET_RX_CL)) - ndev->stats.rx_frame_errors++; + if (unlikely(fec_rx_error_check(ndev, status))) goto rx_processing_done; - } /* Process the incoming frame. */ ndev->stats.rx_packets++; |
