From: Alexander Sverdlin Date: Mon, 13 May 2024 06:26:35 +0000 (+0200) Subject: net: tftp: don't call stop callback from UDP handler X-Git-Tag: v2025.10-rc1~118^2~72 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=44340456475da953a30c5cc4fbe8a9bc013c8c0f;p=thirdparty%2Fu-boot.git net: tftp: don't call stop callback from UDP handler Contrary to doc/develop/driver-model/ethernet.rst contract, eth_ops .free_pkt can be called after .stop, there are several error paths in TFTP, for instance: eth_halt() <= tftp_handler() <= net_process_received_packet() <= eth_rx() ... am65_cpsw_free_pkt() <= eth_rx() Which results in (deliberately "tftpboot"ing non-existing file): TFTP error: 'File not found' (1) Not retrying... am65_cpsw_nuss_port ethernet@8000000port@1: RX dma free_pkt failed -22 Avoid the DMA error message (and follow the documentation) by deferring eth_halt() until net_loop() calls net_start_again() and only do eth_halt_state_only() instead. Fixes: aafda38fb266 ("Add error codes/handling for TFTP-server") Signed-off-by: Alexander Sverdlin --- diff --git a/net/eth-uclass.c b/net/eth-uclass.c index 5555f82f23e..a233912fd8e 100644 --- a/net/eth-uclass.c +++ b/net/eth-uclass.c @@ -461,6 +461,8 @@ int eth_rx(void) eth_get_ops(current)->free_pkt(current, packet, ret); if (ret <= 0) break; + if (!eth_is_active(current)) + break; } if (ret == -EAGAIN) ret = 0; diff --git a/net/tftp.c b/net/tftp.c index fd9c9492929..1ca9a5ea7cf 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -655,7 +655,7 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip, net_set_timeout_handler(timeout_ms, tftp_timeout_handler); if (store_block(tftp_cur_block, pkt + 2, len)) { - eth_halt(); + eth_halt_state_only(); net_set_state(NETLOOP_FAIL); break; } @@ -685,7 +685,7 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip, case TFTP_ERR_FILE_NOT_FOUND: case TFTP_ERR_ACCESS_DENIED: puts("Not retrying...\n"); - eth_halt(); + eth_halt_state_only(); net_set_state(NETLOOP_FAIL); break; case TFTP_ERR_UNDEFINED: