]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
net: lwip: introduce net_lwip_eth_stop() function
authorDavid Lechner <dlechner@baylibre.com>
Thu, 11 Jun 2026 23:36:10 +0000 (18:36 -0500)
committerJerome Forissier <jerome.forissier@arm.com>
Tue, 23 Jun 2026 11:13:16 +0000 (13:13 +0200)
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.

The start/stop is reference-counted since there is at least one command
(dhcp) that calls another command (tftp) to avoid starting and stopping
the network interface multiple times in a single command.

Signed-off-by: David Lechner <dlechner@baylibre.com>
Reviewed-by: Jerome Forissier <jerome.forissier@arm.com>
cmd/lwip/ping.c
cmd/lwip/sntp.c
include/net-lwip.h
net/lwip/dhcp.c
net/lwip/dns.c
net/lwip/net-lwip.c
net/lwip/nfs.c
net/lwip/tftp.c
net/lwip/wget.c

index fc4cf7bde5f96d4052d754355c4f572a003741ec..98fa8e22bce78ee0194d44aaa7e2f723fc498bf9 100644 (file)
@@ -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;
 
        if (argc < 2)
                return CMD_RET_USAGE;
@@ -171,13 +172,15 @@ int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
                return CMD_RET_USAGE;
 
        net_try_count = 1;
-restart:
-       if (net_lwip_eth_start() < 0 || ping_loop(eth_get_dev(), &addr) < 0) {
-               if (net_start_again() == 0)
-                       goto restart;
-               else
-                       return CMD_RET_FAILURE;
-       }
 
-       return CMD_RET_SUCCESS;
+       do {
+               if (net_lwip_eth_start() == 0) {
+                       ret = ping_loop(eth_get_dev(), &addr);
+                       net_lwip_eth_stop();
+                       if (ret == 0)
+                               return CMD_RET_SUCCESS;
+               }
+       } while (net_start_again() == 0);
+
+       return CMD_RET_FAILURE;
 }
index 608345c873b0120979f49cc48a2ad48ef88bfcab..5fa400b104a692feee4f8e77fc835e1fab3d38d6 100644 (file)
@@ -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;
 }
index 20cb0992cce1f9dbca7eaa114b4939028158d9b5..5d0627eb2719ce17961a9ba7f70de2c041dbc14a 100644 (file)
@@ -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);
index acdf601d7eb50a68b8eb049f9bac37d57c253d78..18dc36ae7ca0416d25c46f7bd6930d33a7b7fde2 100644 (file)
@@ -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;
        }
 
-       return CMD_RET_SUCCESS;
+       ret = CMD_RET_SUCCESS;
+
+out:
+       net_lwip_eth_stop();
+
+       return ret;
 }
index 8b7b3b7f970f3072cba4722cf7876a273dc21e8a..b620b0611d690df40e2cd6627a6158049e39afab 100644 (file)
@@ -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;
 }
index 0c83c004cab93b48cf0426b2249b509127d63e09..cfe5a6a640d0892c9661c6384c32afd721e4474e 100644 (file)
@@ -31,6 +31,7 @@ void (*push_packet)(void *, int len) = 0;
 int net_try_count;
 static int net_restarted;
 int net_restart_wrap;
+static int net_lwip_eth_started;
 static uchar net_pkt_buf[(PKTBUFSRX) * PKTSIZE_ALIGN + PKTALIGN]
        __aligned(PKTALIGN);
 const u8 net_bcast_ethaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
@@ -180,11 +181,15 @@ int net_lwip_eth_start(void)
 {
        int ret;
 
+       if (net_lwip_eth_started++ > 0)
+               return 0;
+
        net_init();
        eth_halt();
        eth_set_current();
        ret = eth_init();
        if (ret < 0) {
+               net_lwip_eth_started--;
                eth_halt();
                return ret;
        }
@@ -192,6 +197,17 @@ int net_lwip_eth_start(void)
        return 0;
 }
 
+void net_lwip_eth_stop(void)
+{
+       if (!net_lwip_eth_started)
+               return;
+
+       if (--net_lwip_eth_started)
+               return;
+
+       eth_halt();
+}
+
 static struct netif *new_netif(struct udevice *udev, bool with_ip)
 {
        unsigned char enetaddr[ARP_HLEN];
index 9e6b801e465d230ff7a2ac8d5333acb99e73ea34..4cc36373fdd7378c21b8e60859f274097dd0317c 100644 (file)
@@ -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;
index 7f3b28b8507598efef93edd36752c03cbfd88275..571c38172f99900853152fde945c4787113fa348 100644 (file)
@@ -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;
index 3a0b0dca1457926ac953209f7d8db5fa925fdc58..247ece18e2b0cb19ef00ab9dc6b26bf21d0e72f4 100644 (file)
@@ -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;
 }