summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/freescale/fec_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/freescale/fec_main.c')
-rw-r--r--drivers/net/ethernet/freescale/fec_main.c47
1 files changed, 27 insertions, 20 deletions
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 89355a719625..fd49bd70d15d 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1218,28 +1218,35 @@ fec_enet_rx(struct net_device *ndev, int budget)
writel(FEC_ENET_RXF, fep->hwp + FEC_IEVENT);
/* Check for errors. */
- if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO |
- BD_ENET_RX_CR | BD_ENET_RX_OV)) {
+ if (status & BD_ENET_RX_ERROR) {
ndev->stats.rx_errors++;
- if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH)) {
- /* Frame too long or too short. */
- ndev->stats.rx_length_errors++;
- }
- if (status & BD_ENET_RX_NO) /* Frame alignment */
- ndev->stats.rx_frame_errors++;
- if (status & BD_ENET_RX_CR) /* CRC Error */
- ndev->stats.rx_crc_errors++;
- if (status & BD_ENET_RX_OV) /* FIFO overrun */
- ndev->stats.rx_fifo_errors++;
- }
- /* Report late collisions as a frame error.
- * On this error, the BD is closed, but we don't know what we
- * have in the buffer. So, just drop this frame on the floor.
- */
- if (status & BD_ENET_RX_CL) {
- ndev->stats.rx_errors++;
- ndev->stats.rx_frame_errors++;
+ if (status & BD_ENET_RX_OV) {
+ /*
+ * FIFO overrun - stored frame and the other
+ * status (M, LG, NO, CR, CL) are invalid.
+ * Although docs say these status bits will
+ * be zero, it has been observed on iMX6 FEC
+ * that OV is always accompanied by CR set.
+ */
+ ndev->stats.rx_fifo_errors++;
+ } else if (status & BD_ENET_RX_CL) {
+ /*
+ * Report late collisions as a frame error.
+ * On this error, the BD is closed, but we
+ * don't know what we have in the buffer.
+ * So, just drop this frame on the floor.
+ */
+ ndev->stats.rx_frame_errors++;
+ } else {
+ if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH))
+ /* Frame too long or too short. */
+ ndev->stats.rx_length_errors++;
+ if (status & BD_ENET_RX_NO) /* Frame alignment */
+ ndev->stats.rx_frame_errors++;
+ if (status & BD_ENET_RX_CR) /* CRC Error */
+ ndev->stats.rx_crc_errors++;
+ }
goto rx_processing_done;
}