// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (C) 2015 - 2016 Thomas Körper, esd electronic system design gmbh
 * Copyright (C) 2017 - 2023 Stefan Mätje, esd electronics gmbh
 */

#include "esdacc.h"

#include <linux/bitfield.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/ktime.h>

/* esdACC ID register layout */
#define ACC_ID_ID_MASK GENMASK(28, 0)
#define ACC_ID_EFF_FLAG BIT(29)

/* esdACC DLC register layout */
#define ACC_DLC_DLC_MASK GENMASK(3, 0)
#define ACC_DLC_RTR_FLAG BIT(4)
#define ACC_DLC_SSTX_FLAG BIT(24)	/* Single Shot TX */

/* esdACC DLC in struct acc_bmmsg_rxtxdone::acc_dlc.len only! */
#define ACC_DLC_TXD_FLAG BIT(5)

/* ecc value of esdACC equals SJA1000's ECC register */
#define ACC_ECC_SEG 0x1f
#define ACC_ECC_DIR 0x20
#define ACC_ECC_BIT 0x00
#define ACC_ECC_FORM 0x40
#define ACC_ECC_STUFF 0x80
#define ACC_ECC_MASK 0xc0

/* esdACC Status Register bits. Unused bits not documented. */
#define ACC_REG_STATUS_MASK_STATUS_ES BIT(17)
#define ACC_REG_STATUS_MASK_STATUS_EP BIT(18)
#define ACC_REG_STATUS_MASK_STATUS_BS BIT(19)

/* esdACC Overview Module BM_IRQ_Mask register related defines */
/*   Two bit wide command masks to mask or unmask a single core IRQ */
#define ACC_BM_IRQ_UNMASK BIT(0)
#define ACC_BM_IRQ_MASK (ACC_BM_IRQ_UNMASK << 1)
/*   Command to unmask all IRQ sources. Created by shifting
 *   and oring the two bit wide ACC_BM_IRQ_UNMASK 16 times.
 */
#define ACC_BM_IRQ_UNMASK_ALL 0x55555555U

static void acc_resetmode_enter(struct acc_core *core)
{
	acc_set_bits(core, ACC_CORE_OF_CTRL,
		     ACC_REG_CTRL_MASK_RESETMODE);

	/* Read back reset mode bit to flush PCI write posting */
	acc_resetmode_entered(core);
}

static void acc_resetmode_leave(struct acc_core *core)
{
	acc_clear_bits(core, ACC_CORE_OF_CTRL,
		       ACC_REG_CTRL_MASK_RESETMODE);

	/* Read back reset mode bit to flush PCI write posting */
	acc_resetmode_entered(core);
}

static void acc_txq_put(struct acc_core *core, u32 acc_id, u32 acc_dlc,
			const void *data)
{
	acc_write32_noswap(core, ACC_CORE_OF_TXFIFO_DATA_1,
			   *((const u32 *)(data + 4)));
	acc_write32_noswap(core, ACC_CORE_OF_TXFIFO_DATA_0,
			   *((const u32 *)data));
	acc_write32(core, ACC_CORE_OF_TXFIFO_DLC, acc_dlc);
	/* CAN id must be written at last. This write starts TX. */
	acc_write32(core, ACC_CORE_OF_TXFIFO_ID, acc_id);
}

static u8 acc_tx_fifo_next(struct acc_core *core, u8 tx_fifo_idx)
{
	++tx_fifo_idx;
	if (tx_fifo_idx >= core->tx_fifo_size)
		tx_fifo_idx = 0U;
	return tx_fifo_idx;
}

/* Convert timestamp from esdACC time stamp ticks to ns
 *
 * The conversion factor ts2ns from time stamp counts to ns is basically
 *	ts2ns = NSEC_PER_SEC / timestamp_frequency
 *
 * We handle here only a fixed timestamp frequency of 80MHz. The
 * resulting ts2ns factor would be 12.5.
 *
 * At the end we multiply by 12 and add the half of the HW timestamp
 * to get a multiplication by 12.5. This way any overflow is
 * avoided until ktime_t itself overflows.
 */
#define ACC_TS_FACTOR (NSEC_PER_SEC / ACC_TS_FREQ_80MHZ)
#define ACC_TS_80MHZ_SHIFT 1

static ktime_t acc_ts2ktime(struct acc_ov *ov, u64 ts)
{
	u64 ns;

	ns = (ts * ACC_TS_FACTOR) + (ts >> ACC_TS_80MHZ_SHIFT);

	return ns_to_ktime(ns);
}

