// SPDX-License-Identifier: GPL-2.0+
/*
 * dfu.c -- DFU back-end routines
 *
 * Copyright (C) 2012 Samsung Electronics
 * author: Lukasz Majewski <l.majewski@samsung.com>
 */

#include <env.h>
#include <errno.h>
#include <log.h>
#include <malloc.h>
#include <mmc.h>
#include <fat.h>
#include <dfu.h>
#include <hash.h>
#include <linux/list.h>
#include <linux/compiler.h>
#include <linux/printk.h>

LIST_HEAD(dfu_list);
static int dfu_alt_num;
static int alt_num_cnt;
static struct hash_algo *dfu_hash_algo;
#ifdef CONFIG_DFU_TIMEOUT
static unsigned long dfu_timeout = 0;
#endif

bool dfu_reinit_needed = false;

/*
 * The purpose of the dfu_flush_callback() function is to
 * provide callback for dfu user
 */
__weak void dfu_flush_callback(struct dfu_entity *dfu)
{
}

/*
 * The purpose of the dfu_initiated_callback() function is to
 * provide callback for dfu user
 */
__weak void dfu_initiated_callback(struct dfu_entity *dfu)
{
}

/*
 * The purpose of the dfu_error_callback() function is to
 * provide callback for dfu user
 */
__weak void dfu_error_callback(struct dfu_entity *dfu, const char *msg)
{
}

/*
 * The purpose of the dfu_usb_get_reset() function is to
 * provide information if after USB_DETACH request
 * being sent the dfu-util performed reset of USB
 * bus.
 *
 * Described behaviour is the only way to distinct if
 * user has typed -e (detach) or -R (reset) when invoking
 * dfu-util command.
 *
 */
__weak bool dfu_usb_get_reset(void)
{
#ifdef CONFIG_SPL_DFU_NO_RESET
	return false;
#else
	return true;
#endif
}

#ifdef CONFIG_DFU_TIMEOUT
void dfu_set_timeout(unsigned long timeout)
{
	dfu_timeout = timeout;
}

unsigned long dfu_get_timeout(void)
{
	return dfu_timeout;
}
#endif

static int dfu_find_alt_num(const char *s)
{
	int i = 0;

	for (; *s; s++)
		if (*s == ';')
			i++;

	return ++i;
}

/*
 * treat dfu_alt_info with several interface information
 * to allow DFU on several device with one command,
 * the string format is
 * interface devstring'='alternate list (';' separated)
 * and each interface separated by '&'
 */
int dfu_config_interfaces(char *env)
{
	struct dfu_entity *dfu;
	char *s, *i, *d, *a, *part;
	int ret = -EINVAL;
	int n = 1;

	s = env;
	for (; *s; s++) {
		if (*s == ';')
			n++;
		if (*s == '&')
			n++;
	}
	ret = dfu_alt_init(n, &dfu);
	if (ret)
		return ret;

	s = env;
	while (s) {
		ret = -EINVAL;
		i = strsep(&s, " \t");
		if (!i)
			break;
		s = skip_spaces(s);
		d = strsep(&s, "=");
		if (!d)
			break;
		a = strsep(&s, "&");
		if (!a)
			a = s;
		do {
			part = strsep(&a, ";");
			part = skip_spaces(part);
			ret = dfu_alt_add(dfu, i, d, part);
			if (ret)
				return ret;
		} while (a);
	}

	return ret;
}

int dfu_init_env_entities(char *interface, char *devstr)
{
	const char *str_env;
	char *env_bkp;
	int ret = 0;

	dfu_reinit_needed = false;

#ifdef CONFIG_SET_DFU_ALT_INFO
	set_dfu_alt_info(interface, devstr);
#endif
	str_env = env_get("dfu_alt_info");
	if (!str_env) {
		pr_err("\"dfu_alt_info\" env variable not defined!\n");
		return -EINVAL;
	}

	env_bkp = strdup(str_env);
	if (!interface && !devstr)
		ret = dfu_config_interfaces(env_bkp);
	else
		ret = dfu_config_entities(env_bkp, interface, devstr);

	if (ret) {
		pr_err("DFU entities configuration failed!\n");
		pr_err("(partition table does not match dfu_alt_info?)\n");
		goto done;
	}

done:
	free(env_bkp);
	return ret;
}

