// SPDX-License-Identifier: GPL-2.0
/*
 * NVM helpers
 *
 * Copyright (C) 2020, Intel Corporation
 * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
 */

#include <linux/idr.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>

#include "tb.h"

#define NVM_MIN_SIZE		SZ_32K
#define NVM_MAX_SIZE		SZ_1M
#define NVM_DATA_DWORDS		16

/* Intel specific NVM offsets */
#define INTEL_NVM_DEVID			0x05
#define INTEL_NVM_VERSION		0x08
#define INTEL_NVM_CSS			0x10
#define INTEL_NVM_FLASH_SIZE		0x45

/* ASMedia specific NVM offsets */
#define ASMEDIA_NVM_DATE		0x1c
#define ASMEDIA_NVM_VERSION		0x28

static DEFINE_IDA(nvm_ida);

/**
 * struct tb_nvm_vendor_ops - Vendor specific NVM operations
 * @read_version: Reads out NVM version from the flash
 * @validate: Validates the NVM image before update (optional)
 * @write_headers: Writes headers before the rest of the image (optional)
 */
struct tb_nvm_vendor_ops {
	int (*read_version)(struct tb_nvm *nvm);
	int (*validate)(struct tb_nvm *nvm);
	int (*write_headers)(struct tb_nvm *nvm);
};

/**
 * struct tb_nvm_vendor - Vendor to &struct tb_nvm_vendor_ops mapping
 * @vendor: Vendor ID
 * @vops: Vendor specific NVM operations
 *
 * Maps vendor ID to NVM vendor operations. If there is no mapping then
 * NVM firmware upgrade is disabled for the device.
 */
struct tb_nvm_vendor {
	u16 vendor;
	const struct tb_nvm_vendor_ops *vops;
};

static int intel_switch_nvm_version(struct tb_nvm *nvm)
{
	struct tb_switch *sw = tb_to_switch(nvm->dev);
	u32 val, nvm_size, hdr_size;
	int ret;

	/*
	 * If the switch is in safe-mode the only accessible portion of
	 * the NVM is the non-active one where userspace is expected to
	 * write new functional NVM.
	 */
	if (sw->safe_mode)
		return 0;

	ret = tb_switch_nvm_read(sw, INTEL_NVM_FLASH_SIZE, &val, sizeof(val));
	if (ret)
		return ret;

	hdr_size = sw->generation < 3 ? SZ_8K : SZ_16K;
	nvm_size = (SZ_1M << (val & 7)) / 8;
	nvm_size = (nvm_size - hdr_size) / 2;

	ret = tb_switch_nvm_read(sw, INTEL_NVM_VERSION, &val, sizeof(val));
	if (ret)
		return ret;

	nvm->major = (val >> 16) & 0xff;
	nvm->minor = (val >> 8) & 0xff;
	nvm->active_size = nvm_size;

	return 0;
}

static int intel_switch_nvm_validate(struct tb_nvm *nvm)
{
	struct tb_switch *sw = tb_to_switch(nvm->dev);
	unsigned int image_size, hdr_size;
	u16 ds_size, device_id;
	u8 *buf = nvm->buf;

	image_size = nvm->buf_data_size;

	/*
	 * FARB pointer must point inside the image and must at least
	 * contain parts of the digital section we will be reading here.
	 */
	hdr_size = (*(u32 *)buf) & 0xffffff;
	if (hdr_size + INTEL_NVM_DEVID + 2 >= image_size)
		return -EINVAL;

	/* Digital section start should be aligned to 4k page */
	if (!IS_ALIGNED(hdr_size, SZ_4K))
		return -EINVAL;

	/*
	 * Read digital section size and check that it also fits inside
	 * the image.
	 */
	ds_size = *(u16 *)(buf + hdr_size);
	if (ds_size >= image_size)
		return -EINVAL;

	if (sw->safe_mode)
		return 0;

	/*
	 * Make sure the device ID in the image matches the one
	 * we read from the switch config space.
	 */
	device_id = *(u16 *)(buf + hdr_size + INTEL_NVM_DEVID);
	if (device_id != sw->config.device_id)
		return -EINVAL;

	/* Skip headers in the image */
	nvm->buf_data_start = buf + hdr_size;
	nvm->buf_data_size = image_size - hdr_size;

	return 0;
}

