Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fcdc103d authored by David S. Miller's avatar David S. Miller
Browse files

Merge tag 'linux-can-next-for-4.11-20170206' of...

Merge tag 'linux-can-next-for-4.11-20170206' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next



Marc Kleine-Budde says:

====================
pull-request: can-next 2017-02-06

this is a pull request of 16 patches for net-next/master.

The first two patches by David Jander and me add the rx-offload
framework for CAN devices to the kernel. The remaining 14 patches
convert the flexcan driver to make use of it.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents e158e5ef 096de07f
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -6,7 +6,8 @@ obj-$(CONFIG_CAN_VCAN) += vcan.o
obj-$(CONFIG_CAN_SLCAN)		+= slcan.o

obj-$(CONFIG_CAN_DEV)		+= can-dev.o
can-dev-y			:= dev.o
can-dev-y			+= dev.o
can-dev-y			+= rx-offload.o

can-dev-$(CONFIG_CAN_LEDS)	+= led.o

+243 −176
Original line number Diff line number Diff line
@@ -3,7 +3,8 @@
 *
 * Copyright (c) 2005-2006 Varma Electronics Oy
 * Copyright (c) 2009 Sascha Hauer, Pengutronix
 * Copyright (c) 2010 Marc Kleine-Budde, Pengutronix
 * Copyright (c) 2010-2017 Pengutronix, Marc Kleine-Budde <kernel@pengutronix.de>
 * Copyright (c) 2014 David Jander, Protonic Holland
 *
 * Based on code originally by Andrey Volkov <avolkov@varma-el.com>
 *
@@ -24,6 +25,7 @@
#include <linux/can/dev.h>
#include <linux/can/error.h>
#include <linux/can/led.h>
#include <linux/can/rx-offload.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
@@ -55,9 +57,10 @@
#define FLEXCAN_MCR_WAK_SRC		BIT(19)
#define FLEXCAN_MCR_DOZE		BIT(18)
#define FLEXCAN_MCR_SRX_DIS		BIT(17)
#define FLEXCAN_MCR_BCC			BIT(16)
#define FLEXCAN_MCR_IRMQ		BIT(16)
#define FLEXCAN_MCR_LPRIO_EN		BIT(13)
#define FLEXCAN_MCR_AEN			BIT(12)
/* MCR_MAXMB: maximum used MBs is MAXMB + 1 */
#define FLEXCAN_MCR_MAXMB(x)		((x) & 0x7f)
#define FLEXCAN_MCR_IDAM_A		(0x0 << 8)
#define FLEXCAN_MCR_IDAM_B		(0x1 << 8)
@@ -143,17 +146,20 @@

/* FLEXCAN interrupt flag register (IFLAG) bits */
/* Errata ERR005829 step7: Reserve first valid MB */
#define FLEXCAN_TX_BUF_RESERVED		8
#define FLEXCAN_TX_BUF_ID		9
#define FLEXCAN_IFLAG_BUF(x)		BIT(x)
#define FLEXCAN_TX_MB_RESERVED_OFF_FIFO	8
#define FLEXCAN_TX_MB_OFF_FIFO		9
#define FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP	0
#define FLEXCAN_TX_MB_OFF_TIMESTAMP		1
#define FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST	(FLEXCAN_TX_MB_OFF_TIMESTAMP + 1)
#define FLEXCAN_RX_MB_OFF_TIMESTAMP_LAST	63
#define FLEXCAN_IFLAG_MB(x)		BIT(x)
#define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW	BIT(7)
#define FLEXCAN_IFLAG_RX_FIFO_WARN	BIT(6)
#define FLEXCAN_IFLAG_RX_FIFO_AVAILABLE	BIT(5)
#define FLEXCAN_IFLAG_DEFAULT \
	(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW | FLEXCAN_IFLAG_RX_FIFO_AVAILABLE | \
	 FLEXCAN_IFLAG_BUF(FLEXCAN_TX_BUF_ID))

