// SPDX-License-Identifier: GPL-2.0-only
/*
 * Firmware loading.
 *
 * Copyright (c) 2017-2020, Silicon Laboratories, Inc.
 * Copyright (c) 2010, ST-Ericsson
 */
#include <linux/firmware.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/bitfield.h>

#include "fwio.h"
#include "wfx.h"
#include "hwio.h"

// Addresses below are in SRAM area
#define WFX_DNLD_FIFO             0x09004000
#define     DNLD_BLOCK_SIZE           0x0400
#define     DNLD_FIFO_SIZE            0x8000 // (32 * DNLD_BLOCK_SIZE)
// Download Control Area (DCA)
#define WFX_DCA_IMAGE_SIZE        0x0900C000
#define WFX_DCA_PUT               0x0900C004
#define WFX_DCA_GET               0x0900C008
#define WFX_DCA_HOST_STATUS       0x0900C00C
#define     HOST_READY                0x87654321
#define     HOST_INFO_READ            0xA753BD99
#define     HOST_UPLOAD_PENDING       0xABCDDCBA
#define     HOST_UPLOAD_COMPLETE      0xD4C64A99
#define     HOST_OK_TO_JUMP           0x174FC882
#define WFX_DCA_NCP_STATUS        0x0900C010
#define     NCP_NOT_READY             0x12345678
#define     NCP_READY                 0x87654321
#define     NCP_INFO_READY            0xBD53EF99
#define     NCP_DOWNLOAD_PENDING      0xABCDDCBA
#define     NCP_DOWNLOAD_COMPLETE     0xCAFEFECA
#define     NCP_AUTH_OK               0xD4C64A99
#define     NCP_AUTH_FAIL             0x174FC882
#define     NCP_PUB_KEY_RDY           0x7AB41D19
#define WFX_DCA_FW_SIGNATURE      0x0900C014
#define     FW_SIGNATURE_SIZE         0x40
#define WFX_DCA_FW_HASH           0x0900C054
#define     FW_HASH_SIZE              0x08
#define WFX_DCA_FW_VERSION        0x0900C05C
#define     FW_VERSION_SIZE           0x04
#define WFX_DCA_RESERVED          0x0900C060
#define     DCA_RESERVED_SIZE         0x20
#define WFX_STATUS_INFO           0x0900C080
#define WFX_BOOTLOADER_LABEL      0x0900C084
#define     BOOTLOADER_LABEL_SIZE     0x3C
#define WFX_PTE_INFO              0x0900C0C0
#define     PTE_INFO_KEYSET_IDX       0x0D
#define     PTE_INFO_SIZE             0x10
#define WFX_ERR_INFO              0x0900C0D0
#define     ERR_INVALID_SEC_TYPE      0x05
#define     ERR_SIG_VERIF_FAILED      0x0F
#define     ERR_AES_CTRL_KEY          0x10
#define     ERR_ECC_PUB_KEY           0x11
#define     ERR_MAC_KEY               0x18

#define DCA_TIMEOUT  50 // milliseconds
#define WAKEUP_TIMEOUT 200 // milliseconds

static const char * const fwio_errors[] = {
	[ERR_INVALID_SEC_TYPE] = "Invalid section type or wrong encryption",
	[ERR_SIG_VERIF_FAILED] = "Signature verification failed",
	[ERR_AES_CTRL_KEY] = "AES control key not initialized",
	[ERR_ECC_PUB_KEY] = "ECC public key not initialized",
	[ERR_MAC_KEY] = "MAC key not initialized",
};

/*
 * request_firmware() allocate data using vmalloc(). It is not compatible with
 * underlying hardware that use DMA. Function below detect this case and
 * allocate a bounce buffer if necessary.
 *
 * Notice that, in doubt, you can enable CONFIG_DEBUG_SG to ask kernel to
 * detect this problem at runtime  (else, kernel silently fail).
 *
 * NOTE: it may also be possible to use 'pages' from struct firmware and avoid
 * bounce buffer
 */