static int intel_switch_nvm_write_headers(struct tb_nvm *nvm)
{
	struct tb_switch *sw = tb_to_switch(nvm->dev);

	if (sw->generation < 3) {
		int ret;

		/* Write CSS headers first */
		ret = dma_port_flash_write(sw->dma_port,
			DMA_PORT_CSS_ADDRESS, nvm->buf + INTEL_NVM_CSS,
			DMA_PORT_CSS_MAX_SIZE);
		if (ret)
			return ret;
	}

	return 0;
}

static const struct tb_nvm_vendor_ops intel_switch_nvm_ops = {
	.read_version = intel_switch_nvm_version,
	.validate = intel_switch_nvm_validate,
	.write_headers = intel_switch_nvm_write_headers,
};

static int asmedia_switch_nvm_version(struct tb_nvm *nvm)
{
	struct tb_switch *sw = tb_to_switch(nvm->dev);
	u32 val;
	int ret;

	ret = tb_switch_nvm_read(sw, ASMEDIA_NVM_VERSION, &val, sizeof(val));
	if (ret)
		return ret;

	nvm->major = (val << 16) & 0xff0000;
	nvm->major |= val & 0x00ff00;
	nvm->major |= (val >> 16) & 0x0000ff;

	ret = tb_switch_nvm_read(sw, ASMEDIA_NVM_DATE, &val, sizeof(val));
	if (ret)
		return ret;

	nvm->minor = (val << 16) & 0xff0000;
	nvm->minor |= val & 0x00ff00;
	nvm->minor |= (val >> 16) & 0x0000ff;

	/* ASMedia NVM size is fixed to 512k */
	nvm->active_size = SZ_512K;

	return 0;
}

static const struct tb_nvm_vendor_ops asmedia_switch_nvm_ops = {
	.read_version = asmedia_switch_nvm_version,
};

/* Router vendor NVM support table */
static const struct tb_nvm_vendor switch_nvm_vendors[] = {
	{ 0x174c, &asmedia_switch_nvm_ops },
	{ PCI_VENDOR_ID_INTEL, &intel_switch_nvm_ops },
	{ 0x8087, &intel_switch_nvm_ops },
};

static int intel_retimer_nvm_version(struct tb_nvm *nvm)
{
	struct tb_retimer *rt = tb_to_retimer(nvm->dev);
	u32 val, nvm_size;
	int ret;

	ret = tb_retimer_nvm_read(rt, INTEL_NVM_VERSION, &val, sizeof(val));
	if (ret)
		return ret;

	nvm->major = (val >> 16) & 0xff;
	nvm->minor = (val >> 8) & 0xff;

	ret = tb_retimer_nvm_read(rt, INTEL_NVM_FLASH_SIZE, &val, sizeof(val));
	if (ret)
		return ret;

	nvm_size = (SZ_1M << (val & 7)) / 8;
	nvm_size = (nvm_size - SZ_16K) / 2;
	nvm->active_size = nvm_size;

	return 0;
}

static int intel_retimer_nvm_validate(struct tb_nvm *nvm)
{
	struct tb_retimer *rt = tb_to_retimer(nvm->dev);
	unsigned int image_size, hdr_size;
	u8 *buf = nvm->buf;
	u16 ds_size, device;

	image_size = nvm->buf_data_size;

	/*
	 * FARB pointer must point inside the image and must at least
	 * contain parts of the digital section we will be reading here.
	 */
	hdr_size = (*(u32 *)buf) & 0xffffff;
	if (hdr_size + INTEL_NVM_DEVID + 2 >= image_size)
		return -EINVAL;

	/* Digital section start should be aligned to 4k page */
	if (!IS_ALIGNED(hdr_size, SZ_4K))
		return -EINVAL;

	/*
	 * Read digital section size and check that it also fits inside
	 * the image.
	 */
	ds_size = *(u16 *)(buf + hdr_size);
	if (ds_size >= image_size)
		return -EINVAL;

	/*
	 * Make sure the device ID in the image matches the retimer
	 * hardware.
	 */
	device = *(u16 *)(buf + hdr_size + INTEL_NVM_DEVID);
	if (device != rt->device)
		return -EINVAL;

	/* Skip headers in the image */
	nvm->buf_data_start = buf + hdr_size;
	nvm->buf_data_size = image_size - hdr_size;

	return 0;
}