static unsigned char *dfu_buf;
static unsigned long dfu_buf_size;
static enum dfu_device_type dfu_buf_device_type;

unsigned char *dfu_free_buf(void)
{
	free(dfu_buf);
	dfu_buf = NULL;
	return dfu_buf;
}

unsigned long dfu_get_buf_size(void)
{
	return dfu_buf_size;
}

unsigned char *dfu_get_buf(struct dfu_entity *dfu)
{
	char *s;

	/* manage several entity with several contraint */
	if (dfu_buf && dfu->dev_type != dfu_buf_device_type)
		dfu_free_buf();

	if (dfu_buf != NULL)
		return dfu_buf;

	s = env_get("dfu_bufsiz");
	if (s)
		dfu_buf_size = (unsigned long)simple_strtol(s, NULL, 0);

	if (!s || !dfu_buf_size)
		dfu_buf_size = CONFIG_SYS_DFU_DATA_BUF_SIZE;

	if (dfu->max_buf_size && dfu_buf_size > dfu->max_buf_size)
		dfu_buf_size = dfu->max_buf_size;

	dfu_buf = memalign(CONFIG_SYS_CACHELINE_SIZE, dfu_buf_size);
	if (dfu_buf == NULL)
		printf("%s: Could not memalign 0x%lx bytes\n",
		       __func__, dfu_buf_size);

	dfu_buf_device_type = dfu->dev_type;
	return dfu_buf;
}

static char *dfu_get_hash_algo(void)
{
	char *s;

	s = env_get("dfu_hash_algo");
	if (!s)
		return NULL;

	if (!strcmp(s, "crc32")) {
		debug("%s: DFU hash method: %s\n", __func__, s);
		return s;
	}

	pr_err("DFU hash method: %s not supported!\n", s);
	return NULL;
}

static int dfu_write_buffer_drain(struct dfu_entity *dfu)
{
	long w_size;
	int ret;

	/* flush size? */
	w_size = dfu->i_buf - dfu->i_buf_start;
	if (w_size == 0)
		return 0;

	if (dfu_hash_algo)
		dfu_hash_algo->hash_update(dfu_hash_algo, &dfu->crc,
					   dfu->i_buf_start, w_size, 0);

	ret = dfu->write_medium(dfu, dfu->offset, dfu->i_buf_start, &w_size);
	if (ret)
		debug("%s: Write error!\n", __func__);

	/* point back */
	dfu->i_buf = dfu->i_buf_start;

	/* update offset */
	dfu->offset += w_size;

	puts("#");

	return ret;
}

void dfu_transaction_cleanup(struct dfu_entity *dfu)
{
	/* clear everything */
	dfu->crc = 0;
	dfu->offset = 0;
	dfu->i_blk_seq_num = 0;
	dfu->i_buf_start = dfu_get_buf(dfu);
	dfu->i_buf_end = dfu->i_buf_start;
	dfu->i_buf = dfu->i_buf_start;
	dfu->r_left = 0;
	dfu->b_left = 0;
	dfu->bad_skip = 0;

	dfu->inited = 0;
}

int dfu_transaction_initiate(struct dfu_entity *dfu, bool read)
{
	int ret = 0;

	if (dfu->inited)
		return 0;

	dfu_transaction_cleanup(dfu);

	if (dfu->i_buf_start == NULL)
		return -ENOMEM;

	dfu->i_buf_end = dfu->i_buf_start + dfu_get_buf_size();

	if (read) {
		ret = dfu->get_medium_size(dfu, &dfu->r_left);
		if (ret < 0)
			return ret;
		debug("%s: %s %lld [B]\n", __func__, dfu->name, dfu->r_left);
	}

	dfu->inited = 1;
	dfu_initiated_callback(dfu);

	return 0;
}

