// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2008-2010
 *
 * - Kurt Van Dijck, EIA Electronics
 */

#include <linux/firmware.h>
#include <linux/sched/signal.h>
#include <asm/div64.h>
#include <asm/io.h>

#include "softing.h"

/*
 * low level DPRAM command.
 * Make sure that card->dpram[DPRAM_FCT_HOST] is preset
 */
static int _softing_fct_cmd(struct softing *card, int16_t cmd, uint16_t vector,
		const char *msg)
{
	int ret;
	unsigned long stamp;

	iowrite16(cmd, &card->dpram[DPRAM_FCT_PARAM]);
	iowrite8(vector >> 8, &card->dpram[DPRAM_FCT_HOST + 1]);
	iowrite8(vector, &card->dpram[DPRAM_FCT_HOST]);
	/* be sure to flush this to the card */
	wmb();
	stamp = jiffies + 1 * HZ;
	/* wait for card */
	do {
		/* DPRAM_FCT_HOST is _not_ aligned */
		ret = ioread8(&card->dpram[DPRAM_FCT_HOST]) +
			(ioread8(&card->dpram[DPRAM_FCT_HOST + 1]) << 8);
		/* don't have any cached variables */
		rmb();
		if (ret == RES_OK)
			/* read return-value now */
			return ioread16(&card->dpram[DPRAM_FCT_RESULT]);

		if ((ret != vector) || time_after(jiffies, stamp))
			break;
		/* process context => relax */
		usleep_range(500, 10000);
	} while (1);

	ret = (ret == RES_NONE) ? -ETIMEDOUT : -ECANCELED;
	dev_alert(&card->pdev->dev, "firmware %s failed (%i)\n", msg, ret);
	return ret;
}

static int softing_fct_cmd(struct softing *card, int16_t cmd, const char *msg)
{
	int ret;

	ret = _softing_fct_cmd(card, cmd, 0, msg);
	if (ret > 0) {
		dev_alert(&card->pdev->dev, "%s returned %u\n", msg, ret);
		ret = -EIO;
	}
	return ret;
}

int softing_bootloader_command(struct softing *card, int16_t cmd,
		const char *msg)
{
	int ret;
	unsigned long stamp;

	iowrite16(RES_NONE, &card->dpram[DPRAM_RECEIPT]);
	iowrite16(cmd, &card->dpram[DPRAM_COMMAND]);
	/* be sure to flush this to the card */
	wmb();
	stamp = jiffies + 3 * HZ;
	/* wait for card */
	do {
		ret = ioread16(&card->dpram[DPRAM_RECEIPT]);
		/* don't have any cached variables */
		rmb();
		if (ret == RES_OK)
			return 0;
		if (time_after(jiffies, stamp))
			break;
		/* process context => relax */
		usleep_range(500, 10000);
	} while (!signal_pending(current));

	ret = (ret == RES_NONE) ? -ETIMEDOUT : -ECANCELED;
	dev_alert(&card->pdev->dev, "bootloader %s failed (%i)\n", msg, ret);
	return ret;
}

static int fw_parse(const uint8_t **pmem, uint16_t *ptype, uint32_t *paddr,
		uint16_t *plen, const uint8_t **pdat)
{
	uint16_t checksum[2];
	const uint8_t *mem;
	const uint8_t *end;

	/*
	 * firmware records are a binary, unaligned stream composed of:
	 * uint16_t type;
	 * uint32_t addr;
	 * uint16_t len;
	 * uint8_t dat[len];
	 * uint16_t checksum;
	 * all values in little endian.
	 * We could define a struct for this, with __attribute__((packed)),
	 * but would that solve the alignment in _all_ cases (cfr. the
	 * struct itself may be an odd address)?
	 *
	 * I chose to use leXX_to_cpup() since this solves both
	 * endianness & alignment.
	 */
	mem = *pmem;
	*ptype = le16_to_cpup((void *)&mem[0]);
	*paddr = le32_to_cpup((void *)&mem[2]);
	*plen = le16_to_cpup((void *)&mem[6]);
	*pdat = &mem[8];
	/* verify checksum */
	end = &mem[8 + *plen];
	checksum[0] = le16_to_cpup((void *)end);
	for (checksum[1] = 0; mem < end; ++mem)
		checksum[1] += *mem;
	if (checksum[0] != checksum[1])
		return -EINVAL;
	/* increment */
	*pmem += 10 + *plen;
	return 0;
}