#undef ACC_TS_FACTOR
#undef ACC_TS_80MHZ_SHIFT

void acc_init_ov(struct acc_ov *ov, struct device *dev)
{
	u32 temp;

	temp = acc_ov_read32(ov, ACC_OV_OF_VERSION);
	ov->version = temp;
	ov->features = (temp >> 16);

	temp = acc_ov_read32(ov, ACC_OV_OF_INFO);
	ov->total_cores = temp;
	ov->active_cores = (temp >> 8);

	ov->core_frequency = acc_ov_read32(ov, ACC_OV_OF_CANCORE_FREQ);
	ov->timestamp_frequency = acc_ov_read32(ov, ACC_OV_OF_TS_FREQ_LO);

	/* Depending on esdACC feature NEW_PSC enable the new prescaler
	 * or adjust core_frequency according to the implicit division by 2.
	 */
	if (ov->features & ACC_OV_REG_FEAT_MASK_NEW_PSC) {
		acc_ov_set_bits(ov, ACC_OV_OF_MODE,
				ACC_OV_REG_MODE_MASK_NEW_PSC_ENABLE);
	} else {
		ov->core_frequency /= 2;
	}

	dev_dbg(dev,
		"esdACC v%u, freq: %u/%u, feat/strap: 0x%x/0x%x, cores: %u/%u\n",
		ov->version, ov->core_frequency, ov->timestamp_frequency,
		ov->features, acc_ov_read32(ov, ACC_OV_OF_INFO) >> 16,
		ov->active_cores, ov->total_cores);
}

void acc_init_bm_ptr(struct acc_ov *ov, struct acc_core *cores, const void *mem)
{
	unsigned int u;

	/* DMA buffer layout as follows where N is the number of CAN cores
	 * implemented in the FPGA, i.e. N = ov->total_cores
	 *
	 *  Section Layout           Section size
	 * ----------------------------------------------
	 *  FIFO Card/Overview	     ACC_CORE_DMABUF_SIZE
	 *  FIFO Core0               ACC_CORE_DMABUF_SIZE
	 *  ...                      ...
	 *  FIFO CoreN               ACC_CORE_DMABUF_SIZE
	 *  irq_cnt Card/Overview    sizeof(u32)
	 *  irq_cnt Core0            sizeof(u32)
	 *  ...                      ...
	 *  irq_cnt CoreN            sizeof(u32)
	 */
	ov->bmfifo.messages = mem;
	ov->bmfifo.irq_cnt = mem + (ov->total_cores + 1U) * ACC_CORE_DMABUF_SIZE;

	for (u = 0U; u < ov->active_cores; u++) {
		struct acc_core *core = &cores[u];

		core->bmfifo.messages = mem + (u + 1U) * ACC_CORE_DMABUF_SIZE;
		core->bmfifo.irq_cnt = ov->bmfifo.irq_cnt + (u + 1U);
	}
}

int acc_open(struct net_device *netdev)
{
	struct acc_net_priv *priv = netdev_priv(netdev);
	struct acc_core *core = priv->core;
	u32 tx_fifo_status;
	u32 ctrl;
	int err;

	/* Retry to enter RESET mode if out of sync. */
	if (priv->can.state != CAN_STATE_STOPPED) {
		netdev_warn(netdev, "Entered %s() with bad can.state: %s\n",
			    __func__, can_get_state_str(priv->can.state));
		acc_resetmode_enter(core);
		priv->can.state = CAN_STATE_STOPPED;
	}

	err = open_candev(netdev);
	if (err)
		return err;

	ctrl = ACC_REG_CTRL_MASK_IE_RXTX |
		ACC_REG_CTRL_MASK_IE_TXERROR |
		ACC_REG_CTRL_MASK_IE_ERRWARN |
		ACC_REG_CTRL_MASK_IE_OVERRUN |
		ACC_REG_CTRL_MASK_IE_ERRPASS;

	if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
		ctrl |= ACC_REG_CTRL_MASK_IE_BUSERR;

	if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
		ctrl |= ACC_REG_CTRL_MASK_LOM;

	acc_set_bits(core, ACC_CORE_OF_CTRL, ctrl);

	acc_resetmode_leave(core);
	priv->can.state = CAN_STATE_ERROR_ACTIVE;

	/* Resync TX FIFO indices to HW state after (re-)start. */
	tx_fifo_status = acc_read32(core, ACC_CORE_OF_TXFIFO_STATUS);
	core->tx_fifo_head = tx_fifo_status & 0xff;
	core->tx_fifo_tail = (tx_fifo_status >> 8) & 0xff;

	netif_start_queue(netdev);
	return 0;
}

