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 |
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 = ð->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 --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 = ð->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)