]> git.ipfire.org Git - thirdparty/u-boot.git/blobdiff - cmd/net.c
Merge tag 'xilinx-for-v2024.07-rc1' of https://source.denx.de/u-boot/custodians/u...
[thirdparty/u-boot.git] / cmd / net.c
index d5e20843ddafa4d46b57a55f50855b1018b87c3c..d407d8320a3d84dcf445938eeaef41bced20cb9d 100644 (file)
--- a/cmd/net.c
+++ b/cmd/net.c
@@ -13,6 +13,7 @@
 #include <bootstage.h>
 #include <command.h>
 #include <dm.h>
+#include <dm/devres.h>
 #include <env.h>
 #include <image.h>
 #include <log.h>
@@ -111,6 +112,29 @@ U_BOOT_CMD(
 );
 #endif
 
+#if defined(CONFIG_CMD_DHCP6)
+static int do_dhcp6(struct cmd_tbl *cmdtp, int flag, int argc,
+                   char *const argv[])
+{
+       int i;
+       int dhcp_argc;
+       char *dhcp_argv[] = {NULL, NULL, NULL, NULL};
+
+       /* Add -ipv6 flag for autoload */
+       for (i = 0; i < argc; i++)
+               dhcp_argv[i] = argv[i];
+       dhcp_argc = argc + 1;
+       dhcp_argv[dhcp_argc - 1] =  USE_IP6_CMD_PARAM;
+
+       return netboot_common(DHCP6, cmdtp, dhcp_argc, dhcp_argv);
+}
+
+U_BOOT_CMD(dhcp6,      3,      1,      do_dhcp6,
+          "boot image via network using DHCPv6/TFTP protocol.\n"
+          "Use IPv6 hostIPaddr framed with [] brackets",
+          "[loadAddress] [[hostIPaddr:]bootfilename]");
+#endif
+
 #if defined(CONFIG_CMD_DHCP)
 static int do_dhcp(struct cmd_tbl *cmdtp, int flag, int argc,
                   char *const argv[])
@@ -186,7 +210,7 @@ U_BOOT_CMD(
 
 static void netboot_update_env(void)
 {
-       char tmp[22];
+       char tmp[46];
 
        if (net_gateway.s_addr) {
                ip_to_string(net_gateway, tmp);
@@ -247,6 +271,27 @@ static void netboot_update_env(void)
                env_set("ntpserverip", tmp);
        }
 #endif
+
+       if (IS_ENABLED(CONFIG_IPV6)) {
+               if (!ip6_is_unspecified_addr(&net_ip6) ||
+                   net_prefix_length != 0) {
+                       if (net_prefix_length != 0)
+                               snprintf(tmp, sizeof(tmp), "%pI6c/%d", &net_ip6, net_prefix_length);
+                       else
+                               snprintf(tmp, sizeof(tmp), "%pI6c", &net_ip6);
+                       env_set("ip6addr", tmp);
+               }
+
+               if (!ip6_is_unspecified_addr(&net_server_ip6)) {
+                       snprintf(tmp, sizeof(tmp), "%pI6c", &net_server_ip6);
+                       env_set("serverip6", tmp);
+               }
+
+               if (!ip6_is_unspecified_addr(&net_gateway6)) {
+                       snprintf(tmp, sizeof(tmp), "%pI6c", &net_gateway6);
+                       env_set("gatewayip6", tmp);
+               }
+       }
 }
 
 /**
@@ -647,8 +692,58 @@ static int do_net_list(struct cmd_tbl *cmdtp, int flag, int argc, char *const ar
        return CMD_RET_SUCCESS;
 }
 
+static int do_net_stats(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+       int nstats, err, i, off;
+       struct udevice *dev;
+       u64 *values;
+       u8 *strings;
+
+       if (argc < 2)
+               return CMD_RET_USAGE;
+
+       err = uclass_get_device_by_name(UCLASS_ETH, argv[1], &dev);
+       if (err) {
+               printf("Could not find device %s\n", argv[1]);
+               return CMD_RET_FAILURE;
+       }
+
+       if (!eth_get_ops(dev)->get_sset_count ||
+           !eth_get_ops(dev)->get_strings ||
+           !eth_get_ops(dev)->get_stats) {
+               printf("Driver does not implement stats dump!\n");
+               return CMD_RET_FAILURE;
+       }
+
+       nstats = eth_get_ops(dev)->get_sset_count(dev);
+       strings = kcalloc(nstats, ETH_GSTRING_LEN, GFP_KERNEL);
+       if (!strings)
+               return CMD_RET_FAILURE;
+
+       values = kcalloc(nstats, sizeof(u64), GFP_KERNEL);
+       if (!values)
+               goto err_free_strings;
+
+       eth_get_ops(dev)->get_strings(dev, strings);
+       eth_get_ops(dev)->get_stats(dev, values);
+
+       off = 0;
+       for (i = 0; i < nstats; i++) {
+               printf("  %s: %llu\n", &strings[off], values[i]);
+               off += ETH_GSTRING_LEN;
+       };
+
+       return CMD_RET_SUCCESS;
+
+err_free_strings:
+       kfree(strings);
+
+       return CMD_RET_FAILURE;
+}
+
 static struct cmd_tbl cmd_net[] = {
        U_BOOT_CMD_MKENT(list, 1, 0, do_net_list, "", ""),
+       U_BOOT_CMD_MKENT(stats, 2, 0, do_net_stats, "", ""),
 };
 
 static int do_net(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
@@ -670,9 +765,10 @@ static int do_net(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
 }
 
 U_BOOT_CMD(
-       net, 2, 1, do_net,
+       net, 3, 1, do_net,
        "NET sub-system",
        "list - list available devices\n"
+       "stats <device> - dump statistics for specified device\n"
 );
 
 #if defined(CONFIG_CMD_NCSI)