int acc_close(struct net_device *netdev)
{
	struct acc_net_priv *priv = netdev_priv(netdev);
	struct acc_core *core = priv->core;

	acc_clear_bits(core, ACC_CORE_OF_CTRL,
		       ACC_REG_CTRL_MASK_IE_RXTX |
		       ACC_REG_CTRL_MASK_IE_TXERROR |
		       ACC_REG_CTRL_MASK_IE_ERRWARN |
		       ACC_REG_CTRL_MASK_IE_OVERRUN |
		       ACC_REG_CTRL_MASK_IE_ERRPASS |
		       ACC_REG_CTRL_MASK_IE_BUSERR);

	netif_stop_queue(netdev);
	acc_resetmode_enter(core);
	priv->can.state = CAN_STATE_STOPPED;

	/* Mark pending TX requests to be aborted after controller restart. */
	acc_write32(core, ACC_CORE_OF_TX_ABORT_MASK, 0xffff);

	/* ACC_REG_CTRL_MASK_LOM is only accessible in RESET mode */
	acc_clear_bits(core, ACC_CORE_OF_CTRL,
		       ACC_REG_CTRL_MASK_LOM);

	close_candev(netdev);
	return 0;
}

netdev_tx_t acc_start_xmit(struct sk_buff *skb, struct net_device *netdev)
{
	struct acc_net_priv *priv = netdev_priv(netdev);
	struct acc_core *core = priv->core;
	struct can_frame *cf = (struct can_frame *)skb->data;
	u8 tx_fifo_head = core->tx_fifo_head;
	int fifo_usage;
	u32 acc_id;
	u32 acc_dlc;

	if (can_dropped_invalid_skb(netdev, skb))
		return NETDEV_TX_OK;

	/* Access core->tx_fifo_tail only once because it may be changed
	 * from the interrupt level.
	 */
	fifo_usage = tx_fifo_head - core->tx_fifo_tail;
	if (fifo_usage < 0)
		fifo_usage += core->tx_fifo_size;

	if (fifo_usage >= core->tx_fifo_size - 1) {
		netdev_err(core->netdev,
			   "BUG: TX ring full when queue awake!\n");
		netif_stop_queue(netdev);
		return NETDEV_TX_BUSY;
	}

	if (fifo_usage == core->tx_fifo_size - 2)
		netif_stop_queue(netdev);

	acc_dlc = can_get_cc_dlc(cf, priv->can.ctrlmode);
	if (cf->can_id & CAN_RTR_FLAG)
		acc_dlc |= ACC_DLC_RTR_FLAG;
	if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT)
		acc_dlc |= ACC_DLC_SSTX_FLAG;

	if (cf->can_id & CAN_EFF_FLAG) {
		acc_id = cf->can_id & CAN_EFF_MASK;
		acc_id |= ACC_ID_EFF_FLAG;
	} else {
		acc_id = cf->can_id & CAN_SFF_MASK;
	}

	can_put_echo_skb(skb, netdev, core->tx_fifo_head, 0);

	core->tx_fifo_head = acc_tx_fifo_next(core, tx_fifo_head);

	acc_txq_put(core, acc_id, acc_dlc, cf->data);

	return NETDEV_TX_OK;
}

int acc_get_berr_counter(const struct net_device *netdev,
			 struct can_berr_counter *bec)
{
	struct acc_net_priv *priv = netdev_priv(netdev);
	u32 core_status = acc_read32(priv->core, ACC_CORE_OF_STATUS);

	bec->txerr = (core_status >> 8) & 0xff;
	bec->rxerr = core_status & 0xff;

	return 0;
}

