// SPDX-License-Identifier: GPL-2.0
//
// mcp251xfd - Microchip MCP251xFD Family CAN controller driver
//
// Copyright (c) 2019, 2020, 2021 Pengutronix,
//               Marc Kleine-Budde <kernel@pengutronix.de>
//
// Based on:
//
// CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
//
// Copyright (c) 2019 Martin Sperl <kernel@martin.sperl.org>
//

#include <asm/unaligned.h>

#include "mcp251xfd.h"
#include "mcp251xfd-ram.h"

static inline u8
mcp251xfd_cmd_prepare_write_reg(const struct mcp251xfd_priv *priv,
				union mcp251xfd_write_reg_buf *write_reg_buf,
				const u16 reg, const u32 mask, const u32 val)
{
	u8 first_byte, last_byte, len;
	u8 *data;
	__le32 val_le32;

	first_byte = mcp251xfd_first_byte_set(mask);
	last_byte = mcp251xfd_last_byte_set(mask);
	len = last_byte - first_byte + 1;

	data = mcp251xfd_spi_cmd_write(priv, write_reg_buf, reg + first_byte);
	val_le32 = cpu_to_le32(val >> BITS_PER_BYTE * first_byte);
	memcpy(data, &val_le32, len);

	if (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG) {
		u16 crc;

		mcp251xfd_spi_cmd_crc_set_len_in_reg(&write_reg_buf->crc.cmd,
						     len);
		/* CRC */
		len += sizeof(write_reg_buf->crc.cmd);
		crc = mcp251xfd_crc16_compute(&write_reg_buf->crc, len);
		put_unaligned_be16(crc, (void *)write_reg_buf + len);

		/* Total length */
		len += sizeof(write_reg_buf->crc.crc);
	} else {
		len += sizeof(write_reg_buf->nocrc.cmd);
	}

	return len;
}

static void
mcp251xfd_ring_init_tef(struct mcp251xfd_priv *priv, u16 *base)
{
	struct mcp251xfd_tef_ring *tef_ring;
	struct spi_transfer *xfer;
	u32 val;
	u16 addr;
	u8 len;
	int i;

	/* TEF */
	tef_ring = priv->tef;
	tef_ring->head = 0;
	tef_ring->tail = 0;

	/* TEF- and TX-FIFO have same number of objects */
	*base = mcp251xfd_get_tef_obj_addr(priv->tx->obj_num);

	/* FIFO IRQ enable */
	addr = MCP251XFD_REG_TEFCON;
	val = MCP251XFD_REG_TEFCON_TEFOVIE | MCP251XFD_REG_TEFCON_TEFNEIE;

	len = mcp251xfd_cmd_prepare_write_reg(priv, &tef_ring->irq_enable_buf,
					      addr, val, val);
	tef_ring->irq_enable_xfer.tx_buf = &tef_ring->irq_enable_buf;
	tef_ring->irq_enable_xfer.len = len;
	spi_message_init_with_transfers(&tef_ring->irq_enable_msg,
					&tef_ring->irq_enable_xfer, 1);

	/* FIFO increment TEF tail pointer */
	addr = MCP251XFD_REG_TEFCON;
	val = MCP251XFD_REG_TEFCON_UINC;
	len = mcp251xfd_cmd_prepare_write_reg(priv, &tef_ring->uinc_buf,
					      addr, val, val);

	for (i = 0; i < ARRAY_SIZE(tef_ring->uinc_xfer); i++) {
		xfer = &tef_ring->uinc_xfer[i];
		xfer->tx_buf = &tef_ring->uinc_buf;
		xfer->len = len;
		xfer->cs_change = 1;
		xfer->cs_change_delay.value = 0;
		xfer->cs_change_delay.unit = SPI_DELAY_UNIT_NSECS;
	}

	/* "cs_change == 1" on the last transfer results in an active
	 * chip select after the complete SPI message. This causes the
	 * controller to interpret the next register access as
	 * data. Set "cs_change" of the last transfer to "0" to
	 * properly deactivate the chip select at the end of the
	 * message.
	 */
	xfer->cs_change = 0;

	if (priv->tx_coalesce_usecs_irq || priv->tx_obj_num_coalesce_irq) {
		val = MCP251XFD_REG_TEFCON_UINC |
			MCP251XFD_REG_TEFCON_TEFOVIE |
			MCP251XFD_REG_TEFCON_TEFHIE;

		len = mcp251xfd_cmd_prepare_write_reg(priv,
						      &tef_ring->uinc_irq_disable_buf,
						      addr, val, val);
		xfer->tx_buf = &tef_ring->uinc_irq_disable_buf;
		xfer->len = len;
	}
}

