[PATCH] net: ravb: Fix RX error handling
Paul Barker
paul.barker.ct at bp.renesas.com
Tue Apr 15 12:02:02 CEST 2025
On 13/04/2025 14:11, Marek Vasut wrote:
> 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 <marek.vasut+renesas at mailbox.org>
> ---
> Cc: Joe Hershberger <joe.hershberger at ni.com>
> Cc: Nobuhiro Iwamatsu <iwamatsu at nigauri.org>
> Cc: Paul Barker <paul.barker.ct at bp.renesas.com>
> Cc: Ramon Fried <rfried.dev at gmail.com>
> Cc: Tom Rini <trini at konsulko.com>
> Cc: u-boot at lists.denx.de
> ---
> drivers/net/ravb.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/net/ravb.c b/drivers/net/ravb.c
> index 539fd37ee59..da3e9dbeacd 100644
> --- a/drivers/net/ravb.c
> +++ b/drivers/net/ravb.c
> @@ -192,7 +192,7 @@ static int ravb_recv(struct udevice *dev, int flags, uchar **packetp)
> /* Check for errors */
> if (desc->data.ctrl & RAVB_RX_DESC_MSC_RX_ERR_MASK) {
> desc->data.ctrl &= ~RAVB_RX_DESC_MSC_MASK;
> - return -EAGAIN;
> + return 0;
Hi Marek,
At this point in the function we haven't stored anything to *packetp.
Looking at the relevant bit of eth_rx():
for (i = 0; i < ETH_PACKETS_BATCH_RECV; i++) {
ret = eth_get_ops(current)->recv(current, flags, &packet);
flags = 0;
if (ret > 0)
net_process_received_packet(packet, ret);
if (ret >= 0 && eth_get_ops(current)->free_pkt)
eth_get_ops(current)->free_pkt(current, packet, ret);
if (ret <= 0)
break;
}
So if ->recv() returns zero without storing to *packetp, we will call
->free_pkt() with a packet argument that is either uninitialized or
points to the packet from the last iteration through the loop.
Thanks,
--
Paul Barker
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_0x27F4B3459F002257.asc
Type: application/pgp-keys
Size: 3520 bytes
Desc: OpenPGP public key
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20250415/df526f73/attachment.key>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature.asc
Type: application/pgp-signature
Size: 236 bytes
Desc: OpenPGP digital signature
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20250415/df526f73/attachment.sig>
More information about the U-Boot
mailing list