int acc_set_mode(struct net_device *netdev, enum can_mode mode)
{
	struct acc_net_priv *priv = netdev_priv(netdev);

	switch (mode) {
	case CAN_MODE_START:
		/* Paranoid FIFO index check. */
		{
			const u32 tx_fifo_status =
				acc_read32(priv->core, ACC_CORE_OF_TXFIFO_STATUS);
			const u8 hw_fifo_head = tx_fifo_status;

			if (hw_fifo_head != priv->core->tx_fifo_head ||
			    hw_fifo_head != priv->core->tx_fifo_tail) {
				netdev_warn(netdev,
					    "TX FIFO mismatch: T %2u H %2u; TFHW %#08x\n",
					    priv->core->tx_fifo_tail,
					    priv->core->tx_fifo_head,
					    tx_fifo_status);
			}
		}
		acc_resetmode_leave(priv->core);
		/* To leave the bus-off state the esdACC controller begins
		 * here a grace period where it counts 128 "idle conditions" (each
		 * of 11 consecutive recessive bits) on the bus as required
		 * by the CAN spec.
		 *
		 * During this time the TX FIFO may still contain already
		 * aborted "zombie" frames that are only drained from the FIFO
		 * at the end of the grace period.
		 *
		 * To not to interfere with this drain process we don't
		 * call netif_wake_queue() here. When the controller reaches
		 * the error-active state again, it informs us about that
		 * with an acc_bmmsg_errstatechange message. Then
		 * netif_wake_queue() is called from
		 * handle_core_msg_errstatechange() instead.
		 */
		break;

	default:
		return -EOPNOTSUPP;
	}

	return 0;
}

int acc_set_bittiming(struct net_device *netdev)
{
	struct acc_net_priv *priv = netdev_priv(netdev);
	const struct can_bittiming *bt = &priv->can.bittiming;
	u32 brp;
	u32 btr;

	if (priv->ov->features & ACC_OV_REG_FEAT_MASK_CANFD) {
		u32 fbtr = 0;

		netdev_dbg(netdev, "bit timing: brp %u, prop %u, ph1 %u ph2 %u, sjw %u\n",
			   bt->brp, bt->prop_seg,
			   bt->phase_seg1, bt->phase_seg2, bt->sjw);

		brp = FIELD_PREP(ACC_REG_BRP_FD_MASK_BRP, bt->brp - 1);

		btr = FIELD_PREP(ACC_REG_BTR_FD_MASK_TSEG1, bt->phase_seg1 + bt->prop_seg - 1);
		btr |= FIELD_PREP(ACC_REG_BTR_FD_MASK_TSEG2, bt->phase_seg2 - 1);
		btr |= FIELD_PREP(ACC_REG_BTR_FD_MASK_SJW, bt->sjw - 1);

		/* Keep order of accesses to ACC_CORE_OF_BRP and ACC_CORE_OF_BTR. */
		acc_write32(priv->core, ACC_CORE_OF_BRP, brp);
		acc_write32(priv->core, ACC_CORE_OF_BTR, btr);

		netdev_dbg(netdev, "esdACC: BRP %u, NBTR 0x%08x, DBTR 0x%08x",
			   brp, btr, fbtr);
	} else {
		netdev_dbg(netdev, "bit timing: brp %u, prop %u, ph1 %u ph2 %u, sjw %u\n",
			   bt->brp, bt->prop_seg,
			   bt->phase_seg1, bt->phase_seg2, bt->sjw);

		brp = FIELD_PREP(ACC_REG_BRP_CL_MASK_BRP, bt->brp - 1);

		btr = FIELD_PREP(ACC_REG_BTR_CL_MASK_TSEG1, bt->phase_seg1 + bt->prop_seg - 1);
		btr |= FIELD_PREP(ACC_REG_BTR_CL_MASK_TSEG2, bt->phase_seg2 - 1);
		btr |= FIELD_PREP(ACC_REG_BTR_CL_MASK_SJW, bt->sjw - 1);

		/* Keep order of accesses to ACC_CORE_OF_BRP and ACC_CORE_OF_BTR. */
		acc_write32(priv->core, ACC_CORE_OF_BRP, brp);
		acc_write32(priv->core, ACC_CORE_OF_BTR, btr);

		netdev_dbg(netdev, "esdACC: BRP %u, BTR 0x%08x", brp, btr);
	}

	return 0;
}

