summaryrefslogtreecommitdiffstats
path: root/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0029-net-sh_eth-Workaround-cache-issues.patch
diff options
context:
space:
mode:
Diffstat (limited to 'bsp/meta-rcar/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0029-net-sh_eth-Workaround-cache-issues.patch')
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0029-net-sh_eth-Workaround-cache-issues.patch74
1 files changed, 74 insertions, 0 deletions
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0029-net-sh_eth-Workaround-cache-issues.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0029-net-sh_eth-Workaround-cache-issues.patch
new file mode 100644
index 00000000..79eba33b
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0029-net-sh_eth-Workaround-cache-issues.patch
@@ -0,0 +1,74 @@
+From 869da2f4ee518558382f4a929ca302d1b2f91274 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Mon, 2 Dec 2019 01:13:19 +0300
+Subject: [PATCH 3/4] net: sh_eth: Workaround cache issues
+
+U-Boot writes to RX packets when constructing replies.
+This can cause stale cached data to be written to RX
+buffer while we're receiving a packet. This causes RX
+packet corruption because we invalidate the cache right
+before processing the packet. Invalidate packet buffer
+cache when preparing RX descriptor as well. This seems
+to fix RX packet drops with high RX traffic.
+
+While at it flush the descriptors right before enabling
+RX/TX in sh_eth_tx_desc_init/sh_eth_rx_desc_init callbacks
+when they are ready instead of flushing after allocation.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/net/sh_eth.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
+index fbae6ce..5df078d 100644
+--- a/drivers/net/sh_eth.c
++++ b/drivers/net/sh_eth.c
+@@ -138,6 +138,8 @@ static void sh_eth_recv_finish(struct sh_eth_dev *eth)
+ {
+ struct sh_eth_info *port_info = &eth->port_info[eth->port];
+
++ invalidate_cache(ADDR_TO_P2(port_info->rx_desc_cur->rd2), MAX_BUF_SIZE);
++
+ /* Make current descriptor available again */
+ if (port_info->rx_desc_cur->rd0 & RD_RDLE)
+ port_info->rx_desc_cur->rd0 = RD_RACT | RD_RDLE;
+@@ -206,8 +208,6 @@ static int sh_eth_tx_desc_init(struct sh_eth_dev *eth)
+ goto err;
+ }
+
+- flush_cache_wback(port_info->tx_desc_alloc, alloc_desc_size);
+-
+ /* Make sure we use a P2 address (non-cacheable) */
+ port_info->tx_desc_base =
+ (struct tx_desc_s *)ADDR_TO_P2((uintptr_t)port_info->tx_desc_alloc);
+@@ -225,6 +225,7 @@ static int sh_eth_tx_desc_init(struct sh_eth_dev *eth)
+ cur_tx_desc--;
+ cur_tx_desc->td0 |= TD_TDLE;
+
++ flush_cache_wback(port_info->tx_desc_alloc, alloc_desc_size);
+ /*
+ * Point the controller to the tx descriptor list. Must use physical
+ * addresses
+@@ -260,8 +261,6 @@ static int sh_eth_rx_desc_init(struct sh_eth_dev *eth)
+ goto err;
+ }
+
+- flush_cache_wback(port_info->rx_desc_alloc, alloc_desc_size);
+-
+ /* Make sure we use a P2 address (non-cacheable) */
+ port_info->rx_desc_base =
+ (struct rx_desc_s *)ADDR_TO_P2((uintptr_t)port_info->rx_desc_alloc);
+@@ -295,6 +294,9 @@ static int sh_eth_rx_desc_init(struct sh_eth_dev *eth)
+ cur_rx_desc--;
+ cur_rx_desc->rd0 |= RD_RDLE;
+
++ invalidate_cache(port_info->rx_buf_alloc, NUM_RX_DESC * MAX_BUF_SIZE);
++ flush_cache_wback(port_info->rx_desc_alloc, alloc_desc_size);
++
+ /* Point the controller to the rx descriptor list */
+ sh_eth_write(port_info, ADDR_TO_PHY(port_info->rx_desc_base), RDLAR);
+ #if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ)
+--
+2.7.4
+