net: fec: fix rx error counts
authorTroy Kisky <troy.kisky@boundarydevices.com>
Fri, 5 Feb 2016 21:52:44 +0000 (14:52 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 11 Feb 2016 11:14:51 +0000 (06:14 -0500)
On an overrun, the other flags are not
valid, so don't check them.

Also, don't pass bad frames up the stack.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/freescale/fec_main.c

index 3e5b24a..162fa59 100644 (file)
@@ -1408,37 +1408,31 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
                        break;
                pkt_received++;
 
-               /* Since we have allocated space to hold a complete frame,
-                * the last indicator should be set.
-                */
-               if ((status & BD_ENET_RX_LAST) == 0)
-                       netdev_err(ndev, "rcv is not +last\n");
-
                writel(FEC_ENET_RXF, fep->hwp + FEC_IEVENT);
 
                /* 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_CR | BD_ENET_RX_OV | BD_ENET_RX_LAST |
+                          BD_ENET_RX_CL)) {
                        ndev->stats.rx_errors++;
-                       if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH)) {
+                       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_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++;
+                       /* Report late collisions as a frame error. */
+                       if (status & (BD_ENET_RX_NO | BD_ENET_RX_CL))
+                               ndev->stats.rx_frame_errors++;
                        goto rx_processing_done;
                }