int dfu_flush(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
{
	int ret = 0;

	ret = dfu_write_buffer_drain(dfu);
	if (ret)
		return ret;

	if (dfu->flush_medium)
		ret = dfu->flush_medium(dfu);

	if (dfu_hash_algo)
		printf("\nDFU complete %s: 0x%08x\n", dfu_hash_algo->name,
		       dfu->crc);

	dfu_flush_callback(dfu);

	dfu_transaction_cleanup(dfu);

	return ret;
}

int dfu_write(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
{
	int ret;

	debug("%s: name: %s buf: 0x%p size: 0x%x p_num: 0x%x offset: 0x%llx bufoffset: 0x%lx\n",
	      __func__, dfu->name, buf, size, blk_seq_num, dfu->offset,
	      (unsigned long)(dfu->i_buf - dfu->i_buf_start));

	ret = dfu_transaction_initiate(dfu, false);
	if (ret < 0)
		return ret;

	if (dfu->i_blk_seq_num != blk_seq_num) {
		printf("%s: Wrong sequence number! [%d] [%d]\n",
		       __func__, dfu->i_blk_seq_num, blk_seq_num);
		dfu_transaction_cleanup(dfu);
		dfu_error_callback(dfu, "Wrong sequence number");
		return -1;
	}

	/* DFU 1.1 standard says:
	 * The wBlockNum field is a block sequence number. It increments each
	 * time a block is transferred, wrapping to zero from 65,535. It is used
	 * to provide useful context to the DFU loader in the device."
	 *
	 * This means that it's a 16 bit counter that roll-overs at
	 * 0xffff -> 0x0000. By having a typical 4K transfer block
	 * we roll-over at exactly 256MB. Not very fun to debug.
	 *
	 * Handling rollover, and having an inited variable,
	 * makes things work.
	 */

	/* handle rollover */
	dfu->i_blk_seq_num = (dfu->i_blk_seq_num + 1) & 0xffff;

	/* flush buffer if overflow */
	if ((dfu->i_buf + size) > dfu->i_buf_end) {
		ret = dfu_write_buffer_drain(dfu);
		if (ret) {
			dfu_transaction_cleanup(dfu);
			dfu_error_callback(dfu, "DFU write error");
			return ret;
		}
	}

	/* we should be in buffer now (if not then size too large) */
	if ((dfu->i_buf + size) > dfu->i_buf_end) {
		pr_err("Buffer overflow! (0x%p + 0x%x > 0x%p)\n", dfu->i_buf,
		      size, dfu->i_buf_end);
		dfu_transaction_cleanup(dfu);
		dfu_error_callback(dfu, "Buffer overflow");
		return -1;
	}

	memcpy(dfu->i_buf, buf, size);
	dfu->i_buf += size;

	/* if end or if buffer full flush */
	if (size == 0 || (dfu->i_buf + size) > dfu->i_buf_end) {
		ret = dfu_write_buffer_drain(dfu);
		if (ret) {
			dfu_transaction_cleanup(dfu);
			dfu_error_callback(dfu, "DFU write error");
			return ret;
		}
	}

	return 0;
}

static int dfu_read_buffer_fill(struct dfu_entity *dfu, void *buf, int size)
{
	long chunk;
	int ret, readn;

	readn = 0;
	while (size > 0) {
		/* get chunk that can be read */
		chunk = min((long)size, dfu->b_left);
		/* consume */
		if (chunk > 0) {
			memcpy(buf, dfu->i_buf, chunk);
			if (dfu_hash_algo)
				dfu_hash_algo->hash_update(dfu_hash_algo,
							   &dfu->crc, buf,
							   chunk, 0);

			dfu->i_buf += chunk;
			dfu->b_left -= chunk;
			size -= chunk;
			buf += chunk;
			readn += chunk;
		}

		/* all done */
		if (size > 0) {
			/* no more to read */
			if (dfu->r_left == 0)
				break;

			dfu->i_buf = dfu->i_buf_start;
			dfu->b_left = dfu->i_buf_end - dfu->i_buf_start;

			/* got to read, but buffer is empty */
			if (dfu->b_left > dfu->r_left)
				dfu->b_left = dfu->r_left;
			ret = dfu->read_medium(dfu, dfu->offset, dfu->i_buf,
					&dfu->b_left);
			if (ret != 0) {
				debug("%s: Read error!\n", __func__);
				return ret;
			}
			if (dfu->b_left == 0)
				break;
			dfu->offset += dfu->b_left;
			dfu->r_left -= dfu->b_left;

			puts("#");
		}
	}

	return readn;
}

int dfu_read(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
{
	int ret = 0;

	debug("%s: name: %s buf: 0x%p size: 0x%x p_num: 0x%x i_buf: 0x%p\n",
	       __func__, dfu->name, buf, size, blk_seq_num, dfu->i_buf);

	ret = dfu_transaction_initiate(dfu, true);
	if (ret < 0)
		return ret;

	if (dfu->i_blk_seq_num != blk_seq_num) {
		printf("%s: Wrong sequence number! [%d] [%d]\n",
		       __func__, dfu->i_blk_seq_num, blk_seq_num);
		return -1;
	}
	/* handle rollover */
	dfu->i_blk_seq_num = (dfu->i_blk_seq_num + 1) & 0xffff;

	ret = dfu_read_buffer_fill(dfu, buf, size);
	if (ret < 0) {
		printf("%s: Failed to fill buffer\n", __func__);
		return -1;
	}

	if (ret < size) {
		if (dfu_hash_algo)
			debug("%s: %s %s: 0x%x\n", __func__, dfu->name,
			      dfu_hash_algo->name, dfu->crc);
		puts("\nUPLOAD ... done\nCtrl+C to exit ...\n");

		dfu_transaction_cleanup(dfu);
	}

	return ret;
}

static int dfu_fill_entity(struct dfu_entity *dfu, char *s, int alt,
			   char *interface, char *devstr)
{
	char *argv[DFU_MAX_ENTITY_ARGS];
	int argc;
	char *st;

	debug("%s: %s interface: %s dev: %s\n", __func__, s, interface, devstr);
	st = strsep(&s, " \t");
	strlcpy(dfu->name, st, DFU_NAME_SIZE);

	/* Parse arguments */
	for (argc = 0; s && argc < DFU_MAX_ENTITY_ARGS; argc++) {
		s = skip_spaces(s);
		if (!*s)
			break;
		argv[argc] = strsep(&s, " \t");
	}

	if (argc == DFU_MAX_ENTITY_ARGS && s) {
		s = skip_spaces(s);
		if (*s) {
			log_err("Too many arguments for %s\n", dfu->name);
			return -EINVAL;
		}
	}

	dfu->alt = alt;
	dfu->max_buf_size = 0;
	dfu->free_entity = NULL;

	/* Specific for mmc device */
	if (strcmp(interface, "mmc") == 0) {
		if (dfu_fill_entity_mmc(dfu, devstr, argv, argc))
			return -1;
	} else if (strcmp(interface, "mtd") == 0) {
		if (dfu_fill_entity_mtd(dfu, devstr, argv, argc))
			return -1;
	} else if (strcmp(interface, "nand") == 0) {
		if (dfu_fill_entity_nand(dfu, devstr, argv, argc))
			return -1;
	} else if (strcmp(interface, "ram") == 0) {
		if (dfu_fill_entity_ram(dfu, devstr, argv, argc))
			return -1;
	} else if (strcmp(interface, "sf") == 0) {
		if (dfu_fill_entity_sf(dfu, devstr, argv, argc))
			return -1;
	} else if (strcmp(interface, "virt") == 0) {
		if (dfu_fill_entity_virt(dfu, devstr, argv, argc))
			return -1;
	} else {
		printf("%s: Device %s not (yet) supported!\n",
		       __func__,  interface);
		return -1;
	}
	dfu_get_buf(dfu);

	return 0;
}

void dfu_free_entities(void)
{
	struct dfu_entity *dfu, *p, *t = NULL;

	dfu_free_buf();
	list_for_each_entry_safe_reverse(dfu, p, &dfu_list, list) {
		list_del(&dfu->list);
		if (dfu->free_entity)
			dfu->free_entity(dfu);
		t = dfu;
	}
	if (t)
		free(t);
	INIT_LIST_HEAD(&dfu_list);

	alt_num_cnt = 0;
}

int dfu_alt_init(int num, struct dfu_entity **dfu)
{
	char *s;
	int ret;

	dfu_alt_num = num;
	debug("%s: dfu_alt_num=%d\n", __func__, dfu_alt_num);

	dfu_hash_algo = NULL;
	s = dfu_get_hash_algo();
	if (s) {
		ret = hash_lookup_algo(s, &dfu_hash_algo);
		if (ret)
			pr_err("Hash algorithm %s not supported\n", s);
	}

	*dfu = calloc(sizeof(struct dfu_entity), dfu_alt_num);
	if (!*dfu)
		return -1;

	return 0;
}

int dfu_alt_add(struct dfu_entity *dfu, char *interface, char *devstr, char *s)
{
	struct dfu_entity *p_dfu;
	int ret;

	if (alt_num_cnt >= dfu_alt_num)
		return -1;

	p_dfu = &dfu[alt_num_cnt];
	ret = dfu_fill_entity(p_dfu, s, alt_num_cnt, interface, devstr);
	if (ret)
		return -1;

	list_add_tail(&p_dfu->list, &dfu_list);
	alt_num_cnt++;

	return 0;
}

int dfu_config_entities(char *env, char *interface, char *devstr)
{
	struct dfu_entity *dfu;
	int i, ret;
	char *s;

	ret = dfu_alt_init(dfu_find_alt_num(env), &dfu);
	if (ret)
		return -1;

	for (i = 0; i < dfu_alt_num; i++) {
		s = strsep(&env, ";");
		s = skip_spaces(s);
		ret = dfu_alt_add(dfu, interface, devstr, s);
		if (ret) {
			/* We will free "dfu" in dfu_free_entities() */
			return -1;
		}
	}

	return 0;
}

const char *dfu_get_dev_type(enum dfu_device_type t)
{
	const char *const dev_t[] = {NULL, "eMMC", "OneNAND", "NAND", "RAM",
				     "SF", "MTD", "VIRT"};
	return dev_t[t];
}

const char *dfu_get_layout(enum dfu_layout l)
{
	const char *const dfu_layout[] = {NULL, "RAW_ADDR", "FAT", "EXT2",
					  "EXT3", "EXT4", "RAM_ADDR", "SKIP",
					  "SCRIPT" };
	return dfu_layout[l];
}

void dfu_show_entities(void)
{
	struct dfu_entity *dfu;

	puts("DFU alt settings list:\n");

	list_for_each_entry(dfu, &dfu_list, list) {
		printf("dev: %s alt: %d name: %s layout: %s\n",
		       dfu_get_dev_type(dfu->dev_type), dfu->alt,
		       dfu->name, dfu_get_layout(dfu->layout));
	}
}

int dfu_get_alt_number(void)
{
	return dfu_alt_num;
}

struct dfu_entity *dfu_get_entity(int alt)
{
	struct dfu_entity *dfu;

	list_for_each_entry(dfu, &dfu_list, list) {
		if (dfu->alt == alt)
			return dfu;
	}

	return NULL;
}

int dfu_get_alt(char *name)
{
	struct dfu_entity *dfu;
	char *str;

	list_for_each_entry(dfu, &dfu_list, list) {
		if (dfu->name[0] != '/') {
			if (!strncmp(dfu->name, name, strlen(dfu->name)))
				return dfu->alt;
		} else {
			/*
			 * One must also consider absolute path
			 * (/boot/bin/uImage) available at dfu->name when
			 * compared "plain" file name (uImage)
			 *
			 * It is the case for e.g. thor gadget where lthor SW
			 * sends only the file name, so only the very last part
			 * of path must be checked for equality
			 */

			str = strstr(dfu->name, name);
			if (!str)
				continue;

			/*
			 * Check if matching substring is the last element of
			 * dfu->name (uImage)
			 */
			if (strlen(dfu->name) ==
			    ((str - dfu->name) + strlen(name)))
				return dfu->alt;
		}
	}

	return -ENODEV;
}

int dfu_write_from_mem_addr(struct dfu_entity *dfu, void *buf, int size)
{
	unsigned long dfu_buf_size, write, left = size;
	int i, ret = 0;
	void *dp = buf;

	/*
	 * Here we must call dfu_get_buf(dfu) first to be sure that dfu_buf_size
	 * has been properly initialized - e.g. if "dfu_bufsiz" has been taken
	 * into account.
	 */
	dfu_get_buf(dfu);
	dfu_buf_size = dfu_get_buf_size();
	debug("%s: dfu buf size: %lu\n", __func__, dfu_buf_size);

	for (i = 0; left > 0; i++) {
		write = min(dfu_buf_size, left);

		debug("%s: dp: 0x%p left: %lu write: %lu\n", __func__,
		      dp, left, write);
		ret = dfu_write(dfu, dp, write, i);
		if (ret) {
			pr_err("DFU write failed\n");
			return ret;
		}

		dp += write;
		left -= write;
	}

	ret = dfu_flush(dfu, NULL, 0, i);
	if (ret)
		pr_err("DFU flush failed!");
	puts("\n");

	return ret;
}
