blob: e9d552e235292ec8cdd5f0eada82c72020d93dd9 [file] [log] [blame]
wdenk38635852002-08-27 05:55:31 +00001/*
2 * (C) Copyright 2000
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 */
23
24/*
25 * Boot support
26 */
27#include <common.h>
28#include <command.h>
wdenk38635852002-08-27 05:55:31 +000029#include <net.h>
30
31#if (CONFIG_COMMANDS & CFG_CMD_NET)
32
Heiko Schocher566a4942007-06-22 19:11:54 +020033#ifdef CONFIG_SHOW_BOOT_PROGRESS
34# include <status_led.h>
35extern void show_boot_progress (int val);
36# define SHOW_BOOT_PROGRESS(arg) show_boot_progress (arg)
37#else
38# define SHOW_BOOT_PROGRESS(arg)
39#endif
wdenk38635852002-08-27 05:55:31 +000040
41extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
42
wdenk3c2b3d42005-04-05 23:32:21 +000043static int netboot_common (proto_t, cmd_tbl_t *, int , char *[]);
wdenk38635852002-08-27 05:55:31 +000044
45int do_bootp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
46{
47 return netboot_common (BOOTP, cmdtp, argc, argv);
48}
49
wdenk0d498392003-07-01 21:06:45 +000050U_BOOT_CMD(
51 bootp, 3, 1, do_bootp,
wdenkaa5590b2004-06-09 12:42:26 +000052 "bootp\t- boot image via network using BootP/TFTP protocol\n",
wdenk8bde7f72003-06-27 21:31:46 +000053 "[loadAddress] [bootfilename]\n"
54);
55
wdenk38635852002-08-27 05:55:31 +000056int do_tftpb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
57{
58 return netboot_common (TFTP, cmdtp, argc, argv);
59}
60
wdenk0d498392003-07-01 21:06:45 +000061U_BOOT_CMD(
62 tftpboot, 3, 1, do_tftpb,
wdenkeeacb892003-06-28 23:18:28 +000063 "tftpboot- boot image via network using TFTP protocol\n",
wdenk8bde7f72003-06-27 21:31:46 +000064 "[loadAddress] [bootfilename]\n"
65);
66
wdenk38635852002-08-27 05:55:31 +000067int do_rarpb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
68{
69 return netboot_common (RARP, cmdtp, argc, argv);
70}
71
wdenk0d498392003-07-01 21:06:45 +000072U_BOOT_CMD(
73 rarpboot, 3, 1, do_rarpb,
wdenk8bde7f72003-06-27 21:31:46 +000074 "rarpboot- boot image via network using RARP/TFTP protocol\n",
75 "[loadAddress] [bootfilename]\n"
76);
77
wdenk38635852002-08-27 05:55:31 +000078#if (CONFIG_COMMANDS & CFG_CMD_DHCP)
79int do_dhcp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
80{
81 return netboot_common(DHCP, cmdtp, argc, argv);
82}
wdenk8bde7f72003-06-27 21:31:46 +000083
wdenk0d498392003-07-01 21:06:45 +000084U_BOOT_CMD(
85 dhcp, 3, 1, do_dhcp,
wdenkaa5590b2004-06-09 12:42:26 +000086 "dhcp\t- invoke DHCP client to obtain IP/boot params\n",
wdenk8bde7f72003-06-27 21:31:46 +000087 "\n"
88);
wdenk38635852002-08-27 05:55:31 +000089#endif /* CFG_CMD_DHCP */
90
wdenkcbd8a352004-02-24 02:00:03 +000091#if (CONFIG_COMMANDS & CFG_CMD_NFS)
92int do_nfs (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
93{
94 return netboot_common(NFS, cmdtp, argc, argv);
95}
96
97U_BOOT_CMD(
98 nfs, 3, 1, do_nfs,
wdenkaa5590b2004-06-09 12:42:26 +000099 "nfs\t- boot image via network using NFS protocol\n",
wdenkcbd8a352004-02-24 02:00:03 +0000100 "[loadAddress] [host ip addr:bootfilename]\n"
101);
102#endif /* CFG_CMD_NFS */
103
wdenk6e592382004-04-18 17:39:38 +0000104static void netboot_update_env (void)
wdenk38635852002-08-27 05:55:31 +0000105{
wdenk6e592382004-04-18 17:39:38 +0000106 char tmp[22];
wdenk38635852002-08-27 05:55:31 +0000107
wdenk6e592382004-04-18 17:39:38 +0000108 if (NetOurGatewayIP) {
109 ip_to_string (NetOurGatewayIP, tmp);
110 setenv ("gatewayip", tmp);
111 }
wdenk38635852002-08-27 05:55:31 +0000112
wdenk6e592382004-04-18 17:39:38 +0000113 if (NetOurSubnetMask) {
114 ip_to_string (NetOurSubnetMask, tmp);
115 setenv ("netmask", tmp);
116 }
wdenk38635852002-08-27 05:55:31 +0000117
wdenk6e592382004-04-18 17:39:38 +0000118 if (NetOurHostName[0])
119 setenv ("hostname", NetOurHostName);
wdenk38635852002-08-27 05:55:31 +0000120
wdenk6e592382004-04-18 17:39:38 +0000121 if (NetOurRootPath[0])
122 setenv ("rootpath", NetOurRootPath);
wdenk38635852002-08-27 05:55:31 +0000123
wdenk6e592382004-04-18 17:39:38 +0000124 if (NetOurIP) {
125 ip_to_string (NetOurIP, tmp);
126 setenv ("ipaddr", tmp);
127 }
wdenk38635852002-08-27 05:55:31 +0000128
wdenk6e592382004-04-18 17:39:38 +0000129 if (NetServerIP) {
130 ip_to_string (NetServerIP, tmp);
131 setenv ("serverip", tmp);
132 }
wdenk38635852002-08-27 05:55:31 +0000133
wdenk6e592382004-04-18 17:39:38 +0000134 if (NetOurDNSIP) {
135 ip_to_string (NetOurDNSIP, tmp);
136 setenv ("dnsip", tmp);
137 }
stroesefe389a82003-08-28 14:17:32 +0000138#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_DNS2)
wdenk6e592382004-04-18 17:39:38 +0000139 if (NetOurDNS2IP) {
140 ip_to_string (NetOurDNS2IP, tmp);
141 setenv ("dnsip2", tmp);
142 }
stroesefe389a82003-08-28 14:17:32 +0000143#endif
wdenk6e592382004-04-18 17:39:38 +0000144 if (NetOurNISDomain[0])
145 setenv ("domain", NetOurNISDomain);
wdenkea287de2005-04-01 00:25:43 +0000146
wdenk414eec32005-04-02 22:37:54 +0000147#if (CONFIG_COMMANDS & CFG_CMD_SNTP) && (CONFIG_BOOTP_MASK & CONFIG_BOOTP_TIMEOFFSET)
wdenkea287de2005-04-01 00:25:43 +0000148 if (NetTimeOffset) {
149 sprintf (tmp, "%d", NetTimeOffset);
150 setenv ("timeoffset", tmp);
151 }
152#endif
wdenk414eec32005-04-02 22:37:54 +0000153#if (CONFIG_COMMANDS & CFG_CMD_SNTP) && (CONFIG_BOOTP_MASK & CONFIG_BOOTP_NTPSERVER)
wdenkea287de2005-04-01 00:25:43 +0000154 if (NetNtpServerIP) {
155 ip_to_string (NetNtpServerIP, tmp);
156 setenv ("ntpserverip", tmp);
157 }
158#endif
wdenk38635852002-08-27 05:55:31 +0000159}
wdenk6e592382004-04-18 17:39:38 +0000160
wdenk38635852002-08-27 05:55:31 +0000161static int
wdenk3c2b3d42005-04-05 23:32:21 +0000162netboot_common (proto_t proto, cmd_tbl_t *cmdtp, int argc, char *argv[])
wdenk38635852002-08-27 05:55:31 +0000163{
164 char *s;
165 int rcode = 0;
166 int size;
167
168 /* pre-set load_addr */
169 if ((s = getenv("loadaddr")) != NULL) {
170 load_addr = simple_strtoul(s, NULL, 16);
171 }
172
173 switch (argc) {
174 case 1:
175 break;
176
177 case 2: /* only one arg - accept two forms:
178 * just load address, or just boot file name.
179 * The latter form must be written "filename" here.
180 */
181 if (argv[1][0] == '"') { /* just boot filename */
182 copy_filename (BootFile, argv[1], sizeof(BootFile));
183 } else { /* load address */
184 load_addr = simple_strtoul(argv[1], NULL, 16);
185 }
186 break;
187
188 case 3: load_addr = simple_strtoul(argv[1], NULL, 16);
189 copy_filename (BootFile, argv[2], sizeof(BootFile));
190
191 break;
192
193 default: printf ("Usage:\n%s\n", cmdtp->usage);
Heiko Schocher566a4942007-06-22 19:11:54 +0200194 SHOW_BOOT_PROGRESS(-80);
wdenk38635852002-08-27 05:55:31 +0000195 return 1;
196 }
197
Heiko Schocher566a4942007-06-22 19:11:54 +0200198 SHOW_BOOT_PROGRESS(80);
199 if ((size = NetLoop(proto)) < 0) {
200 SHOW_BOOT_PROGRESS(-81);
wdenk38635852002-08-27 05:55:31 +0000201 return 1;
Heiko Schocher566a4942007-06-22 19:11:54 +0200202 }
wdenk38635852002-08-27 05:55:31 +0000203
Heiko Schocher566a4942007-06-22 19:11:54 +0200204 SHOW_BOOT_PROGRESS(81);
wdenk38635852002-08-27 05:55:31 +0000205 /* NetLoop ok, update environment */
206 netboot_update_env();
207
wdenkeb9401e2002-11-11 02:11:37 +0000208 /* done if no file was loaded (no errors though) */
Heiko Schocher566a4942007-06-22 19:11:54 +0200209 if (size == 0) {
210 SHOW_BOOT_PROGRESS(-82);
wdenkeb9401e2002-11-11 02:11:37 +0000211 return 0;
Heiko Schocher566a4942007-06-22 19:11:54 +0200212 }
wdenkeb9401e2002-11-11 02:11:37 +0000213
wdenk38635852002-08-27 05:55:31 +0000214 /* flush cache */
215 flush_cache(load_addr, size);
216
217 /* Loading ok, check if we should attempt an auto-start */
218 if (((s = getenv("autostart")) != NULL) && (strcmp(s,"yes") == 0)) {
219 char *local_args[2];
220 local_args[0] = argv[0];
221 local_args[1] = NULL;
222
223 printf ("Automatic boot of image at addr 0x%08lX ...\n",
224 load_addr);
Heiko Schocher566a4942007-06-22 19:11:54 +0200225 SHOW_BOOT_PROGRESS(82);
wdenk38635852002-08-27 05:55:31 +0000226 rcode = do_bootm (cmdtp, 0, 1, local_args);
227 }
228
229#ifdef CONFIG_AUTOSCRIPT
230 if (((s = getenv("autoscript")) != NULL) && (strcmp(s,"yes") == 0)) {
231 printf("Running autoscript at addr 0x%08lX ...\n", load_addr);
Heiko Schocher566a4942007-06-22 19:11:54 +0200232 SHOW_BOOT_PROGRESS(83);
wdenk38635852002-08-27 05:55:31 +0000233 rcode = autoscript (load_addr);
234 }
235#endif
Heiko Schocher566a4942007-06-22 19:11:54 +0200236#if defined(CONFIG_SHOW_BOOT_PROGRESS)
237 if (rcode < 0)
238 SHOW_BOOT_PROGRESS(-83);
239 else
240 SHOW_BOOT_PROGRESS(84);
241#endif
wdenk38635852002-08-27 05:55:31 +0000242 return rcode;
243}
244
wdenk73a8b272003-06-05 19:27:42 +0000245#if (CONFIG_COMMANDS & CFG_CMD_PING)
246int do_ping (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
247{
248 if (argc < 2)
249 return -1;
250
251 NetPingIP = string_to_ip(argv[1]);
252 if (NetPingIP == 0) {
253 printf ("Usage:\n%s\n", cmdtp->usage);
254 return -1;
255 }
256
257 if (NetLoop(PING) < 0) {
258 printf("ping failed; host %s is not alive\n", argv[1]);
259 return 1;
260 }
261
262 printf("host %s is alive\n", argv[1]);
263
264 return 0;
265}
wdenk6dff5522003-07-15 07:45:49 +0000266
267U_BOOT_CMD(
268 ping, 2, 1, do_ping,
wdenkaa5590b2004-06-09 12:42:26 +0000269 "ping\t- send ICMP ECHO_REQUEST to network host\n",
wdenk6dff5522003-07-15 07:45:49 +0000270 "pingAddress\n"
271);
wdenk73a8b272003-06-05 19:27:42 +0000272#endif /* CFG_CMD_PING */
273
wdenka3d991b2004-04-15 21:48:45 +0000274#if (CONFIG_COMMANDS & CFG_CMD_CDP)
275
276static void cdp_update_env(void)
277{
278 char tmp[16];
279
280 if (CDPApplianceVLAN != htons(-1)) {
281 printf("CDP offered appliance VLAN %d\n", ntohs(CDPApplianceVLAN));
282 VLAN_to_string(CDPApplianceVLAN, tmp);
283 setenv("vlan", tmp);
284 NetOurVLAN = CDPApplianceVLAN;
285 }
286
287 if (CDPNativeVLAN != htons(-1)) {
288 printf("CDP offered native VLAN %d\n", ntohs(CDPNativeVLAN));
289 VLAN_to_string(CDPNativeVLAN, tmp);
290 setenv("nvlan", tmp);
291 NetOurNativeVLAN = CDPNativeVLAN;
292 }
293
294}
295
296int do_cdp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
297{
298 int r;
299
300 r = NetLoop(CDP);
301 if (r < 0) {
302 printf("cdp failed; perhaps not a CISCO switch?\n");
303 return 1;
304 }
305
306 cdp_update_env();
307
308 return 0;
309}
310
311U_BOOT_CMD(
312 cdp, 1, 1, do_cdp,
wdenkaa5590b2004-06-09 12:42:26 +0000313 "cdp\t- Perform CDP network configuration\n",
wdenka3d991b2004-04-15 21:48:45 +0000314);
315#endif /* CFG_CMD_CDP */
316
wdenkea287de2005-04-01 00:25:43 +0000317#if (CONFIG_COMMANDS & CFG_CMD_SNTP)
318int do_sntp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
319{
320 char *toff;
321
322 if (argc < 2) {
323 NetNtpServerIP = getenv_IPaddr ("ntpserverip");
324 if (NetNtpServerIP == 0) {
325 printf ("ntpserverip not set\n");
326 return (1);
327 }
328 } else {
329 NetNtpServerIP = string_to_ip(argv[1]);
330 if (NetNtpServerIP == 0) {
331 printf ("Bad NTP server IP address\n");
332 return (1);
333 }
334 }
335
336 toff = getenv ("timeoffset");
337 if (toff == NULL) NetTimeOffset = 0;
338 else NetTimeOffset = simple_strtol (toff, NULL, 10);
339
340 if (NetLoop(SNTP) < 0) {
341 printf("SNTP failed: host %s not responding\n", argv[1]);
342 return 1;
343 }
344
345 return 0;
346}
347
348U_BOOT_CMD(
349 sntp, 2, 1, do_sntp,
350 "sntp\t- synchronize RTC via network\n",
351 "[NTP server IP]\n"
352);
353#endif /* CFG_CMD_SNTP */
354
wdenk38635852002-08-27 05:55:31 +0000355#endif /* CFG_CMD_NET */