summaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorIan Abbott <abbotti@mev.co.uk>2019-02-01 12:59:48 +0000
committerSascha Hauer <s.hauer@pengutronix.de>2019-02-05 12:44:39 +0100
commit90e9bfa36ea4deef2f1f322dc2503297420c2d20 (patch)
tree3290fb528480b8594b297c818994ac98699e02f8 /drivers/net
parent7172ee90b728375ee53f7a5186031ba3168ca0eb (diff)
downloadbarebox-90e9bfa36ea4deef2f1f322dc2503297420c2d20.tar.gz
barebox-90e9bfa36ea4deef2f1f322dc2503297420c2d20.tar.xz
net: designware: drop bad RX frames
In dwc_ether_rx(), check the RX descriptor status for various error conditions. On error, issue a warning with the error status bits and drop the received frame. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/designware.c42
1 files changed, 33 insertions, 9 deletions
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index ad70967e8c..21134cd5ab 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -326,24 +326,48 @@ static int dwc_ether_rx(struct eth_device *dev)
u32 status = desc_p->txrx_status;
int length = 0;
+ int ret = 0;
/* Check if the owner is the CPU */
if (status & DESC_RXSTS_OWNBYDMA)
return 0;
- length = (status & DESC_RXSTS_FRMLENMSK) >>
- DESC_RXSTS_FRMLENSHFT;
+ if ((status & (DESC_RXSTS_ERROR | DESC_RXSTS_DAFILTERFAIL |
+ DESC_RXSTS_SAFILTERFAIL)) ||
+ (status & (DESC_RXSTS_RXIPC_GIANTFRAME |
+ DESC_RXSTS_RXFRAMEETHER)) ==
+ DESC_RXSTS_RXIPC_GIANTFRAME) {
+ /* Error in packet - discard it */
+ dev_warn(&dev->dev, "Rx error status (%x)\n",
+ status & (DESC_RXSTS_DAFILTERFAIL |
+ DESC_RXSTS_ERROR |
+ DESC_RXSTS_RXTRUNCATED |
+ DESC_RXSTS_SAFILTERFAIL |
+ DESC_RXSTS_RXIPC_GIANTFRAME |
+ DESC_RXSTS_RXDAMAGED |
+ DESC_RXSTS_RXIPC_GIANT |
+ DESC_RXSTS_RXCOLLISION |
+ DESC_RXSTS_RXFRAMEETHER |
+ DESC_RXSTS_RXWATCHDOG |
+ DESC_RXSTS_RXMIIERROR |
+ DESC_RXSTS_RXCRC));
+ ret = -EIO;
+ } else {
+ length = (status & DESC_RXSTS_FRMLENMSK) >>
+ DESC_RXSTS_FRMLENSHFT;
+
+ dma_sync_single_for_cpu((unsigned long)desc_p->dmamac_addr,
+ length, DMA_FROM_DEVICE);
+ net_receive(dev, desc_p->dmamac_addr, length);
+ dma_sync_single_for_device((unsigned long)desc_p->dmamac_addr,
+ length, DMA_FROM_DEVICE);
+ ret = length;
+ }
/*
* Make the current descriptor valid again and go to
* the next one
*/
- dma_sync_single_for_cpu((unsigned long)desc_p->dmamac_addr, length,
- DMA_FROM_DEVICE);
- net_receive(dev, desc_p->dmamac_addr, length);
- dma_sync_single_for_device((unsigned long)desc_p->dmamac_addr, length,
- DMA_FROM_DEVICE);
-
desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA;
/* Test the wrap-around condition. */
@@ -352,7 +376,7 @@ static int dwc_ether_rx(struct eth_device *dev)
priv->rx_currdescnum = desc_num;
- return length;
+ return ret;
}
static void dwc_ether_halt (struct eth_device *dev)