static void
mcp251xfd_tx_ring_init_tx_obj(const struct mcp251xfd_priv *priv,
			      const struct mcp251xfd_tx_ring *ring,
			      struct mcp251xfd_tx_obj *tx_obj,
			      const u8 rts_buf_len,
			      const u8 n)
{
	struct spi_transfer *xfer;
	u16 addr;

	/* FIFO load */
	addr = mcp251xfd_get_tx_obj_addr(ring, n);
	if (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_TX)
		mcp251xfd_spi_cmd_write_crc_set_addr(&tx_obj->buf.crc.cmd,
						     addr);
	else
		mcp251xfd_spi_cmd_write_nocrc(&tx_obj->buf.nocrc.cmd,
					      addr);

	xfer = &tx_obj->xfer[0];
	xfer->tx_buf = &tx_obj->buf;
	xfer->len = 0;	/* actual len is assigned on the fly */
	xfer->cs_change = 1;
	xfer->cs_change_delay.value = 0;
	xfer->cs_change_delay.unit = SPI_DELAY_UNIT_NSECS;

	/* FIFO request to send */
	xfer = &tx_obj->xfer[1];
	xfer->tx_buf = &ring->rts_buf;
	xfer->len = rts_buf_len;

	/* SPI message */
	spi_message_init_with_transfers(&tx_obj->msg, tx_obj->xfer,
					ARRAY_SIZE(tx_obj->xfer));
}

static void
mcp251xfd_ring_init_tx(struct mcp251xfd_priv *priv, u16 *base, u8 *fifo_nr)
{
	struct mcp251xfd_tx_ring *tx_ring;
	struct mcp251xfd_tx_obj *tx_obj;
	u32 val;
	u16 addr;
	u8 len;
	int i;

	tx_ring = priv->tx;
	tx_ring->head = 0;
	tx_ring->tail = 0;
	tx_ring->base = *base;
	tx_ring->nr = 0;
	tx_ring->fifo_nr = *fifo_nr;

	*base = mcp251xfd_get_tx_obj_addr(tx_ring, tx_ring->obj_num);
	*fifo_nr += 1;

	/* FIFO request to send */
	addr = MCP251XFD_REG_FIFOCON(tx_ring->fifo_nr);
	val = MCP251XFD_REG_FIFOCON_TXREQ | MCP251XFD_REG_FIFOCON_UINC;
	len = mcp251xfd_cmd_prepare_write_reg(priv, &tx_ring->rts_buf,
					      addr, val, val);

	mcp251xfd_for_each_tx_obj(tx_ring, tx_obj, i)
		mcp251xfd_tx_ring_init_tx_obj(priv, tx_ring, tx_obj, len, i);
}

