On 12/05/2026 23:48, David Lechner wrote:
> Add a introduce net_lwip_eth_stop() function and use that to stop the
> network interface after each command that uses the network.
> 
> This makes the behavior the same as the legacy net code and avoids
> potential issues with the network interface being left in an active
> state after a command finishes.
> 
> Signed-off-by: David Lechner <[email protected]>
> ---
>  cmd/lwip/ping.c     | 10 ++++++++--
>  cmd/lwip/sntp.c     | 10 ++++++++--
>  include/net-lwip.h  |  1 +
>  net/lwip/dhcp.c     | 15 +++++++++++----
>  net/lwip/dns.c      |  7 ++++++-
>  net/lwip/net-lwip.c |  5 +++++
>  net/lwip/nfs.c      |  4 ++++
>  net/lwip/tftp.c     |  4 ++++
>  net/lwip/wget.c     |  5 ++++-
>  9 files changed, 51 insertions(+), 10 deletions(-)
> 
> diff --git a/cmd/lwip/ping.c b/cmd/lwip/ping.c
> index fc4cf7bde5f..836d1d8287f 100644
> --- a/cmd/lwip/ping.c
> +++ b/cmd/lwip/ping.c
> @@ -163,6 +163,7 @@ static int ping_loop(struct udevice *udev, const 
> ip_addr_t *addr)
>  int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
>  {
>       ip_addr_t addr;
> +     int ret = CMD_RET_FAILURE;
>  
>       if (argc < 2)
>               return CMD_RET_USAGE;
> @@ -176,8 +177,13 @@ restart:
>               if (net_start_again() == 0)
>                       goto restart;
>               else
> -                     return CMD_RET_FAILURE;
> +                     goto out;
>       }
>  
> -     return CMD_RET_SUCCESS;
> +     ret = CMD_RET_SUCCESS;
> +
> +out:
> +     net_lwip_eth_stop();
> +
> +     return ret;
>  }
> diff --git a/cmd/lwip/sntp.c b/cmd/lwip/sntp.c
> index 608345c873b..5fa400b104a 100644
> --- a/cmd/lwip/sntp.c
> +++ b/cmd/lwip/sntp.c
> @@ -101,6 +101,7 @@ int do_sntp(struct cmd_tbl *cmdtp, int flag, int argc, 
> char *const argv[])
>       ip_addr_t *srvip;
>       char *server;
>       ip_addr_t ipaddr;
> +     int ret = CMD_RET_FAILURE;
>  
>       switch (argc) {
>       case 1:
> @@ -127,7 +128,12 @@ int do_sntp(struct cmd_tbl *cmdtp, int flag, int argc, 
> char *const argv[])
>               return CMD_RET_FAILURE;
>  
>       if (sntp_loop(eth_get_dev(), srvip) < 0)
> -             return CMD_RET_FAILURE;
> +             goto out;
> +
> +     ret = CMD_RET_SUCCESS;
> +
> +out:
> +     net_lwip_eth_stop();
>  
> -     return CMD_RET_SUCCESS;
> +     return ret;
>  }
> diff --git a/include/net-lwip.h b/include/net-lwip.h
> index 20cb0992cce..5d0627eb271 100644
> --- a/include/net-lwip.h
> +++ b/include/net-lwip.h
> @@ -35,6 +35,7 @@ int eth_init_state_only(void); /* Set active state */
>  
>  int net_lwip_dns_init(void);
>  int net_lwip_eth_start(void);
> +void net_lwip_eth_stop(void);
>  struct netif *net_lwip_new_netif(struct udevice *udev);
>  struct netif *net_lwip_new_netif_noip(struct udevice *udev);
>  void net_lwip_remove_netif(struct netif *netif);
> diff --git a/net/lwip/dhcp.c b/net/lwip/dhcp.c
> index acdf601d7eb..18dc36ae7ca 100644
> --- a/net/lwip/dhcp.c
> +++ b/net/lwip/dhcp.c
> @@ -138,18 +138,25 @@ int do_dhcp(struct cmd_tbl *cmdtp, int flag, int argc, 
> char *const argv[])
>       dev = eth_get_dev();
>       if (!dev) {
>               log_err("No network device\n");
> -             return CMD_RET_FAILURE;
> +             ret = CMD_RET_FAILURE;
> +             goto out;
>       }
>  
>       ret = dhcp_loop(dev);
>       if (ret)
> -             return ret;
> +             goto out;
>  
>       if (argc > 1) {
>               struct cmd_tbl cmdtp = {};
>  
> -             return do_tftpb(&cmdtp, 0, argc, argv);
> +             ret = do_tftpb(&cmdtp, 0, argc, argv);
> +             goto out;

do_tftpb() already takes care of net_lwip_eth_stop() so this should
probably be:

+               return do_tftpb(&cmdtp, 0, argc, argv);

But this also raises the qestion of the double call to
net_lwip_eth_start():

do_dhcp()
        net_lwip_eth_start()
        do_tftpb()
                net_lwip_eth_start()

How about adding a static counter to better deal with the nested case?

static int net_lwip_eth_started;

int net_lwip_eth_start(void)
{
        int ret;

        if (net_lwip_eth_started++ > 0)
                return 0;

        ret = eth_init();
        if (ret) {
                net_lwip_eth_started--;
                return ret;
        }

        return 0;
}

void net_lwip_eth_stop(void)
{
        if (!net_lwip_eth_started)
                return;

        if (--net_lwip_eth_started)
                return;

        eth_halt();
}

Thanks,
-- 
Jerome

>       }
>  
> -     return CMD_RET_SUCCESS;
> +     ret = CMD_RET_SUCCESS;
> +
> +out:
> +     net_lwip_eth_stop();
> +
> +     return ret;
>  }
> diff --git a/net/lwip/dns.c b/net/lwip/dns.c
> index 8b7b3b7f970..b620b0611d6 100644
> --- a/net/lwip/dns.c
> +++ b/net/lwip/dns.c
> @@ -91,6 +91,7 @@ int do_dns(struct cmd_tbl *cmdtp, int flag, int argc, char 
> *const argv[])
>  {
>       char *name;
>       char *var = NULL;
> +     int ret;
>  
>       if (argc == 1 || argc > 3)
>               return CMD_RET_USAGE;
> @@ -103,5 +104,9 @@ int do_dns(struct cmd_tbl *cmdtp, int flag, int argc, 
> char *const argv[])
>       if (net_lwip_eth_start() < 0)
>               return CMD_RET_FAILURE;
>  
> -     return dns_loop(eth_get_dev(), name, var);
> +     ret = dns_loop(eth_get_dev(), name, var);
> +
> +     net_lwip_eth_stop();
> +
> +     return ret;
>  }
> diff --git a/net/lwip/net-lwip.c b/net/lwip/net-lwip.c
> index 0c83c004cab..be63531c2a2 100644
> --- a/net/lwip/net-lwip.c
> +++ b/net/lwip/net-lwip.c
> @@ -192,6 +192,11 @@ int net_lwip_eth_start(void)
>       return 0;
>  }
>  
> +void net_lwip_eth_stop(void)
> +{
> +     eth_halt();
> +}
> +
>  static struct netif *new_netif(struct udevice *udev, bool with_ip)
>  {
>       unsigned char enetaddr[ARP_HLEN];
> diff --git a/net/lwip/nfs.c b/net/lwip/nfs.c
> index 9e6b801e465..4cc36373fdd 100644
> --- a/net/lwip/nfs.c
> +++ b/net/lwip/nfs.c
> @@ -187,6 +187,7 @@ static int nfs_loop(struct udevice *udev, ulong addr, 
> char *fname,
>  int do_nfs(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
>  {
>       int ret = CMD_RET_SUCCESS;
> +     bool started = false;
>       char *arg = NULL;
>       char *words[2] = { };
>       char *fname = NULL;
> @@ -281,10 +282,13 @@ int do_nfs(struct cmd_tbl *cmdtp, int flag, int argc, 
> char *const argv[])
>               ret = CMD_RET_FAILURE;
>               goto out;
>       }
> +     started = true;
>  
>       if (nfs_loop(eth_get_dev(), laddr, fname, srvip) < 0)
>               ret = CMD_RET_FAILURE;
>  out:
> +     if (started)
> +             net_lwip_eth_stop();
>       if (arg != net_boot_file_name)
>               free(arg);
>       return ret;
> diff --git a/net/lwip/tftp.c b/net/lwip/tftp.c
> index 7f3b28b8507..571c38172f9 100644
> --- a/net/lwip/tftp.c
> +++ b/net/lwip/tftp.c
> @@ -261,6 +261,7 @@ static int tftp_loop(struct udevice *udev, ulong addr, 
> char *fname,
>  int do_tftpb(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
>  {
>       int ret = CMD_RET_SUCCESS;
> +     bool started = false;
>       char *arg = NULL;
>       char *words[3] = { };
>       char *fname = NULL;
> @@ -365,12 +366,15 @@ int do_tftpb(struct cmd_tbl *cmdtp, int flag, int argc, 
> char *const argv[])
>               ret = CMD_RET_FAILURE;
>               goto out;
>       }
> +     started = true;
>  
>       if (tftp_loop(eth_get_dev(), laddr, fname, srvip, port) < 0)
>               ret = CMD_RET_FAILURE;
>       else
>               image_load_addr = laddr;
>  out:
> +     if (started)
> +             net_lwip_eth_stop();
>       if (arg != net_boot_file_name)
>               free(arg);
>       return ret;
> diff --git a/net/lwip/wget.c b/net/lwip/wget.c
> index 3a0b0dca145..247ece18e2b 100644
> --- a/net/lwip/wget.c
> +++ b/net/lwip/wget.c
> @@ -416,12 +416,15 @@ int wget_do_request(ulong dst_addr, char *uri)
>       udev = eth_get_dev();
>  
>       netif = net_lwip_new_netif(udev);
> -     if (!netif)
> +     if (!netif) {
> +             net_lwip_eth_stop();
>               return -ENODEV;
> +     }
>  
>       ret = wget_handle_request(&ctx, is_https, udev, netif);
>  
>       net_lwip_remove_netif(netif);
> +     net_lwip_eth_stop();
>  
>       return ret;
>  }
> 

Reply via email to