diff mbox series

[13/14] net: sh_eth: Workaround cache issues

Message ID 20230530225131.949721-13-marek.vasut+renesas@mailbox.org
State Accepted
Commit d49ba9c8d70c30d6f009e069cf43b4817be3546d
Delegated to: Ramon Fried
Headers show
Series [01/14] net: eth-phy: staticize eth_phy_reset() | expand

Commit Message

Marek Vasut May 30, 2023, 10:51 p.m. UTC
From: Valentine Barshak <valentine.barshak@cogentembedded.com>

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>
Reviewed-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
---
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Joe Hershberger <joe.hershberger@ni.com>
Cc: Michal Simek <michal.simek@amd.com>
Cc: Nishanth Menon <nm@ti.com>
Cc: Ramon Fried <rfried.dev@gmail.com>
---
 drivers/net/sh_eth.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

Comments

Ramon Fried June 10, 2023, 11:01 a.m. UTC | #1
On Wed, May 31, 2023 at 1:51 AM Marek Vasut
<marek.vasut+renesas@mailbox.org> wrote:
>
> From: Valentine Barshak <valentine.barshak@cogentembedded.com>
>
> 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>
> Reviewed-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
> ---
> Cc: Geert Uytterhoeven <geert+renesas@glider.be>
> Cc: Joe Hershberger <joe.hershberger@ni.com>
> Cc: Michal Simek <michal.simek@amd.com>
> Cc: Nishanth Menon <nm@ti.com>
> Cc: Ramon Fried <rfried.dev@gmail.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 95042daade0..7314caadfdc 100644
> --- a/drivers/net/sh_eth.c
> +++ b/drivers/net/sh_eth.c
> @@ -142,6 +142,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;
> @@ -210,8 +212,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);
> @@ -229,6 +229,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
> @@ -264,8 +265,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);
> @@ -299,6 +298,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.39.2
>
Reviewed-by: Ramon Fried <rfried.dev@gmail.com>
diff mbox series

Patch

diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 95042daade0..7314caadfdc 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -142,6 +142,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;
@@ -210,8 +212,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);
@@ -229,6 +229,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
@@ -264,8 +265,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);
@@ -299,6 +298,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)