[PATCH] net: sh_eth: Fix RX error handling

From: Valentine Barshak valentine.barshak@cogentembedded.com
In case RX error occurs, and the RD_RFE bit is set, the descriptor is never returned back to the queue. Make sh_eth_recv_start return zero length in this case so that the descriptor can be released and pushed back to the list. Also return the more appropriate -EAGAIN instead of -EINVAL if the descriptor is not ready yet.
Reviewed-by: Marek Vasut marek.vasut+renesas@mailbox.org Signed-off-by: Valentine Barshak valentine.barshak@cogentembedded.com --- Cc: Joe Hershberger joe.hershberger@ni.com Cc: Ramon Fried rfried.dev@gmail.com --- drivers/net/sh_eth.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index 8f162ca58fb..da1bc7cb40b 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -129,11 +129,11 @@ static int sh_eth_recv_start(struct sh_eth_dev *eth) /* Check if the rx descriptor is ready */ invalidate_cache(port_info->rx_desc_cur, sizeof(struct rx_desc_s)); if (port_info->rx_desc_cur->rd0 & RD_RACT) - return -EINVAL; + return -EAGAIN;
/* Check for errors */ if (port_info->rx_desc_cur->rd0 & RD_RFE) - return -EINVAL; + return 0;
return port_info->rx_desc_cur->rd1 & 0xffff; } @@ -555,15 +555,13 @@ static int sh_ether_recv(struct udevice *dev, int flags, uchar **packetp) *packetp = packet;
return len; - } else { - len = 0; + }
- /* Restart the receiver if disabled */ - if (!(sh_eth_read(port_info, EDRRR) & EDRRR_R)) - sh_eth_write(port_info, EDRRR_R, EDRRR); + /* Restart the receiver if disabled */ + if (!(sh_eth_read(port_info, EDRRR) & EDRRR_R)) + sh_eth_write(port_info, EDRRR_R, EDRRR);
- return -EAGAIN; - } + return len; }
static int sh_ether_free_pkt(struct udevice *dev, uchar *packet, int length)

On Sun, Apr 30, 2023 at 5:54 PM Marek Vasut marek.vasut+renesas@mailbox.org wrote:
From: Valentine Barshak valentine.barshak@cogentembedded.com
In case RX error occurs, and the RD_RFE bit is set, the descriptor is never returned back to the queue. Make sh_eth_recv_start return zero length in this case so that the descriptor can be released and pushed back to the list. Also return the more appropriate -EAGAIN instead of -EINVAL if the descriptor is not ready yet.
Reviewed-by: Marek Vasut marek.vasut+renesas@mailbox.org Signed-off-by: Valentine Barshak valentine.barshak@cogentembedded.com
Cc: Joe Hershberger joe.hershberger@ni.com Cc: Ramon Fried rfried.dev@gmail.com
drivers/net/sh_eth.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index 8f162ca58fb..da1bc7cb40b 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -129,11 +129,11 @@ static int sh_eth_recv_start(struct sh_eth_dev *eth) /* Check if the rx descriptor is ready */ invalidate_cache(port_info->rx_desc_cur, sizeof(struct rx_desc_s)); if (port_info->rx_desc_cur->rd0 & RD_RACT)
return -EINVAL;
return -EAGAIN; /* Check for errors */ if (port_info->rx_desc_cur->rd0 & RD_RFE)
return -EINVAL;
return 0; return port_info->rx_desc_cur->rd1 & 0xffff;
} @@ -555,15 +555,13 @@ static int sh_ether_recv(struct udevice *dev, int flags, uchar **packetp) *packetp = packet;
return len;
} else {
len = 0;
}
/* Restart the receiver if disabled */
if (!(sh_eth_read(port_info, EDRRR) & EDRRR_R))
sh_eth_write(port_info, EDRRR_R, EDRRR);
/* Restart the receiver if disabled */
if (!(sh_eth_read(port_info, EDRRR) & EDRRR_R))
sh_eth_write(port_info, EDRRR_R, EDRRR);
return -EAGAIN;
}
return len;
}
static int sh_ether_free_pkt(struct udevice *dev, uchar *packet, int length)
2.39.2
Reviewed-by: Ramon Fried rfried.dev@gmail.com
participants (2)
-
Marek Vasut
-
Ramon Fried