static void handle_core_msg_rxtxdone(struct acc_core *core,
				     const struct acc_bmmsg_rxtxdone *msg)
{
	struct acc_net_priv *priv = netdev_priv(core->netdev);
	struct net_device_stats *stats = &core->netdev->stats;
	struct sk_buff *skb;

	if (msg->acc_dlc.len & ACC_DLC_TXD_FLAG) {
		u8 tx_fifo_tail = core->tx_fifo_tail;

		if (core->tx_fifo_head == tx_fifo_tail) {
			netdev_warn(core->netdev,
				    "TX interrupt, but queue is empty!?\n");
			return;
		}

		/* Direct access echo skb to attach HW time stamp. */
		skb = priv->can.echo_skb[tx_fifo_tail];
		if (skb) {
			skb_hwtstamps(skb)->hwtstamp =
				acc_ts2ktime(priv->ov, msg->ts);
		}

		stats->tx_packets++;
		stats->tx_bytes += can_get_echo_skb(core->netdev, tx_fifo_tail,
						    NULL);

		core->tx_fifo_tail = acc_tx_fifo_next(core, tx_fifo_tail);

		netif_wake_queue(core->netdev);

	} else {
		struct can_frame *cf;

		skb = alloc_can_skb(core->netdev, &cf);
		if (!skb) {
			stats->rx_dropped++;
			return;
		}

		cf->can_id = msg->id & ACC_ID_ID_MASK;
		if (msg->id & ACC_ID_EFF_FLAG)
			cf->can_id |= CAN_EFF_FLAG;

		can_frame_set_cc_len(cf, msg->acc_dlc.len & ACC_DLC_DLC_MASK,
				     priv->can.ctrlmode);

		if (msg->acc_dlc.len & ACC_DLC_RTR_FLAG) {
			cf->can_id |= CAN_RTR_FLAG;
		} else {
			memcpy(cf->data, msg->data, cf->len);
			stats->rx_bytes += cf->len;
		}
		stats->rx_packets++;

		skb_hwtstamps(skb)->hwtstamp = acc_ts2ktime(priv->ov, msg->ts);

		netif_rx(skb);
	}
}

static void handle_core_msg_txabort(struct acc_core *core,
				    const struct acc_bmmsg_txabort *msg)
{
	struct net_device_stats *stats = &core->netdev->stats;
	u8 tx_fifo_tail = core->tx_fifo_tail;
	u32 abort_mask = msg->abort_mask;   /* u32 extend to avoid warnings later */

	/* The abort_mask shows which frames were aborted in esdACC's FIFO. */
	while (tx_fifo_tail != core->tx_fifo_head && (abort_mask)) {
		const u32 tail_mask = (1U << tx_fifo_tail);

		if (!(abort_mask & tail_mask))
			break;
		abort_mask &= ~tail_mask;

		can_free_echo_skb(core->netdev, tx_fifo_tail, NULL);
		stats->tx_dropped++;
		stats->tx_aborted_errors++;

		tx_fifo_tail = acc_tx_fifo_next(core, tx_fifo_tail);
	}
	core->tx_fifo_tail = tx_fifo_tail;
	if (abort_mask)
		netdev_warn(core->netdev, "Unhandled aborted messages\n");

	if (!acc_resetmode_entered(core))
		netif_wake_queue(core->netdev);
}

static void handle_core_msg_overrun(struct acc_core *core,
				    const struct acc_bmmsg_overrun *msg)
{
	struct acc_net_priv *priv = netdev_priv(core->netdev);
	struct net_device_stats *stats = &core->netdev->stats;
	struct can_frame *cf;
	struct sk_buff *skb;

	/* lost_cnt may be 0 if not supported by esdACC version */
	if (msg->lost_cnt) {
		stats->rx_errors += msg->lost_cnt;
		stats->rx_over_errors += msg->lost_cnt;
	} else {
		stats->rx_errors++;
		stats->rx_over_errors++;
	}

	skb = alloc_can_err_skb(core->netdev, &cf);
	if (!skb)
		return;

	cf->can_id |= CAN_ERR_CRTL;
	cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;

	skb_hwtstamps(skb)->hwtstamp = acc_ts2ktime(priv->ov, msg->ts);

	netif_rx(skb);
}