static int sram_write_dma_safe(struct wfx_dev *wdev, u32 addr, const u8 *buf,
			       size_t len)
{
	int ret;
	const u8 *tmp;

	if (!virt_addr_valid(buf)) {
		tmp = kmemdup(buf, len, GFP_KERNEL);
		if (!tmp)
			return -ENOMEM;
	} else {
		tmp = buf;
	}
	ret = sram_buf_write(wdev, addr, tmp, len);
	if (tmp != buf)
		kfree(tmp);
	return ret;
}

static int get_firmware(struct wfx_dev *wdev, u32 keyset_chip,
			const struct firmware **fw, int *file_offset)
{
	int keyset_file;
	char filename[256];
	const char *data;
	int ret;

	snprintf(filename, sizeof(filename), "%s_%02X.sec",
		 wdev->pdata.file_fw, keyset_chip);
	ret = firmware_request_nowarn(fw, filename, wdev->dev);
	if (ret) {
		dev_info(wdev->dev, "can't load %s, falling back to %s.sec\n",
			 filename, wdev->pdata.file_fw);
		snprintf(filename, sizeof(filename), "%s.sec",
			 wdev->pdata.file_fw);
		ret = request_firmware(fw, filename, wdev->dev);
		if (ret) {
			dev_err(wdev->dev, "can't load %s\n", filename);
			*fw = NULL;
			return ret;
		}
	}

	data = (*fw)->data;
	if (memcmp(data, "KEYSET", 6) != 0) {
		// Legacy firmware format
		*file_offset = 0;
		keyset_file = 0x90;
	} else {
		*file_offset = 8;
		keyset_file = (hex_to_bin(data[6]) * 16) | hex_to_bin(data[7]);
		if (keyset_file < 0) {
			dev_err(wdev->dev, "%s corrupted\n", filename);
			release_firmware(*fw);
			*fw = NULL;
			return -EINVAL;
		}
	}
	if (keyset_file != keyset_chip) {
		dev_err(wdev->dev, "firmware keyset is incompatible with chip (file: 0x%02X, chip: 0x%02X)\n",
			keyset_file, keyset_chip);
		release_firmware(*fw);
		*fw = NULL;
		return -ENODEV;
	}
	wdev->keyset = keyset_file;
	return 0;
}

static int wait_ncp_status(struct wfx_dev *wdev, u32 status)
{
	ktime_t now, start;
	u32 reg;
	int ret;

	start = ktime_get();
	for (;;) {
		ret = sram_reg_read(wdev, WFX_DCA_NCP_STATUS, &reg);
		if (ret < 0)
			return -EIO;
		now = ktime_get();
		if (reg == status)
			break;
		if (ktime_after(now, ktime_add_ms(start, DCA_TIMEOUT)))
			return -ETIMEDOUT;
	}
	if (ktime_compare(now, start))
		dev_dbg(wdev->dev, "chip answer after %lldus\n",
			ktime_us_delta(now, start));
	else
		dev_dbg(wdev->dev, "chip answer immediately\n");
	return 0;
}

static int upload_firmware(struct wfx_dev *wdev, const u8 *data, size_t len)
{
	int ret;
	u32 offs, bytes_done = 0;
	ktime_t now, start;

	if (len % DNLD_BLOCK_SIZE) {
		dev_err(wdev->dev, "firmware size is not aligned. Buffer overrun will occur\n");
		return -EIO;
	}
	offs = 0;
	while (offs < len) {
		start = ktime_get();
		for (;;) {
			now = ktime_get();
			if (offs + DNLD_BLOCK_SIZE - bytes_done < DNLD_FIFO_SIZE)
				break;
			if (ktime_after(now, ktime_add_ms(start, DCA_TIMEOUT)))
				return -ETIMEDOUT;
			ret = sram_reg_read(wdev, WFX_DCA_GET, &bytes_done);
			if (ret < 0)
				return ret;
		}
		if (ktime_compare(now, start))
			dev_dbg(wdev->dev, "answer after %lldus\n",
				ktime_us_delta(now, start));

		ret = sram_write_dma_safe(wdev, WFX_DNLD_FIFO +
					  (offs % DNLD_FIFO_SIZE),
					  data + offs, DNLD_BLOCK_SIZE);
		if (ret < 0)
			return ret;

		// WFx seems to not support writing 0 in this register during
		// first loop
		offs += DNLD_BLOCK_SIZE;
		ret = sram_reg_write(wdev, WFX_DCA_PUT, offs);
		if (ret < 0)
			return ret;
	}
	return 0;
}

