summaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethernet/freescale/fec.h1
-rw-r--r--drivers/net/ethernet/freescale/fec_main.c47
2 files changed, 28 insertions, 20 deletions
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index ee41d98b44b6..ec4c76264eb9 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -202,6 +202,7 @@ struct bufdesc_ex {
#define BD_ENET_RX_OV ((ushort)0x0002)
#define BD_ENET_RX_CL ((ushort)0x0001)
#define BD_ENET_RX_STATS ((ushort)0x013f) /* All status bits */
+#define BD_ENET_RX_ERROR ((ushort)0x003f)
/* Enhanced buffer descriptor control/status used by Ethernet receive */
#define BD_ENET_RX_VLAN 0x00000004
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;
}