/* FLEXCAN message buffers */
#define FLEXCAN_MB_CODE_MASK		(0xf << 24)
#define FLEXCAN_MB_CODE_RX_BUSY_BIT	(0x1 << 24)
#define FLEXCAN_MB_CODE_RX_INACTIVE	(0x0 << 24)
#define FLEXCAN_MB_CODE_RX_EMPTY	(0x4 << 24)
#define FLEXCAN_MB_CODE_RX_FULL		(0x2 << 24)
@@ -189,7 +195,9 @@
 */
#define FLEXCAN_QUIRK_BROKEN_ERR_STATE	BIT(1) /* [TR]WRN_INT not connected */
#define FLEXCAN_QUIRK_DISABLE_RXFG	BIT(2) /* Disable RX FIFO Global mask */
#define FLEXCAN_QUIRK_DISABLE_MECR	BIT(3) /* Disble Memory error detection */
#define FLEXCAN_QUIRK_ENABLE_EACEN_RRS	BIT(3) /* Enable EACEN and RRS bit in ctrl2 */
#define FLEXCAN_QUIRK_DISABLE_MECR	BIT(4) /* Disble Memory error detection */
#define FLEXCAN_QUIRK_USE_OFF_TIMESTAMP	BIT(5) /* Use timestamp based offloading */

