Add a new netboot_run() function which can be used for simple network
operations, such as loading a file. Put the implementation in an
internal function, used by the existing code.

Place this function into the net/ code, so that it does not need the
command line to be available.

Document which network operations are supported, i.e. a limited subset,
for now.

For the one board which uses lwip, it is not quite clear how to avoid
using the cmdline interface. This will need some discussion.

Signed-off-by: Simon Glass <s...@chromium.org>
---

Changes in v5:
- Split off the first part into a separate series

 cmd/net.c            | 40 +---------------------------------------
 include/net-common.h | 30 ++++++++++++++++++++++++++++++
 net/net.c            | 44 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 75 insertions(+), 39 deletions(-)

diff --git a/cmd/net.c b/cmd/net.c
index 6d1c6374f76..8f33c9f55d5 100644
--- a/cmd/net.c
+++ b/cmd/net.c
@@ -382,44 +382,6 @@ static int parse_args(enum proto_t proto, int argc, char 
*const argv[],
        return 0;
 }
 
-static int netboot_run_(enum proto_t proto, ulong addr, const char *fname,
-                       ulong size, bool fname_explicit, bool ipv6)
-{
-       int ret;
-
-       bootstage_mark(BOOTSTAGE_ID_NET_START);
-
-       /*
-        * For now we use the global variables as that is the only way to
-        * control the network stack. At some point, perhaps, the state could be
-        * in a struct
-        */
-       if (IS_ENABLED(CONFIG_CMD_TFTPPUT) && proto == TFTPPUT)
-               image_save_addr = addr;
-       else
-               image_load_addr = addr;
-
-       net_boot_file_name_explicit = fname_explicit;
-       copy_filename(net_boot_file_name, fname, sizeof(net_boot_file_name));
-       if (IS_ENABLED(CONFIG_IPV6))
-               use_ip6 = ipv6;
-       if (IS_ENABLED(CONFIG_CMD_TFTPPUT) && proto == TFTPPUT) {
-               image_save_addr = addr;
-               image_save_size = size;
-       } else {
-               image_load_addr = addr;
-       }
-
-       ret = net_loop(proto);
-       if (ret < 0) {
-               bootstage_error(BOOTSTAGE_ID_NET_NETLOOP_OK);
-               return ret;
-       }
-       bootstage_mark(BOOTSTAGE_ID_NET_NETLOOP_OK);
-
-       return 0;
-}
-
 static int netboot_common(enum proto_t proto, struct cmd_tbl *cmdtp, int argc,
                          char *const argv[])
 {
@@ -475,7 +437,7 @@ static int netboot_common(enum proto_t proto, struct 
cmd_tbl *cmdtp, int argc,
        }
 
        size = netboot_run_(proto, addr, fname, save_size, fname_explicit,
-                           use_ip6);
+                           IS_ENABLED(CONFIG_IPV6) && use_ip6);
        if (size < 0)
                return CMD_RET_FAILURE;
 
diff --git a/include/net-common.h b/include/net-common.h
index 29d31f37263..210042fc337 100644
--- a/include/net-common.h
+++ b/include/net-common.h
@@ -474,6 +474,36 @@ int net_init(void);
 enum proto_t;
 int net_loop(enum proto_t protocol);
 
+/* internal function: do not use! */
+int netboot_run_(enum proto_t proto, ulong addr, const char *fname, ulong size,
+                bool fname_explicit, bool ipv6);
+
+/**
+ * netboot_run() - Run a network operation
+ *
+ * The following proto values are NOT supported:
+ *     PING, since net_ping_ip cannot be set
+ *     NETCONS, since its parameters cannot bet set
+ *     RS, since first_call cannot be set, along with perhaps other things
+ *     UDP, since udp_ops cannot be set
+ *     DNS, since net_dns_resolve and net_dns_env_var cannot be set
+ *     WGET, since DNS must be done first and that is not supported
+ *     DHCP6, since the required parameters cannot be passed in
+ *
+ * To support one of these, either add the required arguments or perhaps a
+ * separate function and a struct to hold the information.
+ *
+ * @proto: Operation to run: TFTPGET, FASTBOOT_UDP, FASTBOOT_TCP, BOOTP,
+ *     TFTPPUT, RARP, NFS, DHCP
+ * @addr: Load/save address
+ * @fname: Filename
+ * @size: Save size (not used for TFTPGET)
+ * @ipv6: true to use IPv6, false to use IPv4
+ * Return 0 on success, else -ve error code
+ */
+int netboot_run(enum proto_t proto, ulong addr, const char *fname, ulong size,
+               bool ipv6);
+
 /**
  * dhcp_run() - Run DHCP on the current ethernet device
  *
diff --git a/net/net.c b/net/net.c
index 1828f1cca36..ef97377cdec 100644
--- a/net/net.c
+++ b/net/net.c
@@ -775,6 +775,50 @@ done:
        return ret;
 }
 
+int netboot_run_(enum proto_t proto, ulong addr, const char *fname, ulong size,
+                bool fname_explicit, bool ipv6)
+{
+       int ret;
+
+       bootstage_mark(BOOTSTAGE_ID_NET_START);
+
+       /*
+        * For now we use the global variables as that is the only way to
+        * control the network stack. At some point, perhaps, the state could be
+        * in a struct
+        */
+       if (IS_ENABLED(CONFIG_CMD_TFTPPUT) && proto == TFTPPUT)
+               image_save_addr = addr;
+       else
+               image_load_addr = addr;
+
+       net_boot_file_name_explicit = fname_explicit;
+       copy_filename(net_boot_file_name, fname, sizeof(net_boot_file_name));
+       if (IS_ENABLED(CONFIG_IPV6))
+               use_ip6 = ipv6;
+       if (IS_ENABLED(CONFIG_CMD_TFTPPUT) && proto == TFTPPUT) {
+               image_save_addr = addr;
+               image_save_size = size;
+       } else {
+               image_load_addr = addr;
+       }
+
+       ret = net_loop(proto);
+       if (ret < 0) {
+               bootstage_error(BOOTSTAGE_ID_NET_NETLOOP_OK);
+               return ret;
+       }
+       bootstage_mark(BOOTSTAGE_ID_NET_NETLOOP_OK);
+
+       return 0;
+}
+
+int netboot_run(enum proto_t proto, ulong addr, const char *fname, ulong size,
+               bool ipv6)
+{
+       return netboot_run_(proto, addr, fname, size, true, ipv6);
+}
+
 /**********************************************************************/
 
 static void start_again_timeout_handler(void)
-- 
2.43.0

Reply via email to