Discussion:
[U-Boot] [PATCH 1/2] net: designware: fix tx packet length
Simon Goldschmidt
2018-11-17 09:24:41 UTC
Permalink
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 <***@gmail.com>
---

drivers/net/designware.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index 19db0a8114..688cf9fef2 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -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
--
2.17.1
Simon Goldschmidt
2018-11-17 09:24:42 UTC
Permalink
Short frames are padded to the minimum allowed size of 60 bytes.
However, the designware driver sends old data in these padding bytes.
It is common practice to zero out these padding bytes ro prevent
leaking memory contents to other hosts.

Fix the padding code to zero out the padded bytes at the end.

Tested on socfpga gen5.

Signed-off-by: Simon Goldschmidt <***@gmail.com>
---

drivers/net/designware.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index 688cf9fef2..33463de0f8 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -380,9 +380,11 @@ static int _dw_eth_send(struct dw_eth_dev *priv, void *packet, int length)
return -EPERM;
}

- length = max(length, ETH_ZLEN);
-
memcpy((void *)data_start, packet, length);
+ if (length < ETH_ZLEN) {
+ memset(&((char *)data_start)[length], 0, ETH_ZLEN - length);
+ length = ETH_ZLEN;
+ }

/* Flush data to be sent */
flush_dcache_range(data_start, data_end);
--
2.17.1
Joe Hershberger
2018-11-17 16:03:44 UTC
Permalink
On Sat, Nov 17, 2018 at 3:26 AM Simon Goldschmidt
Post by Simon Goldschmidt
Short frames are padded to the minimum allowed size of 60 bytes.
However, the designware driver sends old data in these padding bytes.
It is common practice to zero out these padding bytes ro prevent
leaking memory contents to other hosts.
Fix the padding code to zero out the padded bytes at the end.
Tested on socfpga gen5.
Acked-by: Joe Hershberger <***@ni.com>
Simon Goldschmidt
2018-11-24 19:08:10 UTC
Permalink
Post by Joe Hershberger
On Sat, Nov 17, 2018 at 3:26 AM Simon Goldschmidt
Post by Simon Goldschmidt
Short frames are padded to the minimum allowed size of 60 bytes.
However, the designware driver sends old data in these padding bytes.
It is common practice to zero out these padding bytes ro prevent
leaking memory contents to other hosts.
Fix the padding code to zero out the padded bytes at the end.
Tested on socfpga gen5.
Having searched through the code, there are other drivers that increase
the length to 60 bytes but don't zero out the padding.

Would it be better to do this in eth_send()? That would ensure every
driver does it. I don't know the U-Boot net stack too well, but maybe we
could even do the minimum length check in eth_send()?

Regards,
Simon
Joe Hershberger
2018-11-17 16:02:42 UTC
Permalink
On Sat, Nov 17, 2018 at 3:25 AM Simon Goldschmidt
Post by Simon Goldschmidt
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.
Acked-by: Joe Hershberger <***@ni.com>
Simon Goldschmidt
2018-12-09 20:50:49 UTC
Permalink
Post by Joe Hershberger
On Sat, Nov 17, 2018 at 3:25 AM Simon Goldschmidt
Post by Simon Goldschmidt
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.
Marek, this and 2/2 is a assigned to you in patchwork, will you push
them or is it Joe's code as u-boot-net maintainer?

Thanks,
Simon
Marek Vasut
2018-12-10 04:08:50 UTC
Permalink
Post by Simon Goldschmidt
Post by Joe Hershberger
On Sat, Nov 17, 2018 at 3:25 AM Simon Goldschmidt
Post by Simon Goldschmidt
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.
Marek, this and 2/2 is a assigned to you in patchwork, will you push
them or is it Joe's code as u-boot-net maintainer?
This is net , so Joe should pick it .
--
Best regards,
Marek Vasut
Philipp Tomsich
2018-12-09 21:36:26 UTC
Permalink
Post by Simon Goldschmidt
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.
Reviewed-by: Philipp Tomsich <***@theobroma-systems.com>
Loading...