/* Structure of the message buffer */
struct flexcan_mb {
@@ -213,7 +221,10 @@ struct flexcan_regs {
	u32 imask1;		/* 0x28 */
	u32 iflag2;		/* 0x2c */
	u32 iflag1;		/* 0x30 */
	u32 ctrl2;		/* 0x34 */
	union {			/* 0x34 */
		u32 gfwr_mx28;	/* MX28, MX53 */
		u32 ctrl2;	/* MX6, VF610 */
	};
	u32 esr2;		/* 0x38 */
	u32 imeur;		/* 0x3c */
	u32 lrfr;		/* 0x40 */
@@ -232,7 +243,11 @@ struct flexcan_regs {
	 *				size conf'ed via ctrl2::RFFN
	 *				(mx6, vf610)
	 */
	u32 _reserved4[408];
	u32 _reserved4[256];	/* 0x480 */
	u32 rximr[64];		/* 0x880 */
	u32 _reserved5[24];	/* 0x980 */
	u32 gfwr_mx6;		/* 0x9e0 - MX6 */
	u32 _reserved6[63];	/* 0x9e4 */
	u32 mecr;		/* 0xae0 */
	u32 erriar;		/* 0xae4 */
	u32 erridpr;		/* 0xae8 */
@@ -249,31 +264,36 @@ struct flexcan_devtype_data {

struct flexcan_priv {
	struct can_priv can;
	struct napi_struct napi;
	struct can_rx_offload offload;

	struct flexcan_regs __iomem *regs;
	u32 reg_esr;
	struct flexcan_mb __iomem *tx_mb;
	struct flexcan_mb __iomem *tx_mb_reserved;
	u8 tx_mb_idx;
	u32 reg_ctrl_default;
	u32 reg_imask1_default;
	u32 reg_imask2_default;

	struct clk *clk_ipg;
	struct clk *clk_per;
	struct flexcan_platform_data *pdata;
	const struct flexcan_devtype_data *devtype_data;
	struct regulator *reg_xceiver;
};

static struct flexcan_devtype_data fsl_p1010_devtype_data = {
static const struct flexcan_devtype_data fsl_p1010_devtype_data = {
	.quirks = FLEXCAN_QUIRK_BROKEN_ERR_STATE,
};

static struct flexcan_devtype_data fsl_imx28_devtype_data;
static const struct flexcan_devtype_data fsl_imx28_devtype_data;

static struct flexcan_devtype_data fsl_imx6q_devtype_data = {
	.quirks = FLEXCAN_QUIRK_DISABLE_RXFG,
static const struct flexcan_devtype_data fsl_imx6q_devtype_data = {
	.quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS |
		FLEXCAN_QUIRK_USE_OFF_TIMESTAMP,
};

static struct flexcan_devtype_data fsl_vf610_devtype_data = {
	.quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_DISABLE_MECR,
static const struct flexcan_devtype_data fsl_vf610_devtype_data = {
	.quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS |
		FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP,
};

static const struct can_bittiming_const flexcan_bittiming_const = {
@@ -331,13 +351,6 @@ static inline int flexcan_transceiver_disable(const struct flexcan_priv *priv)
	return regulator_disable(priv->reg_xceiver);
}

static inline int flexcan_has_and_handle_berr(const struct flexcan_priv *priv,
					      u32 reg_esr)
{
	return (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) &&
		(reg_esr & FLEXCAN_ESR_ERR_BUS);
}

static int flexcan_chip_enable(struct flexcan_priv *priv)
{
	struct flexcan_regs __iomem *regs = priv->regs;
@@ -468,7 +481,6 @@ static int flexcan_get_berr_counter(const struct net_device *dev,
static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
	const struct flexcan_priv *priv = netdev_priv(dev);
	struct flexcan_regs __iomem *regs = priv->regs;
	struct can_frame *cf = (struct can_frame *)skb->data;
	u32 can_id;
	u32 data;
@@ -491,68 +503,73 @@ static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)

	if (cf->can_dlc > 0) {
		data = be32_to_cpup((__be32 *)&cf->data[0]);
		flexcan_write(data, &regs->mb[FLEXCAN_TX_BUF_ID].data[0]);
		flexcan_write(data, &priv->tx_mb->data[0]);
	}
	if (cf->can_dlc > 3) {
		data = be32_to_cpup((__be32 *)&cf->data[4]);
		flexcan_write(data, &regs->mb[FLEXCAN_TX_BUF_ID].data[1]);
		flexcan_write(data, &priv->tx_mb->data[1]);
	}

	can_put_echo_skb(skb, dev, 0);

	flexcan_write(can_id, &regs->mb[FLEXCAN_TX_BUF_ID].can_id);
	flexcan_write(ctrl, &regs->mb[FLEXCAN_TX_BUF_ID].can_ctrl);
	flexcan_write(can_id, &priv->tx_mb->can_id);
	flexcan_write(ctrl, &priv->tx_mb->can_ctrl);

	/* Errata ERR005829 step8:
	 * Write twice INACTIVE(0x8) code to first MB.
	 */
	flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
		      &regs->mb[FLEXCAN_TX_BUF_RESERVED].can_ctrl);
		      &priv->tx_mb_reserved->can_ctrl);
	flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
		      &regs->mb[FLEXCAN_TX_BUF_RESERVED].can_ctrl);
		      &priv->tx_mb_reserved->can_ctrl);

	return NETDEV_TX_OK;
}

static void do_bus_err(struct net_device *dev,
		       struct can_frame *cf, u32 reg_esr)
static void flexcan_irq_bus_err(struct net_device *dev, u32 reg_esr)
{
	struct flexcan_priv *priv = netdev_priv(dev);
	int rx_errors = 0, tx_errors = 0;
	struct sk_buff *skb;
	struct can_frame *cf;
	bool rx_errors = false, tx_errors = false;

	skb = alloc_can_err_skb(dev, &cf);
	if (unlikely(!skb))
		return;

	cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;

	if (reg_esr & FLEXCAN_ESR_BIT1_ERR) {
		netdev_dbg(dev, "BIT1_ERR irq\n");
		cf->data[2] |= CAN_ERR_PROT_BIT1;
		tx_errors = 1;
		tx_errors = true;
	}
	if (reg_esr & FLEXCAN_ESR_BIT0_ERR) {
		netdev_dbg(dev, "BIT0_ERR irq\n");
		cf->data[2] |= CAN_ERR_PROT_BIT0;
		tx_errors = 1;
		tx_errors = true;
	}
	if (reg_esr & FLEXCAN_ESR_ACK_ERR) {
		netdev_dbg(dev, "ACK_ERR irq\n");
		cf->can_id |= CAN_ERR_ACK;
		cf->data[3] = CAN_ERR_PROT_LOC_ACK;
		tx_errors = 1;
		tx_errors = true;
	}
	if (reg_esr & FLEXCAN_ESR_CRC_ERR) {
		netdev_dbg(dev, "CRC_ERR irq\n");
		cf->data[2] |= CAN_ERR_PROT_BIT;
		cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
		rx_errors = 1;
		rx_errors = true;
	}
	if (reg_esr & FLEXCAN_ESR_FRM_ERR) {
		netdev_dbg(dev, "FRM_ERR irq\n");
		cf->data[2] |= CAN_ERR_PROT_FORM;
		rx_errors = 1;
		rx_errors = true;
	}
	if (reg_esr & FLEXCAN_ESR_STF_ERR) {
		netdev_dbg(dev, "STF_ERR irq\n");
		cf->data[2] |= CAN_ERR_PROT_STUFF;
		rx_errors = 1;
		rx_errors = true;
	}

	priv->can.can_stats.bus_error++;
@@ -560,32 +577,16 @@ static void do_bus_err(struct net_device *dev,
		dev->stats.rx_errors++;
	if (tx_errors)
		dev->stats.tx_errors++;
}

static int flexcan_poll_bus_err(struct net_device *dev, u32 reg_esr)
{
	struct sk_buff *skb;
	struct can_frame *cf;

	skb = alloc_can_err_skb(dev, &cf);
	if (unlikely(!skb))
		return 0;

	do_bus_err(dev, cf, reg_esr);

	dev->stats.rx_packets++;
	dev->stats.rx_bytes += cf->can_dlc;
	netif_receive_skb(skb);

	return 1;
	can_rx_offload_irq_queue_err_skb(&priv->offload, skb);
}

static int flexcan_poll_state(struct net_device *dev, u32 reg_esr)
static void flexcan_irq_state(struct net_device *dev, u32 reg_esr)
{
	struct flexcan_priv *priv = netdev_priv(dev);
	struct sk_buff *skb;
	struct can_frame *cf;
	enum can_state new_state = 0, rx_state = 0, tx_state = 0;
	enum can_state new_state, rx_state, tx_state;
	int flt;
	struct can_berr_counter bec;

@@ -606,33 +607,63 @@ static int flexcan_poll_state(struct net_device *dev, u32 reg_esr)

	/* state hasn't changed */
	if (likely(new_state == priv->can.state))
		return 0;
		return;

	skb = alloc_can_err_skb(dev, &cf);
	if (unlikely(!skb))
		return 0;
		return;

	can_change_state(dev, cf, tx_state, rx_state);

	if (unlikely(new_state == CAN_STATE_BUS_OFF))
		can_bus_off(dev);

	dev->stats.rx_packets++;
	dev->stats.rx_bytes += cf->can_dlc;
	netif_receive_skb(skb);
	can_rx_offload_irq_queue_err_skb(&priv->offload, skb);
}

	return 1;
static inline struct flexcan_priv *rx_offload_to_priv(struct can_rx_offload *offload)
{
	return container_of(offload, struct flexcan_priv, offload);
}

static void flexcan_read_fifo(const struct net_device *dev,
			      struct can_frame *cf)
static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload,
					 struct can_frame *cf,
					 u32 *timestamp, unsigned int n)
{
	const struct flexcan_priv *priv = netdev_priv(dev);
	struct flexcan_priv *priv = rx_offload_to_priv(offload);
	struct flexcan_regs __iomem *regs = priv->regs;
	struct flexcan_mb __iomem *mb = &regs->mb[0];
	u32 reg_ctrl, reg_id;
	struct flexcan_mb __iomem *mb = &regs->mb[n];
	u32 reg_ctrl, reg_id, reg_iflag1;

	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
		u32 code;

		do {
			reg_ctrl = flexcan_read(&mb->can_ctrl);
		} while (reg_ctrl & FLEXCAN_MB_CODE_RX_BUSY_BIT);

		/* is this MB empty? */
		code = reg_ctrl & FLEXCAN_MB_CODE_MASK;
		if ((code != FLEXCAN_MB_CODE_RX_FULL) &&
		    (code != FLEXCAN_MB_CODE_RX_OVERRUN))
			return 0;

		if (code == FLEXCAN_MB_CODE_RX_OVERRUN) {
			/* This MB was overrun, we lost data */
			offload->dev->stats.rx_over_errors++;
			offload->dev->stats.rx_errors++;
		}
	} else {
		reg_iflag1 = flexcan_read(&regs->iflag1);
		if (!(reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE))
			return 0;

		reg_ctrl = flexcan_read(&mb->can_ctrl);
	}

	/* increase timstamp to full 32 bit */
	*timestamp = reg_ctrl << 16;

	reg_id = flexcan_read(&mb->can_id);
	if (reg_ctrl & FLEXCAN_MB_CNT_IDE)
		cf->can_id = ((reg_id >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG;
@@ -647,69 +678,31 @@ static void flexcan_read_fifo(const struct net_device *dev,
	*(__be32 *)(cf->data + 4) = cpu_to_be32(flexcan_read(&mb->data[1]));

	/* mark as read */
	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
		/* Clear IRQ */
		if (n < 32)
			flexcan_write(BIT(n), &regs->iflag1);
		else
			flexcan_write(BIT(n - 32), &regs->iflag2);
	} else {
		flexcan_write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, &regs->iflag1);
		flexcan_read(&regs->timer);
	}

static int flexcan_read_frame(struct net_device *dev)
{
	struct net_device_stats *stats = &dev->stats;
	struct can_frame *cf;
	struct sk_buff *skb;

	skb = alloc_can_skb(dev, &cf);
	if (unlikely(!skb)) {
		stats->rx_dropped++;
		return 0;
	}

	flexcan_read_fifo(dev, cf);

	stats->rx_packets++;
	stats->rx_bytes += cf->can_dlc;
	netif_receive_skb(skb);

	can_led_event(dev, CAN_LED_EVENT_RX);

	return 1;
}

static int flexcan_poll(struct napi_struct *napi, int quota)

static inline u64 flexcan_read_reg_iflag_rx(struct flexcan_priv *priv)
{
	struct net_device *dev = napi->dev;
	const struct flexcan_priv *priv = netdev_priv(dev);
	struct flexcan_regs __iomem *regs = priv->regs;
	u32 reg_iflag1, reg_esr;
	int work_done = 0;

	/* The error bits are cleared on read,
	 * use saved value from irq handler.
	 */
	reg_esr = flexcan_read(&regs->esr) | priv->reg_esr;

	/* handle state changes */
	work_done += flexcan_poll_state(dev, reg_esr);

	/* handle RX-FIFO */
	reg_iflag1 = flexcan_read(&regs->iflag1);
	while (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE &&
	       work_done < quota) {
		work_done += flexcan_read_frame(dev);
		reg_iflag1 = flexcan_read(&regs->iflag1);
	}

	/* report bus errors */
	if (flexcan_has_and_handle_berr(priv, reg_esr) && work_done < quota)
		work_done += flexcan_poll_bus_err(dev, reg_esr);
	u32 iflag1, iflag2;

	if (work_done < quota) {
		napi_complete_done(napi, work_done);
		/* enable IRQs */
		flexcan_write(FLEXCAN_IFLAG_DEFAULT, &regs->imask1);
		flexcan_write(priv->reg_ctrl_default, &regs->ctrl);
	}
	iflag2 = flexcan_read(&regs->iflag2) & priv->reg_imask2_default;
	iflag1 = flexcan_read(&regs->iflag1) & priv->reg_imask1_default &
		~FLEXCAN_IFLAG_MB(priv->tx_mb_idx);

	return work_done;
	return (u64)iflag2 << 32 | iflag1;
}

static irqreturn_t flexcan_irq(int irq, void *dev_id)
@@ -718,55 +711,70 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
	struct net_device_stats *stats = &dev->stats;
	struct flexcan_priv *priv = netdev_priv(dev);
	struct flexcan_regs __iomem *regs = priv->regs;
	irqreturn_t handled = IRQ_NONE;
	u32 reg_iflag1, reg_esr;

	reg_iflag1 = flexcan_read(&regs->iflag1);
	reg_esr = flexcan_read(&regs->esr);

	/* ACK all bus error and state change IRQ sources */
	if (reg_esr & FLEXCAN_ESR_ALL_INT)
		flexcan_write(reg_esr & FLEXCAN_ESR_ALL_INT, &regs->esr);
	/* reception interrupt */
	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
		u64 reg_iflag;
		int ret;

	/* schedule NAPI in case of:
	 * - rx IRQ
	 * - state change IRQ
	 * - bus error IRQ and bus error reporting is activated
	 */
	if ((reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE) ||
	    (reg_esr & FLEXCAN_ESR_ERR_STATE) ||
	    flexcan_has_and_handle_berr(priv, reg_esr)) {
		/* The error bits are cleared on read,
		 * save them for later use.
		 */
		priv->reg_esr = reg_esr & FLEXCAN_ESR_ERR_BUS;
		flexcan_write(FLEXCAN_IFLAG_DEFAULT &
			      ~FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, &regs->imask1);
		flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
			      &regs->ctrl);
		napi_schedule(&priv->napi);
		while ((reg_iflag = flexcan_read_reg_iflag_rx(priv))) {
			handled = IRQ_HANDLED;
			ret = can_rx_offload_irq_offload_timestamp(&priv->offload,
								   reg_iflag);
			if (!ret)
				break;
		}
	} else {
		if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE) {
			handled = IRQ_HANDLED;
			can_rx_offload_irq_offload_fifo(&priv->offload);
		}

	/* FIFO overflow */
		/* FIFO overflow interrupt */
		if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_OVERFLOW) {
			handled = IRQ_HANDLED;
			flexcan_write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, &regs->iflag1);
			dev->stats.rx_over_errors++;
			dev->stats.rx_errors++;
		}
	}

	/* transmission complete interrupt */
	if (reg_iflag1 & (1 << FLEXCAN_TX_BUF_ID)) {
	if (reg_iflag1 & FLEXCAN_IFLAG_MB(priv->tx_mb_idx)) {
		handled = IRQ_HANDLED;
		stats->tx_bytes += can_get_echo_skb(dev, 0);
		stats->tx_packets++;
		can_led_event(dev, CAN_LED_EVENT_TX);

		/* after sending a RTR frame MB is in RX mode */
		flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
			      &regs->mb[FLEXCAN_TX_BUF_ID].can_ctrl);
		flexcan_write((1 << FLEXCAN_TX_BUF_ID), &regs->iflag1);
			      &priv->tx_mb->can_ctrl);
		flexcan_write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), &regs->iflag1);
		netif_wake_queue(dev);
	}

	return IRQ_HANDLED;
	reg_esr = flexcan_read(&regs->esr);

	/* ACK all bus error and state change IRQ sources */
	if (reg_esr & FLEXCAN_ESR_ALL_INT) {
		handled = IRQ_HANDLED;
		flexcan_write(reg_esr & FLEXCAN_ESR_ALL_INT, &regs->esr);
	}

	/* state change interrupt */
	if (reg_esr & FLEXCAN_ESR_ERR_STATE)
		flexcan_irq_state(dev, reg_esr);

	/* bus error IRQ - handle if bus error reporting is activated */
	if ((reg_esr & FLEXCAN_ESR_ERR_BUS) &&
	    (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING))
		flexcan_irq_bus_err(dev, reg_esr);

	return handled;
}