static void handle_core_msg_buserr(struct acc_core *core,
				   const struct acc_bmmsg_buserr *msg)
{
	struct acc_net_priv *priv = netdev_priv(core->netdev);
	struct net_device_stats *stats = &core->netdev->stats;
	struct can_frame *cf;
	struct sk_buff *skb;
	const u32 reg_status = msg->reg_status;
	const u8 rxerr = reg_status;
	const u8 txerr = (reg_status >> 8);
	u8 can_err_prot_type = 0U;

	priv->can.can_stats.bus_error++;

	/* Error occurred during transmission? */
	if (msg->ecc & ACC_ECC_DIR) {
		stats->rx_errors++;
	} else {
		can_err_prot_type |= CAN_ERR_PROT_TX;
		stats->tx_errors++;
	}
	/* Determine error type */
	switch (msg->ecc & ACC_ECC_MASK) {
	case ACC_ECC_BIT:
		can_err_prot_type |= CAN_ERR_PROT_BIT;
		break;
	case ACC_ECC_FORM:
		can_err_prot_type |= CAN_ERR_PROT_FORM;
		break;
	case ACC_ECC_STUFF:
		can_err_prot_type |= CAN_ERR_PROT_STUFF;
		break;
	default:
		can_err_prot_type |= CAN_ERR_PROT_UNSPEC;
		break;
	}

	skb = alloc_can_err_skb(core->netdev, &cf);
	if (!skb)
		return;

	cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR | CAN_ERR_CNT;

	/* Set protocol error type */
	cf->data[2] = can_err_prot_type;
	/* Set error location */
	cf->data[3] = msg->ecc & ACC_ECC_SEG;

	/* Insert CAN TX and RX error counters. */
	cf->data[6] = txerr;
	cf->data[7] = rxerr;

	skb_hwtstamps(skb)->hwtstamp = acc_ts2ktime(priv->ov, msg->ts);

	netif_rx(skb);
}

static void
handle_core_msg_errstatechange(struct acc_core *core,
			       const struct acc_bmmsg_errstatechange *msg)
{
	struct acc_net_priv *priv = netdev_priv(core->netdev);
	struct can_frame *cf = NULL;
	struct sk_buff *skb;
	const u32 reg_status = msg->reg_status;
	const u8 rxerr = reg_status;
	const u8 txerr = (reg_status >> 8);
	enum can_state new_state;

	if (reg_status & ACC_REG_STATUS_MASK_STATUS_BS) {
		new_state = CAN_STATE_BUS_OFF;
	} else if (reg_status & ACC_REG_STATUS_MASK_STATUS_EP) {
		new_state = CAN_STATE_ERROR_PASSIVE;
	} else if (reg_status & ACC_REG_STATUS_MASK_STATUS_ES) {
		new_state = CAN_STATE_ERROR_WARNING;
	} else {
		new_state = CAN_STATE_ERROR_ACTIVE;
		if (priv->can.state == CAN_STATE_BUS_OFF) {
			/* See comment in acc_set_mode() for CAN_MODE_START */
			netif_wake_queue(core->netdev);
		}
	}

	skb = alloc_can_err_skb(core->netdev, &cf);

	if (new_state != priv->can.state) {
		enum can_state tx_state, rx_state;

		tx_state = (txerr >= rxerr) ?
			new_state : CAN_STATE_ERROR_ACTIVE;
		rx_state = (rxerr >= txerr) ?
			new_state : CAN_STATE_ERROR_ACTIVE;

		/* Always call can_change_state() to update the state
		 * even if alloc_can_err_skb() may have failed.
		 * can_change_state() can cope with a NULL cf pointer.
		 */
		can_change_state(core->netdev, cf, tx_state, rx_state);
	}

	if (skb) {
		cf->can_id |= CAN_ERR_CNT;
		cf->data[6] = txerr;
		cf->data[7] = rxerr;

		skb_hwtstamps(skb)->hwtstamp = acc_ts2ktime(priv->ov, msg->ts);

		netif_rx(skb);
	}

	if (new_state == CAN_STATE_BUS_OFF) {
		acc_write32(core, ACC_CORE_OF_TX_ABORT_MASK, 0xffff);
		can_bus_off(core->netdev);
	}
}

static void handle_core_interrupt(struct acc_core *core)
{
	u32 msg_fifo_head = core->bmfifo.local_irq_cnt & 0xff;

	while (core->bmfifo.msg_fifo_tail != msg_fifo_head) {
		const union acc_bmmsg *msg =
			&core->bmfifo.messages[core->bmfifo.msg_fifo_tail];

		switch (msg->msg_id) {
		case BM_MSG_ID_RXTXDONE:
			handle_core_msg_rxtxdone(core, &msg->rxtxdone);
			break;

		case BM_MSG_ID_TXABORT:
			handle_core_msg_txabort(core, &msg->txabort);
			break;

		case BM_MSG_ID_OVERRUN:
			handle_core_msg_overrun(core, &msg->overrun);
			break;

		case BM_MSG_ID_BUSERR:
			handle_core_msg_buserr(core, &msg->buserr);
			break;

		case BM_MSG_ID_ERRPASSIVE:
		case BM_MSG_ID_ERRWARN:
			handle_core_msg_errstatechange(core,
						       &msg->errstatechange);
			break;

		default:
			/* Ignore all other BM messages (like the CAN-FD messages) */
			break;
		}

		core->bmfifo.msg_fifo_tail =
				(core->bmfifo.msg_fifo_tail + 1) & 0xff;
	}
}

