summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Vasut <[email protected]>2025-04-20 18:35:33 +0200
committerMarek Vasut <[email protected]>2025-05-04 20:23:31 +0200
commit6fae565f5477f0e1c8df2271cc8bedaca5b63759 (patch)
tree6c47a2ada30b8634b2fa61451638857c60a56ff4
parentdcea465e5e299903b889f5f426eac6d6523cbf84 (diff)
net: ravb: Fix RX error handling
Correctly handle RX errors in ravb_recv() by returning 0 instead of -EAGAIN on RX error. In case the RAVB driver detects an RX error in ravb_recv(), it must not return the -EAGAIN, but instead must return 0. Both error codes are handled in eth-uclass.c eth_rx() and -EAGAIN is rewritten to 0 at the end of eth_rx(), but negative return code from the .recv() callback does not trigger .free_pkt() callback, which would clean up and re-enqueue the descriptor which holds the currently received corrupted packet. The .free_pkt() must be called for this descriptor, otherwise the follow up received data become corrupted too, even if those packets are correctly received. Returning 0 from the .recv() callback assures the corrupted packet is not processed by the network stack, but is skipped instead. For TFTP loading, an RX error produces the timeout "T" output and resumes the TFTP loading operation shortly afterward, without any data corruption. Signed-off-by: Marek Vasut <[email protected]> Reviewed-by: Paul Barker <[email protected]>
-rw-r--r--drivers/net/ravb.c9
1 files changed, 4 insertions, 5 deletions
diff --git a/drivers/net/ravb.c b/drivers/net/ravb.c
index 539fd37ee59..e1ce1d8957b 100644
--- a/drivers/net/ravb.c
+++ b/drivers/net/ravb.c
@@ -181,7 +181,7 @@ static int ravb_recv(struct udevice *dev, int flags, uchar **packetp)
{
struct ravb_priv *eth = dev_get_priv(dev);
struct ravb_rxdesc *desc = &eth->rx_desc[eth->rx_desc_idx];
- int len;
+ int len = 0;
u8 *packet;
/* Check if the rx descriptor is ready */
@@ -190,12 +190,11 @@ static int ravb_recv(struct udevice *dev, int flags, uchar **packetp)
return -EAGAIN;
/* Check for errors */
- if (desc->data.ctrl & RAVB_RX_DESC_MSC_RX_ERR_MASK) {
+ if (desc->data.ctrl & RAVB_RX_DESC_MSC_RX_ERR_MASK)
desc->data.ctrl &= ~RAVB_RX_DESC_MSC_MASK;
- return -EAGAIN;
- }
+ else
+ len = desc->data.ctrl & RAVB_DESC_DS_MASK;
- len = desc->data.ctrl & RAVB_DESC_DS_MASK;
packet = (u8 *)(uintptr_t)desc->data.dptr;
ravb_invalidate_dcache((uintptr_t)packet, len);