static void flexcan_set_bittiming(struct net_device *dev)
@@ -839,14 +847,23 @@ static int flexcan_chip_start(struct net_device *dev)
	 * only supervisor access
	 * enable warning int
	 * disable local echo
	 * enable individual RX masking
	 * choose format C
	 * set max mailbox number
	 */
	reg_mcr = flexcan_read(&regs->mcr);
	reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff);
	reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_FEN | FLEXCAN_MCR_HALT |
		FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_SRX_DIS |
		FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_MAXMB(FLEXCAN_TX_BUF_ID);
	reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV |
		FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_SRX_DIS | FLEXCAN_MCR_IRMQ |
		FLEXCAN_MCR_IDAM_C;

	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
		reg_mcr &= ~FLEXCAN_MCR_FEN;
		reg_mcr |= FLEXCAN_MCR_MAXMB(priv->offload.mb_last);
	} else {
		reg_mcr |= FLEXCAN_MCR_FEN |
			FLEXCAN_MCR_MAXMB(priv->tx_mb_idx);
	}
	netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr);
	flexcan_write(reg_mcr, &regs->mcr);

@@ -883,19 +900,31 @@ static int flexcan_chip_start(struct net_device *dev)
	netdev_dbg(dev, "%s: writing ctrl=0x%08x", __func__, reg_ctrl);
	flexcan_write(reg_ctrl, &regs->ctrl);

	if ((priv->devtype_data->quirks & FLEXCAN_QUIRK_ENABLE_EACEN_RRS)) {
		reg_ctrl2 = flexcan_read(&regs->ctrl2);
		reg_ctrl2 |= FLEXCAN_CTRL2_EACEN | FLEXCAN_CTRL2_RRS;
		flexcan_write(reg_ctrl2, &regs->ctrl2);
	}

	/* clear and invalidate all mailboxes first */
	for (i = FLEXCAN_TX_BUF_ID; i < ARRAY_SIZE(regs->mb); i++) {
	for (i = priv->tx_mb_idx; i < ARRAY_SIZE(regs->mb); i++) {
		flexcan_write(FLEXCAN_MB_CODE_RX_INACTIVE,
			      &regs->mb[i].can_ctrl);
	}

	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
		for (i = priv->offload.mb_first; i <= priv->offload.mb_last; i++)
			flexcan_write(FLEXCAN_MB_CODE_RX_EMPTY,
				      &regs->mb[i].can_ctrl);
	}

	/* Errata ERR005829: mark first TX mailbox as INACTIVE */
	flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
		      &regs->mb[FLEXCAN_TX_BUF_RESERVED].can_ctrl);
		      &priv->tx_mb_reserved->can_ctrl);

	/* mark TX mailbox as INACTIVE */
	flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
		      &regs->mb[FLEXCAN_TX_BUF_ID].can_ctrl);
		      &priv->tx_mb->can_ctrl);

	/* acceptance mask/acceptance code (accept everything) */
	flexcan_write(0x0, &regs->rxgmask);