int softing_load_fw(const char *file, struct softing *card,
		__iomem uint8_t *dpram, unsigned int size, int offset)
{
	const struct firmware *fw;
	int ret;
	const uint8_t *mem, *end, *dat;
	uint16_t type, len;
	uint32_t addr;
	uint8_t *buf = NULL, *new_buf;
	int buflen = 0;
	int8_t type_end = 0;

	ret = request_firmware(&fw, file, &card->pdev->dev);
	if (ret < 0)
		return ret;
	dev_dbg(&card->pdev->dev, "%s, firmware(%s) got %u bytes"
		", offset %c0x%04x\n",
		card->pdat->name, file, (unsigned int)fw->size,
		(offset >= 0) ? '+' : '-', (unsigned int)abs(offset));
	/* parse the firmware */
	mem = fw->data;
	end = &mem[fw->size];
	/* look for header record */
	ret = fw_parse(&mem, &type, &addr, &len, &dat);
	if (ret < 0)
		goto failed;
	if (type != 0xffff)
		goto failed;
	if (strncmp("Structured Binary Format, Softing GmbH" , dat, len)) {
		ret = -EINVAL;
		goto failed;
	}
	/* ok, we had a header */
	while (mem < end) {
		ret = fw_parse(&mem, &type, &addr, &len, &dat);
		if (ret < 0)
			goto failed;
		if (type == 3) {
			/* start address, not used here */
			continue;
		} else if (type == 1) {
			/* eof */
			type_end = 1;
			break;
		} else if (type != 0) {
			ret = -EINVAL;
			goto failed;
		}

		if ((addr + len + offset) > size)
			goto failed;
		memcpy_toio(&dpram[addr + offset], dat, len);
		/* be sure to flush caches from IO space */
		mb();
		if (len > buflen) {
			/* align buflen */
			buflen = (len + (1024-1)) & ~(1024-1);
			new_buf = krealloc(buf, buflen, GFP_KERNEL);
			if (!new_buf) {
				ret = -ENOMEM;
				goto failed;
			}
			buf = new_buf;
		}
		/* verify record data */
		memcpy_fromio(buf, &dpram[addr + offset], len);
		if (memcmp(buf, dat, len)) {
			/* is not ok */
			dev_alert(&card->pdev->dev, "DPRAM readback failed\n");
			ret = -EIO;
			goto failed;
		}
	}
	if (!type_end)
		/* no end record seen */
		goto failed;
	ret = 0;
failed:
	kfree(buf);
	release_firmware(fw);
	if (ret < 0)
		dev_info(&card->pdev->dev, "firmware %s failed\n", file);
	return ret;
}

