net: lwip: introduce net_lwip_eth_stop() function

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>
This commit is contained in:
David Lechner
2026-06-23 13:13:16 +02:00
committed by Jerome Forissier
parent 91911aa0c7
commit 9f7906a58c
9 changed files with 65 additions and 16 deletions
+11 -4
View 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;
}
+6 -1
View 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;
}
+16
View 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];
+4
View 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;
+4
View 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;
+4 -1
View 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;
}