@@ -905,6 +934,10 @@ static int flexcan_chip_start(struct net_device *dev)
	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_RXFG)
		flexcan_write(0x0, &regs->rxfgmask);

	/* clear acceptance filters */
	for (i = 0; i < ARRAY_SIZE(regs->mb); i++)
		flexcan_write(0, &regs->rximr[i]);

	/* On Vybrid, disable memory error detection interrupts
	 * and freeze mode.
	 * This also works around errata e5295 which generates
@@ -942,7 +975,8 @@ static int flexcan_chip_start(struct net_device *dev)
	/* enable interrupts atomically */
	disable_irq(dev->irq);
	flexcan_write(priv->reg_ctrl_default, &regs->ctrl);
	flexcan_write(FLEXCAN_IFLAG_DEFAULT, &regs->imask1);
	flexcan_write(priv->reg_imask1_default, &regs->imask1);
	flexcan_write(priv->reg_imask2_default, &regs->imask2);
	enable_irq(dev->irq);

	/* print chip status */
@@ -972,6 +1006,7 @@ static void flexcan_chip_stop(struct net_device *dev)
	flexcan_chip_disable(priv);

	/* Disable all interrupts */
	flexcan_write(0, &regs->imask2);
	flexcan_write(0, &regs->imask1);
	flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
		      &regs->ctrl);