static void
mcp251xfd_ring_init_rx(struct mcp251xfd_priv *priv, u16 *base, u8 *fifo_nr)
{
	struct mcp251xfd_rx_ring *rx_ring;
	struct spi_transfer *xfer;
	u32 val;
	u16 addr;
	u8 len;
	int i, j;

	mcp251xfd_for_each_rx_ring(priv, rx_ring, i) {
		rx_ring->head = 0;
		rx_ring->tail = 0;
		rx_ring->base = *base;
		rx_ring->nr = i;
		rx_ring->fifo_nr = *fifo_nr;

		*base = mcp251xfd_get_rx_obj_addr(rx_ring, rx_ring->obj_num);
		*fifo_nr += 1;

		/* FIFO IRQ enable */
		addr = MCP251XFD_REG_FIFOCON(rx_ring->fifo_nr);
		val = MCP251XFD_REG_FIFOCON_RXOVIE |
			MCP251XFD_REG_FIFOCON_TFNRFNIE;
		len = mcp251xfd_cmd_prepare_write_reg(priv, &rx_ring->irq_enable_buf,
						      addr, val, val);
		rx_ring->irq_enable_xfer.tx_buf = &rx_ring->irq_enable_buf;
		rx_ring->irq_enable_xfer.len = len;
		spi_message_init_with_transfers(&rx_ring->irq_enable_msg,
						&rx_ring->irq_enable_xfer, 1);

		/* FIFO increment RX tail pointer */
		val = MCP251XFD_REG_FIFOCON_UINC;
		len = mcp251xfd_cmd_prepare_write_reg(priv, &rx_ring->uinc_buf,
						      addr, val, val);

		for (j = 0; j < ARRAY_SIZE(rx_ring->uinc_xfer); j++) {
			xfer = &rx_ring->uinc_xfer[j];
			xfer->tx_buf = &rx_ring->uinc_buf;
			xfer->len = len;
			xfer->cs_change = 1;
			xfer->cs_change_delay.value = 0;
			xfer->cs_change_delay.unit = SPI_DELAY_UNIT_NSECS;
		}

		/* "cs_change == 1" on the last transfer results in an
		 * active chip select after the complete SPI
		 * message. This causes the controller to interpret
		 * the next register access as data. Set "cs_change"
		 * of the last transfer to "0" to properly deactivate
		 * the chip select at the end of the message.
		 */
		xfer->cs_change = 0;

		/* Use 1st RX-FIFO for IRQ coalescing. If enabled
		 * (rx_coalesce_usecs_irq or rx_max_coalesce_frames_irq
		 * is activated), use the last transfer to disable:
		 *
		 * - TFNRFNIE (Receive FIFO Not Empty Interrupt)
		 *
		 * and enable:
		 *
		 * - TFHRFHIE (Receive FIFO Half Full Interrupt)
		 *   - or -
		 * - TFERFFIE (Receive FIFO Full Interrupt)
		 *
		 * depending on rx_max_coalesce_frames_irq.
		 *
		 * The RXOVIE (Overflow Interrupt) is always enabled.
		 */
		if (rx_ring->nr == 0 && (priv->rx_coalesce_usecs_irq ||
					 priv->rx_obj_num_coalesce_irq)) {
			val = MCP251XFD_REG_FIFOCON_UINC |
				MCP251XFD_REG_FIFOCON_RXOVIE;

			if (priv->rx_obj_num_coalesce_irq == rx_ring->obj_num)
				val |= MCP251XFD_REG_FIFOCON_TFERFFIE;
			else if (priv->rx_obj_num_coalesce_irq)
				val |= MCP251XFD_REG_FIFOCON_TFHRFHIE;

			len = mcp251xfd_cmd_prepare_write_reg(priv,
							      &rx_ring->uinc_irq_disable_buf,
							      addr, val, val);
			xfer->tx_buf = &rx_ring->uinc_irq_disable_buf;
			xfer->len = len;
		}
	}
}