int softing_load_app_fw(const char *file, struct softing *card)
{
	const struct firmware *fw;
	const uint8_t *mem, *end, *dat;
	int ret, j;
	uint16_t type, len;
	uint32_t addr, start_addr = 0;
	unsigned int sum, rx_sum;
	int8_t type_end = 0, type_entrypoint = 0;

	ret = request_firmware(&fw, file, &card->pdev->dev);
	if (ret) {
		dev_alert(&card->pdev->dev, "request_firmware(%s) got %i\n",
			file, ret);
		return ret;
	}
	dev_dbg(&card->pdev->dev, "firmware(%s) got %lu bytes\n",
		file, (unsigned long)fw->size);
	/* parse the firmware */
	mem = fw->data;
	end = &mem[fw->size];
	/* look for header record */
	ret = fw_parse(&mem, &type, &addr, &len, &dat);
	if (ret)
		goto failed;
	ret = -EINVAL;
	if (type != 0xffff) {
		dev_alert(&card->pdev->dev, "firmware starts with type 0x%x\n",
			type);
		goto failed;
	}
	if (strncmp("Structured Binary Format, Softing GmbH", dat, len)) {
		dev_alert(&card->pdev->dev, "firmware string '%.*s' fault\n",
				len, dat);
		goto failed;
	}
	/* ok, we had a header */
	while (mem < end) {
		ret = fw_parse(&mem, &type, &addr, &len, &dat);
		if (ret)
			goto failed;

		if (type == 3) {
			/* start address */
			start_addr = addr;
			type_entrypoint = 1;
			continue;
		} else if (type == 1) {
			/* eof */
			type_end = 1;
			break;
		} else if (type != 0) {
			dev_alert(&card->pdev->dev,
					"unknown record type 0x%04x\n", type);
			ret = -EINVAL;
			goto failed;
		}

		/* regualar data */
		for (sum = 0, j = 0; j < len; ++j)
			sum += dat[j];
		/* work in 16bit (target) */
		sum &= 0xffff;

		memcpy_toio(&card->dpram[card->pdat->app.offs], dat, len);
		iowrite32(card->pdat->app.offs + card->pdat->app.addr,
				&card->dpram[DPRAM_COMMAND + 2]);
		iowrite32(addr, &card->dpram[DPRAM_COMMAND + 6]);
		iowrite16(len, &card->dpram[DPRAM_COMMAND + 10]);
		iowrite8(1, &card->dpram[DPRAM_COMMAND + 12]);
		ret = softing_bootloader_command(card, 1, "loading app.");
		if (ret < 0)
			goto failed;
		/* verify checksum */
		rx_sum = ioread16(&card->dpram[DPRAM_RECEIPT + 2]);
		if (rx_sum != sum) {
			dev_alert(&card->pdev->dev, "SRAM seems to be damaged"
				", wanted 0x%04x, got 0x%04x\n", sum, rx_sum);
			ret = -EIO;
			goto failed;
		}
	}
	if (!type_end || !type_entrypoint)
		goto failed;
	/* start application in card */
	iowrite32(start_addr, &card->dpram[DPRAM_COMMAND + 2]);
	iowrite8(1, &card->dpram[DPRAM_COMMAND + 6]);
	ret = softing_bootloader_command(card, 3, "start app.");
	if (ret < 0)
		goto failed;
	ret = 0;
failed:
	release_firmware(fw);
	if (ret < 0)
		dev_info(&card->pdev->dev, "firmware %s failed\n", file);
	return ret;
}

static int softing_reset_chip(struct softing *card)
{
	int ret;

	do {
		/* reset chip */
		iowrite8(0, &card->dpram[DPRAM_RESET_RX_FIFO]);
		iowrite8(0, &card->dpram[DPRAM_RESET_RX_FIFO+1]);
		iowrite8(1, &card->dpram[DPRAM_RESET]);
		iowrite8(0, &card->dpram[DPRAM_RESET+1]);

		ret = softing_fct_cmd(card, 0, "reset_can");
		if (!ret)
			break;
		if (signal_pending(current))
			/* don't wait any longer */
			break;
	} while (1);
	card->tx.pending = 0;
	return ret;
}

