xref: /openbmc/u-boot/cmd/net.c (revision 6a69dbe2)
183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
22e192b24SSimon Glass /*
32e192b24SSimon Glass  * (C) Copyright 2000
42e192b24SSimon Glass  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
52e192b24SSimon Glass  */
62e192b24SSimon Glass 
72e192b24SSimon Glass /*
82e192b24SSimon Glass  * Boot support
92e192b24SSimon Glass  */
102e192b24SSimon Glass #include <common.h>
112e192b24SSimon Glass #include <command.h>
122e192b24SSimon Glass #include <net.h>
132e192b24SSimon Glass 
142e192b24SSimon Glass static int netboot_common(enum proto_t, cmd_tbl_t *, int, char * const []);
152e192b24SSimon Glass 
16d7a45eafSJoe Hershberger #ifdef CONFIG_CMD_BOOTP
do_bootp(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])172e192b24SSimon Glass static int do_bootp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
182e192b24SSimon Glass {
192e192b24SSimon Glass 	return netboot_common(BOOTP, cmdtp, argc, argv);
202e192b24SSimon Glass }
212e192b24SSimon Glass 
222e192b24SSimon Glass U_BOOT_CMD(
232e192b24SSimon Glass 	bootp,	3,	1,	do_bootp,
242e192b24SSimon Glass 	"boot image via network using BOOTP/TFTP protocol",
252e192b24SSimon Glass 	"[loadAddress] [[hostIPaddr:]bootfilename]"
262e192b24SSimon Glass );
27d7a45eafSJoe Hershberger #endif
282e192b24SSimon Glass 
29d7a45eafSJoe Hershberger #ifdef CONFIG_CMD_TFTPBOOT
do_tftpb(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])302e192b24SSimon Glass int do_tftpb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
312e192b24SSimon Glass {
322e192b24SSimon Glass 	int ret;
332e192b24SSimon Glass 
342e192b24SSimon Glass 	bootstage_mark_name(BOOTSTAGE_KERNELREAD_START, "tftp_start");
352e192b24SSimon Glass 	ret = netboot_common(TFTPGET, cmdtp, argc, argv);
362e192b24SSimon Glass 	bootstage_mark_name(BOOTSTAGE_KERNELREAD_STOP, "tftp_done");
372e192b24SSimon Glass 	return ret;
382e192b24SSimon Glass }
392e192b24SSimon Glass 
402e192b24SSimon Glass U_BOOT_CMD(
412e192b24SSimon Glass 	tftpboot,	3,	1,	do_tftpb,
422e192b24SSimon Glass 	"boot image via network using TFTP protocol",
432e192b24SSimon Glass 	"[loadAddress] [[hostIPaddr:]bootfilename]"
442e192b24SSimon Glass );
45d7a45eafSJoe Hershberger #endif
462e192b24SSimon Glass 
472e192b24SSimon Glass #ifdef CONFIG_CMD_TFTPPUT
do_tftpput(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])480c1b869bSMasahiro Yamada static int do_tftpput(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
492e192b24SSimon Glass {
502e192b24SSimon Glass 	return netboot_common(TFTPPUT, cmdtp, argc, argv);
512e192b24SSimon Glass }
522e192b24SSimon Glass 
532e192b24SSimon Glass U_BOOT_CMD(
542e192b24SSimon Glass 	tftpput,	4,	1,	do_tftpput,
552e192b24SSimon Glass 	"TFTP put command, for uploading files to a server",
562e192b24SSimon Glass 	"Address Size [[hostIPaddr:]filename]"
572e192b24SSimon Glass );
582e192b24SSimon Glass #endif
592e192b24SSimon Glass 
602e192b24SSimon Glass #ifdef CONFIG_CMD_TFTPSRV
do_tftpsrv(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])612e192b24SSimon Glass static int do_tftpsrv(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
622e192b24SSimon Glass {
632e192b24SSimon Glass 	return netboot_common(TFTPSRV, cmdtp, argc, argv);
642e192b24SSimon Glass }
652e192b24SSimon Glass 
662e192b24SSimon Glass U_BOOT_CMD(
672e192b24SSimon Glass 	tftpsrv,	2,	1,	do_tftpsrv,
682e192b24SSimon Glass 	"act as a TFTP server and boot the first received file",
692e192b24SSimon Glass 	"[loadAddress]\n"
702e192b24SSimon Glass 	"Listen for an incoming TFTP transfer, receive a file and boot it.\n"
712e192b24SSimon Glass 	"The transfer is aborted if a transfer has not been started after\n"
722e192b24SSimon Glass 	"about 50 seconds or if Ctrl-C is pressed."
732e192b24SSimon Glass );
742e192b24SSimon Glass #endif
752e192b24SSimon Glass 
762e192b24SSimon Glass 
772e192b24SSimon Glass #ifdef CONFIG_CMD_RARP
do_rarpb(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])782e192b24SSimon Glass int do_rarpb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
792e192b24SSimon Glass {
802e192b24SSimon Glass 	return netboot_common(RARP, cmdtp, argc, argv);
812e192b24SSimon Glass }
822e192b24SSimon Glass 
832e192b24SSimon Glass U_BOOT_CMD(
842e192b24SSimon Glass 	rarpboot,	3,	1,	do_rarpb,
852e192b24SSimon Glass 	"boot image via network using RARP/TFTP protocol",
862e192b24SSimon Glass 	"[loadAddress] [[hostIPaddr:]bootfilename]"
872e192b24SSimon Glass );
882e192b24SSimon Glass #endif
892e192b24SSimon Glass 
902e192b24SSimon Glass #if defined(CONFIG_CMD_DHCP)
do_dhcp(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])912e192b24SSimon Glass static int do_dhcp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
922e192b24SSimon Glass {
932e192b24SSimon Glass 	return netboot_common(DHCP, cmdtp, argc, argv);
942e192b24SSimon Glass }
952e192b24SSimon Glass 
962e192b24SSimon Glass U_BOOT_CMD(
972e192b24SSimon Glass 	dhcp,	3,	1,	do_dhcp,
982e192b24SSimon Glass 	"boot image via network using DHCP/TFTP protocol",
992e192b24SSimon Glass 	"[loadAddress] [[hostIPaddr:]bootfilename]"
1002e192b24SSimon Glass );
1012e192b24SSimon Glass #endif
1022e192b24SSimon Glass 
1032e192b24SSimon Glass #if defined(CONFIG_CMD_NFS)
do_nfs(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])1042e192b24SSimon Glass static int do_nfs(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1052e192b24SSimon Glass {
1062e192b24SSimon Glass 	return netboot_common(NFS, cmdtp, argc, argv);
1072e192b24SSimon Glass }
1082e192b24SSimon Glass 
1092e192b24SSimon Glass U_BOOT_CMD(
1102e192b24SSimon Glass 	nfs,	3,	1,	do_nfs,
1112e192b24SSimon Glass 	"boot image via network using NFS protocol",
1122e192b24SSimon Glass 	"[loadAddress] [[hostIPaddr:]bootfilename]"
1132e192b24SSimon Glass );
1142e192b24SSimon Glass #endif
1152e192b24SSimon Glass 
netboot_update_env(void)1162e192b24SSimon Glass static void netboot_update_env(void)
1172e192b24SSimon Glass {
1182e192b24SSimon Glass 	char tmp[22];
1192e192b24SSimon Glass 
1202e192b24SSimon Glass 	if (net_gateway.s_addr) {
1212e192b24SSimon Glass 		ip_to_string(net_gateway, tmp);
122382bee57SSimon Glass 		env_set("gatewayip", tmp);
1232e192b24SSimon Glass 	}
1242e192b24SSimon Glass 
1252e192b24SSimon Glass 	if (net_netmask.s_addr) {
1262e192b24SSimon Glass 		ip_to_string(net_netmask, tmp);
127382bee57SSimon Glass 		env_set("netmask", tmp);
1282e192b24SSimon Glass 	}
1292e192b24SSimon Glass 
1302e192b24SSimon Glass 	if (net_hostname[0])
131382bee57SSimon Glass 		env_set("hostname", net_hostname);
1322e192b24SSimon Glass 
1332e192b24SSimon Glass 	if (net_root_path[0])
134382bee57SSimon Glass 		env_set("rootpath", net_root_path);
1352e192b24SSimon Glass 
1362e192b24SSimon Glass 	if (net_ip.s_addr) {
1372e192b24SSimon Glass 		ip_to_string(net_ip, tmp);
138382bee57SSimon Glass 		env_set("ipaddr", tmp);
1392e192b24SSimon Glass 	}
1402e192b24SSimon Glass #if !defined(CONFIG_BOOTP_SERVERIP)
1412e192b24SSimon Glass 	/*
142ff78ad28SBaruch Siach 	 * Only attempt to change serverip if net/bootp.c:store_net_params()
1432e192b24SSimon Glass 	 * could have set it
1442e192b24SSimon Glass 	 */
1452e192b24SSimon Glass 	if (net_server_ip.s_addr) {
1462e192b24SSimon Glass 		ip_to_string(net_server_ip, tmp);
147382bee57SSimon Glass 		env_set("serverip", tmp);
1482e192b24SSimon Glass 	}
1492e192b24SSimon Glass #endif
1502e192b24SSimon Glass 	if (net_dns_server.s_addr) {
1512e192b24SSimon Glass 		ip_to_string(net_dns_server, tmp);
152382bee57SSimon Glass 		env_set("dnsip", tmp);
1532e192b24SSimon Glass 	}
1542e192b24SSimon Glass #if defined(CONFIG_BOOTP_DNS2)
1552e192b24SSimon Glass 	if (net_dns_server2.s_addr) {
1562e192b24SSimon Glass 		ip_to_string(net_dns_server2, tmp);
157382bee57SSimon Glass 		env_set("dnsip2", tmp);
1582e192b24SSimon Glass 	}
1592e192b24SSimon Glass #endif
1602e192b24SSimon Glass 	if (net_nis_domain[0])
161382bee57SSimon Glass 		env_set("domain", net_nis_domain);
1622e192b24SSimon Glass 
1632e192b24SSimon Glass #if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_TIMEOFFSET)
1642e192b24SSimon Glass 	if (net_ntp_time_offset) {
1652e192b24SSimon Glass 		sprintf(tmp, "%d", net_ntp_time_offset);
166382bee57SSimon Glass 		env_set("timeoffset", tmp);
1672e192b24SSimon Glass 	}
1682e192b24SSimon Glass #endif
1692e192b24SSimon Glass #if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_NTPSERVER)
1702e192b24SSimon Glass 	if (net_ntp_server.s_addr) {
1712e192b24SSimon Glass 		ip_to_string(net_ntp_server, tmp);
172382bee57SSimon Glass 		env_set("ntpserverip", tmp);
1732e192b24SSimon Glass 	}
1742e192b24SSimon Glass #endif
1752e192b24SSimon Glass }
1762e192b24SSimon Glass 
netboot_common(enum proto_t proto,cmd_tbl_t * cmdtp,int argc,char * const argv[])1772e192b24SSimon Glass static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc,
1782e192b24SSimon Glass 		char * const argv[])
1792e192b24SSimon Glass {
1802e192b24SSimon Glass 	char *s;
1812e192b24SSimon Glass 	char *end;
1822e192b24SSimon Glass 	int   rcode = 0;
1832e192b24SSimon Glass 	int   size;
1842e192b24SSimon Glass 	ulong addr;
1852e192b24SSimon Glass 
186449312c1SAlexander Graf 	net_boot_file_name_explicit = false;
187449312c1SAlexander Graf 
1882e192b24SSimon Glass 	/* pre-set load_addr */
18900caae6dSSimon Glass 	s = env_get("loadaddr");
1902e192b24SSimon Glass 	if (s != NULL)
1912e192b24SSimon Glass 		load_addr = simple_strtoul(s, NULL, 16);
1922e192b24SSimon Glass 
1932e192b24SSimon Glass 	switch (argc) {
1942e192b24SSimon Glass 	case 1:
195f43308faSJoe Hershberger 		/* refresh bootfile name from env */
196f43308faSJoe Hershberger 		copy_filename(net_boot_file_name, env_get("bootfile"),
197f43308faSJoe Hershberger 			      sizeof(net_boot_file_name));
1982e192b24SSimon Glass 		break;
1992e192b24SSimon Glass 
2002e192b24SSimon Glass 	case 2:	/*
2012e192b24SSimon Glass 		 * Only one arg - accept two forms:
2022e192b24SSimon Glass 		 * Just load address, or just boot file name. The latter
2032e192b24SSimon Glass 		 * form must be written in a format which can not be
2042e192b24SSimon Glass 		 * mis-interpreted as a valid number.
2052e192b24SSimon Glass 		 */
2062e192b24SSimon Glass 		addr = simple_strtoul(argv[1], &end, 16);
207449312c1SAlexander Graf 		if (end == (argv[1] + strlen(argv[1]))) {
2082e192b24SSimon Glass 			load_addr = addr;
209f43308faSJoe Hershberger 			/* refresh bootfile name from env */
210f43308faSJoe Hershberger 			copy_filename(net_boot_file_name, env_get("bootfile"),
211f43308faSJoe Hershberger 				      sizeof(net_boot_file_name));
212449312c1SAlexander Graf 		} else {
213449312c1SAlexander Graf 			net_boot_file_name_explicit = true;
2142e192b24SSimon Glass 			copy_filename(net_boot_file_name, argv[1],
2152e192b24SSimon Glass 				      sizeof(net_boot_file_name));
216449312c1SAlexander Graf 		}
2172e192b24SSimon Glass 		break;
2182e192b24SSimon Glass 
2192e192b24SSimon Glass 	case 3:
2202e192b24SSimon Glass 		load_addr = simple_strtoul(argv[1], NULL, 16);
221449312c1SAlexander Graf 		net_boot_file_name_explicit = true;
2222e192b24SSimon Glass 		copy_filename(net_boot_file_name, argv[2],
2232e192b24SSimon Glass 			      sizeof(net_boot_file_name));
2242e192b24SSimon Glass 
2252e192b24SSimon Glass 		break;
2262e192b24SSimon Glass 
2272e192b24SSimon Glass #ifdef CONFIG_CMD_TFTPPUT
2282e192b24SSimon Glass 	case 4:
2292e192b24SSimon Glass 		if (strict_strtoul(argv[1], 16, &save_addr) < 0 ||
2302e192b24SSimon Glass 		    strict_strtoul(argv[2], 16, &save_size) < 0) {
2312e192b24SSimon Glass 			printf("Invalid address/size\n");
2322e192b24SSimon Glass 			return CMD_RET_USAGE;
2332e192b24SSimon Glass 		}
234449312c1SAlexander Graf 		net_boot_file_name_explicit = true;
2352e192b24SSimon Glass 		copy_filename(net_boot_file_name, argv[3],
2362e192b24SSimon Glass 			      sizeof(net_boot_file_name));
2372e192b24SSimon Glass 		break;
2382e192b24SSimon Glass #endif
2392e192b24SSimon Glass 	default:
2402e192b24SSimon Glass 		bootstage_error(BOOTSTAGE_ID_NET_START);
2412e192b24SSimon Glass 		return CMD_RET_USAGE;
2422e192b24SSimon Glass 	}
2432e192b24SSimon Glass 	bootstage_mark(BOOTSTAGE_ID_NET_START);
2442e192b24SSimon Glass 
2452e192b24SSimon Glass 	size = net_loop(proto);
2462e192b24SSimon Glass 	if (size < 0) {
2472e192b24SSimon Glass 		bootstage_error(BOOTSTAGE_ID_NET_NETLOOP_OK);
2482e192b24SSimon Glass 		return CMD_RET_FAILURE;
2492e192b24SSimon Glass 	}
2502e192b24SSimon Glass 	bootstage_mark(BOOTSTAGE_ID_NET_NETLOOP_OK);
2512e192b24SSimon Glass 
2522e192b24SSimon Glass 	/* net_loop ok, update environment */
2532e192b24SSimon Glass 	netboot_update_env();
2542e192b24SSimon Glass 
2552e192b24SSimon Glass 	/* done if no file was loaded (no errors though) */
2562e192b24SSimon Glass 	if (size == 0) {
2572e192b24SSimon Glass 		bootstage_error(BOOTSTAGE_ID_NET_LOADED);
2582e192b24SSimon Glass 		return CMD_RET_SUCCESS;
2592e192b24SSimon Glass 	}
2602e192b24SSimon Glass 
2612e192b24SSimon Glass 	bootstage_mark(BOOTSTAGE_ID_NET_LOADED);
2622e192b24SSimon Glass 
2632e192b24SSimon Glass 	rcode = bootm_maybe_autostart(cmdtp, argv[0]);
2642e192b24SSimon Glass 
2652e192b24SSimon Glass 	if (rcode == CMD_RET_SUCCESS)
2662e192b24SSimon Glass 		bootstage_mark(BOOTSTAGE_ID_NET_DONE);
2672e192b24SSimon Glass 	else
2682e192b24SSimon Glass 		bootstage_error(BOOTSTAGE_ID_NET_DONE_ERR);
2692e192b24SSimon Glass 	return rcode;
2702e192b24SSimon Glass }
2712e192b24SSimon Glass 
2722e192b24SSimon Glass #if defined(CONFIG_CMD_PING)
do_ping(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])2732e192b24SSimon Glass static int do_ping(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
2742e192b24SSimon Glass {
2752e192b24SSimon Glass 	if (argc < 2)
2762e192b24SSimon Glass 		return CMD_RET_USAGE;
2772e192b24SSimon Glass 
2782e192b24SSimon Glass 	net_ping_ip = string_to_ip(argv[1]);
2792e192b24SSimon Glass 	if (net_ping_ip.s_addr == 0)
2802e192b24SSimon Glass 		return CMD_RET_USAGE;
2812e192b24SSimon Glass 
2822e192b24SSimon Glass 	if (net_loop(PING) < 0) {
2832e192b24SSimon Glass 		printf("ping failed; host %s is not alive\n", argv[1]);
2842e192b24SSimon Glass 		return CMD_RET_FAILURE;
2852e192b24SSimon Glass 	}
2862e192b24SSimon Glass 
2872e192b24SSimon Glass 	printf("host %s is alive\n", argv[1]);
2882e192b24SSimon Glass 
2892e192b24SSimon Glass 	return CMD_RET_SUCCESS;
2902e192b24SSimon Glass }
2912e192b24SSimon Glass 
2922e192b24SSimon Glass U_BOOT_CMD(
2932e192b24SSimon Glass 	ping,	2,	1,	do_ping,
2942e192b24SSimon Glass 	"send ICMP ECHO_REQUEST to network host",
2952e192b24SSimon Glass 	"pingAddress"
2962e192b24SSimon Glass );
2972e192b24SSimon Glass #endif
2982e192b24SSimon Glass 
2992e192b24SSimon Glass #if defined(CONFIG_CMD_CDP)
3002e192b24SSimon Glass 
cdp_update_env(void)3012e192b24SSimon Glass static void cdp_update_env(void)
3022e192b24SSimon Glass {
3032e192b24SSimon Glass 	char tmp[16];
3042e192b24SSimon Glass 
3052e192b24SSimon Glass 	if (cdp_appliance_vlan != htons(-1)) {
3062e192b24SSimon Glass 		printf("CDP offered appliance VLAN %d\n",
3072e192b24SSimon Glass 		       ntohs(cdp_appliance_vlan));
3082e192b24SSimon Glass 		vlan_to_string(cdp_appliance_vlan, tmp);
309382bee57SSimon Glass 		env_set("vlan", tmp);
3102e192b24SSimon Glass 		net_our_vlan = cdp_appliance_vlan;
3112e192b24SSimon Glass 	}
3122e192b24SSimon Glass 
3132e192b24SSimon Glass 	if (cdp_native_vlan != htons(-1)) {
3142e192b24SSimon Glass 		printf("CDP offered native VLAN %d\n", ntohs(cdp_native_vlan));
3152e192b24SSimon Glass 		vlan_to_string(cdp_native_vlan, tmp);
316382bee57SSimon Glass 		env_set("nvlan", tmp);
3172e192b24SSimon Glass 		net_native_vlan = cdp_native_vlan;
3182e192b24SSimon Glass 	}
3192e192b24SSimon Glass }
3202e192b24SSimon Glass 
do_cdp(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])3212e192b24SSimon Glass int do_cdp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
3222e192b24SSimon Glass {
3232e192b24SSimon Glass 	int r;
3242e192b24SSimon Glass 
3252e192b24SSimon Glass 	r = net_loop(CDP);
3262e192b24SSimon Glass 	if (r < 0) {
3272e192b24SSimon Glass 		printf("cdp failed; perhaps not a CISCO switch?\n");
3282e192b24SSimon Glass 		return CMD_RET_FAILURE;
3292e192b24SSimon Glass 	}
3302e192b24SSimon Glass 
3312e192b24SSimon Glass 	cdp_update_env();
3322e192b24SSimon Glass 
3332e192b24SSimon Glass 	return CMD_RET_SUCCESS;
3342e192b24SSimon Glass }
3352e192b24SSimon Glass 
3362e192b24SSimon Glass U_BOOT_CMD(
3372e192b24SSimon Glass 	cdp,	1,	1,	do_cdp,
3382e192b24SSimon Glass 	"Perform CDP network configuration",
3392e192b24SSimon Glass 	"\n"
3402e192b24SSimon Glass );
3412e192b24SSimon Glass #endif
3422e192b24SSimon Glass 
3432e192b24SSimon Glass #if defined(CONFIG_CMD_SNTP)
do_sntp(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])3442e192b24SSimon Glass int do_sntp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
3452e192b24SSimon Glass {
3462e192b24SSimon Glass 	char *toff;
3472e192b24SSimon Glass 
3482e192b24SSimon Glass 	if (argc < 2) {
349723806ccSSimon Glass 		net_ntp_server = env_get_ip("ntpserverip");
3502e192b24SSimon Glass 		if (net_ntp_server.s_addr == 0) {
3512e192b24SSimon Glass 			printf("ntpserverip not set\n");
3522e192b24SSimon Glass 			return CMD_RET_FAILURE;
3532e192b24SSimon Glass 		}
3542e192b24SSimon Glass 	} else {
3552e192b24SSimon Glass 		net_ntp_server = string_to_ip(argv[1]);
3562e192b24SSimon Glass 		if (net_ntp_server.s_addr == 0) {
3572e192b24SSimon Glass 			printf("Bad NTP server IP address\n");
3582e192b24SSimon Glass 			return CMD_RET_FAILURE;
3592e192b24SSimon Glass 		}
3602e192b24SSimon Glass 	}
3612e192b24SSimon Glass 
36200caae6dSSimon Glass 	toff = env_get("timeoffset");
3632e192b24SSimon Glass 	if (toff == NULL)
3642e192b24SSimon Glass 		net_ntp_time_offset = 0;
3652e192b24SSimon Glass 	else
3662e192b24SSimon Glass 		net_ntp_time_offset = simple_strtol(toff, NULL, 10);
3672e192b24SSimon Glass 
3682e192b24SSimon Glass 	if (net_loop(SNTP) < 0) {
3692e192b24SSimon Glass 		printf("SNTP failed: host %pI4 not responding\n",
3702e192b24SSimon Glass 		       &net_ntp_server);
3712e192b24SSimon Glass 		return CMD_RET_FAILURE;
3722e192b24SSimon Glass 	}
3732e192b24SSimon Glass 
3742e192b24SSimon Glass 	return CMD_RET_SUCCESS;
3752e192b24SSimon Glass }
3762e192b24SSimon Glass 
3772e192b24SSimon Glass U_BOOT_CMD(
3782e192b24SSimon Glass 	sntp,	2,	1,	do_sntp,
3792e192b24SSimon Glass 	"synchronize RTC via network",
3802e192b24SSimon Glass 	"[NTP server IP]\n"
3812e192b24SSimon Glass );
3822e192b24SSimon Glass #endif
3832e192b24SSimon Glass 
3842e192b24SSimon Glass #if defined(CONFIG_CMD_DNS)
do_dns(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])3852e192b24SSimon Glass int do_dns(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
3862e192b24SSimon Glass {
3872e192b24SSimon Glass 	if (argc == 1)
3882e192b24SSimon Glass 		return CMD_RET_USAGE;
3892e192b24SSimon Glass 
3902e192b24SSimon Glass 	/*
3912e192b24SSimon Glass 	 * We should check for a valid hostname:
3922e192b24SSimon Glass 	 * - Each label must be between 1 and 63 characters long
3932e192b24SSimon Glass 	 * - the entire hostname has a maximum of 255 characters
3942e192b24SSimon Glass 	 * - only the ASCII letters 'a' through 'z' (case-insensitive),
3952e192b24SSimon Glass 	 *   the digits '0' through '9', and the hyphen
3962e192b24SSimon Glass 	 * - cannot begin or end with a hyphen
3972e192b24SSimon Glass 	 * - no other symbols, punctuation characters, or blank spaces are
3982e192b24SSimon Glass 	 *   permitted
3992e192b24SSimon Glass 	 * but hey - this is a minimalist implmentation, so only check length
4002e192b24SSimon Glass 	 * and let the name server deal with things.
4012e192b24SSimon Glass 	 */
4022e192b24SSimon Glass 	if (strlen(argv[1]) >= 255) {
4032e192b24SSimon Glass 		printf("dns error: hostname too long\n");
4042e192b24SSimon Glass 		return CMD_RET_FAILURE;
4052e192b24SSimon Glass 	}
4062e192b24SSimon Glass 
4072e192b24SSimon Glass 	net_dns_resolve = argv[1];
4082e192b24SSimon Glass 
4092e192b24SSimon Glass 	if (argc == 3)
4102e192b24SSimon Glass 		net_dns_env_var = argv[2];
4112e192b24SSimon Glass 	else
4122e192b24SSimon Glass 		net_dns_env_var = NULL;
4132e192b24SSimon Glass 
4142e192b24SSimon Glass 	if (net_loop(DNS) < 0) {
4152e192b24SSimon Glass 		printf("dns lookup of %s failed, check setup\n", argv[1]);
4162e192b24SSimon Glass 		return CMD_RET_FAILURE;
4172e192b24SSimon Glass 	}
4182e192b24SSimon Glass 
4192e192b24SSimon Glass 	return CMD_RET_SUCCESS;
4202e192b24SSimon Glass }
4212e192b24SSimon Glass 
4222e192b24SSimon Glass U_BOOT_CMD(
4232e192b24SSimon Glass 	dns,	3,	1,	do_dns,
4242e192b24SSimon Glass 	"lookup the IP of a hostname",
4252e192b24SSimon Glass 	"hostname [envvar]"
4262e192b24SSimon Glass );
4272e192b24SSimon Glass 
4282e192b24SSimon Glass #endif	/* CONFIG_CMD_DNS */
4292e192b24SSimon Glass 
4302e192b24SSimon Glass #if defined(CONFIG_CMD_LINK_LOCAL)
do_link_local(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])4312e192b24SSimon Glass static int do_link_local(cmd_tbl_t *cmdtp, int flag, int argc,
4322e192b24SSimon Glass 			char * const argv[])
4332e192b24SSimon Glass {
4342e192b24SSimon Glass 	char tmp[22];
4352e192b24SSimon Glass 
4362e192b24SSimon Glass 	if (net_loop(LINKLOCAL) < 0)
4372e192b24SSimon Glass 		return CMD_RET_FAILURE;
4382e192b24SSimon Glass 
4392e192b24SSimon Glass 	net_gateway.s_addr = 0;
4402e192b24SSimon Glass 	ip_to_string(net_gateway, tmp);
441382bee57SSimon Glass 	env_set("gatewayip", tmp);
4422e192b24SSimon Glass 
4432e192b24SSimon Glass 	ip_to_string(net_netmask, tmp);
444382bee57SSimon Glass 	env_set("netmask", tmp);
4452e192b24SSimon Glass 
4462e192b24SSimon Glass 	ip_to_string(net_ip, tmp);
447382bee57SSimon Glass 	env_set("ipaddr", tmp);
448382bee57SSimon Glass 	env_set("llipaddr", tmp); /* store this for next time */
4492e192b24SSimon Glass 
4502e192b24SSimon Glass 	return CMD_RET_SUCCESS;
4512e192b24SSimon Glass }
4522e192b24SSimon Glass 
4532e192b24SSimon Glass U_BOOT_CMD(
4542e192b24SSimon Glass 	linklocal,	1,	1,	do_link_local,
4552e192b24SSimon Glass 	"acquire a network IP address using the link-local protocol",
4562e192b24SSimon Glass 	""
4572e192b24SSimon Glass );
4582e192b24SSimon Glass 
4592e192b24SSimon Glass #endif  /* CONFIG_CMD_LINK_LOCAL */
460*9ab23354SDylan Hung 
461*9ab23354SDylan Hung #if defined(CONFIG_CMD_NCSI)
do_ncsi(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])462*9ab23354SDylan Hung static int do_ncsi(cmd_tbl_t *cmdtp, int flag, int argc,
463*9ab23354SDylan Hung 		   char * const argv[])
464*9ab23354SDylan Hung {
465*9ab23354SDylan Hung 	if (net_loop(NCSI) < 0)
466*9ab23354SDylan Hung 		return CMD_RET_FAILURE;
467*9ab23354SDylan Hung 
468*9ab23354SDylan Hung 	return CMD_RET_SUCCESS;
469*9ab23354SDylan Hung }
470*9ab23354SDylan Hung 
471*9ab23354SDylan Hung U_BOOT_CMD(
472*9ab23354SDylan Hung 	ncsi,	1,	1,	do_ncsi,
473*9ab23354SDylan Hung 	"Configure attached NIC via NC-SI",
474*9ab23354SDylan Hung 	""
475*9ab23354SDylan Hung );
476*9ab23354SDylan Hung 
477*9ab23354SDylan Hung #endif  /* CONFIG_CMD_NCSI */
478