@@ -1008,7 +1043,7 @@ static int flexcan_open(struct net_device *dev)

	can_led_event(dev, CAN_LED_EVENT_OPEN);

	napi_enable(&priv->napi);
	can_rx_offload_enable(&priv->offload);
	netif_start_queue(dev);

	return 0;
@@ -1030,7 +1065,7 @@ static int flexcan_close(struct net_device *dev)
	struct flexcan_priv *priv = netdev_priv(dev);

	netif_stop_queue(dev);
	napi_disable(&priv->napi);
	can_rx_offload_disable(&priv->offload);
	flexcan_chip_stop(dev);

	free_irq(dev->irq, dev);
@@ -1104,8 +1139,9 @@ static int register_flexcandev(struct net_device *dev)
	flexcan_write(reg, &regs->mcr);

	/* Currently we only support newer versions of this core
	 * featuring a RX FIFO. Older cores found on some Coldfire
	 * derivates are not yet supported.
	 * featuring a RX hardware FIFO (although this driver doesn't
	 * make use of it on some cores). Older cores, found on some
	 * Coldfire derivates are not tested.
	 */
	reg = flexcan_read(&regs->mcr);
	if (!(reg & FLEXCAN_MCR_FEN)) {
@@ -1208,6 +1244,9 @@ static int flexcan_probe(struct platform_device *pdev)
	if (!dev)
		return -ENOMEM;

	platform_set_drvdata(pdev, dev);
	SET_NETDEV_DEV(dev, &pdev->dev);

	dev->netdev_ops = &flexcan_netdev_ops;
	dev->irq = irq;
	dev->flags |= IFF_ECHO;
@@ -1223,14 +1262,41 @@ static int flexcan_probe(struct platform_device *pdev)
	priv->regs = regs;
	priv->clk_ipg = clk_ipg;
	priv->clk_per = clk_per;
	priv->pdata = dev_get_platdata(&pdev->dev);
	priv->devtype_data = devtype_data;
	priv->reg_xceiver = reg_xceiver;

	netif_napi_add(dev, &priv->napi, flexcan_poll, FLEXCAN_NAPI_WEIGHT);
	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
		priv->tx_mb_idx = FLEXCAN_TX_MB_OFF_TIMESTAMP;
		priv->tx_mb_reserved = &regs->mb[FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP];
	} else {
		priv->tx_mb_idx = FLEXCAN_TX_MB_OFF_FIFO;
		priv->tx_mb_reserved = &regs->mb[FLEXCAN_TX_MB_RESERVED_OFF_FIFO];
	}
	priv->tx_mb = &regs->mb[priv->tx_mb_idx];

	platform_set_drvdata(pdev, dev);
	SET_NETDEV_DEV(dev, &pdev->dev);
	priv->reg_imask1_default = FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
	priv->reg_imask2_default = 0;

	priv->offload.mailbox_read = flexcan_mailbox_read;

	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
		u64 imask;

		priv->offload.mb_first = FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST;
		priv->offload.mb_last = FLEXCAN_RX_MB_OFF_TIMESTAMP_LAST;

		imask = GENMASK_ULL(priv->offload.mb_last, priv->offload.mb_first);
		priv->reg_imask1_default |= imask;
		priv->reg_imask2_default |= imask >> 32;

		err = can_rx_offload_add_timestamp(dev, &priv->offload);
	} else {
		priv->reg_imask1_default |= FLEXCAN_IFLAG_RX_FIFO_OVERFLOW |
			FLEXCAN_IFLAG_RX_FIFO_AVAILABLE;
		err = can_rx_offload_add_fifo(dev, &priv->offload, FLEXCAN_NAPI_WEIGHT);
	}
	if (err)
		goto failed_offload;

	err = register_flexcandev(dev);
	if (err) {
@@ -1245,6 +1311,7 @@ static int flexcan_probe(struct platform_device *pdev)

	return 0;

 failed_offload:
 failed_register:
	free_candev(dev);
	return err;
@@ -1256,7 +1323,7 @@ static int flexcan_remove(struct platform_device *pdev)
	struct flexcan_priv *priv = netdev_priv(dev);

	unregister_flexcandev(dev);
	netif_napi_del(&priv->napi);
	can_rx_offload_del(&priv->offload);
	free_candev(dev);

	return 0;