int softing_chip_poweron(struct softing *card)
{
	int ret;
	/* sync */
	ret = _softing_fct_cmd(card, 99, 0x55, "sync-a");
	if (ret < 0)
		goto failed;

	ret = _softing_fct_cmd(card, 99, 0xaa, "sync-b");
	if (ret < 0)
		goto failed;

	ret = softing_reset_chip(card);
	if (ret < 0)
		goto failed;
	/* get_serial */
	ret = softing_fct_cmd(card, 43, "get_serial_number");
	if (ret < 0)
		goto failed;
	card->id.serial = ioread32(&card->dpram[DPRAM_FCT_PARAM]);
	/* get_version */
	ret = softing_fct_cmd(card, 12, "get_version");
	if (ret < 0)
		goto failed;
	card->id.fw_version = ioread16(&card->dpram[DPRAM_FCT_PARAM + 2]);
	card->id.hw_version = ioread16(&card->dpram[DPRAM_FCT_PARAM + 4]);
	card->id.license = ioread16(&card->dpram[DPRAM_FCT_PARAM + 6]);
	card->id.chip[0] = ioread16(&card->dpram[DPRAM_FCT_PARAM + 8]);
	card->id.chip[1] = ioread16(&card->dpram[DPRAM_FCT_PARAM + 10]);
	return 0;
failed:
	return ret;
}

static void softing_initialize_timestamp(struct softing *card)
{
	uint64_t ovf;

	card->ts_ref = ktime_get();

	/* 16MHz is the reference */
	ovf = 0x100000000ULL * 16;
	do_div(ovf, card->pdat->freq ?: 16);

	card->ts_overflow = ktime_add_us(0, ovf);
}

ktime_t softing_raw2ktime(struct softing *card, u32 raw)
{
	uint64_t rawl;
	ktime_t now, real_offset;
	ktime_t target;
	ktime_t tmp;

	now = ktime_get();
	real_offset = ktime_sub(ktime_get_real(), now);

	/* find nsec from card */
	rawl = raw * 16;
	do_div(rawl, card->pdat->freq ?: 16);
	target = ktime_add_us(card->ts_ref, rawl);
	/* test for overflows */
	tmp = ktime_add(target, card->ts_overflow);
	while (unlikely(ktime_to_ns(tmp) > ktime_to_ns(now))) {
		card->ts_ref = ktime_add(card->ts_ref, card->ts_overflow);
		target = tmp;
		tmp = ktime_add(target, card->ts_overflow);
	}
	return ktime_add(target, real_offset);
}

