12e192b24SSimon Glass /*
22e192b24SSimon Glass * (C) Copyright 2000
32e192b24SSimon Glass * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
42e192b24SSimon Glass *
52e192b24SSimon Glass * SPDX-License-Identifier: GPL-2.0+
62e192b24SSimon Glass */
72e192b24SSimon Glass
82e192b24SSimon Glass /*
92e192b24SSimon Glass * Boot support
102e192b24SSimon Glass */
112e192b24SSimon Glass #include <common.h>
122e192b24SSimon Glass #include <command.h>
132e192b24SSimon Glass #include <net.h>
14909b9728SJoseph Chen #include <boot_rkimg.h>
152e192b24SSimon Glass
162e192b24SSimon Glass static int netboot_common(enum proto_t, cmd_tbl_t *, int, char * const []);
172e192b24SSimon Glass
do_bootp(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])182e192b24SSimon Glass static int do_bootp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
192e192b24SSimon Glass {
202e192b24SSimon Glass return netboot_common(BOOTP, cmdtp, argc, argv);
212e192b24SSimon Glass }
222e192b24SSimon Glass
232e192b24SSimon Glass U_BOOT_CMD(
242e192b24SSimon Glass bootp, 3, 1, do_bootp,
252e192b24SSimon Glass "boot image via network using BOOTP/TFTP protocol",
262e192b24SSimon Glass "[loadAddress] [[hostIPaddr:]bootfilename]"
272e192b24SSimon Glass );
282e192b24SSimon Glass
do_tftpb(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])292e192b24SSimon Glass int do_tftpb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
302e192b24SSimon Glass {
312e192b24SSimon Glass int ret;
322e192b24SSimon Glass
332e192b24SSimon Glass bootstage_mark_name(BOOTSTAGE_KERNELREAD_START, "tftp_start");
342e192b24SSimon Glass ret = netboot_common(TFTPGET, cmdtp, argc, argv);
352e192b24SSimon Glass bootstage_mark_name(BOOTSTAGE_KERNELREAD_STOP, "tftp_done");
362e192b24SSimon Glass return ret;
372e192b24SSimon Glass }
382e192b24SSimon Glass
392e192b24SSimon Glass U_BOOT_CMD(
40909b9728SJoseph Chen tftp, 3, 1, do_tftpb,
41909b9728SJoseph Chen "download image via network using TFTP protocol",
422e192b24SSimon Glass "[loadAddress] [[hostIPaddr:]bootfilename]"
432e192b24SSimon Glass );
442e192b24SSimon Glass
45909b9728SJoseph Chen #ifdef CONFIG_CMD_TFTP_BOOTM
do_tftpbootm(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])46909b9728SJoseph Chen int do_tftpbootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
47909b9728SJoseph Chen {
48909b9728SJoseph Chen char *tftp_argv[] = { "tftp", NULL, NULL };
49909b9728SJoseph Chen char *bootm_argv[] = { "bootm", NULL };
50909b9728SJoseph Chen char *fileaddr;
51909b9728SJoseph Chen ulong filesize;
52909b9728SJoseph Chen
53909b9728SJoseph Chen if (argc != 3)
54909b9728SJoseph Chen return CMD_RET_USAGE;
55909b9728SJoseph Chen
56909b9728SJoseph Chen /* tftp download */
57909b9728SJoseph Chen tftp_argv[1] = argv[1];
58909b9728SJoseph Chen tftp_argv[2] = argv[2];
59909b9728SJoseph Chen if (do_tftpb(cmdtp, 0, 3, tftp_argv))
60909b9728SJoseph Chen return -ENOENT;
61909b9728SJoseph Chen
62909b9728SJoseph Chen fileaddr = env_get("fileaddr");
63909b9728SJoseph Chen filesize = env_get_ulong("filesize", 16, 0);
64909b9728SJoseph Chen if (!fileaddr || !filesize)
65909b9728SJoseph Chen return -ENOENT;
66909b9728SJoseph Chen
67909b9728SJoseph Chen /* bootm */
68909b9728SJoseph Chen bootm_argv[1] = fileaddr;
69909b9728SJoseph Chen printf("## TFTP bootm %s at %s size 0x%lx\n",
70909b9728SJoseph Chen argv[2], fileaddr, filesize);
71909b9728SJoseph Chen
72909b9728SJoseph Chen return do_bootm(NULL, 0, ARRAY_SIZE(bootm_argv), bootm_argv);
73909b9728SJoseph Chen }
74909b9728SJoseph Chen
75909b9728SJoseph Chen U_BOOT_CMD(
76909b9728SJoseph Chen tftpbootm, 3, 1, do_tftpbootm,
77909b9728SJoseph Chen "tftpbootm aosp/uImage/FIT image via network using TFTP protocol",
78909b9728SJoseph Chen "[loadAddress] [[hostIPaddr:]bootfilename]"
79909b9728SJoseph Chen );
80909b9728SJoseph Chen #endif
81909b9728SJoseph Chen
82909b9728SJoseph Chen #ifdef CONFIG_CMD_TFTP_FLASH
do_tftpflash(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])83909b9728SJoseph Chen int do_tftpflash(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
84909b9728SJoseph Chen {
85909b9728SJoseph Chen char *tftp_argv[] = { "tftp", NULL, NULL };
86909b9728SJoseph Chen struct blk_desc *dev_desc;
87909b9728SJoseph Chen disk_partition_t part;
88909b9728SJoseph Chen ulong fileaddr;
89909b9728SJoseph Chen ulong filesize;
90909b9728SJoseph Chen char *part_name;
91909b9728SJoseph Chen int ret, blknum;
92909b9728SJoseph Chen
93909b9728SJoseph Chen if (argc != 4)
94909b9728SJoseph Chen return CMD_RET_USAGE;
95909b9728SJoseph Chen
96909b9728SJoseph Chen /* search partition */
97909b9728SJoseph Chen dev_desc = rockchip_get_bootdev();
98909b9728SJoseph Chen if (!dev_desc) {
99909b9728SJoseph Chen printf("No boot device\n");
100909b9728SJoseph Chen return -ENODEV;
101909b9728SJoseph Chen }
102909b9728SJoseph Chen
103909b9728SJoseph Chen part_name = argv[3];
104909b9728SJoseph Chen ret = part_get_info_by_name(dev_desc, part_name, &part);
105909b9728SJoseph Chen if (ret < 0) {
106909b9728SJoseph Chen printf("No partition '%s'\n", part_name);
107909b9728SJoseph Chen return -EINVAL;
108909b9728SJoseph Chen }
109909b9728SJoseph Chen
110909b9728SJoseph Chen /* tftp download */
111909b9728SJoseph Chen tftp_argv[1] = argv[1];
112909b9728SJoseph Chen tftp_argv[2] = argv[2];
113909b9728SJoseph Chen if (do_tftpb(cmdtp, 0, ARRAY_SIZE(tftp_argv), tftp_argv))
114909b9728SJoseph Chen return -ENOENT;
115909b9728SJoseph Chen
116909b9728SJoseph Chen fileaddr = env_get_ulong("fileaddr", 16, 0);
117909b9728SJoseph Chen filesize = env_get_ulong("filesize", 16, 0);
118909b9728SJoseph Chen if (!fileaddr || !filesize)
119909b9728SJoseph Chen return -ENOENT;
120909b9728SJoseph Chen
121909b9728SJoseph Chen /* flash */
122909b9728SJoseph Chen blknum = DIV_ROUND_UP(filesize, dev_desc->blksz);
123909b9728SJoseph Chen if (blknum > part.size) {
124909b9728SJoseph Chen printf("File size 0x%lx is too large to flash\n", filesize);
125909b9728SJoseph Chen return -EINVAL;
126909b9728SJoseph Chen }
127909b9728SJoseph Chen
128909b9728SJoseph Chen printf("## TFTP flash %s to partititon '%s' size 0x%lx ... ",
129909b9728SJoseph Chen argv[2], part_name, filesize);
130909b9728SJoseph Chen
131*3511cb80SJon Lin if (dev_desc->if_type == IF_TYPE_MTD)
132*3511cb80SJon Lin dev_desc->op_flag |= BLK_MTD_CONT_WRITE;
133909b9728SJoseph Chen ret = blk_dwrite(dev_desc, part.start, blknum, (void *)fileaddr);
134*3511cb80SJon Lin if (dev_desc->if_type == IF_TYPE_MTD)
135*3511cb80SJon Lin dev_desc->op_flag &= ~(BLK_MTD_CONT_WRITE);
136909b9728SJoseph Chen if (ret != blknum)
137909b9728SJoseph Chen printf("Failed(%d)\n", ret);
138909b9728SJoseph Chen else
139909b9728SJoseph Chen printf("OK\n");
140909b9728SJoseph Chen
141909b9728SJoseph Chen return 0;
142909b9728SJoseph Chen }
143909b9728SJoseph Chen
144909b9728SJoseph Chen U_BOOT_CMD(
145909b9728SJoseph Chen tftpflash, 4, 0, do_tftpflash,
146909b9728SJoseph Chen "flash image via network using TFTP protocol",
147909b9728SJoseph Chen "[loadAddress] [[hostIPaddr:]bootfilename] [partition]"
148909b9728SJoseph Chen );
149909b9728SJoseph Chen #endif
150909b9728SJoseph Chen
1512e192b24SSimon Glass #ifdef CONFIG_CMD_TFTPPUT
do_tftpput(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])1520c1b869bSMasahiro Yamada static int do_tftpput(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1532e192b24SSimon Glass {
1542e192b24SSimon Glass return netboot_common(TFTPPUT, cmdtp, argc, argv);
1552e192b24SSimon Glass }
1562e192b24SSimon Glass
1572e192b24SSimon Glass U_BOOT_CMD(
1582e192b24SSimon Glass tftpput, 4, 1, do_tftpput,
1592e192b24SSimon Glass "TFTP put command, for uploading files to a server",
1602e192b24SSimon Glass "Address Size [[hostIPaddr:]filename]"
1612e192b24SSimon Glass );
1622e192b24SSimon Glass #endif
1632e192b24SSimon Glass
1642e192b24SSimon Glass #ifdef CONFIG_CMD_TFTPSRV
do_tftpsrv(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])1652e192b24SSimon Glass static int do_tftpsrv(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
1662e192b24SSimon Glass {
1672e192b24SSimon Glass return netboot_common(TFTPSRV, cmdtp, argc, argv);
1682e192b24SSimon Glass }
1692e192b24SSimon Glass
1702e192b24SSimon Glass U_BOOT_CMD(
1712e192b24SSimon Glass tftpsrv, 2, 1, do_tftpsrv,
1722e192b24SSimon Glass "act as a TFTP server and boot the first received file",
1732e192b24SSimon Glass "[loadAddress]\n"
1742e192b24SSimon Glass "Listen for an incoming TFTP transfer, receive a file and boot it.\n"
1752e192b24SSimon Glass "The transfer is aborted if a transfer has not been started after\n"
1762e192b24SSimon Glass "about 50 seconds or if Ctrl-C is pressed."
1772e192b24SSimon Glass );
1782e192b24SSimon Glass #endif
1792e192b24SSimon Glass
180965eda41SJocelyn Bohr #ifdef CONFIG_UDP_FUNCTION_FASTBOOT
do_fastboot_udp(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])181965eda41SJocelyn Bohr int do_fastboot_udp(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
182965eda41SJocelyn Bohr {
183965eda41SJocelyn Bohr return netboot_common(FASTBOOT, cmdtp, argc, argv);
184965eda41SJocelyn Bohr }
185965eda41SJocelyn Bohr #endif
1862e192b24SSimon Glass
1872e192b24SSimon Glass #ifdef CONFIG_CMD_RARP
do_rarpb(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])1882e192b24SSimon Glass int do_rarpb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1892e192b24SSimon Glass {
1902e192b24SSimon Glass return netboot_common(RARP, cmdtp, argc, argv);
1912e192b24SSimon Glass }
1922e192b24SSimon Glass
1932e192b24SSimon Glass U_BOOT_CMD(
1942e192b24SSimon Glass rarpboot, 3, 1, do_rarpb,
1952e192b24SSimon Glass "boot image via network using RARP/TFTP protocol",
1962e192b24SSimon Glass "[loadAddress] [[hostIPaddr:]bootfilename]"
1972e192b24SSimon Glass );
1982e192b24SSimon Glass #endif
1992e192b24SSimon Glass
2002e192b24SSimon Glass #if defined(CONFIG_CMD_DHCP)
do_dhcp(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])2012e192b24SSimon Glass static int do_dhcp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
2022e192b24SSimon Glass {
2032e192b24SSimon Glass return netboot_common(DHCP, cmdtp, argc, argv);
2042e192b24SSimon Glass }
2052e192b24SSimon Glass
2062e192b24SSimon Glass U_BOOT_CMD(
2072e192b24SSimon Glass dhcp, 3, 1, do_dhcp,
2082e192b24SSimon Glass "boot image via network using DHCP/TFTP protocol",
2092e192b24SSimon Glass "[loadAddress] [[hostIPaddr:]bootfilename]"
2102e192b24SSimon Glass );
2112e192b24SSimon Glass #endif
2122e192b24SSimon Glass
2132e192b24SSimon Glass #if defined(CONFIG_CMD_NFS)
do_nfs(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])2142e192b24SSimon Glass static int do_nfs(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
2152e192b24SSimon Glass {
2162e192b24SSimon Glass return netboot_common(NFS, cmdtp, argc, argv);
2172e192b24SSimon Glass }
2182e192b24SSimon Glass
2192e192b24SSimon Glass U_BOOT_CMD(
2202e192b24SSimon Glass nfs, 3, 1, do_nfs,
2212e192b24SSimon Glass "boot image via network using NFS protocol",
2222e192b24SSimon Glass "[loadAddress] [[hostIPaddr:]bootfilename]"
2232e192b24SSimon Glass );
2242e192b24SSimon Glass #endif
2252e192b24SSimon Glass
netboot_update_env(void)2262e192b24SSimon Glass static void netboot_update_env(void)
2272e192b24SSimon Glass {
2282e192b24SSimon Glass char tmp[22];
2292e192b24SSimon Glass
2302e192b24SSimon Glass if (net_gateway.s_addr) {
2312e192b24SSimon Glass ip_to_string(net_gateway, tmp);
232382bee57SSimon Glass env_set("gatewayip", tmp);
2332e192b24SSimon Glass }
2342e192b24SSimon Glass
2352e192b24SSimon Glass if (net_netmask.s_addr) {
2362e192b24SSimon Glass ip_to_string(net_netmask, tmp);
237382bee57SSimon Glass env_set("netmask", tmp);
2382e192b24SSimon Glass }
2392e192b24SSimon Glass
2402e192b24SSimon Glass if (net_hostname[0])
241382bee57SSimon Glass env_set("hostname", net_hostname);
2422e192b24SSimon Glass
2432e192b24SSimon Glass if (net_root_path[0])
244382bee57SSimon Glass env_set("rootpath", net_root_path);
2452e192b24SSimon Glass
2462e192b24SSimon Glass if (net_ip.s_addr) {
2472e192b24SSimon Glass ip_to_string(net_ip, tmp);
248382bee57SSimon Glass env_set("ipaddr", tmp);
2492e192b24SSimon Glass }
2502e192b24SSimon Glass #if !defined(CONFIG_BOOTP_SERVERIP)
2512e192b24SSimon Glass /*
252ff78ad28SBaruch Siach * Only attempt to change serverip if net/bootp.c:store_net_params()
2532e192b24SSimon Glass * could have set it
2542e192b24SSimon Glass */
2552e192b24SSimon Glass if (net_server_ip.s_addr) {
2562e192b24SSimon Glass ip_to_string(net_server_ip, tmp);
257382bee57SSimon Glass env_set("serverip", tmp);
2582e192b24SSimon Glass }
2592e192b24SSimon Glass #endif
2602e192b24SSimon Glass if (net_dns_server.s_addr) {
2612e192b24SSimon Glass ip_to_string(net_dns_server, tmp);
262382bee57SSimon Glass env_set("dnsip", tmp);
2632e192b24SSimon Glass }
2642e192b24SSimon Glass #if defined(CONFIG_BOOTP_DNS2)
2652e192b24SSimon Glass if (net_dns_server2.s_addr) {
2662e192b24SSimon Glass ip_to_string(net_dns_server2, tmp);
267382bee57SSimon Glass env_set("dnsip2", tmp);
2682e192b24SSimon Glass }
2692e192b24SSimon Glass #endif
2702e192b24SSimon Glass if (net_nis_domain[0])
271382bee57SSimon Glass env_set("domain", net_nis_domain);
2722e192b24SSimon Glass
2732e192b24SSimon Glass #if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_TIMEOFFSET)
2742e192b24SSimon Glass if (net_ntp_time_offset) {
2752e192b24SSimon Glass sprintf(tmp, "%d", net_ntp_time_offset);
276382bee57SSimon Glass env_set("timeoffset", tmp);
2772e192b24SSimon Glass }
2782e192b24SSimon Glass #endif
2792e192b24SSimon Glass #if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_NTPSERVER)
2802e192b24SSimon Glass if (net_ntp_server.s_addr) {
2812e192b24SSimon Glass ip_to_string(net_ntp_server, tmp);
282382bee57SSimon Glass env_set("ntpserverip", tmp);
2832e192b24SSimon Glass }
2842e192b24SSimon Glass #endif
2852e192b24SSimon Glass }
2862e192b24SSimon Glass
netboot_common(enum proto_t proto,cmd_tbl_t * cmdtp,int argc,char * const argv[])2872e192b24SSimon Glass static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc,
2882e192b24SSimon Glass char * const argv[])
2892e192b24SSimon Glass {
2902e192b24SSimon Glass char *s;
2912e192b24SSimon Glass char *end;
2922e192b24SSimon Glass int rcode = 0;
2932e192b24SSimon Glass int size;
2942e192b24SSimon Glass ulong addr;
2952e192b24SSimon Glass
2962e192b24SSimon Glass /* pre-set load_addr */
29700caae6dSSimon Glass s = env_get("loadaddr");
2982e192b24SSimon Glass if (s != NULL)
2992e192b24SSimon Glass load_addr = simple_strtoul(s, NULL, 16);
3002e192b24SSimon Glass
3012e192b24SSimon Glass switch (argc) {
3022e192b24SSimon Glass case 1:
3032e192b24SSimon Glass break;
3042e192b24SSimon Glass
3052e192b24SSimon Glass case 2: /*
3062e192b24SSimon Glass * Only one arg - accept two forms:
3072e192b24SSimon Glass * Just load address, or just boot file name. The latter
3082e192b24SSimon Glass * form must be written in a format which can not be
3092e192b24SSimon Glass * mis-interpreted as a valid number.
3102e192b24SSimon Glass */
3112e192b24SSimon Glass addr = simple_strtoul(argv[1], &end, 16);
3122e192b24SSimon Glass if (end == (argv[1] + strlen(argv[1])))
3132e192b24SSimon Glass load_addr = addr;
3142e192b24SSimon Glass else
3152e192b24SSimon Glass copy_filename(net_boot_file_name, argv[1],
3162e192b24SSimon Glass sizeof(net_boot_file_name));
3172e192b24SSimon Glass break;
3182e192b24SSimon Glass
3192e192b24SSimon Glass case 3:
3202e192b24SSimon Glass load_addr = simple_strtoul(argv[1], NULL, 16);
3212e192b24SSimon Glass copy_filename(net_boot_file_name, argv[2],
3222e192b24SSimon Glass sizeof(net_boot_file_name));
3232e192b24SSimon Glass
3242e192b24SSimon Glass break;
3252e192b24SSimon Glass
3262e192b24SSimon Glass #ifdef CONFIG_CMD_TFTPPUT
3272e192b24SSimon Glass case 4:
3282e192b24SSimon Glass if (strict_strtoul(argv[1], 16, &save_addr) < 0 ||
3292e192b24SSimon Glass strict_strtoul(argv[2], 16, &save_size) < 0) {
3302e192b24SSimon Glass printf("Invalid address/size\n");
3312e192b24SSimon Glass return CMD_RET_USAGE;
3322e192b24SSimon Glass }
3332e192b24SSimon Glass copy_filename(net_boot_file_name, argv[3],
3342e192b24SSimon Glass sizeof(net_boot_file_name));
3352e192b24SSimon Glass break;
3362e192b24SSimon Glass #endif
3372e192b24SSimon Glass default:
3382e192b24SSimon Glass bootstage_error(BOOTSTAGE_ID_NET_START);
3392e192b24SSimon Glass return CMD_RET_USAGE;
3402e192b24SSimon Glass }
3412e192b24SSimon Glass bootstage_mark(BOOTSTAGE_ID_NET_START);
3422e192b24SSimon Glass
3432e192b24SSimon Glass size = net_loop(proto);
3442e192b24SSimon Glass if (size < 0) {
3452e192b24SSimon Glass bootstage_error(BOOTSTAGE_ID_NET_NETLOOP_OK);
3462e192b24SSimon Glass return CMD_RET_FAILURE;
3472e192b24SSimon Glass }
3482e192b24SSimon Glass bootstage_mark(BOOTSTAGE_ID_NET_NETLOOP_OK);
3492e192b24SSimon Glass
3502e192b24SSimon Glass /* net_loop ok, update environment */
3512e192b24SSimon Glass netboot_update_env();
3522e192b24SSimon Glass
3532e192b24SSimon Glass /* done if no file was loaded (no errors though) */
3542e192b24SSimon Glass if (size == 0) {
3552e192b24SSimon Glass bootstage_error(BOOTSTAGE_ID_NET_LOADED);
3562e192b24SSimon Glass return CMD_RET_SUCCESS;
3572e192b24SSimon Glass }
3582e192b24SSimon Glass
3592e192b24SSimon Glass bootstage_mark(BOOTSTAGE_ID_NET_LOADED);
3602e192b24SSimon Glass
3612e192b24SSimon Glass rcode = bootm_maybe_autostart(cmdtp, argv[0]);
3622e192b24SSimon Glass
3632e192b24SSimon Glass if (rcode == CMD_RET_SUCCESS)
3642e192b24SSimon Glass bootstage_mark(BOOTSTAGE_ID_NET_DONE);
3652e192b24SSimon Glass else
3662e192b24SSimon Glass bootstage_error(BOOTSTAGE_ID_NET_DONE_ERR);
3672e192b24SSimon Glass return rcode;
3682e192b24SSimon Glass }
3692e192b24SSimon Glass
3702e192b24SSimon Glass #if defined(CONFIG_CMD_PING)
do_ping(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])3712e192b24SSimon Glass static int do_ping(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
3722e192b24SSimon Glass {
3732e192b24SSimon Glass if (argc < 2)
3742e192b24SSimon Glass return CMD_RET_USAGE;
3752e192b24SSimon Glass
3762e192b24SSimon Glass net_ping_ip = string_to_ip(argv[1]);
3772e192b24SSimon Glass if (net_ping_ip.s_addr == 0)
3782e192b24SSimon Glass return CMD_RET_USAGE;
3792e192b24SSimon Glass
3802e192b24SSimon Glass if (net_loop(PING) < 0) {
3812e192b24SSimon Glass printf("ping failed; host %s is not alive\n", argv[1]);
3822e192b24SSimon Glass return CMD_RET_FAILURE;
3832e192b24SSimon Glass }
3842e192b24SSimon Glass
3852e192b24SSimon Glass printf("host %s is alive\n", argv[1]);
3862e192b24SSimon Glass
3872e192b24SSimon Glass return CMD_RET_SUCCESS;
3882e192b24SSimon Glass }
3892e192b24SSimon Glass
3902e192b24SSimon Glass U_BOOT_CMD(
3912e192b24SSimon Glass ping, 2, 1, do_ping,
3922e192b24SSimon Glass "send ICMP ECHO_REQUEST to network host",
3932e192b24SSimon Glass "pingAddress"
3942e192b24SSimon Glass );
3952e192b24SSimon Glass #endif
3962e192b24SSimon Glass
3972e192b24SSimon Glass #if defined(CONFIG_CMD_CDP)
3982e192b24SSimon Glass
cdp_update_env(void)3992e192b24SSimon Glass static void cdp_update_env(void)
4002e192b24SSimon Glass {
4012e192b24SSimon Glass char tmp[16];
4022e192b24SSimon Glass
4032e192b24SSimon Glass if (cdp_appliance_vlan != htons(-1)) {
4042e192b24SSimon Glass printf("CDP offered appliance VLAN %d\n",
4052e192b24SSimon Glass ntohs(cdp_appliance_vlan));
4062e192b24SSimon Glass vlan_to_string(cdp_appliance_vlan, tmp);
407382bee57SSimon Glass env_set("vlan", tmp);
4082e192b24SSimon Glass net_our_vlan = cdp_appliance_vlan;
4092e192b24SSimon Glass }
4102e192b24SSimon Glass
4112e192b24SSimon Glass if (cdp_native_vlan != htons(-1)) {
4122e192b24SSimon Glass printf("CDP offered native VLAN %d\n", ntohs(cdp_native_vlan));
4132e192b24SSimon Glass vlan_to_string(cdp_native_vlan, tmp);
414382bee57SSimon Glass env_set("nvlan", tmp);
4152e192b24SSimon Glass net_native_vlan = cdp_native_vlan;
4162e192b24SSimon Glass }
4172e192b24SSimon Glass }
4182e192b24SSimon Glass
do_cdp(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])4192e192b24SSimon Glass int do_cdp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
4202e192b24SSimon Glass {
4212e192b24SSimon Glass int r;
4222e192b24SSimon Glass
4232e192b24SSimon Glass r = net_loop(CDP);
4242e192b24SSimon Glass if (r < 0) {
4252e192b24SSimon Glass printf("cdp failed; perhaps not a CISCO switch?\n");
4262e192b24SSimon Glass return CMD_RET_FAILURE;
4272e192b24SSimon Glass }
4282e192b24SSimon Glass
4292e192b24SSimon Glass cdp_update_env();
4302e192b24SSimon Glass
4312e192b24SSimon Glass return CMD_RET_SUCCESS;
4322e192b24SSimon Glass }
4332e192b24SSimon Glass
4342e192b24SSimon Glass U_BOOT_CMD(
4352e192b24SSimon Glass cdp, 1, 1, do_cdp,
4362e192b24SSimon Glass "Perform CDP network configuration",
4372e192b24SSimon Glass "\n"
4382e192b24SSimon Glass );
4392e192b24SSimon Glass #endif
4402e192b24SSimon Glass
4412e192b24SSimon Glass #if defined(CONFIG_CMD_SNTP)
do_sntp(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])4422e192b24SSimon Glass int do_sntp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
4432e192b24SSimon Glass {
4442e192b24SSimon Glass char *toff;
4452e192b24SSimon Glass
4462e192b24SSimon Glass if (argc < 2) {
447723806ccSSimon Glass net_ntp_server = env_get_ip("ntpserverip");
4482e192b24SSimon Glass if (net_ntp_server.s_addr == 0) {
4492e192b24SSimon Glass printf("ntpserverip not set\n");
4502e192b24SSimon Glass return CMD_RET_FAILURE;
4512e192b24SSimon Glass }
4522e192b24SSimon Glass } else {
4532e192b24SSimon Glass net_ntp_server = string_to_ip(argv[1]);
4542e192b24SSimon Glass if (net_ntp_server.s_addr == 0) {
4552e192b24SSimon Glass printf("Bad NTP server IP address\n");
4562e192b24SSimon Glass return CMD_RET_FAILURE;
4572e192b24SSimon Glass }
4582e192b24SSimon Glass }
4592e192b24SSimon Glass
46000caae6dSSimon Glass toff = env_get("timeoffset");
4612e192b24SSimon Glass if (toff == NULL)
4622e192b24SSimon Glass net_ntp_time_offset = 0;
4632e192b24SSimon Glass else
4642e192b24SSimon Glass net_ntp_time_offset = simple_strtol(toff, NULL, 10);
4652e192b24SSimon Glass
4662e192b24SSimon Glass if (net_loop(SNTP) < 0) {
4672e192b24SSimon Glass printf("SNTP failed: host %pI4 not responding\n",
4682e192b24SSimon Glass &net_ntp_server);
4692e192b24SSimon Glass return CMD_RET_FAILURE;
4702e192b24SSimon Glass }
4712e192b24SSimon Glass
4722e192b24SSimon Glass return CMD_RET_SUCCESS;
4732e192b24SSimon Glass }
4742e192b24SSimon Glass
4752e192b24SSimon Glass U_BOOT_CMD(
4762e192b24SSimon Glass sntp, 2, 1, do_sntp,
4772e192b24SSimon Glass "synchronize RTC via network",
4782e192b24SSimon Glass "[NTP server IP]\n"
4792e192b24SSimon Glass );
4802e192b24SSimon Glass #endif
4812e192b24SSimon Glass
4822e192b24SSimon Glass #if defined(CONFIG_CMD_DNS)
do_dns(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])4832e192b24SSimon Glass int do_dns(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
4842e192b24SSimon Glass {
4852e192b24SSimon Glass if (argc == 1)
4862e192b24SSimon Glass return CMD_RET_USAGE;
4872e192b24SSimon Glass
4882e192b24SSimon Glass /*
4892e192b24SSimon Glass * We should check for a valid hostname:
4902e192b24SSimon Glass * - Each label must be between 1 and 63 characters long
4912e192b24SSimon Glass * - the entire hostname has a maximum of 255 characters
4922e192b24SSimon Glass * - only the ASCII letters 'a' through 'z' (case-insensitive),
4932e192b24SSimon Glass * the digits '0' through '9', and the hyphen
4942e192b24SSimon Glass * - cannot begin or end with a hyphen
4952e192b24SSimon Glass * - no other symbols, punctuation characters, or blank spaces are
4962e192b24SSimon Glass * permitted
4972e192b24SSimon Glass * but hey - this is a minimalist implmentation, so only check length
4982e192b24SSimon Glass * and let the name server deal with things.
4992e192b24SSimon Glass */
5002e192b24SSimon Glass if (strlen(argv[1]) >= 255) {
5012e192b24SSimon Glass printf("dns error: hostname too long\n");
5022e192b24SSimon Glass return CMD_RET_FAILURE;
5032e192b24SSimon Glass }
5042e192b24SSimon Glass
5052e192b24SSimon Glass net_dns_resolve = argv[1];
5062e192b24SSimon Glass
5072e192b24SSimon Glass if (argc == 3)
5082e192b24SSimon Glass net_dns_env_var = argv[2];
5092e192b24SSimon Glass else
5102e192b24SSimon Glass net_dns_env_var = NULL;
5112e192b24SSimon Glass
5122e192b24SSimon Glass if (net_loop(DNS) < 0) {
5132e192b24SSimon Glass printf("dns lookup of %s failed, check setup\n", argv[1]);
5142e192b24SSimon Glass return CMD_RET_FAILURE;
5152e192b24SSimon Glass }
5162e192b24SSimon Glass
5172e192b24SSimon Glass return CMD_RET_SUCCESS;
5182e192b24SSimon Glass }
5192e192b24SSimon Glass
5202e192b24SSimon Glass U_BOOT_CMD(
5212e192b24SSimon Glass dns, 3, 1, do_dns,
5222e192b24SSimon Glass "lookup the IP of a hostname",
5232e192b24SSimon Glass "hostname [envvar]"
5242e192b24SSimon Glass );
5252e192b24SSimon Glass
5262e192b24SSimon Glass #endif /* CONFIG_CMD_DNS */
5272e192b24SSimon Glass
5282e192b24SSimon Glass #if defined(CONFIG_CMD_LINK_LOCAL)
do_link_local(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])5292e192b24SSimon Glass static int do_link_local(cmd_tbl_t *cmdtp, int flag, int argc,
5302e192b24SSimon Glass char * const argv[])
5312e192b24SSimon Glass {
5322e192b24SSimon Glass char tmp[22];
5332e192b24SSimon Glass
5342e192b24SSimon Glass if (net_loop(LINKLOCAL) < 0)
5352e192b24SSimon Glass return CMD_RET_FAILURE;
5362e192b24SSimon Glass
5372e192b24SSimon Glass net_gateway.s_addr = 0;
5382e192b24SSimon Glass ip_to_string(net_gateway, tmp);
539382bee57SSimon Glass env_set("gatewayip", tmp);
5402e192b24SSimon Glass
5412e192b24SSimon Glass ip_to_string(net_netmask, tmp);
542382bee57SSimon Glass env_set("netmask", tmp);
5432e192b24SSimon Glass
5442e192b24SSimon Glass ip_to_string(net_ip, tmp);
545382bee57SSimon Glass env_set("ipaddr", tmp);
546382bee57SSimon Glass env_set("llipaddr", tmp); /* store this for next time */
5472e192b24SSimon Glass
5482e192b24SSimon Glass return CMD_RET_SUCCESS;
5492e192b24SSimon Glass }
5502e192b24SSimon Glass
5512e192b24SSimon Glass U_BOOT_CMD(
5522e192b24SSimon Glass linklocal, 1, 1, do_link_local,
5532e192b24SSimon Glass "acquire a network IP address using the link-local protocol",
5542e192b24SSimon Glass ""
5552e192b24SSimon Glass );
5562e192b24SSimon Glass
5572e192b24SSimon Glass #endif /* CONFIG_CMD_LINK_LOCAL */
558