int mcp251xfd_ring_init(struct mcp251xfd_priv *priv)
{
	const struct mcp251xfd_rx_ring *rx_ring;
	u16 base = 0, ram_used;
	u8 fifo_nr = 1;
	int i;

	netdev_reset_queue(priv->ndev);

	mcp251xfd_ring_init_tef(priv, &base);
	mcp251xfd_ring_init_rx(priv, &base, &fifo_nr);
	mcp251xfd_ring_init_tx(priv, &base, &fifo_nr);

	/* mcp251xfd_handle_rxif() will iterate over all RX rings.
	 * Rings with their corresponding bit set in
	 * priv->regs_status.rxif are read out.
	 *
	 * If the chip is configured for only 1 RX-FIFO, and if there
	 * is an RX interrupt pending (RXIF in INT register is set),
	 * it must be the 1st RX-FIFO.
	 *
	 * We mark the RXIF of the 1st FIFO as pending here, so that
	 * we can skip the read of the RXIF register in
	 * mcp251xfd_read_regs_status() for the 1 RX-FIFO only case.
	 *
	 * If we use more than 1 RX-FIFO, this value gets overwritten
	 * in mcp251xfd_read_regs_status(), so set it unconditionally
	 * here.
	 */
	priv->regs_status.rxif = BIT(priv->rx[0]->fifo_nr);

	if (priv->tx_obj_num_coalesce_irq) {
		netdev_dbg(priv->ndev,
			   "FIFO setup: TEF:         0x%03x: %2d*%zu bytes = %4zu bytes (coalesce)\n",
			   mcp251xfd_get_tef_obj_addr(0),
			   priv->tx_obj_num_coalesce_irq,
			   sizeof(struct mcp251xfd_hw_tef_obj),
			   priv->tx_obj_num_coalesce_irq *
			   sizeof(struct mcp251xfd_hw_tef_obj));

		netdev_dbg(priv->ndev,
			   "                         0x%03x: %2d*%zu bytes = %4zu bytes\n",
			   mcp251xfd_get_tef_obj_addr(priv->tx_obj_num_coalesce_irq),
			   priv->tx->obj_num - priv->tx_obj_num_coalesce_irq,
			   sizeof(struct mcp251xfd_hw_tef_obj),
			   (priv->tx->obj_num - priv->tx_obj_num_coalesce_irq) *
			   sizeof(struct mcp251xfd_hw_tef_obj));
	} else {
		netdev_dbg(priv->ndev,
			   "FIFO setup: TEF:         0x%03x: %2d*%zu bytes = %4zu bytes\n",
			   mcp251xfd_get_tef_obj_addr(0),
			   priv->tx->obj_num, sizeof(struct mcp251xfd_hw_tef_obj),
			   priv->tx->obj_num * sizeof(struct mcp251xfd_hw_tef_obj));
	}

	mcp251xfd_for_each_rx_ring(priv, rx_ring, i) {
		if (rx_ring->nr == 0 && priv->rx_obj_num_coalesce_irq) {
			netdev_dbg(priv->ndev,
				   "FIFO setup: RX-%u: FIFO %u/0x%03x: %2u*%u bytes = %4u bytes (coalesce)\n",
				   rx_ring->nr, rx_ring->fifo_nr,
				   mcp251xfd_get_rx_obj_addr(rx_ring, 0),
				   priv->rx_obj_num_coalesce_irq, rx_ring->obj_size,
				   priv->rx_obj_num_coalesce_irq * rx_ring->obj_size);

			if (priv->rx_obj_num_coalesce_irq == MCP251XFD_FIFO_DEPTH)
				continue;

			netdev_dbg(priv->ndev,
				   "                         0x%03x: %2u*%u bytes = %4u bytes\n",
				   mcp251xfd_get_rx_obj_addr(rx_ring,
							     priv->rx_obj_num_coalesce_irq),
				   rx_ring->obj_num - priv->rx_obj_num_coalesce_irq,
				   rx_ring->obj_size,
				   (rx_ring->obj_num - priv->rx_obj_num_coalesce_irq) *
				   rx_ring->obj_size);
		} else {
			netdev_dbg(priv->ndev,
				   "FIFO setup: RX-%u: FIFO %u/0x%03x: %2u*%u bytes = %4u bytes\n",
				   rx_ring->nr, rx_ring->fifo_nr,
				   mcp251xfd_get_rx_obj_addr(rx_ring, 0),
				   rx_ring->obj_num, rx_ring->obj_size,
				   rx_ring->obj_num * rx_ring->obj_size);
		}
	}

	netdev_dbg(priv->ndev,
		   "FIFO setup: TX:   FIFO %u/0x%03x: %2u*%u bytes = %4u bytes\n",
		   priv->tx->fifo_nr,
		   mcp251xfd_get_tx_obj_addr(priv->tx, 0),
		   priv->tx->obj_num, priv->tx->obj_size,
		   priv->tx->obj_num * priv->tx->obj_size);

	netdev_dbg(priv->ndev,
		   "FIFO setup: free:                             %4d bytes\n",
		   MCP251XFD_RAM_SIZE - (base - MCP251XFD_RAM_START));

	ram_used = base - MCP251XFD_RAM_START;
	if (ram_used > MCP251XFD_RAM_SIZE) {
		netdev_err(priv->ndev,
			   "Error during ring configuration, using more RAM (%u bytes) than available (%u bytes).\n",
			   ram_used, MCP251XFD_RAM_SIZE);
		return -ENOMEM;
	}

	return 0;
}

void mcp251xfd_ring_free(struct mcp251xfd_priv *priv)
{
	int i;

	for (i = ARRAY_SIZE(priv->rx) - 1; i >= 0; i--) {
		kfree(priv->rx[i]);
		priv->rx[i] = NULL;
	}
}

static enum hrtimer_restart mcp251xfd_rx_irq_timer(struct hrtimer *t)
{
	struct mcp251xfd_priv *priv = container_of(t, struct mcp251xfd_priv,
						   rx_irq_timer);
	struct mcp251xfd_rx_ring *ring = priv->rx[0];

	if (test_bit(MCP251XFD_FLAGS_DOWN, priv->flags))
		return HRTIMER_NORESTART;

	spi_async(priv->spi, &ring->irq_enable_msg);

	return HRTIMER_NORESTART;
}

static enum hrtimer_restart mcp251xfd_tx_irq_timer(struct hrtimer *t)
{
	struct mcp251xfd_priv *priv = container_of(t, struct mcp251xfd_priv,
						   tx_irq_timer);
	struct mcp251xfd_tef_ring *ring = priv->tef;

	if (test_bit(MCP251XFD_FLAGS_DOWN, priv->flags))
		return HRTIMER_NORESTART;

	spi_async(priv->spi, &ring->irq_enable_msg);

	return HRTIMER_NORESTART;
}

