net: fastboot: Merge AOSP UDP fastboot

Merge UDP fastboot support from AOSP:

  https://android.googlesource.com/platform/external/u-boot/+/android-o-mr1-iot-preview-8

Signed-off-by: Alex Kiernan <alex.kiernan@gmail.com>
Signed-off-by: Alex Deymo <deymo@google.com>
Signed-off-by: Jocelyn Bohr <bohr@google.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
diff --git a/drivers/fastboot/fb_common.c b/drivers/fastboot/fb_common.c
index 79e080a..c6e06aa 100644
--- a/drivers/fastboot/fb_common.c
+++ b/drivers/fastboot/fb_common.c
@@ -12,8 +12,24 @@
 
 #include <common.h>
 #include <fastboot.h>
+#include <net/fastboot.h>
 
 /**
+ * fastboot_buf_addr - base address of the fastboot download buffer
+ */
+void *fastboot_buf_addr;
+
+/**
+ * fastboot_buf_size - size of the fastboot download buffer
+ */
+u32 fastboot_buf_size;
+
+/**
+ * fastboot_progress_callback - callback executed during long operations
+ */
+void (*fastboot_progress_callback)(const char *msg);
+
+/**
  * fastboot_response() - Writes a response of the form "$tag$reason".
  *
  * @tag: The first part of the response
@@ -74,3 +90,80 @@
 {
 	return -ENOSYS;
 }
+
+/**
+ * fastboot_get_progress_callback() - Return progress callback
+ *
+ * Return: Pointer to function called during long operations
+ */
+void (*fastboot_get_progress_callback(void))(const char *)
+{
+	return fastboot_progress_callback;
+}
+
+/**
+ * fastboot_boot() - Execute fastboot boot command
+ *
+ * If ${fastboot_bootcmd} is set, run that command to execute the boot
+ * process, if that returns, then exit the fastboot server and return
+ * control to the caller.
+ *
+ * Otherwise execute "bootm <fastboot_buf_addr>", if that fails, reset
+ * the board.
+ */
+void fastboot_boot(void)
+{
+	char *s;
+
+	s = env_get("fastboot_bootcmd");
+	if (s) {
+		run_command(s, CMD_FLAG_ENV);
+	} else {
+		static char boot_addr_start[12];
+		static char *const bootm_args[] = {
+			"bootm", boot_addr_start, NULL
+		};
+
+		snprintf(boot_addr_start, sizeof(boot_addr_start) - 1,
+			 "0x%p", fastboot_buf_addr);
+		printf("Booting kernel at %s...\n\n\n", boot_addr_start);
+
+		do_bootm(NULL, 0, 2, bootm_args);
+
+		/*
+		 * This only happens if image is somehow faulty so we start
+		 * over. We deliberately leave this policy to the invocation
+		 * of fastbootcmd if that's what's being run
+		 */
+		do_reset(NULL, 0, 0, NULL);
+	}
+}
+
+/**
+ * fastboot_set_progress_callback() - set progress callback
+ *
+ * @progress: Pointer to progress callback
+ *
+ * Set a callback which is invoked periodically during long running operations
+ * (flash and erase). This can be used (for example) by the UDP transport to
+ * send INFO responses to keep the client alive whilst those commands are
+ * executing.
+ */
+void fastboot_set_progress_callback(void (*progress)(const char *msg))
+{
+	fastboot_progress_callback = progress;
+}
+
+/*
+ * fastboot_init() - initialise new fastboot protocol session
+ *
+ * @buf_addr: Pointer to download buffer, or NULL for default
+ * @buf_size: Size of download buffer, or zero for default
+ */
+void fastboot_init(void *buf_addr, u32 buf_size)
+{
+	fastboot_buf_addr = buf_addr ? buf_addr :
+				       (void *)CONFIG_FASTBOOT_BUF_ADDR;
+	fastboot_buf_size = buf_size ? buf_size : CONFIG_FASTBOOT_BUF_SIZE;
+	fastboot_set_progress_callback(NULL);
+}