/**
 * acc_card_interrupt() - handle the interrupts of an esdACC FPGA
 *
 * @ov: overview module structure
 * @cores: array of core structures
 *
 * This function handles all interrupts pending for the overview module and the
 * CAN cores of the esdACC FPGA.
 *
 * It examines for all cores (the overview module core and the CAN cores)
 * the bmfifo.irq_cnt and compares it with the previously saved
 * bmfifo.local_irq_cnt. An IRQ is pending if they differ. The esdACC FPGA
 * updates the bmfifo.irq_cnt values by DMA.
 *
 * The pending interrupts are masked by writing to the IRQ mask register at
 * ACC_OV_OF_BM_IRQ_MASK. This register has for each core a two bit command
 * field evaluated as follows:
 *
 * Define,   bit pattern: meaning
 *                    00: no action
 * ACC_BM_IRQ_UNMASK, 01: unmask interrupt
 * ACC_BM_IRQ_MASK,   10: mask interrupt
 *                    11: no action
 *
 * For each CAN core with a pending IRQ handle_core_interrupt() handles all
 * busmaster messages from the message FIFO. The last handled message (FIFO
 * index) is written to the CAN core to acknowledge its handling.
 *
 * Last step is to unmask all interrupts in the FPGA using
 * ACC_BM_IRQ_UNMASK_ALL.
 *
 * Return:
 *	IRQ_HANDLED, if card generated an interrupt that was handled
 *	IRQ_NONE, if the interrupt is not ours
 */
irqreturn_t acc_card_interrupt(struct acc_ov *ov, struct acc_core *cores)
{
	u32 irqmask;
	int i;

	/* First we look for whom interrupts are pending, card/overview
	 * or any of the cores. Two bits in irqmask are used for each;
	 * Each two bit field is set to ACC_BM_IRQ_MASK if an IRQ is
	 * pending.
	 */
	irqmask = 0U;
	if (READ_ONCE(*ov->bmfifo.irq_cnt) != ov->bmfifo.local_irq_cnt) {
		irqmask |= ACC_BM_IRQ_MASK;
		ov->bmfifo.local_irq_cnt = READ_ONCE(*ov->bmfifo.irq_cnt);
	}

	for (i = 0; i < ov->active_cores; i++) {
		struct acc_core *core = &cores[i];

		if (READ_ONCE(*core->bmfifo.irq_cnt) != core->bmfifo.local_irq_cnt) {
			irqmask |= (ACC_BM_IRQ_MASK << (2 * (i + 1)));
			core->bmfifo.local_irq_cnt = READ_ONCE(*core->bmfifo.irq_cnt);
		}
	}

	if (!irqmask)
		return IRQ_NONE;

	/* At second we tell the card we're working on them by writing irqmask,
	 * call handle_{ov|core}_interrupt and then acknowledge the
	 * interrupts by writing irq_cnt:
	 */
	acc_ov_write32(ov, ACC_OV_OF_BM_IRQ_MASK, irqmask);

	if (irqmask & ACC_BM_IRQ_MASK) {
		/* handle_ov_interrupt(); - no use yet. */
		acc_ov_write32(ov, ACC_OV_OF_BM_IRQ_COUNTER,
			       ov->bmfifo.local_irq_cnt);
	}

	for (i = 0; i < ov->active_cores; i++) {
		struct acc_core *core = &cores[i];

		if (irqmask & (ACC_BM_IRQ_MASK << (2 * (i + 1)))) {
			handle_core_interrupt(core);
			acc_write32(core, ACC_OV_OF_BM_IRQ_COUNTER,
				    core->bmfifo.local_irq_cnt);
		}
	}

	acc_ov_write32(ov, ACC_OV_OF_BM_IRQ_MASK, ACC_BM_IRQ_UNMASK_ALL);

	return IRQ_HANDLED;
}
