xref: /rk3399_rockchip-uboot/cmd/net.c (revision 2e192b245ed36a63bab0ef576999a95e23f60ecd)
1*2e192b24SSimon Glass /*
2*2e192b24SSimon Glass  * (C) Copyright 2000
3*2e192b24SSimon Glass  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4*2e192b24SSimon Glass  *
5*2e192b24SSimon Glass  * SPDX-License-Identifier:	GPL-2.0+
6*2e192b24SSimon Glass  */
7*2e192b24SSimon Glass 
8*2e192b24SSimon Glass /*
9*2e192b24SSimon Glass  * Boot support
10*2e192b24SSimon Glass  */
11*2e192b24SSimon Glass #include <common.h>
12*2e192b24SSimon Glass #include <command.h>
13*2e192b24SSimon Glass #include <net.h>
14*2e192b24SSimon Glass 
15*2e192b24SSimon Glass static int netboot_common(enum proto_t, cmd_tbl_t *, int, char * const []);
16*2e192b24SSimon Glass 
17*2e192b24SSimon Glass static int do_bootp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
18*2e192b24SSimon Glass {
19*2e192b24SSimon Glass 	return netboot_common(BOOTP, cmdtp, argc, argv);
20*2e192b24SSimon Glass }
21*2e192b24SSimon Glass 
22*2e192b24SSimon Glass U_BOOT_CMD(
23*2e192b24SSimon Glass 	bootp,	3,	1,	do_bootp,
24*2e192b24SSimon Glass 	"boot image via network using BOOTP/TFTP protocol",
25*2e192b24SSimon Glass 	"[loadAddress] [[hostIPaddr:]bootfilename]"
26*2e192b24SSimon Glass );
27*2e192b24SSimon Glass 
28*2e192b24SSimon Glass int do_tftpb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
29*2e192b24SSimon Glass {
30*2e192b24SSimon Glass 	int ret;
31*2e192b24SSimon Glass 
32*2e192b24SSimon Glass 	bootstage_mark_name(BOOTSTAGE_KERNELREAD_START, "tftp_start");
33*2e192b24SSimon Glass 	ret = netboot_common(TFTPGET, cmdtp, argc, argv);
34*2e192b24SSimon Glass 	bootstage_mark_name(BOOTSTAGE_KERNELREAD_STOP, "tftp_done");
35*2e192b24SSimon Glass 	return ret;
36*2e192b24SSimon Glass }
37*2e192b24SSimon Glass 
38*2e192b24SSimon Glass U_BOOT_CMD(
39*2e192b24SSimon Glass 	tftpboot,	3,	1,	do_tftpb,
40*2e192b24SSimon Glass 	"boot image via network using TFTP protocol",
41*2e192b24SSimon Glass 	"[loadAddress] [[hostIPaddr:]bootfilename]"
42*2e192b24SSimon Glass );
43*2e192b24SSimon Glass 
44*2e192b24SSimon Glass #ifdef CONFIG_CMD_TFTPPUT
45*2e192b24SSimon Glass int do_tftpput(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
46*2e192b24SSimon Glass {
47*2e192b24SSimon Glass 	return netboot_common(TFTPPUT, cmdtp, argc, argv);
48*2e192b24SSimon Glass }
49*2e192b24SSimon Glass 
50*2e192b24SSimon Glass U_BOOT_CMD(
51*2e192b24SSimon Glass 	tftpput,	4,	1,	do_tftpput,
52*2e192b24SSimon Glass 	"TFTP put command, for uploading files to a server",
53*2e192b24SSimon Glass 	"Address Size [[hostIPaddr:]filename]"
54*2e192b24SSimon Glass );
55*2e192b24SSimon Glass #endif
56*2e192b24SSimon Glass 
57*2e192b24SSimon Glass #ifdef CONFIG_CMD_TFTPSRV
58*2e192b24SSimon Glass static int do_tftpsrv(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
59*2e192b24SSimon Glass {
60*2e192b24SSimon Glass 	return netboot_common(TFTPSRV, cmdtp, argc, argv);
61*2e192b24SSimon Glass }
62*2e192b24SSimon Glass 
63*2e192b24SSimon Glass U_BOOT_CMD(
64*2e192b24SSimon Glass 	tftpsrv,	2,	1,	do_tftpsrv,
65*2e192b24SSimon Glass 	"act as a TFTP server and boot the first received file",
66*2e192b24SSimon Glass 	"[loadAddress]\n"
67*2e192b24SSimon Glass 	"Listen for an incoming TFTP transfer, receive a file and boot it.\n"
68*2e192b24SSimon Glass 	"The transfer is aborted if a transfer has not been started after\n"
69*2e192b24SSimon Glass 	"about 50 seconds or if Ctrl-C is pressed."
70*2e192b24SSimon Glass );
71*2e192b24SSimon Glass #endif
72*2e192b24SSimon Glass 
73*2e192b24SSimon Glass 
74*2e192b24SSimon Glass #ifdef CONFIG_CMD_RARP
75*2e192b24SSimon Glass int do_rarpb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
76*2e192b24SSimon Glass {
77*2e192b24SSimon Glass 	return netboot_common(RARP, cmdtp, argc, argv);
78*2e192b24SSimon Glass }
79*2e192b24SSimon Glass 
80*2e192b24SSimon Glass U_BOOT_CMD(
81*2e192b24SSimon Glass 	rarpboot,	3,	1,	do_rarpb,
82*2e192b24SSimon Glass 	"boot image via network using RARP/TFTP protocol",
83*2e192b24SSimon Glass 	"[loadAddress] [[hostIPaddr:]bootfilename]"
84*2e192b24SSimon Glass );
85*2e192b24SSimon Glass #endif
86*2e192b24SSimon Glass 
87*2e192b24SSimon Glass #if defined(CONFIG_CMD_DHCP)
88*2e192b24SSimon Glass static int do_dhcp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
89*2e192b24SSimon Glass {
90*2e192b24SSimon Glass 	return netboot_common(DHCP, cmdtp, argc, argv);
91*2e192b24SSimon Glass }
92*2e192b24SSimon Glass 
93*2e192b24SSimon Glass U_BOOT_CMD(
94*2e192b24SSimon Glass 	dhcp,	3,	1,	do_dhcp,
95*2e192b24SSimon Glass 	"boot image via network using DHCP/TFTP protocol",
96*2e192b24SSimon Glass 	"[loadAddress] [[hostIPaddr:]bootfilename]"
97*2e192b24SSimon Glass );
98*2e192b24SSimon Glass #endif
99*2e192b24SSimon Glass 
100*2e192b24SSimon Glass #if defined(CONFIG_CMD_NFS)
101*2e192b24SSimon Glass static int do_nfs(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
102*2e192b24SSimon Glass {
103*2e192b24SSimon Glass 	return netboot_common(NFS, cmdtp, argc, argv);
104*2e192b24SSimon Glass }
105*2e192b24SSimon Glass 
106*2e192b24SSimon Glass U_BOOT_CMD(
107*2e192b24SSimon Glass 	nfs,	3,	1,	do_nfs,
108*2e192b24SSimon Glass 	"boot image via network using NFS protocol",
109*2e192b24SSimon Glass 	"[loadAddress] [[hostIPaddr:]bootfilename]"
110*2e192b24SSimon Glass );
111*2e192b24SSimon Glass #endif
112*2e192b24SSimon Glass 
113*2e192b24SSimon Glass static void netboot_update_env(void)
114*2e192b24SSimon Glass {
115*2e192b24SSimon Glass 	char tmp[22];
116*2e192b24SSimon Glass 
117*2e192b24SSimon Glass 	if (net_gateway.s_addr) {
118*2e192b24SSimon Glass 		ip_to_string(net_gateway, tmp);
119*2e192b24SSimon Glass 		setenv("gatewayip", tmp);
120*2e192b24SSimon Glass 	}
121*2e192b24SSimon Glass 
122*2e192b24SSimon Glass 	if (net_netmask.s_addr) {
123*2e192b24SSimon Glass 		ip_to_string(net_netmask, tmp);
124*2e192b24SSimon Glass 		setenv("netmask", tmp);
125*2e192b24SSimon Glass 	}
126*2e192b24SSimon Glass 
127*2e192b24SSimon Glass 	if (net_hostname[0])
128*2e192b24SSimon Glass 		setenv("hostname", net_hostname);
129*2e192b24SSimon Glass 
130*2e192b24SSimon Glass 	if (net_root_path[0])
131*2e192b24SSimon Glass 		setenv("rootpath", net_root_path);
132*2e192b24SSimon Glass 
133*2e192b24SSimon Glass 	if (net_ip.s_addr) {
134*2e192b24SSimon Glass 		ip_to_string(net_ip, tmp);
135*2e192b24SSimon Glass 		setenv("ipaddr", tmp);
136*2e192b24SSimon Glass 	}
137*2e192b24SSimon Glass #if !defined(CONFIG_BOOTP_SERVERIP)
138*2e192b24SSimon Glass 	/*
139*2e192b24SSimon Glass 	 * Only attempt to change serverip if net/bootp.c:BootpCopyNetParams()
140*2e192b24SSimon Glass 	 * could have set it
141*2e192b24SSimon Glass 	 */
142*2e192b24SSimon Glass 	if (net_server_ip.s_addr) {
143*2e192b24SSimon Glass 		ip_to_string(net_server_ip, tmp);
144*2e192b24SSimon Glass 		setenv("serverip", tmp);
145*2e192b24SSimon Glass 	}
146*2e192b24SSimon Glass #endif
147*2e192b24SSimon Glass 	if (net_dns_server.s_addr) {
148*2e192b24SSimon Glass 		ip_to_string(net_dns_server, tmp);
149*2e192b24SSimon Glass 		setenv("dnsip", tmp);
150*2e192b24SSimon Glass 	}
151*2e192b24SSimon Glass #if defined(CONFIG_BOOTP_DNS2)
152*2e192b24SSimon Glass 	if (net_dns_server2.s_addr) {
153*2e192b24SSimon Glass 		ip_to_string(net_dns_server2, tmp);
154*2e192b24SSimon Glass 		setenv("dnsip2", tmp);
155*2e192b24SSimon Glass 	}
156*2e192b24SSimon Glass #endif
157*2e192b24SSimon Glass 	if (net_nis_domain[0])
158*2e192b24SSimon Glass 		setenv("domain", net_nis_domain);
159*2e192b24SSimon Glass 
160*2e192b24SSimon Glass #if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_TIMEOFFSET)
161*2e192b24SSimon Glass 	if (net_ntp_time_offset) {
162*2e192b24SSimon Glass 		sprintf(tmp, "%d", net_ntp_time_offset);
163*2e192b24SSimon Glass 		setenv("timeoffset", tmp);
164*2e192b24SSimon Glass 	}
165*2e192b24SSimon Glass #endif
166*2e192b24SSimon Glass #if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_NTPSERVER)
167*2e192b24SSimon Glass 	if (net_ntp_server.s_addr) {
168*2e192b24SSimon Glass 		ip_to_string(net_ntp_server, tmp);
169*2e192b24SSimon Glass 		setenv("ntpserverip", tmp);
170*2e192b24SSimon Glass 	}
171*2e192b24SSimon Glass #endif
172*2e192b24SSimon Glass }
173*2e192b24SSimon Glass 
174*2e192b24SSimon Glass static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc,
175*2e192b24SSimon Glass 		char * const argv[])
176*2e192b24SSimon Glass {
177*2e192b24SSimon Glass 	char *s;
178*2e192b24SSimon Glass 	char *end;
179*2e192b24SSimon Glass 	int   rcode = 0;
180*2e192b24SSimon Glass 	int   size;
181*2e192b24SSimon Glass 	ulong addr;
182*2e192b24SSimon Glass 
183*2e192b24SSimon Glass 	/* pre-set load_addr */
184*2e192b24SSimon Glass 	s = getenv("loadaddr");
185*2e192b24SSimon Glass 	if (s != NULL)
186*2e192b24SSimon Glass 		load_addr = simple_strtoul(s, NULL, 16);
187*2e192b24SSimon Glass 
188*2e192b24SSimon Glass 	switch (argc) {
189*2e192b24SSimon Glass 	case 1:
190*2e192b24SSimon Glass 		break;
191*2e192b24SSimon Glass 
192*2e192b24SSimon Glass 	case 2:	/*
193*2e192b24SSimon Glass 		 * Only one arg - accept two forms:
194*2e192b24SSimon Glass 		 * Just load address, or just boot file name. The latter
195*2e192b24SSimon Glass 		 * form must be written in a format which can not be
196*2e192b24SSimon Glass 		 * mis-interpreted as a valid number.
197*2e192b24SSimon Glass 		 */
198*2e192b24SSimon Glass 		addr = simple_strtoul(argv[1], &end, 16);
199*2e192b24SSimon Glass 		if (end == (argv[1] + strlen(argv[1])))
200*2e192b24SSimon Glass 			load_addr = addr;
201*2e192b24SSimon Glass 		else
202*2e192b24SSimon Glass 			copy_filename(net_boot_file_name, argv[1],
203*2e192b24SSimon Glass 				      sizeof(net_boot_file_name));
204*2e192b24SSimon Glass 		break;
205*2e192b24SSimon Glass 
206*2e192b24SSimon Glass 	case 3:
207*2e192b24SSimon Glass 		load_addr = simple_strtoul(argv[1], NULL, 16);
208*2e192b24SSimon Glass 		copy_filename(net_boot_file_name, argv[2],
209*2e192b24SSimon Glass 			      sizeof(net_boot_file_name));
210*2e192b24SSimon Glass 
211*2e192b24SSimon Glass 		break;
212*2e192b24SSimon Glass 
213*2e192b24SSimon Glass #ifdef CONFIG_CMD_TFTPPUT
214*2e192b24SSimon Glass 	case 4:
215*2e192b24SSimon Glass 		if (strict_strtoul(argv[1], 16, &save_addr) < 0 ||
216*2e192b24SSimon Glass 		    strict_strtoul(argv[2], 16, &save_size) < 0) {
217*2e192b24SSimon Glass 			printf("Invalid address/size\n");
218*2e192b24SSimon Glass 			return CMD_RET_USAGE;
219*2e192b24SSimon Glass 		}
220*2e192b24SSimon Glass 		copy_filename(net_boot_file_name, argv[3],
221*2e192b24SSimon Glass 			      sizeof(net_boot_file_name));
222*2e192b24SSimon Glass 		break;
223*2e192b24SSimon Glass #endif
224*2e192b24SSimon Glass 	default:
225*2e192b24SSimon Glass 		bootstage_error(BOOTSTAGE_ID_NET_START);
226*2e192b24SSimon Glass 		return CMD_RET_USAGE;
227*2e192b24SSimon Glass 	}
228*2e192b24SSimon Glass 	bootstage_mark(BOOTSTAGE_ID_NET_START);
229*2e192b24SSimon Glass 
230*2e192b24SSimon Glass 	size = net_loop(proto);
231*2e192b24SSimon Glass 	if (size < 0) {
232*2e192b24SSimon Glass 		bootstage_error(BOOTSTAGE_ID_NET_NETLOOP_OK);
233*2e192b24SSimon Glass 		return CMD_RET_FAILURE;
234*2e192b24SSimon Glass 	}
235*2e192b24SSimon Glass 	bootstage_mark(BOOTSTAGE_ID_NET_NETLOOP_OK);
236*2e192b24SSimon Glass 
237*2e192b24SSimon Glass 	/* net_loop ok, update environment */
238*2e192b24SSimon Glass 	netboot_update_env();
239*2e192b24SSimon Glass 
240*2e192b24SSimon Glass 	/* done if no file was loaded (no errors though) */
241*2e192b24SSimon Glass 	if (size == 0) {
242*2e192b24SSimon Glass 		bootstage_error(BOOTSTAGE_ID_NET_LOADED);
243*2e192b24SSimon Glass 		return CMD_RET_SUCCESS;
244*2e192b24SSimon Glass 	}
245*2e192b24SSimon Glass 
246*2e192b24SSimon Glass 	/* flush cache */
247*2e192b24SSimon Glass 	flush_cache(load_addr, size);
248*2e192b24SSimon Glass 
249*2e192b24SSimon Glass 	bootstage_mark(BOOTSTAGE_ID_NET_LOADED);
250*2e192b24SSimon Glass 
251*2e192b24SSimon Glass 	rcode = bootm_maybe_autostart(cmdtp, argv[0]);
252*2e192b24SSimon Glass 
253*2e192b24SSimon Glass 	if (rcode == CMD_RET_SUCCESS)
254*2e192b24SSimon Glass 		bootstage_mark(BOOTSTAGE_ID_NET_DONE);
255*2e192b24SSimon Glass 	else
256*2e192b24SSimon Glass 		bootstage_error(BOOTSTAGE_ID_NET_DONE_ERR);
257*2e192b24SSimon Glass 	return rcode;
258*2e192b24SSimon Glass }
259*2e192b24SSimon Glass 
260*2e192b24SSimon Glass #if defined(CONFIG_CMD_PING)
261*2e192b24SSimon Glass static int do_ping(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
262*2e192b24SSimon Glass {
263*2e192b24SSimon Glass 	if (argc < 2)
264*2e192b24SSimon Glass 		return CMD_RET_USAGE;
265*2e192b24SSimon Glass 
266*2e192b24SSimon Glass 	net_ping_ip = string_to_ip(argv[1]);
267*2e192b24SSimon Glass 	if (net_ping_ip.s_addr == 0)
268*2e192b24SSimon Glass 		return CMD_RET_USAGE;
269*2e192b24SSimon Glass 
270*2e192b24SSimon Glass 	if (net_loop(PING) < 0) {
271*2e192b24SSimon Glass 		printf("ping failed; host %s is not alive\n", argv[1]);
272*2e192b24SSimon Glass 		return CMD_RET_FAILURE;
273*2e192b24SSimon Glass 	}
274*2e192b24SSimon Glass 
275*2e192b24SSimon Glass 	printf("host %s is alive\n", argv[1]);
276*2e192b24SSimon Glass 
277*2e192b24SSimon Glass 	return CMD_RET_SUCCESS;
278*2e192b24SSimon Glass }
279*2e192b24SSimon Glass 
280*2e192b24SSimon Glass U_BOOT_CMD(
281*2e192b24SSimon Glass 	ping,	2,	1,	do_ping,
282*2e192b24SSimon Glass 	"send ICMP ECHO_REQUEST to network host",
283*2e192b24SSimon Glass 	"pingAddress"
284*2e192b24SSimon Glass );
285*2e192b24SSimon Glass #endif
286*2e192b24SSimon Glass 
287*2e192b24SSimon Glass #if defined(CONFIG_CMD_CDP)
288*2e192b24SSimon Glass 
289*2e192b24SSimon Glass static void cdp_update_env(void)
290*2e192b24SSimon Glass {
291*2e192b24SSimon Glass 	char tmp[16];
292*2e192b24SSimon Glass 
293*2e192b24SSimon Glass 	if (cdp_appliance_vlan != htons(-1)) {
294*2e192b24SSimon Glass 		printf("CDP offered appliance VLAN %d\n",
295*2e192b24SSimon Glass 		       ntohs(cdp_appliance_vlan));
296*2e192b24SSimon Glass 		vlan_to_string(cdp_appliance_vlan, tmp);
297*2e192b24SSimon Glass 		setenv("vlan", tmp);
298*2e192b24SSimon Glass 		net_our_vlan = cdp_appliance_vlan;
299*2e192b24SSimon Glass 	}
300*2e192b24SSimon Glass 
301*2e192b24SSimon Glass 	if (cdp_native_vlan != htons(-1)) {
302*2e192b24SSimon Glass 		printf("CDP offered native VLAN %d\n", ntohs(cdp_native_vlan));
303*2e192b24SSimon Glass 		vlan_to_string(cdp_native_vlan, tmp);
304*2e192b24SSimon Glass 		setenv("nvlan", tmp);
305*2e192b24SSimon Glass 		net_native_vlan = cdp_native_vlan;
306*2e192b24SSimon Glass 	}
307*2e192b24SSimon Glass }
308*2e192b24SSimon Glass 
309*2e192b24SSimon Glass int do_cdp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
310*2e192b24SSimon Glass {
311*2e192b24SSimon Glass 	int r;
312*2e192b24SSimon Glass 
313*2e192b24SSimon Glass 	r = net_loop(CDP);
314*2e192b24SSimon Glass 	if (r < 0) {
315*2e192b24SSimon Glass 		printf("cdp failed; perhaps not a CISCO switch?\n");
316*2e192b24SSimon Glass 		return CMD_RET_FAILURE;
317*2e192b24SSimon Glass 	}
318*2e192b24SSimon Glass 
319*2e192b24SSimon Glass 	cdp_update_env();
320*2e192b24SSimon Glass 
321*2e192b24SSimon Glass 	return CMD_RET_SUCCESS;
322*2e192b24SSimon Glass }
323*2e192b24SSimon Glass 
324*2e192b24SSimon Glass U_BOOT_CMD(
325*2e192b24SSimon Glass 	cdp,	1,	1,	do_cdp,
326*2e192b24SSimon Glass 	"Perform CDP network configuration",
327*2e192b24SSimon Glass 	"\n"
328*2e192b24SSimon Glass );
329*2e192b24SSimon Glass #endif
330*2e192b24SSimon Glass 
331*2e192b24SSimon Glass #if defined(CONFIG_CMD_SNTP)
332*2e192b24SSimon Glass int do_sntp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
333*2e192b24SSimon Glass {
334*2e192b24SSimon Glass 	char *toff;
335*2e192b24SSimon Glass 
336*2e192b24SSimon Glass 	if (argc < 2) {
337*2e192b24SSimon Glass 		net_ntp_server = getenv_ip("ntpserverip");
338*2e192b24SSimon Glass 		if (net_ntp_server.s_addr == 0) {
339*2e192b24SSimon Glass 			printf("ntpserverip not set\n");
340*2e192b24SSimon Glass 			return CMD_RET_FAILURE;
341*2e192b24SSimon Glass 		}
342*2e192b24SSimon Glass 	} else {
343*2e192b24SSimon Glass 		net_ntp_server = string_to_ip(argv[1]);
344*2e192b24SSimon Glass 		if (net_ntp_server.s_addr == 0) {
345*2e192b24SSimon Glass 			printf("Bad NTP server IP address\n");
346*2e192b24SSimon Glass 			return CMD_RET_FAILURE;
347*2e192b24SSimon Glass 		}
348*2e192b24SSimon Glass 	}
349*2e192b24SSimon Glass 
350*2e192b24SSimon Glass 	toff = getenv("timeoffset");
351*2e192b24SSimon Glass 	if (toff == NULL)
352*2e192b24SSimon Glass 		net_ntp_time_offset = 0;
353*2e192b24SSimon Glass 	else
354*2e192b24SSimon Glass 		net_ntp_time_offset = simple_strtol(toff, NULL, 10);
355*2e192b24SSimon Glass 
356*2e192b24SSimon Glass 	if (net_loop(SNTP) < 0) {
357*2e192b24SSimon Glass 		printf("SNTP failed: host %pI4 not responding\n",
358*2e192b24SSimon Glass 		       &net_ntp_server);
359*2e192b24SSimon Glass 		return CMD_RET_FAILURE;
360*2e192b24SSimon Glass 	}
361*2e192b24SSimon Glass 
362*2e192b24SSimon Glass 	return CMD_RET_SUCCESS;
363*2e192b24SSimon Glass }
364*2e192b24SSimon Glass 
365*2e192b24SSimon Glass U_BOOT_CMD(
366*2e192b24SSimon Glass 	sntp,	2,	1,	do_sntp,
367*2e192b24SSimon Glass 	"synchronize RTC via network",
368*2e192b24SSimon Glass 	"[NTP server IP]\n"
369*2e192b24SSimon Glass );
370*2e192b24SSimon Glass #endif
371*2e192b24SSimon Glass 
372*2e192b24SSimon Glass #if defined(CONFIG_CMD_DNS)
373*2e192b24SSimon Glass int do_dns(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
374*2e192b24SSimon Glass {
375*2e192b24SSimon Glass 	if (argc == 1)
376*2e192b24SSimon Glass 		return CMD_RET_USAGE;
377*2e192b24SSimon Glass 
378*2e192b24SSimon Glass 	/*
379*2e192b24SSimon Glass 	 * We should check for a valid hostname:
380*2e192b24SSimon Glass 	 * - Each label must be between 1 and 63 characters long
381*2e192b24SSimon Glass 	 * - the entire hostname has a maximum of 255 characters
382*2e192b24SSimon Glass 	 * - only the ASCII letters 'a' through 'z' (case-insensitive),
383*2e192b24SSimon Glass 	 *   the digits '0' through '9', and the hyphen
384*2e192b24SSimon Glass 	 * - cannot begin or end with a hyphen
385*2e192b24SSimon Glass 	 * - no other symbols, punctuation characters, or blank spaces are
386*2e192b24SSimon Glass 	 *   permitted
387*2e192b24SSimon Glass 	 * but hey - this is a minimalist implmentation, so only check length
388*2e192b24SSimon Glass 	 * and let the name server deal with things.
389*2e192b24SSimon Glass 	 */
390*2e192b24SSimon Glass 	if (strlen(argv[1]) >= 255) {
391*2e192b24SSimon Glass 		printf("dns error: hostname too long\n");
392*2e192b24SSimon Glass 		return CMD_RET_FAILURE;
393*2e192b24SSimon Glass 	}
394*2e192b24SSimon Glass 
395*2e192b24SSimon Glass 	net_dns_resolve = argv[1];
396*2e192b24SSimon Glass 
397*2e192b24SSimon Glass 	if (argc == 3)
398*2e192b24SSimon Glass 		net_dns_env_var = argv[2];
399*2e192b24SSimon Glass 	else
400*2e192b24SSimon Glass 		net_dns_env_var = NULL;
401*2e192b24SSimon Glass 
402*2e192b24SSimon Glass 	if (net_loop(DNS) < 0) {
403*2e192b24SSimon Glass 		printf("dns lookup of %s failed, check setup\n", argv[1]);
404*2e192b24SSimon Glass 		return CMD_RET_FAILURE;
405*2e192b24SSimon Glass 	}
406*2e192b24SSimon Glass 
407*2e192b24SSimon Glass 	return CMD_RET_SUCCESS;
408*2e192b24SSimon Glass }
409*2e192b24SSimon Glass 
410*2e192b24SSimon Glass U_BOOT_CMD(
411*2e192b24SSimon Glass 	dns,	3,	1,	do_dns,
412*2e192b24SSimon Glass 	"lookup the IP of a hostname",
413*2e192b24SSimon Glass 	"hostname [envvar]"
414*2e192b24SSimon Glass );
415*2e192b24SSimon Glass 
416*2e192b24SSimon Glass #endif	/* CONFIG_CMD_DNS */
417*2e192b24SSimon Glass 
418*2e192b24SSimon Glass #if defined(CONFIG_CMD_LINK_LOCAL)
419*2e192b24SSimon Glass static int do_link_local(cmd_tbl_t *cmdtp, int flag, int argc,
420*2e192b24SSimon Glass 			char * const argv[])
421*2e192b24SSimon Glass {
422*2e192b24SSimon Glass 	char tmp[22];
423*2e192b24SSimon Glass 
424*2e192b24SSimon Glass 	if (net_loop(LINKLOCAL) < 0)
425*2e192b24SSimon Glass 		return CMD_RET_FAILURE;
426*2e192b24SSimon Glass 
427*2e192b24SSimon Glass 	net_gateway.s_addr = 0;
428*2e192b24SSimon Glass 	ip_to_string(net_gateway, tmp);
429*2e192b24SSimon Glass 	setenv("gatewayip", tmp);
430*2e192b24SSimon Glass 
431*2e192b24SSimon Glass 	ip_to_string(net_netmask, tmp);
432*2e192b24SSimon Glass 	setenv("netmask", tmp);
433*2e192b24SSimon Glass 
434*2e192b24SSimon Glass 	ip_to_string(net_ip, tmp);
435*2e192b24SSimon Glass 	setenv("ipaddr", tmp);
436*2e192b24SSimon Glass 	setenv("llipaddr", tmp); /* store this for next time */
437*2e192b24SSimon Glass 
438*2e192b24SSimon Glass 	return CMD_RET_SUCCESS;
439*2e192b24SSimon Glass }
440*2e192b24SSimon Glass 
441*2e192b24SSimon Glass U_BOOT_CMD(
442*2e192b24SSimon Glass 	linklocal,	1,	1,	do_link_local,
443*2e192b24SSimon Glass 	"acquire a network IP address using the link-local protocol",
444*2e192b24SSimon Glass 	""
445*2e192b24SSimon Glass );
446*2e192b24SSimon Glass 
447*2e192b24SSimon Glass #endif  /* CONFIG_CMD_LINK_LOCAL */
448