static inline int softing_error_reporting(struct net_device *netdev)
{
	struct softing_priv *priv = netdev_priv(netdev);

	return (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
		? 1 : 0;
}

int softing_startstop(struct net_device *dev, int up)
{
	int ret;
	struct softing *card;
	struct softing_priv *priv;
	struct net_device *netdev;
	int bus_bitmask_start;
	int j, error_reporting;
	struct can_frame msg;
	const struct can_bittiming *bt;

	priv = netdev_priv(dev);
	card = priv->card;

	if (!card->fw.up)
		return -EIO;

	ret = mutex_lock_interruptible(&card->fw.lock);
	if (ret)
		return ret;

	bus_bitmask_start = 0;
	if (dev && up)
		/* prepare to start this bus as well */
		bus_bitmask_start |= (1 << priv->index);
	/* bring netdevs down */
	for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
		netdev = card->net[j];
		if (!netdev)
			continue;
		priv = netdev_priv(netdev);

		if (dev != netdev)
			netif_stop_queue(netdev);

		if (netif_running(netdev)) {
			if (dev != netdev)
				bus_bitmask_start |= (1 << j);
			priv->tx.pending = 0;
			priv->tx.echo_put = 0;
			priv->tx.echo_get = 0;
			/*
			 * this bus' may just have called open_candev()
			 * which is rather stupid to call close_candev()
			 * already
			 * but we may come here from busoff recovery too
			 * in which case the echo_skb _needs_ flushing too.
			 * just be sure to call open_candev() again
			 */
			close_candev(netdev);
		}
		priv->can.state = CAN_STATE_STOPPED;
	}
	card->tx.pending = 0;

	softing_enable_irq(card, 0);
	ret = softing_reset_chip(card);
	if (ret)
		goto failed;
	if (!bus_bitmask_start)
		/* no busses to be brought up */
		goto card_done;

	if ((bus_bitmask_start & 1) && (bus_bitmask_start & 2)
			&& (softing_error_reporting(card->net[0])
				!= softing_error_reporting(card->net[1]))) {
		dev_alert(&card->pdev->dev,
				"err_reporting flag differs for busses\n");
		goto invalid;
	}
	error_reporting = 0;
	if (bus_bitmask_start & 1) {
		netdev = card->net[0];
		priv = netdev_priv(netdev);
		error_reporting += softing_error_reporting(netdev);
		/* init chip 1 */
		bt = &priv->can.bittiming;
		iowrite16(bt->brp, &card->dpram[DPRAM_FCT_PARAM + 2]);
		iowrite16(bt->sjw, &card->dpram[DPRAM_FCT_PARAM + 4]);
		iowrite16(bt->phase_seg1 + bt->prop_seg,
				&card->dpram[DPRAM_FCT_PARAM + 6]);
		iowrite16(bt->phase_seg2, &card->dpram[DPRAM_FCT_PARAM + 8]);
		iowrite16((priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) ? 1 : 0,
				&card->dpram[DPRAM_FCT_PARAM + 10]);
		ret = softing_fct_cmd(card, 1, "initialize_chip[0]");
		if (ret < 0)
			goto failed;
		/* set mode */
		iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 2]);
		iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 4]);
		ret = softing_fct_cmd(card, 3, "set_mode[0]");
		if (ret < 0)
			goto failed;
		/* set filter */
		/* 11bit id & mask */
		iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 2]);
		iowrite16(0x07ff, &card->dpram[DPRAM_FCT_PARAM + 4]);
		/* 29bit id.lo & mask.lo & id.hi & mask.hi */
		iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 6]);
		iowrite16(0xffff, &card->dpram[DPRAM_FCT_PARAM + 8]);
		iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 10]);
		iowrite16(0x1fff, &card->dpram[DPRAM_FCT_PARAM + 12]);
		ret = softing_fct_cmd(card, 7, "set_filter[0]");
		if (ret < 0)
			goto failed;
		/* set output control */
		iowrite16(priv->output, &card->dpram[DPRAM_FCT_PARAM + 2]);
		ret = softing_fct_cmd(card, 5, "set_output[0]");
		if (ret < 0)
			goto failed;
	}
	if (bus_bitmask_start & 2) {
		netdev = card->net[1];
		priv = netdev_priv(netdev);
		error_reporting += softing_error_reporting(netdev);
		/* init chip2 */
		bt = &priv->can.bittiming;
		iowrite16(bt->brp, &card->dpram[DPRAM_FCT_PARAM + 2]);
		iowrite16(bt->sjw, &card->dpram[DPRAM_FCT_PARAM + 4]);
		iowrite16(bt->phase_seg1 + bt->prop_seg,
				&card->dpram[DPRAM_FCT_PARAM + 6]);
		iowrite16(bt->phase_seg2, &card->dpram[DPRAM_FCT_PARAM + 8]);
		iowrite16((priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) ? 1 : 0,
				&card->dpram[DPRAM_FCT_PARAM + 10]);
		ret = softing_fct_cmd(card, 2, "initialize_chip[1]");
		if (ret < 0)
			goto failed;
		/* set mode2 */
		iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 2]);
		iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 4]);
		ret = softing_fct_cmd(card, 4, "set_mode[1]");
		if (ret < 0)
			goto failed;
		/* set filter2 */
		/* 11bit id & mask */
		iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 2]);
		iowrite16(0x07ff, &card->dpram[DPRAM_FCT_PARAM + 4]);
		/* 29bit id.lo & mask.lo & id.hi & mask.hi */
		iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 6]);
		iowrite16(0xffff, &card->dpram[DPRAM_FCT_PARAM + 8]);
		iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 10]);
		iowrite16(0x1fff, &card->dpram[DPRAM_FCT_PARAM + 12]);
		ret = softing_fct_cmd(card, 8, "set_filter[1]");
		if (ret < 0)
			goto failed;
		/* set output control2 */
		iowrite16(priv->output, &card->dpram[DPRAM_FCT_PARAM + 2]);
		ret = softing_fct_cmd(card, 6, "set_output[1]");
		if (ret < 0)
			goto failed;
	}
	/* enable_error_frame */
	/*
	 * Error reporting is switched off at the moment since
	 * the receiving of them is not yet 100% verified
	 * This should be enabled sooner or later
	 *
	if (error_reporting) {
		ret = softing_fct_cmd(card, 51, "enable_error_frame");
		if (ret < 0)
			goto failed;
	}
	*/
	/* initialize interface */
	iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 2]);
	iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 4]);
	iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 6]);
	iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 8]);
	iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 10]);
	iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 12]);
	iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 14]);
	iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 16]);
	iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 18]);
	iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 20]);
	ret = softing_fct_cmd(card, 17, "initialize_interface");
	if (ret < 0)
		goto failed;
	/* enable_fifo */
	ret = softing_fct_cmd(card, 36, "enable_fifo");
	if (ret < 0)
		goto failed;
	/* enable fifo tx ack */
	ret = softing_fct_cmd(card, 13, "fifo_tx_ack[0]");
	if (ret < 0)
		goto failed;
	/* enable fifo tx ack2 */
	ret = softing_fct_cmd(card, 14, "fifo_tx_ack[1]");
	if (ret < 0)
		goto failed;
	/* start_chip */
	ret = softing_fct_cmd(card, 11, "start_chip");
	if (ret < 0)
		goto failed;
	iowrite8(0, &card->dpram[DPRAM_INFO_BUSSTATE]);
	iowrite8(0, &card->dpram[DPRAM_INFO_BUSSTATE2]);
	if (card->pdat->generation < 2) {
		iowrite8(0, &card->dpram[DPRAM_V2_IRQ_TOHOST]);
		/* flush the DPRAM caches */
		wmb();
	}

	softing_initialize_timestamp(card);

	/*
	 * do socketcan notifications/status changes
	 * from here, no errors should occur, or the failed: part
	 * must be reviewed
	 */
	memset(&msg, 0, sizeof(msg));
	msg.can_id = CAN_ERR_FLAG | CAN_ERR_RESTARTED;
	msg.can_dlc = CAN_ERR_DLC;
	for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
		if (!(bus_bitmask_start & (1 << j)))
			continue;
		netdev = card->net[j];
		if (!netdev)
			continue;
		priv = netdev_priv(netdev);
		priv->can.state = CAN_STATE_ERROR_ACTIVE;
		open_candev(netdev);
		if (dev != netdev) {
			/* notify other busses on the restart */
			softing_netdev_rx(netdev, &msg, 0);
			++priv->can.can_stats.restarts;
		}
		netif_wake_queue(netdev);
	}

	/* enable interrupts */
	ret = softing_enable_irq(card, 1);
	if (ret)
		goto failed;
card_done:
	mutex_unlock(&card->fw.lock);
	return 0;
invalid:
	ret = -EINVAL;
failed:
	softing_enable_irq(card, 0);
	softing_reset_chip(card);
	mutex_unlock(&card->fw.lock);
	/* bring all other interfaces down */
	for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
		netdev = card->net[j];
		if (!netdev)
			continue;
		dev_close(netdev);
	}
	return ret;
}

int softing_default_output(struct net_device *netdev)
{
	struct softing_priv *priv = netdev_priv(netdev);
	struct softing *card = priv->card;

	switch (priv->chip) {
	case 1000:
		return (card->pdat->generation < 2) ? 0xfb : 0xfa;
	case 5:
		return 0x60;
	default:
		return 0x40;
	}
}