static const struct tb_nvm_vendor_ops intel_retimer_nvm_ops = {
	.read_version = intel_retimer_nvm_version,
	.validate = intel_retimer_nvm_validate,
};

/* Retimer vendor NVM support table */
static const struct tb_nvm_vendor retimer_nvm_vendors[] = {
	{ 0x8087, &intel_retimer_nvm_ops },
};

/**
 * tb_nvm_alloc() - Allocate new NVM structure
 * @dev: Device owning the NVM
 *
 * Allocates new NVM structure with unique @id and returns it.
 *
 * Return:
 * * Pointer to &struct tb_nvm - On success.
 * * %-EOPNOTSUPP - If the NVM format of the @dev is not known by the
 *   kernel.
 * * %ERR_PTR - In case of failure.
 */
struct tb_nvm *tb_nvm_alloc(struct device *dev)
{
	const struct tb_nvm_vendor_ops *vops = NULL;
	struct tb_nvm *nvm;
	int ret, i;

	if (tb_is_switch(dev)) {
		const struct tb_switch *sw = tb_to_switch(dev);

		for (i = 0; i < ARRAY_SIZE(switch_nvm_vendors); i++) {
			const struct tb_nvm_vendor *v = &switch_nvm_vendors[i];

			if (v->vendor == sw->config.vendor_id) {
				vops = v->vops;
				break;
			}
		}

		if (!vops) {
			tb_sw_dbg(sw, "router NVM format of vendor %#x unknown\n",
				  sw->config.vendor_id);
			return ERR_PTR(-EOPNOTSUPP);
		}
	} else if (tb_is_retimer(dev)) {
		const struct tb_retimer *rt = tb_to_retimer(dev);

		for (i = 0; i < ARRAY_SIZE(retimer_nvm_vendors); i++) {
			const struct tb_nvm_vendor *v = &retimer_nvm_vendors[i];

			if (v->vendor == rt->vendor) {
				vops = v->vops;
				break;
			}
		}

		if (!vops) {
			dev_dbg(dev, "retimer NVM format of vendor %#x unknown\n",
				rt->vendor);
			return ERR_PTR(-EOPNOTSUPP);
		}
	} else {
		return ERR_PTR(-EOPNOTSUPP);
	}

	nvm = kzalloc(sizeof(*nvm), GFP_KERNEL);
	if (!nvm)
		return ERR_PTR(-ENOMEM);

	ret = ida_alloc(&nvm_ida, GFP_KERNEL);
	if (ret < 0) {
		kfree(nvm);
		return ERR_PTR(ret);
	}

	nvm->id = ret;
	nvm->dev = dev;
	nvm->vops = vops;

	return nvm;
}

/**
 * tb_nvm_read_version() - Read and populate NVM version
 * @nvm: NVM structure
 *
 * Uses vendor specific means to read and fill out the existing
 * active NVM version.
 *
 * Return: %0 on success, negative errno otherwise.
 */
int tb_nvm_read_version(struct tb_nvm *nvm)
{
	const struct tb_nvm_vendor_ops *vops = nvm->vops;

	if (vops && vops->read_version)
		return vops->read_version(nvm);

	return -EOPNOTSUPP;
}

/**
 * tb_nvm_validate() - Validate new NVM image
 * @nvm: NVM structure
 *
 * Runs vendor specific validation over the new NVM image. As a
 * side effect, updates @nvm->buf_data_start and @nvm->buf_data_size
 * fields to match the actual data to be written to the NVM.
 *
 * Return: %0 on successful validation, negative errno otherwise.
 */
