// SPDX-License-Identifier: GPL-2.0-only
/*
 * Firmware loading.
 *
 * Copyright (c) 2017-2019, 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 (!virt_addr_valid(buf))
		kfree(tmp);
	return ret;
}

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;
	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 (;;) {
			ret = sram_reg_read(wdev, WFX_DCA_GET, &bytes_done);
			if (ret < 0)
				return ret;
			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;
		}
		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 || hw_revision > 2) {
		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;
	ret = config_reg_write_bits(wdev,
				    CFG_DIRECT_ACCESS_MODE |
				    CFG_IRQ_ENABLE_DATA |
				    CFG_IRQ_ENABLE_WRDY,
				    CFG_IRQ_ENABLE_DATA);
	return ret;
}
