| From dfc566f6ec0ac43624afa9866b934c9cbd761270 Mon Sep 17 00:00:00 2001 |
| From: Thor Thayer <thor.thayer@linux.intel.com> |
| Date: Thu, 8 Nov 2018 11:42:14 -0600 |
| Subject: net: stmmac: Fix RX packet size > 8191 |
| |
| [ Upstream commit 8137b6ef0ce469154e5cf19f8e7fe04d9a72ac5e ] |
| |
| Ping problems with packets > 8191 as shown: |
| |
| PING 192.168.1.99 (192.168.1.99) 8150(8178) bytes of data. |
| 8158 bytes from 192.168.1.99: icmp_seq=1 ttl=64 time=0.669 ms |
| wrong data byte 8144 should be 0xd0 but was 0x0 |
| 16 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |
| 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f |
| %< ---------------snip-------------------------------------- |
| 8112 b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf |
| c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf |
| 8144 0 0 0 0 d0 d1 |
| ^^^^^^^ |
| Notice the 4 bytes of 0 before the expected byte of d0. |
| |
| Databook notes that the RX buffer must be a multiple of 4/8/16 |
| bytes [1]. |
| |
| Update the DMA Buffer size define to 8188 instead of 8192. Remove |
| the -1 from the RX buffer size allocations and use the new |
| DMA Buffer size directly. |
| |
| [1] Synopsys DesignWare Cores Ethernet MAC Universal v3.70a |
| [section 8.4.2 - Table 8-24] |
| |
| Tested on SoCFPGA Stratix10 with ping sweep from 100 to 8300 byte packets. |
| |
| Fixes: 286a83721720 ("stmmac: add CHAINED descriptor mode support (V4)") |
| Suggested-by: Jose Abreu <jose.abreu@synopsys.com> |
| Signed-off-by: Thor Thayer <thor.thayer@linux.intel.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/net/ethernet/stmicro/stmmac/common.h | 3 ++- |
| drivers/net/ethernet/stmicro/stmmac/descs_com.h | 2 +- |
| drivers/net/ethernet/stmicro/stmmac/enh_desc.c | 2 +- |
| drivers/net/ethernet/stmicro/stmmac/ring_mode.c | 2 +- |
| 4 files changed, 5 insertions(+), 4 deletions(-) |
| |
| diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h |
| index b1b305f8f414..272b9ca66314 100644 |
| --- a/drivers/net/ethernet/stmicro/stmmac/common.h |
| +++ b/drivers/net/ethernet/stmicro/stmmac/common.h |
| @@ -365,7 +365,8 @@ struct dma_features { |
| |
| /* GMAC TX FIFO is 8K, Rx FIFO is 16K */ |
| #define BUF_SIZE_16KiB 16384 |
| -#define BUF_SIZE_8KiB 8192 |
| +/* RX Buffer size must be < 8191 and multiple of 4/8/16 bytes */ |
| +#define BUF_SIZE_8KiB 8188 |
| #define BUF_SIZE_4KiB 4096 |
| #define BUF_SIZE_2KiB 2048 |
| |
| diff --git a/drivers/net/ethernet/stmicro/stmmac/descs_com.h b/drivers/net/ethernet/stmicro/stmmac/descs_com.h |
| index ca9d7e48034c..40d6356a7e73 100644 |
| --- a/drivers/net/ethernet/stmicro/stmmac/descs_com.h |
| +++ b/drivers/net/ethernet/stmicro/stmmac/descs_com.h |
| @@ -31,7 +31,7 @@ |
| /* Enhanced descriptors */ |
| static inline void ehn_desc_rx_set_on_ring(struct dma_desc *p, int end) |
| { |
| - p->des1 |= cpu_to_le32(((BUF_SIZE_8KiB - 1) |
| + p->des1 |= cpu_to_le32((BUF_SIZE_8KiB |
| << ERDES1_BUFFER2_SIZE_SHIFT) |
| & ERDES1_BUFFER2_SIZE_MASK); |
| |
| diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c |
| index 77914c89d749..5ef91a790f9d 100644 |
| --- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c |
| +++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c |
| @@ -262,7 +262,7 @@ static void enh_desc_init_rx_desc(struct dma_desc *p, int disable_rx_ic, |
| int mode, int end) |
| { |
| p->des0 |= cpu_to_le32(RDES0_OWN); |
| - p->des1 |= cpu_to_le32((BUF_SIZE_8KiB - 1) & ERDES1_BUFFER1_SIZE_MASK); |
| + p->des1 |= cpu_to_le32(BUF_SIZE_8KiB & ERDES1_BUFFER1_SIZE_MASK); |
| |
| if (mode == STMMAC_CHAIN_MODE) |
| ehn_desc_rx_set_on_chain(p); |
| diff --git a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c |
| index a7ffc73fffe8..bc83ced94e1b 100644 |
| --- a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c |
| +++ b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c |
| @@ -140,7 +140,7 @@ static void clean_desc3(void *priv_ptr, struct dma_desc *p) |
| static int set_16kib_bfsize(int mtu) |
| { |
| int ret = 0; |
| - if (unlikely(mtu >= BUF_SIZE_8KiB)) |
| + if (unlikely(mtu > BUF_SIZE_8KiB)) |
| ret = BUF_SIZE_16KiB; |
| return ret; |
| } |
| -- |
| 2.17.1 |
| |