static void print_boot_status(struct wfx_dev *wdev)
{
	u32 reg;

	sram_reg_read(wdev, WFX_STATUS_INFO, &reg);
	if (reg == 0x12345678)
		return;
	sram_reg_read(wdev, WFX_ERR_INFO, &reg);
	if (reg < ARRAY_SIZE(fwio_errors) && fwio_errors[reg])
		dev_info(wdev->dev, "secure boot: %s\n", fwio_errors[reg]);
	else
		dev_info(wdev->dev, "secure boot: Error %#02x\n", reg);
}

static int load_firmware_secure(struct wfx_dev *wdev)
{
	const struct firmware *fw = NULL;
	int header_size;
	int fw_offset;
	ktime_t start;
	u8 *buf;
	int ret;

	BUILD_BUG_ON(PTE_INFO_SIZE > BOOTLOADER_LABEL_SIZE);
	buf = kmalloc(BOOTLOADER_LABEL_SIZE + 1, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	sram_reg_write(wdev, WFX_DCA_HOST_STATUS, HOST_READY);
	ret = wait_ncp_status(wdev, NCP_INFO_READY);
	if (ret)
		goto error;

	sram_buf_read(wdev, WFX_BOOTLOADER_LABEL, buf, BOOTLOADER_LABEL_SIZE);
	buf[BOOTLOADER_LABEL_SIZE] = 0;
	dev_dbg(wdev->dev, "bootloader: \"%s\"\n", buf);

	sram_buf_read(wdev, WFX_PTE_INFO, buf, PTE_INFO_SIZE);
	ret = get_firmware(wdev, buf[PTE_INFO_KEYSET_IDX], &fw, &fw_offset);
	if (ret)
		goto error;
	header_size = fw_offset + FW_SIGNATURE_SIZE + FW_HASH_SIZE;

	sram_reg_write(wdev, WFX_DCA_HOST_STATUS, HOST_INFO_READ);
	ret = wait_ncp_status(wdev, NCP_READY);
	if (ret)
		goto error;

	sram_reg_write(wdev, WFX_DNLD_FIFO, 0xFFFFFFFF); // Fifo init
	sram_write_dma_safe(wdev, WFX_DCA_FW_VERSION, "\x01\x00\x00\x00",
			    FW_VERSION_SIZE);
	sram_write_dma_safe(wdev, WFX_DCA_FW_SIGNATURE, fw->data + fw_offset,
			    FW_SIGNATURE_SIZE);
	sram_write_dma_safe(wdev, WFX_DCA_FW_HASH,
			    fw->data + fw_offset + FW_SIGNATURE_SIZE,
			    FW_HASH_SIZE);
	sram_reg_write(wdev, WFX_DCA_IMAGE_SIZE, fw->size - header_size);
	sram_reg_write(wdev, WFX_DCA_HOST_STATUS, HOST_UPLOAD_PENDING);
	ret = wait_ncp_status(wdev, NCP_DOWNLOAD_PENDING);
	if (ret)
		goto error;

	start = ktime_get();
	ret = upload_firmware(wdev, fw->data + header_size,
			      fw->size - header_size);
	if (ret)
		goto error;
	dev_dbg(wdev->dev, "firmware load after %lldus\n",
		ktime_us_delta(ktime_get(), start));

	sram_reg_write(wdev, WFX_DCA_HOST_STATUS, HOST_UPLOAD_COMPLETE);
	ret = wait_ncp_status(wdev, NCP_AUTH_OK);
	// Legacy ROM support
	if (ret < 0)
		ret = wait_ncp_status(wdev, NCP_PUB_KEY_RDY);
	if (ret < 0)
		goto error;
	sram_reg_write(wdev, WFX_DCA_HOST_STATUS, HOST_OK_TO_JUMP);

error:
	kfree(buf);
	if (fw)
		release_firmware(fw);
	if (ret)
		print_boot_status(wdev);
	return ret;
}

static int init_gpr(struct wfx_dev *wdev)
{
	int ret, i;
	static const struct {
		int index;
		u32 value;
	} gpr_init[] = {
		{ 0x07, 0x208775 },
		{ 0x08, 0x2EC020 },
		{ 0x09, 0x3C3C3C },
		{ 0x0B, 0x322C44 },
		{ 0x0C, 0xA06497 },
	};

	for (i = 0; i < ARRAY_SIZE(gpr_init); i++) {
		ret = igpr_reg_write(wdev, gpr_init[i].index,
				     gpr_init[i].value);
		if (ret < 0)
			return ret;
		dev_dbg(wdev->dev, "  index %02x: %08x\n",
			gpr_init[i].index, gpr_init[i].value);
	}
	return 0;
}

int wfx_init_device(struct wfx_dev *wdev)
{
	int ret;
	int hw_revision, hw_type;
	int wakeup_timeout = 50; // ms
	ktime_t now, start;
	u32 reg;

	reg = CFG_DIRECT_ACCESS_MODE | CFG_CPU_RESET | CFG_BYTE_ORDER_ABCD;
	if (wdev->pdata.use_rising_clk)
		reg |= CFG_CLK_RISE_EDGE;
	ret = config_reg_write(wdev, reg);
	if (ret < 0) {
		dev_err(wdev->dev, "bus returned an error during first write access. Host configuration error?\n");
		return -EIO;
	}

	ret = config_reg_read(wdev, &reg);
	if (ret < 0) {
		dev_err(wdev->dev, "bus returned an error during first read access. Bus configuration error?\n");
		return -EIO;
	}
	if (reg == 0 || reg == ~0) {
		dev_err(wdev->dev, "chip mute. Bus configuration error or chip wasn't reset?\n");
		return -EIO;
	}
	dev_dbg(wdev->dev, "initial config register value: %08x\n", reg);

	hw_revision = FIELD_GET(CFG_DEVICE_ID_MAJOR, reg);
	if (hw_revision == 0) {
		dev_err(wdev->dev, "bad hardware revision number: %d\n",
			hw_revision);
		return -ENODEV;
	}
	hw_type = FIELD_GET(CFG_DEVICE_ID_TYPE, reg);
	if (hw_type == 1) {
		dev_notice(wdev->dev, "development hardware detected\n");
		wakeup_timeout = 2000;
	}

	ret = init_gpr(wdev);
	if (ret < 0)
		return ret;

	ret = control_reg_write(wdev, CTRL_WLAN_WAKEUP);
	if (ret < 0)
		return -EIO;
	start = ktime_get();
	for (;;) {
		ret = control_reg_read(wdev, &reg);
		now = ktime_get();
		if (reg & CTRL_WLAN_READY)
			break;
		if (ktime_after(now, ktime_add_ms(start, wakeup_timeout))) {
			dev_err(wdev->dev, "chip didn't wake up. Chip wasn't reset?\n");
			return -ETIMEDOUT;
		}
	}
	dev_dbg(wdev->dev, "chip wake up after %lldus\n",
		ktime_us_delta(now, start));

	ret = config_reg_write_bits(wdev, CFG_CPU_RESET, 0);
	if (ret < 0)
		return ret;
	ret = load_firmware_secure(wdev);
	if (ret < 0)
		return ret;
	return config_reg_write_bits(wdev,
				     CFG_DIRECT_ACCESS_MODE |
				     CFG_IRQ_ENABLE_DATA |
				     CFG_IRQ_ENABLE_WRDY,
				     CFG_IRQ_ENABLE_DATA);
}
