// 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 <common.h>
#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>

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_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, " ");
		if (!i)
			break;
		d = strsep(&s, "=");
		if (!d)
			break;
		a = strsep(&s, "&");
		if (!a)
			a = s;
		do {
			part = strsep(&a, ";");
			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);
		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);
			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);
		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);
			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 *st;

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

	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, s))
			return -1;
	} else if (strcmp(interface, "mtd") == 0) {
		if (dfu_fill_entity_mtd(dfu, devstr, s))
			return -1;
	} else if (strcmp(interface, "nand") == 0) {
		if (dfu_fill_entity_nand(dfu, devstr, s))
			return -1;
	} else if (strcmp(interface, "ram") == 0) {
		if (dfu_fill_entity_ram(dfu, devstr, s))
			return -1;
	} else if (strcmp(interface, "sf") == 0) {
		if (dfu_fill_entity_sf(dfu, devstr, s))
			return -1;
	} else if (strcmp(interface, "virt") == 0) {
		if (dfu_fill_entity_virt(dfu, devstr, s))
			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, ";");
		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!");

	return ret;
}