int tb_nvm_validate(struct tb_nvm *nvm)
{
	const struct tb_nvm_vendor_ops *vops = nvm->vops;
	unsigned int image_size;
	u8 *buf = nvm->buf;

	if (!buf)
		return -EINVAL;
	if (!vops)
		return -EOPNOTSUPP;

	/* Just do basic image size checks */
	image_size = nvm->buf_data_size;
	if (image_size < NVM_MIN_SIZE || image_size > NVM_MAX_SIZE)
		return -EINVAL;

	/*
	 * Set the default data start in the buffer. The validate method
	 * below can change this if needed.
	 */
	nvm->buf_data_start = buf;

	return vops->validate ? vops->validate(nvm) : 0;
}

/**
 * tb_nvm_write_headers() - Write headers before the rest of the image
 * @nvm: NVM structure
 *
 * If the vendor NVM format requires writing headers before the rest of
 * the image, this function does that. Can be called even if the device
 * does not need this.
 *
 * Return: %0 on success, negative errno otherwise.
 */
int tb_nvm_write_headers(struct tb_nvm *nvm)
{
	const struct tb_nvm_vendor_ops *vops = nvm->vops;

	return vops->write_headers ? vops->write_headers(nvm) : 0;
}

/**
 * tb_nvm_add_active() - Adds active NVMem device to NVM
 * @nvm: NVM structure
 * @reg_read: Pointer to the function to read the NVM (passed directly to the
 *	      NVMem device)
 *
 * Registers new active NVmem device for @nvm. The @reg_read is called
 * directly from NVMem so it must handle possible concurrent access if
 * needed. The first parameter passed to @reg_read is @nvm structure.
 *
 * Return: %0 on success, negative errno otherwise.
 */
int tb_nvm_add_active(struct tb_nvm *nvm, nvmem_reg_read_t reg_read)
{
	struct nvmem_config config;
	struct nvmem_device *nvmem;

	memset(&config, 0, sizeof(config));

	config.name = "nvm_active";
	config.reg_read = reg_read;
	config.read_only = true;
	config.id = nvm->id;
	config.stride = 4;
	config.word_size = 4;
	config.size = nvm->active_size;
	config.dev = nvm->dev;
	config.owner = THIS_MODULE;
	config.priv = nvm;

	nvmem = nvmem_register(&config);
	if (IS_ERR(nvmem))
		return PTR_ERR(nvmem);

	nvm->active = nvmem;
	return 0;
}

/**
 * tb_nvm_write_buf() - Write data to @nvm buffer
 * @nvm: NVM structure
 * @offset: Offset where to write the data
 * @val: Data buffer to write
 * @bytes: Number of bytes to write
 *
 * Helper function to cache the new NVM image before it is actually
 * written to the flash. Copies @bytes from @val to @nvm->buf starting
 * from @offset.
 *
 * Return:
 * * %0 - On success.
 * * %-ENOMEM - If buffer allocation failed.
 * * Negative errno - Another error occurred.
 */
int tb_nvm_write_buf(struct tb_nvm *nvm, unsigned int offset, void *val,
		     size_t bytes)
{
	if (!nvm->buf) {
		nvm->buf = vmalloc(NVM_MAX_SIZE);
		if (!nvm->buf)
			return -ENOMEM;
	}

	nvm->flushed = false;
	nvm->buf_data_size = offset + bytes;
	memcpy(nvm->buf + offset, val, bytes);
	return 0;
}

/**
 * tb_nvm_add_non_active() - Adds non-active NVMem device to NVM
 * @nvm: NVM structure
 * @reg_write: Pointer to the function to write the NVM (passed directly
 *	       to the NVMem device)
 *
 * Registers new non-active NVmem device for @nvm. The @reg_write is called
 * directly from NVMem so it must handle possible concurrent access if
 * needed. The first parameter passed to @reg_write is @nvm structure.
 * The size of the NVMem device is set to %NVM_MAX_SIZE.
 *
 * Return: %0 on success, negative errno otherwise.
 */