const struct can_ram_config mcp251xfd_ram_config = {
	.rx = {
		.size[CAN_RAM_MODE_CAN] = sizeof(struct mcp251xfd_hw_rx_obj_can),
		.size[CAN_RAM_MODE_CANFD] = sizeof(struct mcp251xfd_hw_rx_obj_canfd),
		.min = MCP251XFD_RX_OBJ_NUM_MIN,
		.max = MCP251XFD_RX_OBJ_NUM_MAX,
		.def[CAN_RAM_MODE_CAN] = CAN_RAM_NUM_MAX,
		.def[CAN_RAM_MODE_CANFD] = CAN_RAM_NUM_MAX,
		.fifo_num = MCP251XFD_FIFO_RX_NUM,
		.fifo_depth_min = MCP251XFD_RX_FIFO_DEPTH_MIN,
		.fifo_depth_coalesce_min = MCP251XFD_RX_FIFO_DEPTH_COALESCE_MIN,
	},
	.tx = {
		.size[CAN_RAM_MODE_CAN] = sizeof(struct mcp251xfd_hw_tef_obj) +
			sizeof(struct mcp251xfd_hw_tx_obj_can),
		.size[CAN_RAM_MODE_CANFD] = sizeof(struct mcp251xfd_hw_tef_obj) +
			sizeof(struct mcp251xfd_hw_tx_obj_canfd),
		.min = MCP251XFD_TX_OBJ_NUM_MIN,
		.max = MCP251XFD_TX_OBJ_NUM_MAX,
		.def[CAN_RAM_MODE_CAN] = MCP251XFD_TX_OBJ_NUM_CAN_DEFAULT,
		.def[CAN_RAM_MODE_CANFD] = MCP251XFD_TX_OBJ_NUM_CANFD_DEFAULT,
		.fifo_num = MCP251XFD_FIFO_TX_NUM,
		.fifo_depth_min = MCP251XFD_TX_FIFO_DEPTH_MIN,
		.fifo_depth_coalesce_min = MCP251XFD_TX_FIFO_DEPTH_COALESCE_MIN,
	},
	.size = MCP251XFD_RAM_SIZE,
	.fifo_depth = MCP251XFD_FIFO_DEPTH,
};

int mcp251xfd_ring_alloc(struct mcp251xfd_priv *priv)
{
	const bool fd_mode = mcp251xfd_is_fd_mode(priv);
	struct mcp251xfd_tx_ring *tx_ring = priv->tx;
	struct mcp251xfd_rx_ring *rx_ring;
	u8 tx_obj_size, rx_obj_size;
	u8 rem, i;

	/* switching from CAN-2.0 to CAN-FD mode or vice versa */
	if (fd_mode != test_bit(MCP251XFD_FLAGS_FD_MODE, priv->flags)) {
		struct can_ram_layout layout;

		can_ram_get_layout(&layout, &mcp251xfd_ram_config, NULL, NULL, fd_mode);
		priv->rx_obj_num = layout.default_rx;
		tx_ring->obj_num = layout.default_tx;
	}

	if (fd_mode) {
		tx_obj_size = sizeof(struct mcp251xfd_hw_tx_obj_canfd);
		rx_obj_size = sizeof(struct mcp251xfd_hw_rx_obj_canfd);
		set_bit(MCP251XFD_FLAGS_FD_MODE, priv->flags);
	} else {
		tx_obj_size = sizeof(struct mcp251xfd_hw_tx_obj_can);
		rx_obj_size = sizeof(struct mcp251xfd_hw_rx_obj_can);
		clear_bit(MCP251XFD_FLAGS_FD_MODE, priv->flags);
	}

	tx_ring->obj_size = tx_obj_size;

	rem = priv->rx_obj_num;
	for (i = 0; i < ARRAY_SIZE(priv->rx) && rem; i++) {
		u8 rx_obj_num;

		if (i == 0 && priv->rx_obj_num_coalesce_irq)
			rx_obj_num = min_t(u8, priv->rx_obj_num_coalesce_irq * 2,
					   MCP251XFD_FIFO_DEPTH);
		else
			rx_obj_num = min_t(u8, rounddown_pow_of_two(rem),
					   MCP251XFD_FIFO_DEPTH);
		rem -= rx_obj_num;

		rx_ring = kzalloc(sizeof(*rx_ring) + rx_obj_size * rx_obj_num,
				  GFP_KERNEL);
		if (!rx_ring) {
			mcp251xfd_ring_free(priv);
			return -ENOMEM;
		}

		rx_ring->obj_num = rx_obj_num;
		rx_ring->obj_size = rx_obj_size;
		priv->rx[i] = rx_ring;
	}
	priv->rx_ring_num = i;

	hrtimer_init(&priv->rx_irq_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	priv->rx_irq_timer.function = mcp251xfd_rx_irq_timer;

	hrtimer_init(&priv->tx_irq_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	priv->tx_irq_timer.function = mcp251xfd_tx_irq_timer;

	return 0;
}
