net: designware: fix tx packet length
authorSimon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
Sat, 17 Nov 2018 09:24:41 +0000 (10:24 +0100)
committerJoe Hershberger <joe.hershberger@ni.com>
Thu, 24 Jan 2019 17:35:27 +0000 (11:35 -0600)
The designware driver has a bug in setting the tx length into the dma
descriptor: it always or's the length into the descriptor without
zeroing out the length mask before.

This results in occasional packets being transmitted with a length
greater than they should be (trailer). Due to the nature of Ethernet
allowing such a trailer, most packets seem to be parsed fine by remote
hosts, which is probably why this hasn't been noticed.

Fix this by correctly clearing the size mask before setting the new
length.

Tested on socfpga gen5.

Signed-off-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
Acked-by: Joe Hershberger <joe.hershberger@ni.com>
Reviewed-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
drivers/net/designware.c

index 4fa26abc1b870277d9f461b862a8ab7edbcc2364..01abcc21d2bdfe558b3a25101b8287839544e573 100644 (file)
@@ -389,15 +389,17 @@ static int _dw_eth_send(struct dw_eth_dev *priv, void *packet, int length)
 
 #if defined(CONFIG_DW_ALTDESCRIPTOR)
        desc_p->txrx_status |= DESC_TXSTS_TXFIRST | DESC_TXSTS_TXLAST;
-       desc_p->dmamac_cntl |= (length << DESC_TXCTRL_SIZE1SHFT) &
-                              DESC_TXCTRL_SIZE1MASK;
+       desc_p->dmamac_cntl = (desc_p->dmamac_cntl & ~DESC_TXCTRL_SIZE1MASK) |
+                             ((length << DESC_TXCTRL_SIZE1SHFT) &
+                             DESC_TXCTRL_SIZE1MASK);
 
        desc_p->txrx_status &= ~(DESC_TXSTS_MSK);
        desc_p->txrx_status |= DESC_TXSTS_OWNBYDMA;
 #else
-       desc_p->dmamac_cntl |= ((length << DESC_TXCTRL_SIZE1SHFT) &
-                              DESC_TXCTRL_SIZE1MASK) | DESC_TXCTRL_TXLAST |
-                              DESC_TXCTRL_TXFIRST;
+       desc_p->dmamac_cntl = (desc_p->dmamac_cntl & ~DESC_TXCTRL_SIZE1MASK) |
+                             ((length << DESC_TXCTRL_SIZE1SHFT) &
+                             DESC_TXCTRL_SIZE1MASK) | DESC_TXCTRL_TXLAST |
+                             DESC_TXCTRL_TXFIRST;
 
        desc_p->txrx_status = DESC_TXSTS_OWNBYDMA;
 #endif