int tb_nvm_add_non_active(struct tb_nvm *nvm, nvmem_reg_write_t reg_write)
{
	struct nvmem_config config;
	struct nvmem_device *nvmem;

	memset(&config, 0, sizeof(config));

	config.name = "nvm_non_active";
	config.reg_write = reg_write;
	config.root_only = true;
	config.id = nvm->id;
	config.stride = 4;
	config.word_size = 4;
	config.size = NVM_MAX_SIZE;
	config.dev = nvm->dev;
	config.owner = THIS_MODULE;
	config.priv = nvm;

	nvmem = nvmem_register(&config);
	if (IS_ERR(nvmem))
		return PTR_ERR(nvmem);

	nvm->non_active = nvmem;
	return 0;
}

/**
 * tb_nvm_free() - Release NVM and its resources
 * @nvm: NVM structure to release
 *
 * Releases NVM and the NVMem devices if they were registered.
 */
void tb_nvm_free(struct tb_nvm *nvm)
{
	if (nvm) {
		nvmem_unregister(nvm->non_active);
		nvmem_unregister(nvm->active);
		vfree(nvm->buf);
		ida_free(&nvm_ida, nvm->id);
	}
	kfree(nvm);
}

/**
 * tb_nvm_read_data() - Read data from NVM
 * @address: Start address on the flash
 * @buf: Buffer where the read data is copied
 * @size: Size of the buffer in bytes
 * @retries: Number of retries if block read fails
 * @read_block: Function that reads block from the flash
 * @read_block_data: Data passsed to @read_block
 *
 * This is a generic function that reads data from NVM or NVM like
 * device.
 *
 * Return: %0 on success, negative errno otherwise.
 */
int tb_nvm_read_data(unsigned int address, void *buf, size_t size,
		     unsigned int retries, read_block_fn read_block,
		     void *read_block_data)
{
	do {
		unsigned int dwaddress, dwords, offset;
		u8 data[NVM_DATA_DWORDS * 4];
		size_t nbytes;
		int ret;

		offset = address & 3;
		nbytes = min_t(size_t, size + offset, NVM_DATA_DWORDS * 4);

		dwaddress = address / 4;
		dwords = ALIGN(nbytes, 4) / 4;

		ret = read_block(read_block_data, dwaddress, data, dwords);
		if (ret) {
			if (ret != -ENODEV && retries--)
				continue;
			return ret;
		}

		nbytes -= offset;
		memcpy(buf, data + offset, nbytes);

		size -= nbytes;
		address += nbytes;
		buf += nbytes;
	} while (size > 0);

	return 0;
}

/**
 * tb_nvm_write_data() - Write data to NVM
 * @address: Start address on the flash
 * @buf: Buffer where the data is copied from
 * @size: Size of the buffer in bytes
 * @retries: Number of retries if the block write fails
 * @write_block: Function that writes block to the flash
 * @write_block_data: Data passed to @write_block
 *
 * This is generic function that writes data to NVM or NVM like device.
 *
 * Return: %0 on success, negative errno otherwise.
 */
int tb_nvm_write_data(unsigned int address, const void *buf, size_t size,
		      unsigned int retries, write_block_fn write_block,
		      void *write_block_data)
{
	do {
		unsigned int offset, dwaddress;
		u8 data[NVM_DATA_DWORDS * 4];
		size_t nbytes;
		int ret;

		offset = address & 3;
		nbytes = min_t(u32, size + offset, NVM_DATA_DWORDS * 4);

		memcpy(data + offset, buf, nbytes);

		dwaddress = address / 4;
		ret = write_block(write_block_data, dwaddress, data, nbytes / 4);
		if (ret) {
			if (ret == -ETIMEDOUT) {
				if (retries--)
					continue;
				ret = -EIO;
			}
			return ret;
		}

		size -= nbytes;
		address += nbytes;
		buf += nbytes;
	} while (size > 0);

	return 0;
}

void tb_nvm_exit(void)
{
	ida_destroy(&nvm_ida);
}
