All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] can: grcan: Add device driver for GRCAN and GRHCAN cores
@ 2012-10-02 14:38 Andreas Larsson
  2012-10-04  9:45 ` Marc Kleine-Budde
  0 siblings, 1 reply; 41+ messages in thread
From: Andreas Larsson @ 2012-10-02 14:38 UTC (permalink / raw)
  To: linux-can; +Cc: software

This driver supports GRCAN and CRHCAN CAN controllers available in the GRLIB
VHDL IP core library.

Signed-off-by: Andreas Larsson <andreas@gaisler.com>
---
 drivers/net/can/Kconfig  |    6 +
 drivers/net/can/Makefile |    1 +
 drivers/net/can/grcan.c  | 1283 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/net/can/grcan.h  |  273 ++++++++++
 4 files changed, 1563 insertions(+), 0 deletions(-)
 create mode 100644 drivers/net/can/grcan.c
 create mode 100644 drivers/net/can/grcan.h

diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
index bb709fd..e039f2b 100644
--- a/drivers/net/can/Kconfig
+++ b/drivers/net/can/Kconfig
@@ -110,6 +110,12 @@ config PCH_CAN
 	  is an IOH for x86 embedded processor (Intel Atom E6xx series).
 	  This driver can access CAN bus.
 
+config CAN_GRCAN
+	tristate "Aeroflex Gaisler GRCAN and GRHCAN CAN devices"
+	depends on CAN_DEV && OF
+	---help---
+	  Say Y here if you want to use Aeroflex Gaisler GRCAN or GRHCAN.
+
 source "drivers/net/can/mscan/Kconfig"
 
 source "drivers/net/can/sja1000/Kconfig"
diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
index 938be37..7de5986 100644
--- a/drivers/net/can/Makefile
+++ b/drivers/net/can/Makefile
@@ -22,5 +22,6 @@ obj-$(CONFIG_CAN_BFIN)		+= bfin_can.o
 obj-$(CONFIG_CAN_JANZ_ICAN3)	+= janz-ican3.o
 obj-$(CONFIG_CAN_FLEXCAN)	+= flexcan.o
 obj-$(CONFIG_PCH_CAN)		+= pch_can.o
+obj-$(CONFIG_CAN_GRCAN)		+= grcan.o
 
 ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/grcan.c b/drivers/net/can/grcan.c
new file mode 100644
index 0000000..854b469
--- /dev/null
+++ b/drivers/net/can/grcan.c
@@ -0,0 +1,1283 @@
+/*
+ * Socket CAN driver for Aeroflex Gaisler GRCAN and GRHCAN.
+ *
+ * 2012 (c) Aeroflex Gaisler AB
+ *
+ * This driver supports GRCAN and CRHCAN CAN controllers available in the GRLIB
+ * VHDL IP core library.
+ *
+ * Full documentation of the GRCAN core can be found here:
+ * http://www.gaisler.com/products/grlib/grip.pdf
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Contributors: Andreas Larsson <andreas@gaisler.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/can/dev.h>
+#include <linux/spinlock.h>
+
+#include <linux/of_platform.h>
+#include <asm/prom.h>
+
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+
+#include <linux/dma-mapping.h>
+
+#include "grcan.h"
+
+#define DRV_NAME "grcan"
+
+static inline u32 grcan_read_reg(const struct grcan_priv *priv, int reg)
+{
+	return ioread32be(priv->reg_base + reg);
+}
+
+static inline void grcan_write_reg(const struct grcan_priv *priv,
+				  int reg, u32 val)
+{
+	iowrite32be(val, priv->reg_base + reg);
+}
+
+static inline void grcan_clearbits(const struct grcan_priv *priv,
+				   int reg, u32 mask)
+{
+	grcan_write_reg(priv, reg, grcan_read_reg(priv, reg) & ~mask);
+}
+
+static inline void grcan_setbits(const struct grcan_priv *priv,
+				 int reg, u32 mask)
+{
+	grcan_write_reg(priv, reg, grcan_read_reg(priv, reg) | mask);
+}
+
+static inline u32 grcan_readbits(const struct grcan_priv *priv,
+				 int reg, u32 mask)
+{
+	return grcan_read_reg(priv, reg) & mask;
+}
+
+static inline void grcan_writebits(const struct grcan_priv *priv,
+				   int reg, u32 value, u32 mask)
+{
+	u32 old = grcan_read_reg(priv, reg);
+	grcan_write_reg(priv, reg, (old & ~mask) | (value & mask));
+}
+
+
+/* Configuration parameters that can be set via module parameters */
+static struct grcan_device_config grcan_module_config = DEFAULT_DEVICE_CONFIG;
+
+static struct can_bittiming_const grcan_bittiming_const = {
+	.name = DRV_NAME,
+	.tseg1_min = CONF_PS1_MIN + 1,
+	.tseg1_max = CONF_PS1_MAX + 1,
+	.tseg2_min = CONF_PS2_MIN,
+	.tseg2_max = CONF_PS2_MAX,
+	.sjw_max   = CONF_RSJ_MAX,
+	.brp_min   = CONF_SCALER_MIN + 1,
+	.brp_max   = CONF_SCALER_MAX + 1,
+	.brp_inc   = CONF_SCALER_INC,
+};
+
+static int grcan_set_bittiming(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct can_bittiming *bt = &priv->can.bittiming;
+	u32 timing = 0;
+	int bpr, rsj, ps1, ps2, scaler;
+
+	/* Should never happen - function will not be called when
+	 * device is up */
+	if (grcan_readbits(priv, REG_CTRL, CTRL_ENABLE))
+		return -EBUSY;
+
+	/* Note bpr and brp are different concepts */
+	bpr    = priv->config.bpr;
+	rsj    = bt->sjw;
+	ps1    = (bt->prop_seg + bt->phase_seg1) - 1; /* tseg1-1 */
+	ps2    = bt->phase_seg2;
+	scaler = (bt->brp - 1);
+	timing |= (bpr << CONF_BPR_BIT) & CONF_BPR;
+	timing |= (rsj << CONF_RSJ_BIT) & CONF_RSJ;
+	timing |= (ps1 << CONF_PS1_BIT) & CONF_PS1;
+	timing |= (ps2 << CONF_PS2_BIT) & CONF_PS2;
+	timing |= (scaler << CONF_SCALER_BIT) & CONF_SCALER;
+
+	dev_info(dev->dev.parent,
+		 "setting timing=0x%x\n", timing);
+	grcan_writebits(priv, REG_CONF, timing, CONF_TIMING);
+	return 0;
+}
+
+
+static int grcan_get_berr_counter(const struct net_device *dev,
+				    struct can_berr_counter *bec)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	u32 status = grcan_read_reg(priv, REG_STAT);
+	bec->txerr = (status & STAT_TXERRCNT) >> STAT_TXERRCNT_BIT;
+	bec->rxerr = (status & STAT_RXERRCNT) >> STAT_RXERRCNT_BIT;
+	return 0;
+}
+
+
+static void grcan_receive(struct net_device *dev);
+
+/* Reset device, but keep timing information */
+static void grcan_reset(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	u32 timing = grcan_readbits(priv, REG_CONF, CONF_TIMING);
+	grcan_setbits(priv, REG_CTRL, CTRL_RESET);
+	grcan_writebits(priv, REG_CONF, timing, CONF_TIMING);
+	priv->eskbp = grcan_read_reg(priv, REG_TXRD);
+	priv->can.state = CAN_STATE_STOPPED;
+}
+
+/*
+ * priv->lock *must* be held when calling this function
+ */
+static void catch_up_echo_skb(struct net_device *dev, bool echo)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_dma *dma = &priv->dma;
+	struct net_device_stats *stats = &dev->stats;
+	int i;
+
+	/* Updates to priv->eskbp and wake-ups of the queue needs to
+	 * be atomic towards the reads of priv->eskbp and shut-downs
+	 * of the queue in grcan_start_xmit. */
+	u32 txrd = grcan_read_reg(priv, REG_TXRD);
+	while (priv->eskbp != txrd) {
+		i = priv->eskbp / MSG_SIZE;
+		if (echo) {
+			/* Normal echo of messages */
+			stats->tx_packets++;
+			stats->tx_bytes += priv->txdlc[i];
+			priv->txdlc[i] = 0;
+			can_get_echo_skb(dev, i);
+		} else {
+			/* For cleanup of untransmitted messages */
+			can_free_echo_skb(dev, i);
+		}
+
+		priv->eskbp = (priv->eskbp + MSG_SIZE)
+			% dma->tx.size;
+		txrd = grcan_read_reg(priv, REG_TXRD);
+	}
+}
+
+static void grcan_lost_one_shot_frame(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_dma *dma = &priv->dma;
+	u32 txrd;
+
+	spin_lock(&priv->lock);
+
+	catch_up_echo_skb(dev, true);
+
+	if (unlikely(grcan_readbits(priv, REG_TXCTRL, TXCTRL_ENABLE))) {
+		/* Should never happen */
+		netdev_err(dev, "TXCTRL enabled at TXLOSS in one shot mode\n");
+	} else {
+		/* By the time an IRQ_TXLOSS is generated in
+		 * one-shot mode there is no problem in writing
+		 * to TXRD even in versions of the hardware in
+		 * which TXCTRL_ONGOING is not cleared properly
+		 * in one-shot mode. */
+
+		/* Skip message and discard echo-skb */
+		txrd = grcan_read_reg(priv, REG_TXRD);
+		grcan_write_reg(priv, REG_TXRD,
+				(txrd + MSG_SIZE) % dma->tx.size);
+		catch_up_echo_skb(dev, false);
+
+		if (!priv->resetting && !priv->closing) {
+			if (netif_queue_stopped(dev))
+				netif_wake_queue(dev);
+			grcan_setbits(priv, REG_TXCTRL, TXCTRL_ENABLE);
+		}
+	}
+
+	spin_unlock(&priv->lock);
+}
+
+static void grcan_err(struct net_device *dev, u32 sources, u32 status)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct net_device_stats *stats = &dev->stats;
+	struct sk_buff *skb;
+	struct can_frame *cf;
+
+	/* Allocate zeroed error buffer */
+	skb = alloc_can_err_skb(dev, &cf);
+	if (skb == NULL)
+		netdev_dbg(dev, "could not allocate error frame\n");
+
+	/* Arbitration lost interrupt */
+	if (sources & IRQ_TXLOSS) {
+		netdev_dbg(dev,
+			   "arbitration lost (or other comm failure)\n");
+		stats->tx_errors++;
+		priv->can.can_stats.arbitration_lost++;
+
+		/* Take care of failed one-shot transmit */
+		if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT)
+			grcan_lost_one_shot_frame(dev);
+
+		if (skb)
+			cf->can_id |= CAN_ERR_LOSTARB;
+	}
+
+	/* Conditions dealing with the error counters */
+	if (sources & IRQ_ERRCTR_RELATED) {
+		enum can_state state = priv->can.state;
+		enum can_state oldstate = state;
+		u32 txerr = (status & STAT_TXERRCNT) >> STAT_TXERRCNT_BIT;
+		u32 rxerr = (status & STAT_RXERRCNT) >> STAT_RXERRCNT_BIT;
+
+		if (status & STAT_OFF) {
+			netdev_dbg(dev, "Bus off condition\n");
+			state = CAN_STATE_BUS_OFF;
+			can_bus_off(dev);
+			if (skb)
+				cf->can_id |= CAN_ERR_BUSOFF;
+		} else if (status & STAT_PASS) {
+			netdev_dbg(dev, "Error passive condition\n");
+			state = CAN_STATE_ERROR_PASSIVE;
+			priv->can.can_stats.error_passive++;
+			if (skb) {
+				cf->can_id |= CAN_ERR_CRTL;
+				if (txerr >= STAT_ERRCNT_PASSIVE_LIMIT)
+					cf->data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
+				if (rxerr >= STAT_ERRCNT_PASSIVE_LIMIT)
+					cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
+			}
+		} else if (txerr >= STAT_ERRCNT_WARNING_LIMIT ||
+			   rxerr >= STAT_ERRCNT_WARNING_LIMIT) {
+			state = CAN_STATE_ERROR_WARNING;
+			priv->can.can_stats.error_warning++;
+			if (oldstate != state)
+				netdev_dbg(dev, "Error warning condition\n");
+			if (skb) {
+				cf->can_id |= CAN_ERR_CRTL;
+				if (txerr >= STAT_ERRCNT_WARNING_LIMIT)
+					cf->data[1] |= CAN_ERR_CRTL_TX_WARNING;
+				if (rxerr >= STAT_ERRCNT_WARNING_LIMIT)
+					cf->data[1] |= CAN_ERR_CRTL_RX_WARNING;
+			}
+		} else {
+			state = CAN_STATE_ERROR_ACTIVE;
+			if (oldstate != state)
+				netdev_dbg(dev, "Error active condition\n");
+		}
+		if (state != CAN_STATE_ERROR_ACTIVE) {
+			cf->data[6] = txerr;
+			cf->data[7] = rxerr;
+		}
+		priv->can.state = state;
+	}
+
+	/* Data overrun interrupt */
+	if (sources & IRQ_OR) {
+		netdev_dbg(dev, "got data overrun interrupt\n");
+		stats->rx_over_errors++;
+		stats->rx_errors++;
+		if (skb) {
+			cf->can_id  |= CAN_ERR_CRTL;
+			cf->data[1] |= CAN_ERR_CRTL_RX_OVERFLOW;
+		}
+	}
+
+	/* AHB bus error interrupts (not CAN bus errors) - shut down the
+	 * device. */
+	if (sources & (IRQ_TXAHBERR | IRQ_RXAHBERR)) {
+		if (sources & IRQ_TXAHBERR) {
+			netdev_err(dev, "got AHB bus error on tx\n");
+			stats->tx_errors++;
+			if (priv->trackgstats)
+				priv->gstats.tx_ahberr++;
+		} else {
+			netdev_err(dev, "got AHB bus error on rx\n");
+			stats->rx_errors++;
+			if (priv->trackgstats)
+				priv->gstats.rx_ahberr++;
+		}
+		netdev_err(dev, "halting device\n");
+
+		/* Prevent anything to be enabled again and halt device */
+		spin_lock(&priv->lock);
+		priv->closing = true;
+		netif_stop_queue(dev);
+		grcan_reset(dev);
+		spin_unlock(&priv->lock);
+	}
+
+	/* Message filtered interrupt */
+	if (sources & IRQ_RXMISS) {
+		if (priv->trackgstats)
+			priv->gstats.rx_hwfiltered++;
+	}
+
+
+	/* Pass on error frame if something to report, i.e. id
+	 * contains more than just CAN_ERR_FLAG */
+	if (skb) {
+		if (cf->can_id != CAN_ERR_FLAG)
+			netif_rx(skb);
+		else
+			kfree_skb(skb);
+	}
+}
+
+static irqreturn_t grcan_interrupt(int irq, void *dev_id)
+{
+	struct net_device *dev = (struct net_device *)dev_id;
+	struct grcan_priv *priv = netdev_priv(dev);
+	u32 sources, status;
+	int n = 0;
+	bool handled = false; /* Whether any interrupt was handled */
+
+	while (true) {
+		sources = grcan_read_reg(priv, REG_PIMSR); /* PIMSR? */
+
+		if (!sources)
+			return handled ? IRQ_HANDLED : IRQ_NONE;
+
+		/* No locking needed for disabling the hang_timer */
+		if (sources & (IRQ_TX | IRQ_TXLOSS)
+		   && timer_pending(&priv->hang_timer))
+			del_timer(&priv->hang_timer);
+
+		if (n >= GRCAN_MAX_IRQ)
+			netdev_dbg(dev,
+				   "%d interrupt loops handled in a row\n", n);
+		grcan_write_reg(priv, REG_PICR, sources);
+		status = grcan_read_reg(priv, REG_STAT);
+		handled = true;
+
+		/* Frame(s) received */
+		if (sources & IRQ_RX)
+			grcan_receive(dev);
+
+		/* Frame(s) transmitted */
+		if (sources & IRQ_TX) {
+			spin_lock(&priv->lock);
+			catch_up_echo_skb(dev, true);
+			if (!priv->resetting && !priv->closing)
+				if (netif_queue_stopped(dev))
+					netif_wake_queue(dev);
+			spin_unlock(&priv->lock);
+
+		}
+
+		/* (Potential) error conditions to take care of */
+		if (sources & IRQ_ERRORS)
+			grcan_err(dev, sources, status);
+
+		n++;
+	}
+}
+
+/* Reset device and restart operations from where they were.
+ *
+ * This assumes that RXCTRL & RXCTRL is properly disabled and that RX
+ * is not ONGOING (TX might be stuck in ONGOING due to a harwrware bug
+ * for single shot) */
+static void grcan_running_reset(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *) data;
+	struct grcan_priv *priv = netdev_priv(dev);
+	u32 txwr, txrd, rxwr, rxrd, eskbp;
+	unsigned long flags;
+
+	/* This temporarily messes with eskbp, so we need to lock
+	 * priv->lock */
+	spin_lock_irqsave(&priv->lock, flags);
+	if (!priv->closing && priv->resetting) {
+		txwr = grcan_read_reg(priv, REG_TXWR);
+		txrd = grcan_read_reg(priv, REG_TXRD);
+		rxwr = grcan_read_reg(priv, REG_RXWR);
+		rxrd = grcan_read_reg(priv, REG_RXRD);
+		eskbp = priv->eskbp;
+
+		grcan_reset(dev);
+
+		grcan_write_reg(priv, REG_TXWR, txwr);
+		grcan_write_reg(priv, REG_TXRD, txrd);
+		grcan_write_reg(priv, REG_RXWR, rxwr);
+		grcan_write_reg(priv, REG_RXRD, rxrd);
+		priv->eskbp = eskbp;
+
+		priv->can.state = CAN_STATE_ERROR_ACTIVE;
+		grcan_setbits(priv, REG_TXCTRL, TXCTRL_ENABLE
+			      | (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT
+				 ? TXCTRL_SINGLE : 0));
+		grcan_setbits(priv, REG_RXCTRL, RXCTRL_ENABLE);
+		/* Start queue if there is size */
+		if (TXSPACE(priv->dma.tx.size, txwr, priv->eskbp))
+			netif_wake_queue(dev);
+
+		del_timer(&priv->hang_timer);
+		del_timer(&priv->rr_timer);
+
+		priv->resetting = false;
+	}
+	spin_unlock_irqrestore(&priv->lock, flags);
+	netdev_err(dev, "Device reset and restored\n");
+
+}
+
+static void grcan_initiate_running_reset(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *)data;
+	struct grcan_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+
+	netdev_err(dev, "Device seems hanged - reset scheduled\n");
+
+	spin_lock_irqsave(&priv->lock, flags);
+	/* The main body of this function must never be executed again
+	 * until after an execution of grcan_running_reset */
+	if (!priv->resetting && !priv->closing) {
+
+		priv->resetting = true;
+		netif_stop_queue(dev);
+		grcan_clearbits(priv, REG_TXCTRL, TXCTRL_ENABLE);
+		grcan_clearbits(priv, REG_RXCTRL, RXCTRL_ENABLE);
+		RESET_TIMER(&priv->rr_timer, priv->can.bittiming.bitrate);
+	}
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+}
+
+static void grcan_free_dma_buffers(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_dma *dma = &priv->dma;
+	dma_free_coherent(&dev->dev,
+			  dma->base_size,
+			  dma->base_buf,
+			  dma->base_handle);
+	dma->base_size = 0;
+	dma->base_buf = NULL;
+	dma->base_handle = 0;
+	dma->rx.size = 0;
+	dma->rx.buf = NULL;
+	dma->rx.handle = 0;
+	dma->tx.size = 0;
+	dma->tx.buf = NULL;
+	dma->tx.handle = 0;
+}
+
+static int grcan_allocate_dma_buffers(struct net_device *dev,
+				      size_t tsize, size_t rsize)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_dma *dma = &priv->dma;
+	struct grcan_dma_buffer *large = rsize > tsize ? &dma->rx : &dma->tx;
+	struct grcan_dma_buffer *small = rsize > tsize ? &dma->tx : &dma->rx;
+	size_t shift;
+
+	/* Need a whole number of BUFFER_ALIGNMENT for the large,
+	 * i.e. first buffer */
+	size_t maxs  = max(tsize, rsize);
+	size_t lsize = ALIGN(maxs, BUFFER_ALIGNMENT);
+
+	/* Put the small buffer after that */
+	size_t ssize = min(tsize, rsize);
+
+	/* Extra BUFFER_ALIGNMENT to allow for alignment  */
+	dma->base_size = lsize + ssize + BUFFER_ALIGNMENT;
+	dma->base_buf = dma_alloc_coherent(&dev->dev,
+					   dma->base_size,
+					   &dma->base_handle,
+					   GFP_KERNEL);
+
+	if (!dma->base_buf)
+		return -ENOMEM;
+
+	dma->tx.size = tsize;
+	dma->rx.size = rsize;
+
+	large->handle = ALIGN(dma->base_handle, BUFFER_ALIGNMENT);
+	small->handle = large->handle + lsize;
+	shift = large->handle - dma->base_handle;
+
+	large->buf = dma->base_buf + shift;
+	small->buf = large->buf + lsize;
+
+	return 0;
+}
+
+
+/*
+ * priv->lock *must* be held when calling this function
+ */
+static int grcan_start(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+
+	grcan_reset(dev);
+
+	grcan_write_reg(priv, REG_TXADDR, priv->dma.tx.handle);
+	grcan_write_reg(priv, REG_TXSIZE, priv->dma.tx.size);
+	/* REG_TXWR and REG_TXRD already set to 0 by reset*/
+
+	grcan_write_reg(priv, REG_RXADDR, priv->dma.rx.handle);
+	grcan_write_reg(priv, REG_RXSIZE, priv->dma.rx.size);
+	/* REG_RXWR and REG_RXRD already set to 0 by reset*/
+
+	/* Set up hardware message filtering */
+	grcan_write_reg(priv, REG_RXCODE, priv->config.rxcode);
+	grcan_write_reg(priv, REG_RXMASK, priv->config.rxmask);
+
+	/* Enable interrupts */
+	grcan_read_reg(priv, REG_PIR);
+	grcan_write_reg(priv, REG_IMR, IRQ_DEFAULT);
+
+	/* Enable interfaces, channels and device */
+	grcan_setbits(priv, REG_CONF,
+		      ((priv->config.output0 ? CONF_ENABLE0 : 0)
+		       | (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY ?
+			  CONF_SILENT : 0)
+		       | (priv->config.output1 ? CONF_ENABLE1 : 0)
+		       | (priv->config.selection ? CONF_SELECTION : 0)
+		       | CONF_ABORT));
+	grcan_setbits(priv, REG_TXCTRL, TXCTRL_ENABLE
+		      | (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT
+			 ? TXCTRL_SINGLE : 0));
+	grcan_setbits(priv, REG_RXCTRL, RXCTRL_ENABLE);
+	grcan_setbits(priv, REG_CTRL, CTRL_ENABLE);
+
+	priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+	return 0;
+}
+
+static int grcan_set_mode(struct net_device *dev, enum can_mode mode)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+	int err;
+
+	if (mode == CAN_MODE_START) {
+		/* This is called to restarts the device to recover from bus off
+		 * errors */
+		spin_lock_irqsave(&priv->lock, flags);
+		if (priv->closing || priv->resetting) {
+			err = -EBUSY;
+		} else {
+			netdev_info(dev, "Restarting device\n");
+			grcan_start(dev);
+			if (netif_queue_stopped(dev))
+				netif_wake_queue(dev);
+			err = 0;
+		}
+		spin_unlock_irqrestore(&priv->lock, flags);
+		return err;
+	}
+	return -EOPNOTSUPP;
+}
+
+static int grcan_open(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_dma *dma = &priv->dma;
+	unsigned long flags;
+	int err;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	err = open_candev(dev);
+	if (err)
+		goto exit_unlock;
+
+	err = request_irq(dev->irq, grcan_interrupt, IRQF_SHARED,
+			  dev->name, (void *)dev);
+	if (err)
+		goto exit_close_candev;
+
+	if (INVALID_BUFFER_SIZE(priv->config.txsize)
+	    || INVALID_BUFFER_SIZE(priv->config.rxsize)) {
+		/* Should never be able go this far with invalid sizes */
+		netdev_err(dev, "Invalid buffer size pair 0x%x 0x%x\n",
+			   priv->config.txsize, priv->config.rxsize);
+		err = -EINVAL;
+		goto exit_free_irq;
+	}
+	err = grcan_allocate_dma_buffers(dev, priv->config.txsize,
+					 priv->config.rxsize);
+	if (err) {
+		netdev_err(dev, "could not allocate DMA buffers\n");
+		goto exit_free_irq;
+	}
+
+	priv->echo_skb = devm_kzalloc(&dev->dev,
+				      dma->tx.size * sizeof(*priv->echo_skb),
+				      GFP_KERNEL);
+	if (!priv->echo_skb) {
+		err = -ENOMEM;
+		goto exit_free_dma_buffers;
+	}
+	priv->can.echo_skb_max = dma->tx.size;
+	priv->can.echo_skb = priv->echo_skb;
+
+	priv->txdlc = devm_kzalloc(&dev->dev,
+				   dma->tx.size * sizeof(*priv->txdlc),
+				   GFP_KERNEL);
+	if (!priv->txdlc) {
+		err = -ENOMEM;
+		goto exit_free_echo_skb;
+	}
+
+	grcan_start(dev);
+
+	netif_start_queue(dev);
+	priv->resetting = false;
+	priv->closing = false;
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+	return 0;
+
+exit_free_echo_skb:
+	devm_kfree(&dev->dev, priv->echo_skb);
+exit_free_dma_buffers:
+	grcan_free_dma_buffers(dev);
+exit_free_irq:
+	free_irq(dev->irq, (void *)dev);
+exit_close_candev:
+	close_candev(dev);
+exit_unlock:
+	spin_unlock_irqrestore(&priv->lock, flags);
+	return err;
+}
+
+static int grcan_close(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+	int i;
+	unsigned long waitusecs;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	priv->closing = true;
+	del_timer_sync(&priv->hang_timer);
+	del_timer_sync(&priv->rr_timer);
+
+	netif_stop_queue(dev);
+	grcan_clearbits(priv, REG_TXCTRL, TXCTRL_ENABLE);
+	grcan_clearbits(priv, REG_RXCTRL, RXCTRL_ENABLE);
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	waitusecs = ONGOING_WAIT_USECS(priv->can.bittiming.bitrate);
+	for (i = 0; i < waitusecs; i += 10) {
+		udelay(10);
+		if (!grcan_readbits(priv, REG_RXCTRL, RXCTRL_ONGOING)
+		    && (!grcan_readbits(priv, REG_TXCTRL, TXCTRL_ONGOING)
+			|| (grcan_read_reg(priv, REG_TXWR)
+			    == grcan_read_reg(priv, REG_TXRD))))
+			break;
+	}
+	free_irq(dev->irq, (void *)dev);
+	grcan_reset(dev);
+	close_candev(dev);
+
+	grcan_free_dma_buffers(dev);
+	priv->can.echo_skb_max = 0;
+	priv->can.echo_skb = NULL;
+	devm_kfree(&dev->dev, priv->echo_skb);
+	devm_kfree(&dev->dev, priv->txdlc);
+
+	return 0;
+}
+
+static void grcan_receive(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_dma *dma = &priv->dma;
+	struct net_device_stats *stats = &dev->stats;
+	struct can_frame *cf;
+	struct sk_buff *skb;
+	u32 wr, rd, startrd;
+	u32 *slot;
+	u32 i, rtr, eff, j, shift;
+
+	startrd = grcan_read_reg(priv, REG_RXRD);
+	for (rd = startrd ; rd != (wr = grcan_read_reg(priv, REG_RXWR));
+	     rd = (rd + MSG_SIZE) % dma->rx.size) {
+		skb = alloc_can_skb(dev, &cf);
+		if (skb == NULL) {
+			netdev_dbg(dev,
+				   "dropping frame: skb allocation failed\n");
+			stats->rx_dropped++;
+			continue;
+		}
+		slot = dma->rx.buf + rd;
+		eff = slot[0] & MSG_IDE;
+		rtr = slot[0] & MSG_RTR;
+		if (eff) {
+			cf->can_id = ((slot[0] & MSG_EID) >> MSG_EID_BIT);
+			cf->can_id |= CAN_EFF_FLAG;
+		} else {
+			cf->can_id = (slot[0] & MSG_BID) >> MSG_BID_BIT;
+		}
+		cf->can_dlc = get_can_dlc((slot[1] & MSG_DLC) >> MSG_DLC_BIT);
+		if (rtr) {
+			cf->can_id |= CAN_RTR_FLAG;
+		} else {
+			for (i = 0; i < cf->can_dlc; i++) {
+				j = MSG_DATA_SLOT_INDEX(i);
+				shift = MSG_DATA_SHIFT(i);
+				cf->data[i] = (u8)((slot[j] >> shift) & 0xff);
+			}
+		}
+
+		netif_rx(skb);
+		stats->rx_packets++;
+		stats->rx_bytes += cf->can_dlc;
+	}
+
+	/* Update read pointer - no need to check for ongoing */
+	if (likely(rd != startrd))
+		grcan_write_reg(priv, REG_RXRD, rd);
+}
+
+/* Work tx bug by waiting while for the risky situation to clear. If that fails,
+ * drop a frame in one-shot mode or indicate a busy device otherwise.
+ *
+ * Returns 0 on successful wait. Otherwise it sets *netdev_tx_status to the
+ * value that should be returned by grcan_start_xmit when aborting the xmit.
+ */
+static int grcan_txbug_workaround(struct net_device *dev, struct sk_buff *skb,
+				  u32 txwr, u32 oneshotmode,
+				  netdev_tx_t *netdev_tx_status)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_dma *dma = &priv->dma;
+	int i;
+	unsigned long flags;
+
+	/* Wait a while for ongoing to be cleared or read pointer to catch up to
+	 * write pointer. The latter is needed due to a bug in older versions of
+	 * GRCAN in which ONGOING is not cleared properly one-shot mode when a
+	 * transmission fails. */
+	for (i = 0; i < ONGOING_SHORTWAIT_USECS; i++) {
+		udelay(1);
+		if (!grcan_readbits(priv, REG_TXCTRL, TXCTRL_ONGOING)
+		    || grcan_read_reg(priv, REG_TXRD) == txwr) {
+			return 0;
+		}
+	}
+
+	/* Clean up, in case the situation was not resolved */
+	spin_lock_irqsave(&priv->lock, flags);
+	if (!priv->resetting && !priv->closing) {
+		/* Queue might have been stopped earlier in grcan_start_xmit */
+		if (TXSPACE(dma->tx.size, txwr, priv->eskbp))
+			if (netif_queue_stopped(dev))
+				netif_wake_queue(dev);
+		/* Set a timer to resolve a hanged tx controller */
+		if (!timer_pending(&priv->hang_timer))
+			RESET_TIMER(&priv->hang_timer,
+				    priv->can.bittiming.bitrate);
+	}
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	if (oneshotmode) {
+		/* In one-shot mode we should never end up here because
+		 * then the interrupt handler increases txrd on TXLOSS,
+		 * but it is consistent with one-shot mode to drop the
+		 * frame in this case.  */
+		kfree_skb(skb);
+		*netdev_tx_status = NETDEV_TX_OK;
+	} else {
+		/* In normal mode the socket-can transmission queue get
+		 * to keep the frame so that it can be retransmitted
+		 * later */
+		*netdev_tx_status = NETDEV_TX_BUSY;
+	}
+	return -EBUSY;
+}
+
+/*
+ * Notes on the tx cyclic buffer handling:
+ *
+ * REG_TXWR	- the next slot for the driver to put data to be sent
+ * REG_TXRD	- the next slot for the device to read data
+ * priv->eskbp	- the next slot for the driver to call can_put_echo_skb for
+ *
+ * grcan_start_xmit can enter more messages as long as REG_TXWR does
+ * not reach priv->eskbp (within 1 message gap)
+ *
+ * The device sends messages until REG_TXRD reaches REG_TXWR
+ *
+ * The interrupt calls handler calls can_put_echo_skb until
+ * priv->eskbp reaces REG_TXRD
+ */
+static netdev_tx_t grcan_start_xmit(struct sk_buff *skb,
+				    struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_dma *dma = &priv->dma;
+	struct can_frame *cf = (struct can_frame *)skb->data;
+	u32 id, txwr, txrd, space, txctrl;
+	int slotindex;
+	u32 *slot;
+	u32 i, rtr, eff, dlc, tmp, err;
+	int j, shift;
+	unsigned long flags;
+	u32 oneshotmode = priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT;
+
+	if (can_dropped_invalid_skb(dev, skb))
+		return NETDEV_TX_OK;
+
+	/* Trying to transmit in silent mode will generate error interrupts */
+	if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
+		return NETDEV_TX_BUSY;
+
+	/* Reads of priv->eskbp and shut-downs of the queue needs to
+	 * be atomic towards the updates to priv->eskbp and wake-ups
+	 * of the queue in the interrupt handler. */
+	spin_lock_irqsave(&priv->lock, flags);
+
+	txwr = grcan_read_reg(priv, REG_TXWR);
+	space = TXSPACE(dma->tx.size, txwr, priv->eskbp);
+
+	slotindex = txwr / MSG_SIZE;
+	slot = dma->tx.buf + txwr;
+
+	if (unlikely(space == 1))
+		netif_stop_queue(dev);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+	/* End of critical section*/
+
+	/* This should never happen. If circular buffer is full, the
+	 * netif_stop_queue should have been stopped already. */
+	if (unlikely(!space)) {
+		netdev_err(dev, "No buffer space, but queue is non-stopped.\n");
+		return NETDEV_TX_BUSY;
+	}
+
+	/* Convert and write CAN message to DMA buffer */
+	eff = cf->can_id & CAN_EFF_FLAG;
+	rtr = cf->can_id & CAN_RTR_FLAG;
+	id  = cf->can_id & (eff ? CAN_EFF_MASK : CAN_SFF_MASK);
+	dlc = cf->can_dlc;
+	if (eff)
+		tmp = (id << MSG_EID_BIT) & MSG_EID;
+	else
+		tmp = (id << MSG_BID_BIT) & MSG_BID;
+	slot[0] = (eff ? MSG_IDE : 0) | (rtr ? MSG_RTR : 0) | tmp;
+
+	slot[1] = ((dlc << MSG_DLC_BIT) & MSG_DLC);
+	slot[2] = 0;
+	slot[3] = 0;
+	for (i = 0; i < dlc; i++) {
+		j = MSG_DATA_SLOT_INDEX(i);
+		shift = MSG_DATA_SHIFT(i);
+		slot[j] |= cf->data[i] << shift;
+	}
+
+	/* Checking that channel has not been disabled. These cases
+	 * should never happen */
+	txctrl = grcan_read_reg(priv, REG_TXCTRL);
+	if (!(txctrl & TXCTRL_ENABLE))
+		netdev_err(dev, "tx channel spuriously disabled\n");
+
+	if (oneshotmode && !(txctrl & TXCTRL_SINGLE))
+		netdev_err(dev, "one-shot mode spuriously disabled\n");
+
+	/* Bug workaround for old version of grcan where updating txwr
+	 * in the same clock cycle as the controller updates txrd to
+	 * the current txwr could hang the can controller */
+	if (priv->need_txbug_workaround) {
+		txrd = grcan_read_reg(priv, REG_TXRD) ;
+		if (unlikely((txwr - txrd) % dma->tx.size == 1)) {
+			netdev_tx_t txstatus;
+			err = grcan_txbug_workaround(dev, skb, txwr,
+						     oneshotmode, &txstatus);
+			if (err)
+				return txstatus;
+		}
+	}
+
+	/* Prepare skb for echoing. This must be after the bug workaround above
+	 * as ownership of the skb is passed on by calling can_put_echo_skb.
+	 * Returning NETDEV_TX_BUSY or accessing skb or cf after a call to
+	 * can_put_echo_skb would be an error unless other measures are
+	 * taken. */
+	priv->txdlc[slotindex] = cf->can_dlc; /* Store dlc for statistics */
+	can_put_echo_skb(skb, dev, slotindex);
+
+	/* Update write pointer to start transmission */
+	grcan_write_reg(priv, REG_TXWR, (txwr + MSG_SIZE) % dma->tx.size);
+
+	return NETDEV_TX_OK;
+}
+
+
+/* ========== Setting up the sysfs interface ========== */
+
+#define DECF "%d"
+#define HEXF "0x%08x"
+
+#define RANGECHECK(val, minval, maxval)		\
+	((val) < (minval) || (val) > (maxval))
+
+#define NOVALCHECK(val, minval, maxval) 0
+
+#define NOPOSTSETF(dev)
+#define NOMANIP(x) (x)
+
+#define SYSFS_WRITE_ATTR(name, type, lval, manip,			\
+			 minval, maxval, valcheckf, postsetf)		\
+	static ssize_t grcan_store_##name(struct device *sdev,		\
+					  struct device_attribute *att,	\
+					  const char *buf,		\
+					  size_t count)			\
+	{								\
+		struct net_device *dev = to_net_dev(sdev);		\
+		struct grcan_priv *priv = netdev_priv(dev);		\
+		type val;						\
+		int ret;						\
+		if (dev->flags & IFF_UP)				\
+			return -EBUSY;					\
+		ret = kstrto##type(buf, 0, &val);			\
+		if (ret < 0 || valcheckf(val, (minval), (maxval)))	\
+			return -EINVAL;					\
+		lval = manip(val);					\
+		postsetf(dev);						\
+		return count;						\
+	}
+
+#define SYSFS_RESET_ATTR(name, lval, val)				\
+	static ssize_t grcan_reset_##name(struct device *sdev,		\
+					  struct device_attribute *att,	\
+					  const char *buf,		\
+					  size_t count)			\
+	{								\
+		struct net_device *dev = to_net_dev(sdev);		\
+		struct grcan_priv *priv = netdev_priv(dev);		\
+		lval = val;						\
+		return count;						\
+	}
+
+#define SYSFS_READ_ATTR(name, rval, format)				\
+	static ssize_t grcan_show_##name(struct device *sdev,		\
+					 struct device_attribute *att,	\
+					 char *buf)			\
+	{								\
+		struct net_device *dev = to_net_dev(sdev);		\
+		struct grcan_priv *priv = netdev_priv(dev);		\
+		return sprintf(buf, format "\n", rval);			\
+	}
+
+/* Configuration */
+
+#define CONFIG_ATTR(name, type, mtype, format,				\
+		    minval, maxval, valcheckf, postsetf)		\
+	SYSFS_READ_ATTR(name, priv->config.name, format)		\
+	SYSFS_WRITE_ATTR(name, type, priv->config.name, NOMANIP,	\
+			 minval, maxval, valcheckf, postsetf)		\
+	static DEVICE_ATTR(name, S_IRUGO | S_IWUSR,			\
+				 grcan_show_##name,			\
+				 grcan_store_##name);			\
+	static void grcan_sanitize_##name(struct platform_device *pd)	\
+	{								\
+		struct grcan_device_config grcan_default_config		\
+			= DEFAULT_DEVICE_CONFIG;			\
+		type val = grcan_module_config.name;			\
+		if (valcheckf(val, (minval), (maxval)))	{		\
+			dev_err(&pd->dev,				\
+				"Invalid module parameter value for "	\
+				#name " - setting default\n");		\
+			grcan_module_config.name =			\
+				grcan_default_config.name;		\
+		}							\
+	}								\
+	module_param_named(name, grcan_module_config.name,		\
+			   mtype, S_IRUGO)
+
+CONFIG_ATTR(output0,   u8, ushort, DECF, 0, 1, RANGECHECK, NOPOSTSETF);
+CONFIG_ATTR(output1,   u8, ushort, DECF, 0, 1, RANGECHECK, NOPOSTSETF);
+CONFIG_ATTR(selection, u8, ushort, DECF, 0, 1, RANGECHECK, NOPOSTSETF);
+
+static void grcan_postset_bpr(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	priv->can.clock.freq = priv->ambafreq >> priv->config.bpr;
+	netdev_info(dev, "bpr will be set to %d when bitrate is set\n",
+		    priv->config.bpr);
+}
+CONFIG_ATTR(bpr, u8, ushort, DECF, 0, 3, RANGECHECK, grcan_postset_bpr);
+
+static int dma_buf_check(u32 val, u32 minval, u32 maxval)
+{
+	return INVALID_BUFFER_SIZE(val);
+}
+
+CONFIG_ATTR(txsize, u32, uint, DECF, 0, 0, dma_buf_check, NOPOSTSETF);
+CONFIG_ATTR(rxsize, u32, uint, DECF, 0, 0, dma_buf_check, NOPOSTSETF);
+CONFIG_ATTR(rxcode, u32, uint, HEXF, 0, MSG_EID, RANGECHECK, NOPOSTSETF);
+CONFIG_ATTR(rxmask, u32, uint, HEXF, 0, MSG_EID, RANGECHECK, NOPOSTSETF);
+
+
+#define BASIC_ID_SHIFT(x) (((x) << MSG_BID_BIT) & MSG_BID)
+
+#define CONFIG_ATTR_BASIC_ID(name, lval)				\
+	SYSFS_WRITE_ATTR(name, u32, lval, BASIC_ID_SHIFT,		\
+			 0, MSG_BID >> MSG_BID_BIT, RANGECHECK,		\
+			 NOPOSTSETF)					\
+	static DEVICE_ATTR(name, S_IWUSR,				\
+				 NULL, grcan_store_##name)
+
+CONFIG_ATTR_BASIC_ID(rxcode_basic, priv->config.rxcode);
+CONFIG_ATTR_BASIC_ID(rxmask_basic, priv->config.rxmask);
+
+static const struct attribute *const sysfs_config_attrs[] = {
+	&dev_attr_output0.attr,
+	&dev_attr_output1.attr,
+	&dev_attr_selection.attr,
+	&dev_attr_bpr.attr,
+	&dev_attr_txsize.attr,
+	&dev_attr_rxsize.attr,
+	&dev_attr_rxcode.attr,
+	&dev_attr_rxmask.attr,
+	&dev_attr_rxcode_basic.attr,
+	&dev_attr_rxmask_basic.attr,
+	NULL,
+};
+
+static void grcan_sanitize_module_config(struct platform_device *ofdev)
+{
+	grcan_sanitize_output0(ofdev);
+	grcan_sanitize_output1(ofdev);
+	grcan_sanitize_selection(ofdev);
+	grcan_sanitize_bpr(ofdev);
+	grcan_sanitize_txsize(ofdev);
+	grcan_sanitize_rxsize(ofdev);
+	grcan_sanitize_rxcode(ofdev);
+	grcan_sanitize_rxmask(ofdev);
+}
+
+static const struct attribute_group sysfs_config_group = {
+	.name = "config",
+	.attrs = (struct attribute **)sysfs_config_attrs,
+};
+
+/* More statistics */
+
+#define GSTATS_ATTR(name)						\
+	SYSFS_READ_ATTR(name, priv->gstats.name, DECF)			\
+	SYSFS_RESET_ATTR(name, priv->gstats.name, 0)			\
+	static DEVICE_ATTR(name, S_IRUGO | S_IWUSR,			\
+				 grcan_show_##name, grcan_reset_##name)
+
+GSTATS_ATTR(tx_ahberr);
+GSTATS_ATTR(rx_ahberr);
+GSTATS_ATTR(rx_hwfiltered);
+
+static const struct attribute *const sysfs_stats_attrs[] = {
+	&dev_attr_tx_ahberr.attr,
+	&dev_attr_rx_ahberr.attr,
+	&dev_attr_rx_hwfiltered.attr,
+	NULL,
+};
+
+static const struct attribute_group sysfs_stats_group = {
+	.name = "grcan_statistics",
+	.attrs = (struct attribute **)sysfs_stats_attrs,
+};
+
+
+/* ========== Setting up the driver ========== */
+
+static const struct net_device_ops grcan_netdev_ops = {
+	.ndo_open               = grcan_open,
+	.ndo_stop               = grcan_close,
+	.ndo_start_xmit         = grcan_start_xmit,
+};
+
+static int grcan_setup_netdev(struct platform_device *ofdev,
+			      void __iomem *base,
+			      int irq, u32 ambafreq, bool txbug)
+{
+	struct net_device *dev;
+	struct grcan_priv *priv;
+	int err;
+
+	/* One skb buffer per slot in the circular tx buffer */
+	dev = alloc_candev(sizeof(struct grcan_priv), 0);
+	if (!dev)
+		return -ENOMEM;
+
+	dev->irq = irq;
+	dev->flags |= IFF_ECHO;	/* We support local echo */
+	dev->netdev_ops = &grcan_netdev_ops;
+	dev->sysfs_groups[0] = &sysfs_config_group;
+
+	priv = netdev_priv(dev);
+	memcpy(&priv->config, &grcan_module_config,
+	       sizeof(struct grcan_device_config));
+	priv->dev = dev;
+	priv->reg_base = base;
+	priv->can.bittiming_const     = &grcan_bittiming_const;
+	priv->can.do_set_bittiming    = grcan_set_bittiming;
+	priv->can.do_set_mode         = grcan_set_mode;
+	priv->can.do_get_berr_counter = grcan_get_berr_counter;
+	priv->ambafreq                = ambafreq;
+	priv->can.clock.freq          = ambafreq >> priv->config.bpr;
+	priv->can.ctrlmode_supported  =
+		CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_ONE_SHOT;
+	priv->gstats.tx_ahberr = 0;
+	priv->gstats.rx_ahberr = 0;
+	priv->gstats.rx_hwfiltered = 0;
+	priv->need_txbug_workaround = txbug;
+
+	spin_lock_init(&priv->lock);
+
+	init_timer(&priv->rr_timer);
+	priv->rr_timer.function = grcan_running_reset;
+	priv->rr_timer.data = (unsigned long)dev;
+
+	init_timer(&priv->hang_timer);
+	priv->hang_timer.function = grcan_initiate_running_reset;
+	priv->hang_timer.data = (unsigned long)dev;
+
+	SET_NETDEV_DEV(dev, &ofdev->dev);
+	dev_info(&ofdev->dev,
+		 "reg_base=0x%p irq=%d clock=%d\n",
+		 priv->reg_base, dev->irq, priv->can.clock.freq);
+
+	err = register_candev(dev);
+	if (err) {
+		dev_err(&ofdev->dev, "registering %s failed (err=%d)\n",
+			DRV_NAME, err);
+		goto exit_free_candev;
+	}
+	dev_set_drvdata(&ofdev->dev, dev);
+
+	priv->trackgstats = !sysfs_create_group(&dev->dev.kobj,
+						&sysfs_stats_group);
+
+	/* Reset device to allow bit-timing to be set. No need to call
+	 * grcan_reset at this stage. That is done in grcan_open. */
+	grcan_write_reg(priv, REG_CTRL, CTRL_RESET);
+
+	return 0;
+exit_free_candev:
+	free_candev(dev);
+	return err;
+}
+
+static int __devinit grcan_probe(struct platform_device *ofdev)
+{
+	struct device_node *np = ofdev->dev.of_node;
+	struct resource *res;
+	u32 sysid, ambafreq;
+	int irq, err;
+	void __iomem *base;
+	bool txbug = true;
+
+	/* Compare GRLIB version number with the first that does not
+	 * have the tx bug (see start_xmit) */
+	err = of_property_read_u32(np, "systemid", &sysid);
+	if (!err && ((sysid & GRLIB_VERSION_MASK) >= TXBUG_SAFE_GRLIB_VERSION))
+		txbug = false;
+
+	err = of_property_read_u32(np, "freq", &ambafreq);
+	if (err) {
+		dev_err(&ofdev->dev, "unable to fetch \"freq\" property\n");
+		goto exit_error;
+	}
+
+	res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
+	base = devm_request_and_ioremap(&ofdev->dev, res);
+	if (!base) {
+		dev_err(&ofdev->dev, "couldn't map IO resource\n");
+		err = -EADDRNOTAVAIL;
+		goto exit_error;
+	}
+
+	irq = irq_of_parse_and_map(np, 0);
+	if (irq == NO_IRQ) {
+		dev_err(&ofdev->dev, "no irq found\n");
+		err = -ENODEV;
+		goto exit_error;
+	}
+
+	grcan_sanitize_module_config(ofdev);
+
+	err = grcan_setup_netdev(ofdev, base, irq, ambafreq, txbug);
+	if (err)
+		goto exit_dispose_irq;
+
+	return 0;
+
+exit_dispose_irq:
+	irq_dispose_mapping(irq);
+exit_error:
+	dev_err(&ofdev->dev,
+		"%s socket CAN driver initialization failed with error %d\n",
+		DRV_NAME, err);
+	return err;
+}
+
+static  int __devexit grcan_remove(struct platform_device *ofdev)
+{
+	struct net_device *dev = dev_get_drvdata(&ofdev->dev);
+	struct grcan_priv *priv = netdev_priv(dev);
+
+	if (priv->trackgstats)
+		sysfs_remove_group(&dev->dev.kobj, &sysfs_stats_group);
+
+	unregister_candev(dev); /* Will in turn call grcan_close */
+
+	irq_dispose_mapping(dev->irq);
+	dev_set_drvdata(&ofdev->dev, NULL);
+	free_candev(dev);
+
+	dev_info(&ofdev->dev, "%s socket CAN driver removed\n", DRV_NAME);
+	return 0;
+}
+
+static struct of_device_id grcan_match[] = {
+	{.name = "GAISLER_GRCAN"},
+	{.name = "01_03d"},
+	{.name = "GAISLER_GRHCAN"},
+	{.name = "01_034"},
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, grcan_match);
+
+static struct platform_driver grcan_driver = {
+	.driver = {
+		.name = "grlib-" DRV_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = grcan_match,
+	},
+	.probe = grcan_probe,
+	.remove = __devexit_p(grcan_remove),
+};
+
+module_platform_driver(grcan_driver);
+
+MODULE_AUTHOR("Aeroflex Gaisler AB.");
+MODULE_DESCRIPTION("Socket CAN driver for Aeroflex Gaisler GRCAN");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/can/grcan.h b/drivers/net/can/grcan.h
new file mode 100644
index 0000000..1b69c59
--- /dev/null
+++ b/drivers/net/can/grcan.h
@@ -0,0 +1,273 @@
+
+#ifndef GRCAN_H
+#define GRCAN_H
+
+#include <linux/spinlock.h>
+
+#define REG_CONF 0x00
+#define REG_STAT 0x04
+#define REG_CTRL 0x08
+
+#define REG_SMASK 0x18 /* CanMASK */
+#define REG_SCODE 0x1C /* CanCODE */
+
+#define REG_PIMSR 0x100
+#define REG_PIMR  0x104
+#define REG_PISR  0x108
+#define REG_PIR   0x10C
+#define REG_IMR   0x110
+#define REG_PICR  0x114
+
+#define REG_TXCTRL 0x200
+#define REG_TXADDR 0x204
+#define REG_TXSIZE 0x208
+#define REG_TXWR   0x20C
+#define REG_TXRD   0x210
+#define REG_TXIRQ  0x214
+
+#define REG_RXCTRL 0x300
+#define REG_RXADDR 0x304
+#define REG_RXSIZE 0x308
+#define REG_RXWR   0x30C
+#define REG_RXRD   0x310
+#define REG_RXIRQ  0x314
+#define REG_RXMASK 0x318
+#define REG_RXCODE 0x31C
+
+#define TR_ADDR 0xfffffc00
+#define TR_SIZE 0x001fffc0
+#define TR_RDWR 0x000ffff0
+
+#define CONF_ABORT      0x00000001
+#define CONF_ENABLE0    0x00000002
+#define CONF_ENABLE1    0x00000004
+#define CONF_SELECTION  0x00000008
+#define CONF_SILENT     0x00000010
+#define CONF_BPR        0x00000300  /* Note: not BRP */
+#define CONF_RSJ        0x00007000
+#define CONF_PS1        0x00f00000
+#define CONF_PS2        0x000f0000
+#define CONF_SCALER     0xff000000
+#define CONF_OPERATION  (CONF_ABORT | CONF_ENABLE0 | CONF_ENABLE1 | \
+			 CONF_SELECTION | CONF_SILENT)
+#define CONF_TIMING     (CONF_BPR | CONF_RSJ | CONF_PS1 | \
+			 CONF_PS2 | CONF_SCALER)
+
+#define CONF_RSJ_MIN    1
+#define CONF_RSJ_MAX    4
+#define CONF_PS1_MIN    1
+#define CONF_PS1_MAX    15
+#define CONF_PS2_MIN    2
+#define CONF_PS2_MAX    8
+#define CONF_SCALER_MIN 0
+#define CONF_SCALER_MAX 255
+#define CONF_SCALER_INC 1
+
+#define CONF_BPR_BIT    8
+#define CONF_RSJ_BIT    12
+#define CONF_PS1_BIT    20
+#define CONF_PS2_BIT    16
+#define CONF_SCALER_BIT 24
+
+#define STAT_PASS      0x000001
+#define STAT_OFF       0x000002
+#define STAT_OR        0x000004
+#define STAT_AHBERR    0x000008
+#define STAT_ACTIVE    0x000010
+#define STAT_RXERRCNT  0x00ff00
+#define STAT_TXERRCNT  0xff0000
+
+#define STAT_RXERRCNT_BIT  8
+#define STAT_TXERRCNT_BIT  16
+
+#define STAT_ERRCNT_WARNING_LIMIT 96
+#define STAT_ERRCNT_PASSIVE_LIMIT 127
+
+
+#define CTRL_RESET  0x2
+#define CTRL_ENABLE 0x1
+
+#define TXCTRL_ENABLE  0x1
+#define TXCTRL_ONGOING 0x2
+#define TXCTRL_SINGLE  0x4
+
+#define RXCTRL_ENABLE  0x1
+#define RXCTRL_ONGOING 0x2
+
+/* Relative offset of IRQ sources to AMBA Plug&Play */
+#define IRQIX_IRQ    0
+#define IRQIX_TXSYNC 1
+#define IRQIX_RXSYNC 2
+
+#define IRQ_PASS       0x00001
+#define IRQ_OFF        0x00002
+#define IRQ_OR         0x00004
+#define IRQ_RXAHBERR   0x00008
+#define IRQ_TXAHBERR   0x00010
+#define IRQ_RXIRQ      0x00020
+#define IRQ_TXIRQ      0x00040
+#define IRQ_RXFULL     0x00080
+#define IRQ_TXEMPTY    0x00100
+#define IRQ_RX         0x00200
+#define IRQ_TX         0x00400
+#define IRQ_RXSYNC     0x00800
+#define IRQ_TXSYNC     0x01000
+#define IRQ_RXERRCTR   0x02000
+#define IRQ_TXERRCTR   0x04000
+#define IRQ_RXMISS     0x08000
+#define IRQ_TXLOSS     0x10000
+
+#define IRQ_NONE 0
+#define IRQ_ALL (IRQ_PASS | IRQ_OFF | IRQ_OR | IRQ_RXAHBERR		\
+		 | IRQ_TXAHBERR | IRQ_RXIRQ | IRQ_TXIRQ | IRQ_RXFULL	\
+		 | IRQ_TXEMPTY | IRQ_RX | IRQ_TX | IRQ_RXSYNC		\
+		 | IRQ_TXSYNC | IRQ_RXERRCTR | IRQ_TXERRCTR		\
+		 | IRQ_RXMISS | IRQ_TXLOSS)
+
+#define IRQ_ERRCTR_RELATED (IRQ_RXERRCTR | IRQ_TXERRCTR | IRQ_PASS | IRQ_OFF)
+#define IRQ_ERRORS (IRQ_ERRCTR_RELATED | IRQ_OR | IRQ_TXAHBERR |	\
+		    IRQ_RXAHBERR | IRQ_RXMISS | IRQ_TXLOSS)
+#define IRQ_DEFAULT (IRQ_RX | IRQ_TX | IRQ_ERRORS)
+
+#define MSG_SIZE 16
+
+#define MSG_IDE 0x80000000
+#define MSG_RTR 0x40000000
+#define MSG_BID 0x1ffc0000
+#define MSG_EID 0x1fffffff
+#define MSG_IDE_BIT 31
+#define MSG_RTR_BIT 30
+#define MSG_BID_BIT 18
+#define MSG_EID_BIT 0
+
+#define MSG_DLC    0xf0000000
+#define MSG_TXERRC 0x00ff0000
+#define MSG_RXERRC 0x0000ff00
+#define MSG_DLC_BIT    28
+#define MSG_TXERRC_BIT 16
+#define MSG_RXERRC_BIT 8
+#define MSG_AHBERR 0x00000008
+#define MSG_OR     0x00000004
+#define MSG_OFF    0x00000002
+#define MSG_PASS   0x00000001
+
+#define MSG_DATA_SLOT_INDEX(i) (2 + (i) / 4)
+#define MSG_DATA_SHIFT(i) ((3 - (i) % 4) * 8)
+
+#define BUFFER_ALIGNMENT 1024
+#define DEFAULT_BUFFER_SIZE 1024
+
+#define INVALID_BUFFER_SIZE(s) ((s) == 0 || ((s) & ~TR_SIZE))
+
+#if INVALID_BUFFER_SIZE(DEFAULT_BUFFER_SIZE)
+#error "Invalid default buffer size"
+#endif
+
+struct grcan_dma_buffer {
+	size_t size;
+	void *buf;
+	dma_addr_t handle;
+};
+
+struct grcan_dma {
+	size_t base_size;
+	void *base_buf;
+	dma_addr_t base_handle;
+	struct grcan_dma_buffer tx;
+	struct grcan_dma_buffer rx;
+};
+
+/*
+ * GRCAN configuration parameters
+ */
+struct grcan_device_config {
+	unsigned short output0;
+	unsigned short output1;
+	unsigned short selection;
+	unsigned short bpr;
+	unsigned int txsize;
+	unsigned int rxsize;
+	unsigned int rxcode;
+	unsigned int rxmask;
+};
+
+#define DEFAULT_DEVICE_CONFIG {			\
+		.output0 = 0,			\
+		.output1 = 0,			\
+		.selection = 0,			\
+		.bpr = 0,			\
+		.txsize = DEFAULT_BUFFER_SIZE,	\
+		.rxsize = DEFAULT_BUFFER_SIZE,	\
+		.rxcode = 0,			\
+		.rxmask = 0,			\
+		}
+
+struct grcan_stats {
+	u32 tx_ahberr;
+	u32 rx_ahberr;
+	u32 rx_hwfiltered;
+};
+
+#define TXBUG_SAFE_GRLIB_VERSION 0x4100
+#define GRLIB_VERSION_MASK 0xffff
+
+
+/*
+ * GRCAN private data structure
+ */
+struct grcan_priv {
+	struct can_priv can;	/* must be the first member */
+	struct net_device *dev;
+	void __iomem *reg_base;	 /* ioremap'ed address to registers */
+	u32 ambafreq;
+	struct grcan_device_config config;
+	struct grcan_dma dma;
+	struct sk_buff **echo_skb;	/* We allocate this on our own */
+	u32 eskbp;			/* Pointer into echo_skb */
+	u8 *txdlc;			/* Length of queued frames */
+
+	/* Lock for stopping and waking the netif tx queue and for
+	 * acesses to eskbp  */
+	spinlock_t lock;
+
+	/* Whether a workaround is needed due to a bug in older hardware. */
+	bool need_txbug_workaround;
+
+	/* To trigger initization of running reset and to trigger running reset
+	 * respectively in the case of a hanged device due to a txbug. */
+	struct timer_list hang_timer;
+	struct timer_list rr_timer;
+
+	/* To avoid waking up the netif queue and restarting timers
+	 * when a reset is scheduled or when closing of the device is
+	 * undergoing */
+	bool resetting;
+	bool closing;
+
+	bool trackgstats;
+	struct grcan_stats gstats;
+};
+
+/* Max # lopps in interrupt handler before reporting it  */
+#define GRCAN_MAX_IRQ          20
+
+/* Wait time for a short wait for ongoing to clear */
+#define ONGOING_SHORTWAIT_USECS 10
+
+/* Waiting for a time corresponding to transmission of three can frames */
+#define EFF_FRAME_MAX_BITS (1+32+6+8*8+16+2+7)
+#define ONGOING_WAIT_USECS(bitrate)			\
+	(1000000 * 3 * EFF_FRAME_MAX_BITS / (bitrate))
+#define ONGOING_WAIT_JIFFIES(bitrate)			\
+	usecs_to_jiffies(ONGOING_WAIT_USECS((bitrate)))
+
+#define RESET_TIMER(timer, bitrate)					\
+	mod_timer((timer), jiffies + ONGOING_WAIT_JIFFIES((bitrate)))
+
+
+#define TXSPACE(txsize, txwr, eskbp)					\
+	(((txsize) / MSG_SIZE - 1)					\
+	 - ((((txwr) - (eskbp)) % (txsize)) / MSG_SIZE))
+
+
+#endif /* GRCAN_H */
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* Re: [PATCH] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-10-02 14:38 [PATCH] can: grcan: Add device driver for GRCAN and GRHCAN cores Andreas Larsson
@ 2012-10-04  9:45 ` Marc Kleine-Budde
  2012-10-11 10:04   ` Marc Kleine-Budde
  0 siblings, 1 reply; 41+ messages in thread
From: Marc Kleine-Budde @ 2012-10-04  9:45 UTC (permalink / raw)
  To: Andreas Larsson; +Cc: linux-can, software

[-- Attachment #1: Type: text/plain, Size: 1370 bytes --]

Hello,

On 10/02/2012 04:38 PM, Andreas Larsson wrote:
> This driver supports GRCAN and CRHCAN CAN controllers available in the GRLIB
> VHDL IP core library.
> 
> Signed-off-by: Andreas Larsson <andreas@gaisler.com>
> ---
>  drivers/net/can/Kconfig  |    6 +
>  drivers/net/can/Makefile |    1 +
>  drivers/net/can/grcan.c  | 1283 ++++++++++++++++++++++++++++++++++++++++++++++
>  drivers/net/can/grcan.h  |  273 ++++++++++
>  4 files changed, 1563 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/net/can/grcan.c
>  create mode 100644 drivers/net/can/grcan.h

Some general remarks while scrolling though the driver:
- please provide a device tree binding documentation
  Documentation/devicetree/bindings/net/can/grcan.txt
  and add devicetree-discuss@lists.ozlabs.org on Cc
- please provide a documentation for the sysfs entries:
  Documentation/ABI/testing/sys-XXX-grcan.txt
- please implement a NAPI
- please include the .h file into the C code,
  as the C code is the one and only user of the .h file
- please give every macro a GRCAN_ prefix

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-10-04  9:45 ` Marc Kleine-Budde
@ 2012-10-11 10:04   ` Marc Kleine-Budde
  2012-10-11 11:22     ` Andreas Larsson
  2012-10-23  9:57     ` [PATCH v2] " Andreas Larsson
  0 siblings, 2 replies; 41+ messages in thread
From: Marc Kleine-Budde @ 2012-10-11 10:04 UTC (permalink / raw)
  To: Andreas Larsson; +Cc: linux-can, software

[-- Attachment #1: Type: text/plain, Size: 1737 bytes --]

On 10/04/2012 11:45 AM, Marc Kleine-Budde wrote:
> Hello,
> 
> On 10/02/2012 04:38 PM, Andreas Larsson wrote:
>> This driver supports GRCAN and CRHCAN CAN controllers available in the GRLIB
>> VHDL IP core library.
>>
>> Signed-off-by: Andreas Larsson <andreas@gaisler.com>
>> ---
>>  drivers/net/can/Kconfig  |    6 +
>>  drivers/net/can/Makefile |    1 +
>>  drivers/net/can/grcan.c  | 1283 ++++++++++++++++++++++++++++++++++++++++++++++
>>  drivers/net/can/grcan.h  |  273 ++++++++++
>>  4 files changed, 1563 insertions(+), 0 deletions(-)
>>  create mode 100644 drivers/net/can/grcan.c
>>  create mode 100644 drivers/net/can/grcan.h
> 
> Some general remarks while scrolling though the driver:
> - please provide a device tree binding documentation
>   Documentation/devicetree/bindings/net/can/grcan.txt
>   and add devicetree-discuss@lists.ozlabs.org on Cc
> - please provide a documentation for the sysfs entries:
>   Documentation/ABI/testing/sys-XXX-grcan.txt
> - please implement a NAPI
> - please include the .h file into the C code,
>   as the C code is the one and only user of the .h file
> - please give every macro a GRCAN_ prefix

Your driver should work on little as well as on big endian systems. You
need probably two implementations of the grcan_{read,write}_reg
functions, you can take the flexcan driver [1] as an example.

Marc

[1] http://lxr.free-electrons.com/source/drivers/net/can/flexcan.c#L222

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-10-11 10:04   ` Marc Kleine-Budde
@ 2012-10-11 11:22     ` Andreas Larsson
  2012-10-11 11:28       ` Marc Kleine-Budde
  2012-10-23  9:57     ` [PATCH v2] " Andreas Larsson
  1 sibling, 1 reply; 41+ messages in thread
From: Andreas Larsson @ 2012-10-11 11:22 UTC (permalink / raw)
  To: Marc Kleine-Budde; +Cc: linux-can, software

On 2012-10-11 12:04, Marc Kleine-Budde wrote:
> On 10/04/2012 11:45 AM, Marc Kleine-Budde wrote:
>> Hello,
>>
>> On 10/02/2012 04:38 PM, Andreas Larsson wrote:
>>> This driver supports GRCAN and CRHCAN CAN controllers available in the GRLIB
>>> VHDL IP core library.
>>>
>>> Signed-off-by: Andreas Larsson <andreas@gaisler.com>
>>> ---
>>>   drivers/net/can/Kconfig  |    6 +
>>>   drivers/net/can/Makefile |    1 +
>>>   drivers/net/can/grcan.c  | 1283 ++++++++++++++++++++++++++++++++++++++++++++++
>>>   drivers/net/can/grcan.h  |  273 ++++++++++
>>>   4 files changed, 1563 insertions(+), 0 deletions(-)
>>>   create mode 100644 drivers/net/can/grcan.c
>>>   create mode 100644 drivers/net/can/grcan.h
>>
>> Some general remarks while scrolling though the driver:
>> - please provide a device tree binding documentation
>>    Documentation/devicetree/bindings/net/can/grcan.txt
>>    and add devicetree-discuss@lists.ozlabs.org on Cc
>> - please provide a documentation for the sysfs entries:
>>    Documentation/ABI/testing/sys-XXX-grcan.txt
>> - please implement a NAPI
>> - please include the .h file into the C code,
>>    as the C code is the one and only user of the .h file
>> - please give every macro a GRCAN_ prefix
>
> Your driver should work on little as well as on big endian systems. You
> need probably two implementations of the grcan_{read,write}_reg
> functions, you can take the flexcan driver [1] as an example.

Adding that is easy of course, but that gives the impression of support 
for little endian systems. If the core would be instantiated in a little 
endian fashion in a little endian environment, the DMA accessing parts 
of the hardware would still not work in a little endian system without 
modifications to the hardware design.

 From the driver point of view either way works for me, but I am not 
sure what is best.

Cheers,
Andreas

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-10-11 11:22     ` Andreas Larsson
@ 2012-10-11 11:28       ` Marc Kleine-Budde
  2012-10-11 12:08         ` Andreas Larsson
  0 siblings, 1 reply; 41+ messages in thread
From: Marc Kleine-Budde @ 2012-10-11 11:28 UTC (permalink / raw)
  To: Andreas Larsson; +Cc: linux-can, software

[-- Attachment #1: Type: text/plain, Size: 2408 bytes --]

On 10/11/2012 01:22 PM, Andreas Larsson wrote:
> On 2012-10-11 12:04, Marc Kleine-Budde wrote:
>> On 10/04/2012 11:45 AM, Marc Kleine-Budde wrote:
>>> Hello,
>>>
>>> On 10/02/2012 04:38 PM, Andreas Larsson wrote:
>>>> This driver supports GRCAN and CRHCAN CAN controllers available in
>>>> the GRLIB
>>>> VHDL IP core library.
>>>>
>>>> Signed-off-by: Andreas Larsson <andreas@gaisler.com>
>>>> ---
>>>>   drivers/net/can/Kconfig  |    6 +
>>>>   drivers/net/can/Makefile |    1 +
>>>>   drivers/net/can/grcan.c  | 1283
>>>> ++++++++++++++++++++++++++++++++++++++++++++++
>>>>   drivers/net/can/grcan.h  |  273 ++++++++++
>>>>   4 files changed, 1563 insertions(+), 0 deletions(-)
>>>>   create mode 100644 drivers/net/can/grcan.c
>>>>   create mode 100644 drivers/net/can/grcan.h
>>>
>>> Some general remarks while scrolling though the driver:
>>> - please provide a device tree binding documentation
>>>    Documentation/devicetree/bindings/net/can/grcan.txt
>>>    and add devicetree-discuss@lists.ozlabs.org on Cc
>>> - please provide a documentation for the sysfs entries:
>>>    Documentation/ABI/testing/sys-XXX-grcan.txt
>>> - please implement a NAPI
>>> - please include the .h file into the C code,
>>>    as the C code is the one and only user of the .h file
>>> - please give every macro a GRCAN_ prefix
>>
>> Your driver should work on little as well as on big endian systems. You
>> need probably two implementations of the grcan_{read,write}_reg
>> functions, you can take the flexcan driver [1] as an example.
> 
> Adding that is easy of course, but that gives the impression of support
> for little endian systems. If the core would be instantiated in a little
> endian fashion in a little endian environment, the DMA accessing parts
> of the hardware would still not work in a little endian system without
> modifications to the hardware design.

Can you add this to the Kconfig help text.

> From the driver point of view either way works for me, but I am not sure
> what is best.

In this case you should limit the driver to big endian systems via kconfig.

Marc
-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-10-11 11:28       ` Marc Kleine-Budde
@ 2012-10-11 12:08         ` Andreas Larsson
  0 siblings, 0 replies; 41+ messages in thread
From: Andreas Larsson @ 2012-10-11 12:08 UTC (permalink / raw)
  To: Marc Kleine-Budde; +Cc: linux-can, software

On 2012-10-11 13:28, Marc Kleine-Budde wrote:
> On 10/11/2012 01:22 PM, Andreas Larsson wrote:
>> On 2012-10-11 12:04, Marc Kleine-Budde wrote:
>>> On 10/04/2012 11:45 AM, Marc Kleine-Budde wrote:
>>>> Hello,
>>>>
>>>> On 10/02/2012 04:38 PM, Andreas Larsson wrote:
>>>>> This driver supports GRCAN and CRHCAN CAN controllers available in
>>>>> the GRLIB
>>>>> VHDL IP core library.
>>>>>
>>>>> Signed-off-by: Andreas Larsson <andreas@gaisler.com>
>>>>> ---
>>>>>    drivers/net/can/Kconfig  |    6 +
>>>>>    drivers/net/can/Makefile |    1 +
>>>>>    drivers/net/can/grcan.c  | 1283
>>>>> ++++++++++++++++++++++++++++++++++++++++++++++
>>>>>    drivers/net/can/grcan.h  |  273 ++++++++++
>>>>>    4 files changed, 1563 insertions(+), 0 deletions(-)
>>>>>    create mode 100644 drivers/net/can/grcan.c
>>>>>    create mode 100644 drivers/net/can/grcan.h
>>>>
>>>> Some general remarks while scrolling though the driver:
>>>> - please provide a device tree binding documentation
>>>>     Documentation/devicetree/bindings/net/can/grcan.txt
>>>>     and add devicetree-discuss@lists.ozlabs.org on Cc
>>>> - please provide a documentation for the sysfs entries:
>>>>     Documentation/ABI/testing/sys-XXX-grcan.txt
>>>> - please implement a NAPI
>>>> - please include the .h file into the C code,
>>>>     as the C code is the one and only user of the .h file
>>>> - please give every macro a GRCAN_ prefix
>>>
>>> Your driver should work on little as well as on big endian systems. You
>>> need probably two implementations of the grcan_{read,write}_reg
>>> functions, you can take the flexcan driver [1] as an example.
>>
>> Adding that is easy of course, but that gives the impression of support
>> for little endian systems. If the core would be instantiated in a little
>> endian fashion in a little endian environment, the DMA accessing parts
>> of the hardware would still not work in a little endian system without
>> modifications to the hardware design.
>
> Can you add this to the Kconfig help text.
>
>>  From the driver point of view either way works for me, but I am not sure
>> what is best.
>
> In this case you should limit the driver to big endian systems via kconfig.

That would of course be nice. One problem with that is that there seems 
to be no Kconfig configuration option to depend on to match big endian 
systems in general.

One solution is to depend on SPARC (the standard environment of the 
core) and having anyone instantiating the core outside of a sparc 
environment patch his or her kernel.

Another solution is of course to do the ifdef on endianness solution 
like in flexcan and have a note in Kconfig text about the hardware not 
being compatible with little endian in an unchanged fashion.

I am not comfortable to try to come up with some hairy dependency that 
tries to catch all kinds of architectures that might or might not be 
configured big endian at compile time.

Cheers,
Andreas


^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH v2] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-10-11 10:04   ` Marc Kleine-Budde
  2012-10-11 11:22     ` Andreas Larsson
@ 2012-10-23  9:57     ` Andreas Larsson
  2012-10-23 16:26       ` Wolfgang Grandegger
  1 sibling, 1 reply; 41+ messages in thread
From: Andreas Larsson @ 2012-10-23  9:57 UTC (permalink / raw)
  To: linux-can; +Cc: mkl, devicetree-discuss, software

This driver supports GRCAN and CRHCAN CAN controllers available in the GRLIB
VHDL IP core library.

Signed-off-by: Andreas Larsson <andreas@gaisler.com>
---
 Documentation/ABI/testing/sysfs-class-net-grcan    |  136 ++
 .../devicetree/bindings/net/can/grcan.txt          |   27 +
 Documentation/kernel-parameters.txt                |   88 +-
 drivers/net/can/Kconfig                            |    9 +
 drivers/net/can/Makefile                           |    1 +
 drivers/net/can/grcan.c                            | 1735 ++++++++++++++++++++
 6 files changed, 1952 insertions(+), 44 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-class-net-grcan
 create mode 100644 Documentation/devicetree/bindings/net/can/grcan.txt
 create mode 100644 drivers/net/can/grcan.c

diff --git a/Documentation/ABI/testing/sysfs-class-net-grcan b/Documentation/ABI/testing/sysfs-class-net-grcan
new file mode 100644
index 0000000..c6eed07
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-net-grcan
@@ -0,0 +1,136 @@
+
+What:		/sys/class/net/<iface>/grcan/enable0
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas@gaisler.com>
+Description:
+		Hardware configuration of physical interface 0. This file reads
+		and writes the "Enable 0" bit of the configuration register.
+		Possible values: 0 or 1. See the GRCAN chapter of the GRLIB IP
+		core library documentation for details.
+		The default value is set by the module parameter enable0 and can
+		be read at /sys/module/grcan/parameters/enable0.
+
+What:		/sys/class/net/<iface>/grcan/enable1
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas@gaisler.com>
+Description:
+		Hardware configuration of physical interface 1. This file reads
+		and writes the "Enable 1" bit of the configuration register.
+		Possible values: 0 or 1. See the GRCAN chapter of the GRLIB IP
+		core library documentation for details.
+		The default value is set by the module parameter enable1 and can
+		be read at /sys/module/grcan/parameters/enable1.
+
+What:		/sys/class/net/<iface>/grcan/selection
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas@gaisler.com>
+Description:
+		Configuration of which physical interface to be used. Possible
+		values: 0 or 1. See the GRCAN chapter of the GRLIB IP core
+		library documentation for details.
+		The default value is set by the module parameter selection and can
+		be read at /sys/module/grcan/parameters/selection.
+
+What:		/sys/class/net/<iface>/grcan/bpr
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas@gaisler.com>
+Description:
+		Configuration of the bpr baud rate scaler (not to be confused
+		with the "brp" concept which in grcan is called scaler). From
+		the socket can layer's point of view, divides the external clock
+		frequency by 1 << value. Possible values in [0, 3].
+		The default value is set by the module parameter bpr and can
+		be read at /sys/module/grcan/parameters/bpr.
+
+What:		/sys/class/net/<iface>/grcan/txsize
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas@gaisler.com>
+Description:
+		Configures the size of the tx buffer. Possible values: (value &
+		0x1fffc0) == 0.
+		The default value is set by the module parameter txsize and can
+		be read at /sys/module/grcan/parameters/txsize.
+
+
+What:		/sys/class/net/<iface>/grcan/rxsize
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas@gaisler.com>
+Description:
+		Configures the size of the rx buffer. Possible values: (value &
+		0x1fffc0) == 0.
+		The default value is set by the module parameter rxsize and can
+		be read at /sys/module/grcan/parameters/rxsize.
+
+
+What:		/sys/class/net/<iface>/grcan/rxcode
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas@gaisler.com>
+Description:
+		Configures the rxcode of the hardware filter. Received messages
+		for which ((message_id ^ rxcode) & rxmask) != 0 holds will be
+		filtered out in harware. Possible values in [0, 0x1fffffff].
+		The default value is set by the module parameter rxcode and can
+		be read at /sys/module/grcan/parameters/rxcode.
+
+What:		/sys/class/net/<iface>/grcan/rxmask
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas@gaisler.com>
+Description:
+		Configures the rxmask of the hardware filter. Received messages
+		for which ((message_id ^ rxcode) & rxmask) != 0 holds will be
+		filtered out in harware. Possible values in [0, 0x1fffffff].
+		The default value is set by the module parameter rxmask and can
+		be read at /sys/module/grcan/parameters/rxmask.
+
+
+What:		/sys/class/net/<iface>/grcan/rxcode_basic
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas@gaisler.com>
+Description:
+		Configures the rxcode of the hardware filter to match a basic
+		id. Writable only. Result can be read in rxcode. Possible values
+		in [0, 0x7ff].
+
+What:		/sys/class/net/<iface>/grcan/rxmask_basic
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas@gaisler.com>
+Description:
+		Configures the rxmask of the hardware filter to match a basic
+		id. Writable only. Result can be read in rxcode. Possible values
+		in [0, 0x7ff].
+
+What:		/sys/class/net/<iface>/grcan/stat_ahberr_tx
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas@gaisler.com>
+Description:
+		Statistics on number of AHB errors that has happened during tx
+		(note that the device halts on AHB errors). Write anything to
+		reset to 0.
+
+What:		/sys/class/net/<iface>/grcan/stat_ahberr_rx
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas@gaisler.com>
+Description:
+		Statistics on number of AHB errors that has happened during rx
+		(note that the device halts on AHB errors). Write anything to
+		reset to 0.
+
+What:		/sys/class/net/<iface>/grcan/stat_hwfiltered
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas@gaisler.com>
+Description:
+		Statistics on number of hardware-filtered messages. Write anything to
+		reset to 0.
diff --git a/Documentation/devicetree/bindings/net/can/grcan.txt b/Documentation/devicetree/bindings/net/can/grcan.txt
new file mode 100644
index 0000000..a7180f1
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/can/grcan.txt
@@ -0,0 +1,27 @@
+CAN controller for Aeroflex Gaisler GRCAN and GRHCAN.
+
+The GRCAN and CRHCAN CAN controllers are available in the GRLIB VHDL IP core
+library.
+
+Note: These properties are built from the AMBA plug&play in a Leon SPARC
+system (the ordinary environment for GRCAN and GRHCAN). There are no bsp
+files for sparc.
+
+Required properties:
+
+- name : Should be "GAISLER_GRCAN", "01_03d", "GAISLER_GRHCAN" or "01_034"
+
+- reg : Address and length of the register set for the device
+
+- freq : Frequency of the external oscillator clock in Hz (the frequency of
+	the amba bus in the ordinary case)
+
+- interrupts : Interrupt number for this device
+
+Optional properties:
+
+- systemid : If not present or if the value of the least significant 16 bits
+	of this 32-bit property is smaller than GRCAN_TXBUG_SAFE_GRLIB_VERSION
+	a bug workaround is activated.
+
+For further information look in the documentation for the GLIB IP core library.
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 9776f06..32c924f 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -905,6 +905,46 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 	gpt		[EFI] Forces disk with valid GPT signature but
 			invalid Protective MBR to be treated as GPT.
 
+	grcan.enable0=	[HW] The "Enable 0" bit of the configuration
+			register. For more documentation, see
+			Documentation/ABI/testing/sysfs-class-net-grcan
+			Format: 0 | 1
+			Default: 0
+	grcan.enable1=	[HW] The "Enable 1" bit of the configuration
+			register. For more documentation, see
+			Documentation/ABI/testing/sysfs-class-net-grcan.
+			Format: 0 | 1
+			Default: 0
+	grcan.selection=
+			[HW] Selection of which physical interface to be
+			used. For more documentation, see
+			Documentation/ABI/testing/sysfs-class-net-grcan.
+			Format: 0 | 1
+			Default: 0
+	grcan.bpr=	[HW] Configuration of the bpr baud rate scaler. For
+			more documentation, see
+			Documentation/ABI/testing/sysfs-class-net-grcan.
+			Format: 0 | 1 | 2 | 3
+			Default: 0
+	grcan.txsize=	[HW] The size of the tx buffer. For more documentation,
+			see Documentation/ABI/testing/sysfs-class-net-grcan.
+			Format: <value> such that (value & 0x1fffc0) == 0.
+			Default: 1024
+	grcan.rxsize=	[HW] The size of the rx buffer. For more documentation,
+			see Documentation/ABI/testing/sysfs-class-net-grcan.
+			Format: <value> such that (value & 0x1fffc0) == 0.
+			Default: 1024
+	grcan.rxcode=	[HW] The rxcode of the hardware filter. For more
+			documentation, see
+			Documentation/ABI/testing/sysfs-class-net-grcan.
+			Format: <value> in the range [0, 0x1fffffff]
+			Default: 0
+	grcan.rxmask=	[HW] The rxmask of the hardware filter. For more
+			documentation, see
+			Documentation/ABI/testing/sysfs-class-net-grcan.
+			Format: <value> in the range [0, 0x1fffffff]
+			Default: 0
+
 	hashdist=	[KNL,NUMA] Large hashes allocated during boot
 			are distributed across NUMA nodes.  Defaults on
 			for 64-bit NUMA, off otherwise.
@@ -1051,14 +1091,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 	ihash_entries=	[KNL]
 			Set number of hash buckets for inode cache.
 
-	ima_appraise=	[IMA] appraise integrity measurements
-			Format: { "off" | "enforce" | "fix" }
-			default: "enforce"
-
-	ima_appraise_tcb [IMA]
-			The builtin appraise policy appraises all files
-			owned by uid=0.
-
 	ima_audit=	[IMA]
 			Format: { "0" | "1" }
 			0 -- integrity auditing messages. (Default)
@@ -1358,9 +1390,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			* nohrst, nosrst, norst: suppress hard, soft
                           and both resets.
 
-			* rstonce: only attempt one reset during
-			  hot-unplug link recovery
-
 			* dump_id: dump IDENTIFY data.
 
 			If there are multiple matching configurations changing
@@ -1593,12 +1622,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			log everything. Information is printed at KERN_DEBUG
 			so loglevel=8 may also need to be specified.
 
-	module.sig_enforce
-			[KNL] When CONFIG_MODULE_SIG is set, this means that
-			modules without (valid) signatures will fail to load.
-			Note that if CONFIG_MODULE_SIG_ENFORCE is set, that
-			is always true, so this option does nothing.
-
 	mousedev.tap_time=
 			[MOUSE] Maximum time between finger touching and
 			leaving touchpad surface for touch to be considered
@@ -1736,11 +1759,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			will be autodetected by the client, and it will fall
 			back to using the idmapper.
 			To turn off this behaviour, set the value to '0'.
-	nfs.nfs4_unique_id=
-			[NFS4] Specify an additional fixed unique ident-
-			ification string that NFSv4 clients can insert into
-			their nfs_client_id4 string.  This is typically a
-			UUID that is generated at system install time.
 
 	nfs.send_implementation_id =
 			[NFSv4.1] Send client implementation identification
@@ -1834,12 +1852,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			noexec=on: enable non-executable mappings (default)
 			noexec=off: disable non-executable mappings
 
-	nosmap		[X86]
-			Disable SMAP (Supervisor Mode Access Prevention)
-			even if it is supported by processor.
-
 	nosmep		[X86]
-			Disable SMEP (Supervisor Mode Execution Prevention)
+			Disable SMEP (Supervisor Mode Execution Protection)
 			even if it is supported by processor.
 
 	noexec32	[X86-64]
@@ -1859,12 +1873,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			and restore using xsave. The kernel will fallback to
 			enabling legacy floating-point and sse state.
 
-	eagerfpu=	[X86]
-			on	enable eager fpu restore
-			off	disable eager fpu restore
-			auto	selects the default scheme, which automatically
-				enables eagerfpu restore for xsaveopt.
-
 	nohlt		[BUGS=ARM,SH] Tells the kernel that the sleep(SH) or
 			wfi(ARM) instruction doesn't work correctly and not to
 			use it. This is also useful when using JTAG debugger.
@@ -2417,17 +2425,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 	rcutree.rcu_cpu_stall_timeout= [KNL,BOOT]
 			Set timeout for RCU CPU stall warning messages.
 
-	rcutree.jiffies_till_first_fqs= [KNL,BOOT]
-			Set delay from grace-period initialization to
-			first attempt to force quiescent states.
-			Units are jiffies, minimum value is zero,
-			and maximum value is HZ.
-
-	rcutree.jiffies_till_next_fqs= [KNL,BOOT]
-			Set delay between subsequent attempts to force
-			quiescent states.  Units are jiffies, minimum
-			value is one, and maximum value is HZ.
-
 	rcutorture.fqs_duration= [KNL,BOOT]
 			Set duration of force_quiescent_state bursts.
 
@@ -2681,6 +2678,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 	smart2=		[HW]
 			Format: <io1>[,<io2>[,...,<io8>]]
 
+	smp-alt-once	[X86-32,SMP] On a hotplug CPU system, only
+			attempt to substitute SMP alternatives once at boot.
+
 	smsc-ircc2.nopnp	[HW] Don't use PNP to discover SMC devices
 	smsc-ircc2.ircc_cfg=	[HW] Device configuration I/O port
 	smsc-ircc2.ircc_sir=	[HW] SIR base I/O port
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
index bb709fd..b56bd9e 100644
--- a/drivers/net/can/Kconfig
+++ b/drivers/net/can/Kconfig
@@ -110,6 +110,15 @@ config PCH_CAN
 	  is an IOH for x86 embedded processor (Intel Atom E6xx series).
 	  This driver can access CAN bus.
 
+config CAN_GRCAN
+	tristate "Aeroflex Gaisler GRCAN and GRHCAN CAN devices"
+	depends on CAN_DEV && OF
+	---help---
+	  Say Y here if you want to use Aeroflex Gaisler GRCAN or GRHCAN.
+	  Note that the driver supports little endian, even though little
+	  endian syntheses of the cores would need some modifications on
+	  the hardware level to work.
+
 source "drivers/net/can/mscan/Kconfig"
 
 source "drivers/net/can/sja1000/Kconfig"
diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
index 938be37..7de5986 100644
--- a/drivers/net/can/Makefile
+++ b/drivers/net/can/Makefile
@@ -22,5 +22,6 @@ obj-$(CONFIG_CAN_BFIN)		+= bfin_can.o
 obj-$(CONFIG_CAN_JANZ_ICAN3)	+= janz-ican3.o
 obj-$(CONFIG_CAN_FLEXCAN)	+= flexcan.o
 obj-$(CONFIG_PCH_CAN)		+= pch_can.o
+obj-$(CONFIG_CAN_GRCAN)		+= grcan.o
 
 ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/grcan.c b/drivers/net/can/grcan.c
new file mode 100644
index 0000000..856eff5
--- /dev/null
+++ b/drivers/net/can/grcan.c
@@ -0,0 +1,1735 @@
+/*
+ * Socket CAN driver for Aeroflex Gaisler GRCAN and GRHCAN.
+ *
+ * 2012 (c) Aeroflex Gaisler AB
+ *
+ * This driver supports GRCAN and CRHCAN CAN controllers available in the GRLIB
+ * VHDL IP core library.
+ *
+ * Full documentation of the GRCAN core can be found here:
+ * http://www.gaisler.com/products/grlib/grip.pdf
+ *
+ * See "Documentation/devicetree/bindings/net/can/grcan.txt" for information on
+ * open firmware properties.
+ *
+ * See "Documentation/ABI/testing/sysfs-class-net-grcan" for information on the
+ * sysfs interface.
+ *
+ * See "Documentation/kernel-parameters.txt" for information on the module
+ * parameters.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Contributors: Andreas Larsson <andreas@gaisler.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/can/dev.h>
+#include <linux/spinlock.h>
+
+#include <linux/of_platform.h>
+#include <asm/prom.h>
+
+#include <linux/of_irq.h>
+
+#include <linux/dma-mapping.h>
+
+#define DRV_NAME "grcan"
+
+#define GRCAN_NAPI_WEIGHT	16
+
+#define GRCAN_RESERVE_SIZE(slot1, slot2) (((slot2) - (slot1)) / 4 - 1)
+
+#define SPIN_LOCK(lock)						\
+	do { spin_lock(lock); priv->holder = __LINE__; } while (0)
+#define SPIN_LOCK_IRQSAVE(lock, flags)					\
+	do {spin_lock_irqsave(lock, flags); priv->holder = __LINE__; } while (0)
+#define SPIN_UNLOCK(lock)					\
+	do { priv->holder = 0; spin_unlock(lock); } while (0)
+#define SPIN_UNLOCK_IRQRESTORE(lock, flags)				\
+	do { priv->holder = 0; spin_unlock_irqrestore(lock, flags); } while (0)
+
+
+struct grcan_registers {
+	u32 conf;	/* 0x00 */
+	u32 stat;	/* 0x04 */
+	u32 ctrl;	/* 0x08 */
+	u32 __reserved1[GRCAN_RESERVE_SIZE(0x08, 0x18)];
+	u32 smask;	/* 0x18 - CanMASK */
+	u32 scode;	/* 0x1c - CanCODE */
+	u32 __reserved2[GRCAN_RESERVE_SIZE(0x1c, 0x100)];
+	u32 pimsr;	/* 0x100 */
+	u32 pimr;	/* 0x104 */
+	u32 pisr;	/* 0x108 */
+	u32 pir;	/* 0x10C */
+	u32 imr;	/* 0x110 */
+	u32 picr;	/* 0x114 */
+	u32 __reserved3[GRCAN_RESERVE_SIZE(0x114, 0x200)];
+	u32 txctrl;	/* 0x200 */
+	u32 txaddr;	/* 0x204 */
+	u32 txsize;	/* 0x208 */
+	u32 txwr;	/* 0x20C */
+	u32 txrd;	/* 0x210 */
+	u32 txirq;	/* 0x214 */
+	u32 __reserved4[GRCAN_RESERVE_SIZE(0x214, 0x300)];
+	u32 rxctrl;	/* 0x300 */
+	u32 rxaddr;	/* 0x304 */
+	u32 rxsize;	/* 0x308 */
+	u32 rxwr;	/* 0x30C */
+	u32 rxrd;	/* 0x310 */
+	u32 rxirq;	/* 0x314 */
+	u32 rxmask;	/* 0x318 */
+	u32 rxcode;	/* 0x31C */
+};
+
+#define GRCAN_CONF_ABORT      0x00000001
+#define GRCAN_CONF_ENABLE0    0x00000002
+#define GRCAN_CONF_ENABLE1    0x00000004
+#define GRCAN_CONF_SELECTION  0x00000008
+#define GRCAN_CONF_SILENT     0x00000010
+#define GRCAN_CONF_BPR        0x00000300  /* Note: not BRP */
+#define GRCAN_CONF_RSJ        0x00007000
+#define GRCAN_CONF_PS1        0x00f00000
+#define GRCAN_CONF_PS2        0x000f0000
+#define GRCAN_CONF_SCALER     0xff000000
+#define GRCAN_CONF_OPERATION						\
+	(GRCAN_CONF_ABORT | GRCAN_CONF_ENABLE0 | GRCAN_CONF_ENABLE1	\
+	 | GRCAN_CONF_SELECTION | GRCAN_CONF_SILENT)
+#define GRCAN_CONF_TIMING						\
+	(GRCAN_CONF_BPR | GRCAN_CONF_RSJ | GRCAN_CONF_PS1		\
+	 | GRCAN_CONF_PS2 | GRCAN_CONF_SCALER)
+
+#define GRCAN_CONF_RSJ_MIN    1
+#define GRCAN_CONF_RSJ_MAX    4
+#define GRCAN_CONF_PS1_MIN    1
+#define GRCAN_CONF_PS1_MAX    15
+#define GRCAN_CONF_PS2_MIN    2
+#define GRCAN_CONF_PS2_MAX    8
+#define GRCAN_CONF_SCALER_MIN 0
+#define GRCAN_CONF_SCALER_MAX 255
+#define GRCAN_CONF_SCALER_INC 1
+
+#define GRCAN_CONF_BPR_BIT    8
+#define GRCAN_CONF_RSJ_BIT    12
+#define GRCAN_CONF_PS1_BIT    20
+#define GRCAN_CONF_PS2_BIT    16
+#define GRCAN_CONF_SCALER_BIT 24
+
+#define GRCAN_STAT_PASS      0x000001
+#define GRCAN_STAT_OFF       0x000002
+#define GRCAN_STAT_OR        0x000004
+#define GRCAN_STAT_AHBERR    0x000008
+#define GRCAN_STAT_ACTIVE    0x000010
+#define GRCAN_STAT_RXERRCNT  0x00ff00
+#define GRCAN_STAT_TXERRCNT  0xff0000
+
+#define GRCAN_STAT_RXERRCNT_BIT  8
+#define GRCAN_STAT_TXERRCNT_BIT  16
+
+#define GRCAN_STAT_ERRCNT_WARNING_LIMIT 96
+#define GRCAN_STAT_ERRCNT_PASSIVE_LIMIT 127
+
+
+#define GRCAN_CTRL_RESET  0x2
+#define GRCAN_CTRL_ENABLE 0x1
+
+#define GRCAN_TXCTRL_ENABLE  0x1
+#define GRCAN_TXCTRL_ONGOING 0x2
+#define GRCAN_TXCTRL_SINGLE  0x4
+
+#define GRCAN_RXCTRL_ENABLE  0x1
+#define GRCAN_RXCTRL_ONGOING 0x2
+
+/* Relative offset of IRQ sources to AMBA Plug&Play */
+#define GRCAN_IRQIX_IRQ    0
+#define GRCAN_IRQIX_TXSYNC 1
+#define GRCAN_IRQIX_RXSYNC 2
+
+#define GRCAN_IRQ_PASS       0x00001
+#define GRCAN_IRQ_OFF        0x00002
+#define GRCAN_IRQ_OR         0x00004
+#define GRCAN_IRQ_RXAHBERR   0x00008
+#define GRCAN_IRQ_TXAHBERR   0x00010
+#define GRCAN_IRQ_RXIRQ      0x00020
+#define GRCAN_IRQ_TXIRQ      0x00040
+#define GRCAN_IRQ_RXFULL     0x00080
+#define GRCAN_IRQ_TXEMPTY    0x00100
+#define GRCAN_IRQ_RX         0x00200
+#define GRCAN_IRQ_TX         0x00400
+#define GRCAN_IRQ_RXSYNC     0x00800
+#define GRCAN_IRQ_TXSYNC     0x01000
+#define GRCAN_IRQ_RXERRCTR   0x02000
+#define GRCAN_IRQ_TXERRCTR   0x04000
+#define GRCAN_IRQ_RXMISS     0x08000
+#define GRCAN_IRQ_TXLOSS     0x10000
+
+#define GRCAN_IRQ_NONE 0
+#define GRCAN_IRQ_ALL \
+(GRCAN_IRQ_PASS | GRCAN_IRQ_OFF | GRCAN_IRQ_OR				\
+		       | GRCAN_IRQ_RXAHBERR | GRCAN_IRQ_TXAHBERR	\
+		       | GRCAN_IRQ_RXIRQ | GRCAN_IRQ_TXIRQ		\
+		       | GRCAN_IRQ_RXFULL | GRCAN_IRQ_TXEMPTY		\
+		       | GRCAN_IRQ_RX | GRCAN_IRQ_TX | GRCAN_IRQ_RXSYNC \
+		       | GRCAN_IRQ_TXSYNC | GRCAN_IRQ_RXERRCTR		\
+		       | GRCAN_IRQ_TXERRCTR | GRCAN_IRQ_RXMISS		\
+		       | GRCAN_IRQ_TXLOSS)
+
+#define GRCAN_IRQ_ERRCTR_RELATED (GRCAN_IRQ_RXERRCTR | GRCAN_IRQ_TXERRCTR \
+				  | GRCAN_IRQ_PASS | GRCAN_IRQ_OFF)
+#define GRCAN_IRQ_ERRORS (GRCAN_IRQ_ERRCTR_RELATED | GRCAN_IRQ_OR	\
+			  | GRCAN_IRQ_TXAHBERR | GRCAN_IRQ_RXAHBERR	\
+			  | GRCAN_IRQ_RXMISS | GRCAN_IRQ_TXLOSS)
+#define GRCAN_IRQ_DEFAULT (GRCAN_IRQ_RX | GRCAN_IRQ_TX | GRCAN_IRQ_ERRORS)
+
+#define GRCAN_MSG_SIZE 16
+
+#define GRCAN_MSG_IDE 0x80000000
+#define GRCAN_MSG_RTR 0x40000000
+#define GRCAN_MSG_BID 0x1ffc0000
+#define GRCAN_MSG_EID 0x1fffffff
+#define GRCAN_MSG_IDE_BIT 31
+#define GRCAN_MSG_RTR_BIT 30
+#define GRCAN_MSG_BID_BIT 18
+#define GRCAN_MSG_EID_BIT 0
+
+#define GRCAN_MSG_DLC    0xf0000000
+#define GRCAN_MSG_TXERRC 0x00ff0000
+#define GRCAN_MSG_RXERRC 0x0000ff00
+#define GRCAN_MSG_DLC_BIT 28
+#define GRCAN_MSG_TXERRC_BIT 16
+#define GRCAN_MSG_RXERRC_BIT 8
+#define GRCAN_MSG_AHBERR 0x00000008
+#define GRCAN_MSG_OR     0x00000004
+#define GRCAN_MSG_OFF    0x00000002
+#define GRCAN_MSG_PASS   0x00000001
+
+#define GRCAN_MSG_DATA_SLOT_INDEX(i) (2 + (i) / 4)
+#define GRCAN_MSG_DATA_SHIFT(i) ((3 - (i) % 4) * 8)
+
+#define GRCAN_BUFFER_ALIGNMENT 1024
+#define GRCAN_DEFAULT_BUFFER_SIZE 1024
+
+#define GRCAN_VALID_TR_SIZE_MASK 0x001fffc0
+#define GRCAN_INVALID_BUFFER_SIZE(s)		\
+	((s) == 0 || ((s) & ~GRCAN_VALID_TR_SIZE_MASK))
+
+#if GRCAN_INVALID_BUFFER_SIZE(GRCAN_DEFAULT_BUFFER_SIZE)
+#error "Invalid default buffer size"
+#endif
+
+struct grcan_dma_buffer {
+	size_t size;
+	void *buf;
+	dma_addr_t handle;
+};
+
+struct grcan_dma {
+	size_t base_size;
+	void *base_buf;
+	dma_addr_t base_handle;
+	struct grcan_dma_buffer tx;
+	struct grcan_dma_buffer rx;
+};
+
+/* GRCAN configuration parameters */
+struct grcan_device_config {
+	unsigned short enable0;
+	unsigned short enable1;
+	unsigned short selection;
+	unsigned short bpr;
+	unsigned int txsize;
+	unsigned int rxsize;
+	unsigned int rxcode;
+	unsigned int rxmask;
+};
+
+#define GRCAN_DEFAULT_DEVICE_CONFIG {			\
+		.enable0 = 0,				\
+		.enable1 = 0,				\
+		.selection = 0,				\
+		.bpr = 0,				\
+		.txsize = GRCAN_DEFAULT_BUFFER_SIZE,	\
+		.rxsize = GRCAN_DEFAULT_BUFFER_SIZE,	\
+		.rxcode = 0,				\
+		.rxmask = 0,				\
+		}
+
+struct grcan_stats {
+	u32 ahberr_tx;
+	u32 ahberr_rx;
+	u32 hwfiltered;
+};
+
+#define GRCAN_TXBUG_SAFE_GRLIB_VERSION 0x4100
+#define GRLIB_VERSION_MASK 0xffff
+
+
+/* GRCAN private data structure */
+struct grcan_priv {
+	struct can_priv can;	/* must be the first member */
+	struct net_device *dev;
+	struct napi_struct napi;
+
+	struct grcan_registers __iomem *regs; /* ioremap'ed registers */
+	struct grcan_device_config config;
+	struct grcan_dma dma;
+	struct sk_buff **echo_skb;	/* We allocate this on our own */
+	u32 eskbp;			/* Pointer into echo_skb */
+	u8 *txdlc;			/* Length of queued frames */
+	u32 ambafreq;
+
+	/* Lock for stopping and waking the netif tx queue and for
+	 * accesses to eskbp
+	 */
+	spinlock_t lock;
+	int holder;
+
+	/* Whether a workaround is needed due to a bug in older hardware. */
+	bool need_txbug_workaround;
+
+	/* To trigger initization of running reset and to trigger running reset
+	 * respectively in the case of a hanged device due to a txbug.
+	 */
+	struct timer_list hang_timer;
+	struct timer_list rr_timer;
+
+	/* To avoid waking up the netif queue and restarting timers
+	 * when a reset is scheduled or when closing of the device is
+	 * undergoing
+	 */
+	bool resetting;
+	bool closing;
+
+	struct grcan_stats gstats;
+};
+
+/* Wait time for a short wait for ongoing to clear */
+#define GRCAN_SHORTWAIT_USECS 10
+
+/* Waiting for a time corresponding to transmission of three can frames */
+#define GRCAN_EFF_FRAME_MAX_BITS (1+32+6+8*8+16+2+7)
+
+#if defined(__BIG_ENDIAN)
+static inline u32 grcan_read_reg(u32 __iomem *reg)
+{
+	return ioread32be(reg);
+}
+
+static inline void grcan_write_reg(u32 __iomem *reg, u32 val)
+{
+	iowrite32be(val, reg);
+}
+#else
+static inline u32 grcan_read_reg(u32 __iomem *reg)
+{
+	return ioread32(reg);
+}
+
+static inline void grcan_write_reg(u32 __iomem *reg, u32 val)
+{
+	iowrite32(val, reg);
+}
+#endif
+
+static inline void grcan_clear_bits(u32 __iomem *reg, u32 mask)
+{
+	grcan_write_reg(reg, grcan_read_reg(reg) & ~mask);
+}
+
+static inline void grcan_set_bits(u32 __iomem *reg, u32 mask)
+{
+	grcan_write_reg(reg, grcan_read_reg(reg) | mask);
+}
+
+static inline u32 grcan_read_bits(u32 __iomem *reg, u32 mask)
+{
+	return grcan_read_reg(reg) & mask;
+}
+
+static inline void grcan_write_bits(u32 __iomem *reg, u32 value, u32 mask)
+{
+	u32 old = grcan_read_reg(reg);
+	grcan_write_reg(reg, (old & ~mask) | (value & mask));
+}
+
+static inline u32 grcan_ring_add(u32 a, u32 b, u32 size)
+{
+	u32 sum = a + b;
+	if (sum < size)
+		return sum;
+	else
+		return sum - size;
+}
+
+static inline u32 grcan_ring_sub(u32 a, u32 b, u32 size)
+{
+	u32 diff = a - b;
+	if (a < b)
+		return diff + size;
+	else
+		return diff;
+}
+
+static inline u32 grcan_txspace(size_t txsize, u32 txwr, u32 eskbp)
+{
+	u32 slots = txsize / GRCAN_MSG_SIZE - 1;
+	u32 used = grcan_ring_sub(txwr, eskbp, txsize);
+	return slots - used;
+}
+
+/* Configuration parameters that can be set via module parameters */
+static struct grcan_device_config grcan_module_config =
+	GRCAN_DEFAULT_DEVICE_CONFIG;
+
+static struct can_bittiming_const grcan_bittiming_const = {
+	.name = DRV_NAME,
+	.tseg1_min = GRCAN_CONF_PS1_MIN + 1,
+	.tseg1_max = GRCAN_CONF_PS1_MAX + 1,
+	.tseg2_min = GRCAN_CONF_PS2_MIN,
+	.tseg2_max = GRCAN_CONF_PS2_MAX,
+	.sjw_max   = GRCAN_CONF_RSJ_MAX,
+	.brp_min   = GRCAN_CONF_SCALER_MIN + 1,
+	.brp_max   = GRCAN_CONF_SCALER_MAX + 1,
+	.brp_inc   = GRCAN_CONF_SCALER_INC,
+};
+
+static int grcan_set_bittiming(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct can_bittiming *bt = &priv->can.bittiming;
+	u32 timing = 0;
+	int bpr, rsj, ps1, ps2, scaler;
+
+	/* Should never happen - function will not be called when
+	 * device is up
+	 */
+	if (grcan_read_bits(&regs->ctrl, GRCAN_CTRL_ENABLE))
+		return -EBUSY;
+
+	/* Note bpr and brp are different concepts */
+	bpr    = priv->config.bpr;
+	rsj    = bt->sjw;
+	ps1    = (bt->prop_seg + bt->phase_seg1) - 1; /* tseg1-1 */
+	ps2    = bt->phase_seg2;
+	scaler = (bt->brp - 1);
+	timing |= (bpr << GRCAN_CONF_BPR_BIT) & GRCAN_CONF_BPR;
+	timing |= (rsj << GRCAN_CONF_RSJ_BIT) & GRCAN_CONF_RSJ;
+	timing |= (ps1 << GRCAN_CONF_PS1_BIT) & GRCAN_CONF_PS1;
+	timing |= (ps2 << GRCAN_CONF_PS2_BIT) & GRCAN_CONF_PS2;
+	timing |= (scaler << GRCAN_CONF_SCALER_BIT) & GRCAN_CONF_SCALER;
+
+	dev_info(dev->dev.parent,
+		 "setting timing=0x%x\n", timing);
+	grcan_write_bits(&regs->conf, timing, GRCAN_CONF_TIMING);
+	return 0;
+}
+
+static int grcan_get_berr_counter(const struct net_device *dev,
+				  struct can_berr_counter *bec)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	u32 status = grcan_read_reg(&regs->stat);
+	bec->txerr = (status & GRCAN_STAT_TXERRCNT) >> GRCAN_STAT_TXERRCNT_BIT;
+	bec->rxerr = (status & GRCAN_STAT_RXERRCNT) >> GRCAN_STAT_RXERRCNT_BIT;
+	return 0;
+}
+
+static int grcan_poll(struct napi_struct *napi, int budget);
+
+/* Reset device, but keep timing information */
+static void grcan_reset(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	u32 timing = grcan_read_bits(&regs->conf, GRCAN_CONF_TIMING);
+	grcan_set_bits(&regs->ctrl, GRCAN_CTRL_RESET);
+	grcan_write_bits(&regs->conf, timing, GRCAN_CONF_TIMING);
+	priv->eskbp = grcan_read_reg(&regs->txrd);
+	priv->can.state = CAN_STATE_STOPPED;
+}
+
+/* stop device without changing any configurations */
+static void grcan_stop(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	grcan_write_reg(&regs->imr, GRCAN_IRQ_NONE);
+	grcan_clear_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
+	grcan_clear_bits(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+	grcan_clear_bits(&regs->ctrl, GRCAN_CTRL_ENABLE);
+	priv->can.state = CAN_STATE_STOPPED;
+}
+
+/* Let priv->eskp catch up to regs->txrd and echo back the skbs if echo is true
+ * and free them otherwise.
+ *
+ * If budget is >= 0, stop after handling at most budget skbs. Otherwise,
+ * continue until priv->eskp catches up to regs->txrd.
+ *
+ * priv->lock *must* be held when calling this function
+ */
+static int catch_up_echo_skb(struct net_device *dev, int budget, bool echo)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	struct net_device_stats *stats = &dev->stats;
+	int i, work_done;
+
+	/* Updates to priv->eskbp and wake-ups of the queue needs to
+	 * be atomic towards the reads of priv->eskbp and shut-downs
+	 * of the queue in grcan_start_xmit.
+	 */
+	u32 txrd = grcan_read_reg(&regs->txrd);
+	for (work_done = 0; work_done < budget || budget < 0; work_done++) {
+		if (priv->eskbp == txrd)
+			break;
+		i = priv->eskbp / GRCAN_MSG_SIZE;
+		if (echo) {
+			/* Normal echo of messages */
+			stats->tx_packets++;
+			stats->tx_bytes += priv->txdlc[i];
+			priv->txdlc[i] = 0;
+			can_get_echo_skb(dev, i);
+		} else {
+			/* For cleanup of untransmitted messages */
+			can_free_echo_skb(dev, i);
+		}
+
+		priv->eskbp = grcan_ring_add(priv->eskbp, GRCAN_MSG_SIZE,
+					     dma->tx.size);
+		txrd = grcan_read_reg(&regs->txrd);
+	}
+	return work_done;
+}
+
+static void grcan_lost_one_shot_frame(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	u32 txrd;
+
+	SPIN_LOCK(&priv->lock);
+	priv->holder = 1;
+
+	catch_up_echo_skb(dev, -1, true);
+
+	if (unlikely(grcan_read_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE))) {
+		/* Should never happen */
+		netdev_err(dev, "TXCTRL enabled at TXLOSS in one shot mode\n");
+	} else {
+		/* By the time an GRCAN_IRQ_TXLOSS is generated in
+		 * one-shot mode there is no problem in writing
+		 * to TXRD even in versions of the hardware in
+		 * which GRCAN_TXCTRL_ONGOING is not cleared properly
+		 * in one-shot mode.
+		 */
+
+		/* Skip message and discard echo-skb */
+		txrd = grcan_read_reg(&regs->txrd);
+		txrd = grcan_ring_add(txrd, GRCAN_MSG_SIZE, dma->tx.size);
+		grcan_write_reg(&regs->txrd, txrd);
+		catch_up_echo_skb(dev, -1, false);
+
+		if (!priv->resetting && !priv->closing) {
+			if (netif_queue_stopped(dev))
+				netif_wake_queue(dev);
+			grcan_set_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
+		}
+	}
+
+	priv->holder = 0;
+	SPIN_UNLOCK(&priv->lock);
+}
+
+static void grcan_err(struct net_device *dev, u32 sources, u32 status)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct net_device_stats *stats = &dev->stats;
+	struct can_frame cf;
+
+	/* Zero potential error_frame */
+	memset(&cf, 0, sizeof(cf));
+
+	/* Arbitration lost interrupt */
+	if (sources & GRCAN_IRQ_TXLOSS) {
+		netdev_dbg(dev,
+			   "arbitration lost (or other comm failure)\n");
+		stats->tx_errors++;
+		priv->can.can_stats.arbitration_lost++;
+
+		/* Take care of failed one-shot transmit */
+		if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT)
+			grcan_lost_one_shot_frame(dev);
+
+		cf.can_id |= CAN_ERR_LOSTARB;
+	}
+
+	/* Conditions dealing with the error counters */
+	if (sources & GRCAN_IRQ_ERRCTR_RELATED) {
+		enum can_state state = priv->can.state;
+		enum can_state oldstate = state;
+		u32 txerr = (status & GRCAN_STAT_TXERRCNT)
+			>> GRCAN_STAT_TXERRCNT_BIT;
+		u32 rxerr = (status & GRCAN_STAT_RXERRCNT)
+			>> GRCAN_STAT_RXERRCNT_BIT;
+
+		if (status & GRCAN_STAT_OFF) {
+			netdev_dbg(dev, "Bus off condition\n");
+			state = CAN_STATE_BUS_OFF;
+			can_bus_off(dev);
+
+			cf.can_id |= CAN_ERR_BUSOFF;
+		} else if (status & GRCAN_STAT_PASS) {
+			netdev_dbg(dev, "Error passive condition\n");
+			state = CAN_STATE_ERROR_PASSIVE;
+			priv->can.can_stats.error_passive++;
+
+			cf.can_id |= CAN_ERR_CRTL;
+			if (txerr >= GRCAN_STAT_ERRCNT_PASSIVE_LIMIT)
+				cf.data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
+			if (rxerr >= GRCAN_STAT_ERRCNT_PASSIVE_LIMIT)
+				cf.data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
+		} else if (txerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT ||
+			   rxerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT) {
+			state = CAN_STATE_ERROR_WARNING;
+			priv->can.can_stats.error_warning++;
+			if (oldstate != state)
+				netdev_dbg(dev, "Error warning condition\n");
+
+			cf.can_id |= CAN_ERR_CRTL;
+			if (txerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT)
+				cf.data[1] |= CAN_ERR_CRTL_TX_WARNING;
+			if (rxerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT)
+				cf.data[1] |= CAN_ERR_CRTL_RX_WARNING;
+		} else {
+			state = CAN_STATE_ERROR_ACTIVE;
+			if (oldstate != state)
+				netdev_dbg(dev, "Error active condition\n");
+		}
+		if (state != CAN_STATE_ERROR_ACTIVE) {
+			cf.data[6] = txerr;
+			cf.data[7] = rxerr;
+		}
+		priv->can.state = state;
+	}
+
+	/* Data overrun interrupt */
+	if (sources & GRCAN_IRQ_OR) {
+		netdev_dbg(dev, "got data overrun interrupt\n");
+		stats->rx_over_errors++;
+		stats->rx_errors++;
+
+		cf.can_id  |= CAN_ERR_CRTL;
+		cf.data[1] |= CAN_ERR_CRTL_RX_OVERFLOW;
+	}
+
+	/* AHB bus error interrupts (not CAN bus errors) - shut down the
+	 * device.
+	 */
+	if (sources & (GRCAN_IRQ_TXAHBERR | GRCAN_IRQ_RXAHBERR)) {
+		if (sources & GRCAN_IRQ_TXAHBERR) {
+			netdev_err(dev, "got AHB bus error on tx\n");
+			stats->tx_errors++;
+			priv->gstats.ahberr_tx++;
+		} else {
+			netdev_err(dev, "got AHB bus error on rx\n");
+			stats->rx_errors++;
+			priv->gstats.ahberr_rx++;
+		}
+		netdev_err(dev, "halting device\n");
+
+		/* Prevent anything to be enabled again and halt device */
+		SPIN_LOCK(&priv->lock);
+		priv->closing = true;
+		netif_stop_queue(dev);
+		grcan_stop(dev);
+		SPIN_UNLOCK(&priv->lock);
+	}
+
+	/* Message filtered interrupt */
+	if (sources & GRCAN_IRQ_RXMISS)
+		priv->gstats.hwfiltered++;
+
+	/* Pass on error frame if something to report,
+	 * i.e. id contains some information
+	 */
+	if (cf.can_id) {
+		struct can_frame *skb_cf;
+		struct sk_buff *skb = alloc_can_err_skb(dev, &skb_cf);
+		if (skb == NULL)
+			netdev_dbg(dev, "could not allocate error frame\n");
+		skb_cf->can_id |= cf.can_id;
+		memcpy(skb_cf->data, cf.data, sizeof(cf.data));
+
+		netif_rx(skb);
+	}
+}
+
+static irqreturn_t grcan_interrupt(int irq, void *dev_id)
+{
+	struct net_device *dev = (struct net_device *)dev_id;
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	u32 sources, status;
+
+	/* Find out the source */
+	sources = grcan_read_reg(&regs->pimsr);
+	if (!sources)
+		return IRQ_NONE;
+	grcan_write_reg(&regs->picr, sources);
+	status = grcan_read_reg(&regs->stat);
+
+	/* If we got TX progress, the device has not hanged,
+	 * so disable the hang timer
+	 */
+	if (priv->need_txbug_workaround
+	    && (sources & (GRCAN_IRQ_TX | GRCAN_IRQ_TXLOSS))) {
+		SPIN_LOCK(&priv->lock);
+		if (timer_pending(&priv->hang_timer))
+			del_timer(&priv->hang_timer);
+		SPIN_UNLOCK(&priv->lock);
+	}
+
+	/* Frame(s) received or transmitted */
+	if (sources & (GRCAN_IRQ_TX | GRCAN_IRQ_RX)) {
+		/* Disable tx/rx interrupts and schedule poll() */
+		grcan_clear_bits(&regs->imr, GRCAN_IRQ_TX | GRCAN_IRQ_RX);
+		napi_schedule(&priv->napi);
+	}
+
+	/* (Potential) error conditions to take care of */
+	if (sources & GRCAN_IRQ_ERRORS)
+		grcan_err(dev, sources, status);
+
+	return IRQ_HANDLED;
+}
+
+/* Reset device and restart operations from where they were.
+ *
+ * This assumes that RXCTRL & RXCTRL is properly disabled and that RX
+ * is not ONGOING (TX might be stuck in ONGOING due to a harwrware bug
+ * for single shot)
+ */
+static void grcan_running_reset(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *) data;
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	u32 txwr, txrd, rxwr, rxrd, eskbp;
+	unsigned long flags;
+
+	/* This temporarily messes with eskbp, so we need to lock
+	 * priv->lock
+	 */
+	SPIN_LOCK_IRQSAVE(&priv->lock, flags);
+	if (!priv->closing && priv->resetting) {
+		txwr = grcan_read_reg(&regs->txwr);
+		txrd = grcan_read_reg(&regs->txrd);
+		rxwr = grcan_read_reg(&regs->rxwr);
+		rxrd = grcan_read_reg(&regs->rxrd);
+		eskbp = priv->eskbp;
+
+		grcan_reset(dev);
+
+		grcan_write_reg(&regs->txwr, txwr);
+		grcan_write_reg(&regs->txrd, txrd);
+		grcan_write_reg(&regs->rxwr, rxwr);
+		grcan_write_reg(&regs->rxrd, rxrd);
+		priv->eskbp = eskbp;
+
+		priv->can.state = CAN_STATE_ERROR_ACTIVE;
+		grcan_set_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE
+			      | (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT
+				 ? GRCAN_TXCTRL_SINGLE : 0));
+		grcan_set_bits(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+		/* Start queue if there is size */
+		if (grcan_txspace(priv->dma.tx.size, txwr, priv->eskbp))
+			netif_wake_queue(dev);
+
+		del_timer(&priv->hang_timer);
+		del_timer(&priv->rr_timer);
+
+		priv->resetting = false;
+	}
+	SPIN_UNLOCK_IRQRESTORE(&priv->lock, flags);
+	netdev_err(dev, "Device reset and restored\n");
+
+}
+
+/* A time in usecs within which the can controller have time to finish sending
+ * or receiving a frame with a good margin
+ */
+static inline u32 grcan_ongoing_wait_usecs(__u32 bitrate)
+{
+	return 1000000 * 3 * GRCAN_EFF_FRAME_MAX_BITS / bitrate;
+}
+
+/* Set timer so that it will not fire until after a period in which the can
+ * controller have a good margin to finish transmitting a frame unless it has
+ * hanged
+ */
+static inline void grcan_reset_timer(struct timer_list *timer, __u32 bitrate)
+{
+	u32 wait_jiffies = usecs_to_jiffies(grcan_ongoing_wait_usecs(bitrate));
+	mod_timer(timer, jiffies + wait_jiffies);
+}
+
+/* Disable channels and schedule a running reset */
+static void grcan_initiate_running_reset(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *)data;
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	unsigned long flags;
+
+	netdev_err(dev, "Device seems hanged - reset scheduled\n");
+
+
+	SPIN_LOCK_IRQSAVE(&priv->lock, flags);
+
+	/* The main body of this function must never be executed again
+	 * until after an execution of grcan_running_reset
+	 */
+	if (!priv->resetting && !priv->closing) {
+		priv->resetting = true;
+		netif_stop_queue(dev);
+		grcan_clear_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
+		grcan_clear_bits(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+		grcan_reset_timer(&priv->rr_timer, priv->can.bittiming.bitrate);
+	}
+
+	SPIN_UNLOCK_IRQRESTORE(&priv->lock, flags);
+}
+
+static void grcan_free_dma_buffers(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_dma *dma = &priv->dma;
+	dma_free_coherent(&dev->dev,
+			  dma->base_size,
+			  dma->base_buf,
+			  dma->base_handle);
+	dma->base_size = 0;
+	dma->base_buf = NULL;
+	dma->base_handle = 0;
+	dma->rx.size = 0;
+	dma->rx.buf = NULL;
+	dma->rx.handle = 0;
+	dma->tx.size = 0;
+	dma->tx.buf = NULL;
+	dma->tx.handle = 0;
+}
+
+static int grcan_allocate_dma_buffers(struct net_device *dev,
+				      size_t tsize, size_t rsize)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_dma *dma = &priv->dma;
+	struct grcan_dma_buffer *large = rsize > tsize ? &dma->rx : &dma->tx;
+	struct grcan_dma_buffer *small = rsize > tsize ? &dma->tx : &dma->rx;
+	size_t shift;
+
+	/* Need a whole number of GRCAN_BUFFER_ALIGNMENT for the large,
+	 * i.e. first buffer
+	 */
+	size_t maxs  = max(tsize, rsize);
+	size_t lsize = ALIGN(maxs, GRCAN_BUFFER_ALIGNMENT);
+
+	/* Put the small buffer after that */
+	size_t ssize = min(tsize, rsize);
+
+	/* Extra GRCAN_BUFFER_ALIGNMENT to allow for alignment */
+	dma->base_size = lsize + ssize + GRCAN_BUFFER_ALIGNMENT;
+	dma->base_buf = dma_alloc_coherent(&dev->dev,
+					   dma->base_size,
+					   &dma->base_handle,
+					   GFP_KERNEL);
+
+	if (!dma->base_buf)
+		return -ENOMEM;
+
+	dma->tx.size = tsize;
+	dma->rx.size = rsize;
+
+	large->handle = ALIGN(dma->base_handle, GRCAN_BUFFER_ALIGNMENT);
+	small->handle = large->handle + lsize;
+	shift = large->handle - dma->base_handle;
+
+	large->buf = dma->base_buf + shift;
+	small->buf = large->buf + lsize;
+
+	return 0;
+}
+
+
+/* priv->lock *must* be held when calling this function */
+static int grcan_start(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+
+	grcan_reset(dev);
+
+	grcan_write_reg(&regs->txaddr, priv->dma.tx.handle);
+	grcan_write_reg(&regs->txsize, priv->dma.tx.size);
+	/* REG_TXWR and REG_TXRD already set to 0 by reset */
+
+	grcan_write_reg(&regs->rxaddr, priv->dma.rx.handle);
+	grcan_write_reg(&regs->rxsize, priv->dma.rx.size);
+	/* REG_RXWR and REG_RXRD already set to 0 by reset */
+
+	/* Set up hardware message filtering */
+	grcan_write_reg(&regs->rxcode, priv->config.rxcode);
+	grcan_write_reg(&regs->rxmask, priv->config.rxmask);
+
+	/* Enable interrupts */
+	grcan_read_reg(&regs->pir);
+	grcan_write_reg(&regs->imr, GRCAN_IRQ_DEFAULT);
+
+	/* Enable interfaces, channels and device */
+	grcan_set_bits(&regs->conf,
+		      ((priv->config.enable0 ? GRCAN_CONF_ENABLE0 : 0)
+		       | (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY ?
+			  GRCAN_CONF_SILENT : 0)
+		       | (priv->config.enable1 ? GRCAN_CONF_ENABLE1 : 0)
+		       | (priv->config.selection ? GRCAN_CONF_SELECTION : 0)
+		       | GRCAN_CONF_ABORT));
+	grcan_set_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE
+		      | (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT
+			 ? GRCAN_TXCTRL_SINGLE : 0));
+	grcan_set_bits(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+	grcan_set_bits(&regs->ctrl, GRCAN_CTRL_ENABLE);
+
+	priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+	return 0;
+}
+
+static int grcan_set_mode(struct net_device *dev, enum can_mode mode)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+	int err;
+
+	if (mode == CAN_MODE_START) {
+		/* This might be called to restart the device to recover from
+		 * bus off errors
+		 */
+		SPIN_LOCK_IRQSAVE(&priv->lock, flags);
+		if (priv->closing || priv->resetting) {
+			err = -EBUSY;
+		} else {
+			netdev_info(dev, "Restarting device\n");
+			grcan_start(dev);
+			if (netif_queue_stopped(dev))
+				netif_wake_queue(dev);
+			err = 0;
+		}
+		SPIN_UNLOCK_IRQRESTORE(&priv->lock, flags);
+		return err;
+	}
+	return -EOPNOTSUPP;
+}
+
+static int grcan_open(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_dma *dma = &priv->dma;
+	unsigned long flags;
+	int err;
+
+	SPIN_LOCK_IRQSAVE(&priv->lock, flags);
+
+	/* Allocate memory */
+	if (GRCAN_INVALID_BUFFER_SIZE(priv->config.txsize)
+	    || GRCAN_INVALID_BUFFER_SIZE(priv->config.rxsize)) {
+		/* Should never be able go this far with invalid sizes */
+		netdev_err(dev, "Invalid buffer size pair 0x%x 0x%x\n",
+			   priv->config.txsize, priv->config.rxsize);
+		err = -EINVAL;
+		goto exit_unlock;
+	}
+	err = grcan_allocate_dma_buffers(dev, priv->config.txsize,
+					 priv->config.rxsize);
+	if (err) {
+		netdev_err(dev, "could not allocate DMA buffers\n");
+		goto exit_unlock;
+	}
+
+	priv->echo_skb = devm_kzalloc(&dev->dev,
+				      dma->tx.size * sizeof(*priv->echo_skb),
+				      GFP_KERNEL);
+	if (!priv->echo_skb) {
+		err = -ENOMEM;
+		goto exit_free_dma_buffers;
+	}
+	priv->can.echo_skb_max = dma->tx.size;
+	priv->can.echo_skb = priv->echo_skb;
+
+	priv->txdlc = devm_kzalloc(&dev->dev,
+				   dma->tx.size * sizeof(*priv->txdlc),
+				   GFP_KERNEL);
+	if (!priv->txdlc) {
+		err = -ENOMEM;
+		goto exit_free_echo_skb;
+	}
+
+	/* Get can device up */
+	err = open_candev(dev);
+	if (err)
+		goto exit_free_txdlc;
+
+	err = devm_request_irq(&dev->dev, dev->irq, grcan_interrupt,
+			       IRQF_SHARED, dev->name, (void *)dev);
+	if (err)
+		goto exit_close_candev;
+
+	grcan_start(dev);
+	napi_enable(&priv->napi);
+	netif_start_queue(dev);
+
+	priv->resetting = false;
+	priv->closing = false;
+
+	SPIN_UNLOCK_IRQRESTORE(&priv->lock, flags);
+	return 0;
+
+exit_close_candev:
+	close_candev(dev);
+exit_free_txdlc:
+	devm_kfree(&dev->dev, priv->txdlc);
+exit_free_echo_skb:
+	devm_kfree(&dev->dev, priv->echo_skb);
+exit_free_dma_buffers:
+	grcan_free_dma_buffers(dev);
+exit_unlock:
+	SPIN_UNLOCK_IRQRESTORE(&priv->lock, flags);
+	return err;
+}
+
+static int grcan_close(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+
+	napi_disable(&priv->napi);
+
+	SPIN_LOCK_IRQSAVE(&priv->lock, flags);
+
+	priv->closing = true;
+	if (priv->need_txbug_workaround) {
+		del_timer_sync(&priv->hang_timer);
+		del_timer_sync(&priv->rr_timer);
+	}
+	netif_stop_queue(dev);
+	grcan_stop(dev);
+
+	SPIN_UNLOCK_IRQRESTORE(&priv->lock, flags);
+
+	devm_free_irq(&dev->dev, dev->irq, (void *)dev);
+	close_candev(dev);
+
+	grcan_free_dma_buffers(dev);
+	priv->can.echo_skb_max = 0;
+	priv->can.echo_skb = NULL;
+	devm_kfree(&dev->dev, priv->echo_skb);
+	devm_kfree(&dev->dev, priv->txdlc);
+
+	return 0;
+}
+
+static int grcan_transmit_catch_up(struct net_device *dev, int budget)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+	int work_done;
+
+	SPIN_LOCK_IRQSAVE(&priv->lock, flags);
+
+	work_done = catch_up_echo_skb(dev, budget, true);
+	if (work_done) {
+		if (!priv->resetting && !priv->closing
+		    && netif_queue_stopped(dev))
+			netif_wake_queue(dev);
+
+		/* With napi we don't get TX interrupts for a while,
+		 * so prevent a running reset while catching up
+		 */
+		if (priv->need_txbug_workaround
+		    && timer_pending(&priv->hang_timer))
+			del_timer(&priv->hang_timer);
+	}
+
+	SPIN_UNLOCK_IRQRESTORE(&priv->lock, flags);
+
+	return work_done;
+}
+
+static int grcan_receive(struct net_device *dev, int budget)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	struct net_device_stats *stats = &dev->stats;
+	struct can_frame *cf;
+	struct sk_buff *skb;
+	u32 wr, rd, startrd;
+	u32 *slot;
+	u32 i, rtr, eff, j, shift;
+	int work_done = 0;
+
+	rd = grcan_read_reg(&regs->rxrd);
+	startrd = rd;
+	for (work_done = 0; work_done < budget; work_done++) {
+		/* Check for packet to receive */
+		wr = grcan_read_reg(&regs->rxwr);
+		if (rd == wr)
+			break;
+
+		/* Take care of packet */
+		skb = alloc_can_skb(dev, &cf);
+		if (skb == NULL) {
+			netdev_dbg(dev,
+				   "dropping frame: skb allocation failed\n");
+			stats->rx_dropped++;
+			continue;
+		}
+
+		slot = dma->rx.buf + rd;
+		eff = slot[0] & GRCAN_MSG_IDE;
+		rtr = slot[0] & GRCAN_MSG_RTR;
+		if (eff) {
+			cf->can_id = ((slot[0] & GRCAN_MSG_EID)
+				      >> GRCAN_MSG_EID_BIT);
+			cf->can_id |= CAN_EFF_FLAG;
+		} else {
+			cf->can_id = ((slot[0] & GRCAN_MSG_BID)
+				      >> GRCAN_MSG_BID_BIT);
+		}
+		cf->can_dlc = get_can_dlc((slot[1] & GRCAN_MSG_DLC)
+					  >> GRCAN_MSG_DLC_BIT);
+		if (rtr) {
+			cf->can_id |= CAN_RTR_FLAG;
+		} else {
+			for (i = 0; i < cf->can_dlc; i++) {
+				j = GRCAN_MSG_DATA_SLOT_INDEX(i);
+				shift = GRCAN_MSG_DATA_SHIFT(i);
+				cf->data[i] = (u8)((slot[j] >> shift) & 0xff);
+			}
+		}
+		netif_receive_skb(skb);
+
+		/* Update statistics and read pointer */
+		stats->rx_packets++;
+		stats->rx_bytes += cf->can_dlc;
+		rd = grcan_ring_add(rd, GRCAN_MSG_SIZE, dma->rx.size);
+	}
+
+	/* Make sure everything is read before allowing hardware to
+	 * use the memory
+	 */
+	mb();
+
+	/* Update read pointer - no need to check for ongoing */
+	if (likely(rd != startrd))
+		grcan_write_reg(&regs->rxrd, rd);
+
+	return work_done;
+}
+
+static int grcan_poll(struct napi_struct *napi, int budget)
+{
+	struct grcan_priv *priv = container_of(napi, struct grcan_priv, napi);
+	struct net_device *dev = priv->dev;
+	struct grcan_registers __iomem *regs = priv->regs;
+	int rx_work_done = grcan_receive(dev, budget);
+	int tx_work_done = grcan_transmit_catch_up(dev, budget);
+	if (rx_work_done < budget && tx_work_done < budget) {
+		napi_complete(napi);
+		/* Enable tx and rx interrupts again */
+		if (!priv->closing)
+			grcan_set_bits(&regs->imr, GRCAN_IRQ_TX | GRCAN_IRQ_RX);
+	}
+	return rx_work_done;
+}
+
+/* Work tx bug by waiting while for the risky situation to clear. If that fails,
+ * drop a frame in one-shot mode or indicate a busy device otherwise.
+ *
+ * Returns 0 on successful wait. Otherwise it sets *netdev_tx_status to the
+ * value that should be returned by grcan_start_xmit when aborting the xmit.
+ */
+static int grcan_txbug_workaround(struct net_device *dev, struct sk_buff *skb,
+				  u32 txwr, u32 oneshotmode,
+				  netdev_tx_t *netdev_tx_status)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	int i;
+	unsigned long flags;
+
+	/* Wait a while for ongoing to be cleared or read pointer to catch up to
+	 * write pointer. The latter is needed due to a bug in older versions of
+	 * GRCAN in which ONGOING is not cleared properly one-shot mode when a
+	 * transmission fails.
+	 */
+	for (i = 0; i < GRCAN_SHORTWAIT_USECS; i++) {
+		udelay(1);
+		if (!grcan_read_bits(&regs->txctrl, GRCAN_TXCTRL_ONGOING)
+		    || grcan_read_reg(&regs->txrd) == txwr) {
+			return 0;
+		}
+	}
+
+	/* Clean up, in case the situation was not resolved */
+	SPIN_LOCK_IRQSAVE(&priv->lock, flags);
+	if (!priv->resetting && !priv->closing) {
+		/* Queue might have been stopped earlier in grcan_start_xmit */
+		if (grcan_txspace(dma->tx.size, txwr, priv->eskbp))
+			if (netif_queue_stopped(dev))
+				netif_wake_queue(dev);
+		/* Set a timer to resolve a hanged tx controller */
+		if (!timer_pending(&priv->hang_timer))
+			grcan_reset_timer(&priv->hang_timer,
+					  priv->can.bittiming.bitrate);
+	}
+	SPIN_UNLOCK_IRQRESTORE(&priv->lock, flags);
+
+	if (oneshotmode) {
+		/* In one-shot mode we should never end up here because
+		 * then the interrupt handler increases txrd on TXLOSS,
+		 * but it is consistent with one-shot mode to drop the
+		 * frame in this case.
+		 */
+		kfree_skb(skb);
+		*netdev_tx_status = NETDEV_TX_OK;
+	} else {
+		/* In normal mode the socket-can transmission queue get
+		 * to keep the frame so that it can be retransmitted
+		 * later
+		 */
+		*netdev_tx_status = NETDEV_TX_BUSY;
+	}
+	return -EBUSY;
+}
+
+/* Notes on the tx cyclic buffer handling:
+ *
+ * REG_TXWR	- the next slot for the driver to put data to be sent
+ * REG_TXRD	- the next slot for the device to read data
+ * priv->eskbp	- the next slot for the driver to call can_put_echo_skb for
+ *
+ * grcan_start_xmit can enter more messages as long as REG_TXWR does
+ * not reach priv->eskbp (within 1 message gap)
+ *
+ * The device sends messages until REG_TXRD reaches REG_TXWR
+ *
+ * The interrupt calls handler calls can_put_echo_skb until
+ * priv->eskbp reaces REG_TXRD
+ */
+static netdev_tx_t grcan_start_xmit(struct sk_buff *skb,
+				    struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	struct can_frame *cf = (struct can_frame *)skb->data;
+	u32 id, txwr, txrd, space, txctrl;
+	int slotindex;
+	u32 *slot;
+	u32 i, rtr, eff, dlc, tmp, err;
+	int j, shift;
+	unsigned long flags;
+	u32 oneshotmode = priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT;
+
+	if (can_dropped_invalid_skb(dev, skb))
+		return NETDEV_TX_OK;
+
+	/* Trying to transmit in silent mode will generate error interrupts */
+	if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
+		return NETDEV_TX_BUSY;
+
+	/* Reads of priv->eskbp and shut-downs of the queue needs to
+	 * be atomic towards the updates to priv->eskbp and wake-ups
+	 * of the queue in the interrupt handler.
+	 */
+	SPIN_LOCK_IRQSAVE(&priv->lock, flags);
+
+	txwr = grcan_read_reg(&regs->txwr);
+	space = grcan_txspace(dma->tx.size, txwr, priv->eskbp);
+
+	slotindex = txwr / GRCAN_MSG_SIZE;
+	slot = dma->tx.buf + txwr;
+
+	if (unlikely(space == 1))
+		netif_stop_queue(dev);
+
+	SPIN_UNLOCK_IRQRESTORE(&priv->lock, flags);
+	/* End of critical section*/
+
+	/* This should never happen. If circular buffer is full, the
+	 * netif_stop_queue should have been stopped already.
+	 */
+	if (unlikely(!space)) {
+		netdev_err(dev, "No buffer space, but queue is non-stopped.\n");
+		return NETDEV_TX_BUSY;
+	}
+
+	/* Convert and write CAN message to DMA buffer */
+	eff = cf->can_id & CAN_EFF_FLAG;
+	rtr = cf->can_id & CAN_RTR_FLAG;
+	id  = cf->can_id & (eff ? CAN_EFF_MASK : CAN_SFF_MASK);
+	dlc = cf->can_dlc;
+	if (eff)
+		tmp = (id << GRCAN_MSG_EID_BIT) & GRCAN_MSG_EID;
+	else
+		tmp = (id << GRCAN_MSG_BID_BIT) & GRCAN_MSG_BID;
+	slot[0] = (eff ? GRCAN_MSG_IDE : 0) | (rtr ? GRCAN_MSG_RTR : 0) | tmp;
+
+	slot[1] = ((dlc << GRCAN_MSG_DLC_BIT) & GRCAN_MSG_DLC);
+	slot[2] = 0;
+	slot[3] = 0;
+	for (i = 0; i < dlc; i++) {
+		j = GRCAN_MSG_DATA_SLOT_INDEX(i);
+		shift = GRCAN_MSG_DATA_SHIFT(i);
+		slot[j] |= cf->data[i] << shift;
+	}
+
+	/* Checking that channel has not been disabled. These cases
+	 * should never happen
+	 */
+	txctrl = grcan_read_reg(&regs->txctrl);
+	if (!(txctrl & GRCAN_TXCTRL_ENABLE))
+		netdev_err(dev, "tx channel spuriously disabled\n");
+
+	if (oneshotmode && !(txctrl & GRCAN_TXCTRL_SINGLE))
+		netdev_err(dev, "one-shot mode spuriously disabled\n");
+
+	/* Bug workaround for old version of grcan where updating txwr
+	 * in the same clock cycle as the controller updates txrd to
+	 * the current txwr could hang the can controller
+	 */
+	if (priv->need_txbug_workaround) {
+		txrd = grcan_read_reg(&regs->txrd) ;
+		if (unlikely(grcan_ring_sub(txwr, txrd, dma->tx.size) == 1)) {
+			netdev_tx_t txstatus;
+			err = grcan_txbug_workaround(dev, skb, txwr,
+						     oneshotmode, &txstatus);
+			if (err)
+				return txstatus;
+		}
+	}
+
+	/* Prepare skb for echoing. This must be after the bug workaround above
+	 * as ownership of the skb is passed on by calling can_put_echo_skb.
+	 * Returning NETDEV_TX_BUSY or accessing skb or cf after a call to
+	 * can_put_echo_skb would be an error unless other measures are
+	 * taken.
+	 */
+	priv->txdlc[slotindex] = cf->can_dlc; /* Store dlc for statistics */
+	can_put_echo_skb(skb, dev, slotindex);
+
+	/* Make sure everything is written before allowing hardware to
+	 * read from the memory
+	 */
+	wmb();
+
+	/* Update write pointer to start transmission */
+	grcan_write_reg(&regs->txwr,
+			grcan_ring_add(txwr, GRCAN_MSG_SIZE, dma->tx.size));
+
+	return NETDEV_TX_OK;
+}
+
+
+/* ========== Setting up sysfs interface and module parameters  ========== */
+
+#define GRCAN_DECF "%d"
+#define GRCAN_HEXF "0x%08x"
+
+#define GRCAN_RANGECHECK(val, minval, maxval)	\
+	((val) < (minval) || (val) > (maxval))
+
+#define GRCAN_NOPOSTSETF(dev)
+#define GRCAN_NOMANIP(x) (x)
+
+#define GRCAN_WRITE_ATTR(name, type, lval, manip,			\
+			 minval, maxval, valcheckf, postsetf)		\
+	static ssize_t grcan_store_##name(struct device *sdev,		\
+					  struct device_attribute *att,	\
+					  const char *buf,		\
+					  size_t count)			\
+	{								\
+		struct net_device *dev = to_net_dev(sdev);		\
+		struct grcan_priv *priv = netdev_priv(dev);		\
+		type val;						\
+		int ret;						\
+		if (dev->flags & IFF_UP)				\
+			return -EBUSY;					\
+		ret = kstrto##type(buf, 0, &val);			\
+		if (ret < 0 || valcheckf(val, (minval), (maxval)))	\
+			return -EINVAL;					\
+		lval = manip(val);					\
+		postsetf(dev);						\
+		return count;						\
+	}
+
+#define GRCAN_RESET_ATTR(name, lval, val)				\
+	static ssize_t grcan_reset_##name(struct device *sdev,		\
+					  struct device_attribute *att,	\
+					  const char *buf,		\
+					  size_t count)			\
+	{								\
+		struct net_device *dev = to_net_dev(sdev);		\
+		struct grcan_priv *priv = netdev_priv(dev);		\
+		lval = val;						\
+		return count;						\
+	}
+
+#define GRCAN_READ_ATTR(name, rval, format)				\
+	static ssize_t grcan_show_##name(struct device *sdev,		\
+					 struct device_attribute *att,	\
+					 char *buf)			\
+	{								\
+		struct net_device *dev = to_net_dev(sdev);		\
+		struct grcan_priv *priv = netdev_priv(dev);		\
+		return sprintf(buf, format "\n", rval);			\
+	}
+
+#define GRCAN_CONFIG_ATTR(name, type, mtype, format,			\
+			  minval, maxval, valcheckf, postsetf)		\
+	GRCAN_READ_ATTR(name, priv->config.name, format)		\
+	GRCAN_WRITE_ATTR(name, type, priv->config.name, GRCAN_NOMANIP,	\
+			 minval, maxval, valcheckf, postsetf)		\
+	static DEVICE_ATTR(name, S_IRUGO | S_IWUSR,			\
+			   grcan_show_##name,				\
+			   grcan_store_##name);				\
+	static void grcan_sanitize_##name(struct platform_device *pd)	\
+	{								\
+		struct grcan_device_config grcan_default_config		\
+			= GRCAN_DEFAULT_DEVICE_CONFIG;			\
+		type val = grcan_module_config.name;			\
+		if (valcheckf(val, (minval), (maxval)))	{		\
+			dev_err(&pd->dev,				\
+				"Invalid module parameter value for "	\
+				#name " - setting default\n");		\
+			grcan_module_config.name =			\
+				grcan_default_config.name;		\
+		}							\
+	}								\
+	module_param_named(name, grcan_module_config.name,		\
+			   mtype, S_IRUGO)
+
+/* The following configuration options are made available both via modle
+ * parameters and writable sysfs files. See the chapter about GRCAN in the
+ * documentation for the GRLIB VHDL library for further details.
+ */
+
+/* Configure enable0 - Configuration for interface 0 */
+GRCAN_CONFIG_ATTR(enable0,   u8, ushort, GRCAN_DECF, 0, 1,	\
+		  GRCAN_RANGECHECK, GRCAN_NOPOSTSETF);
+
+/* Configure enable1 - Configuration for interface 0  */
+GRCAN_CONFIG_ATTR(enable1,   u8, ushort, GRCAN_DECF, 0, 1,	\
+		  GRCAN_RANGECHECK, GRCAN_NOPOSTSETF);
+
+/* Configure selection - Selection on which interface to use */
+GRCAN_CONFIG_ATTR(selection, u8, ushort, GRCAN_DECF, 0, 1,	\
+		  GRCAN_RANGECHECK, GRCAN_NOPOSTSETF);
+
+/* Configure bpr - A prescaler separate from SCALER (which corresponds to brp
+ * (note the spelling difference))
+*/
+static void grcan_postset_bpr(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	priv->can.clock.freq = priv->ambafreq >> priv->config.bpr;
+	netdev_info(dev, "bpr will be set to %d when bitrate is set\n",
+		    priv->config.bpr);
+}
+GRCAN_CONFIG_ATTR(bpr, u8, ushort, GRCAN_DECF, 0, 3,	\
+		  GRCAN_RANGECHECK, grcan_postset_bpr);
+
+static int dma_buf_check(u32 val, u32 minval, u32 maxval)
+{
+	return GRCAN_INVALID_BUFFER_SIZE(val);
+}
+
+/* Configure size of tx buffer */
+GRCAN_CONFIG_ATTR(txsize, u32, uint, GRCAN_DECF, 0, 0,	\
+		  dma_buf_check, GRCAN_NOPOSTSETF);
+
+/* Configure size of rx buffer */
+GRCAN_CONFIG_ATTR(rxsize, u32, uint, GRCAN_DECF, 0, 0,	\
+		  dma_buf_check, GRCAN_NOPOSTSETF);
+
+/* Configure rxcode and rxmask that provides hardware filtering on device level
+ * (configurable only by root)
+ */
+GRCAN_CONFIG_ATTR(rxcode, u32, uint, GRCAN_HEXF, 0, GRCAN_MSG_EID,	\
+		  GRCAN_RANGECHECK, GRCAN_NOPOSTSETF);
+GRCAN_CONFIG_ATTR(rxmask, u32, uint, GRCAN_HEXF, 0, GRCAN_MSG_EID,	\
+		  GRCAN_RANGECHECK, GRCAN_NOPOSTSETF);
+
+
+#define GRCAN_BASIC_ID_SHIFT(x) (((x) << GRCAN_MSG_BID_BIT) & GRCAN_MSG_BID)
+
+#define GRCAN_BASIC_ID_ATTR(name, lval)					\
+	GRCAN_WRITE_ATTR(name, u32, lval, GRCAN_BASIC_ID_SHIFT,		\
+			 0, GRCAN_MSG_BID >> GRCAN_MSG_BID_BIT,		\
+			 GRCAN_RANGECHECK, GRCAN_NOPOSTSETF)		\
+	static DEVICE_ATTR(name, S_IWUSR,				\
+			   NULL, grcan_store_##name)
+
+/* Convenience parameters for setting up hardware filtering of basic ID
+ * frames
+ */
+GRCAN_BASIC_ID_ATTR(rxcode_basic, priv->config.rxcode);
+GRCAN_BASIC_ID_ATTR(rxmask_basic, priv->config.rxmask);
+
+/* Function that makes sure that configuration done using
+ * module parameters are set to valid values
+ */
+static void grcan_sanitize_module_config(struct platform_device *ofdev)
+{
+	grcan_sanitize_enable0(ofdev);
+	grcan_sanitize_enable1(ofdev);
+	grcan_sanitize_selection(ofdev);
+	grcan_sanitize_bpr(ofdev);
+	grcan_sanitize_txsize(ofdev);
+	grcan_sanitize_rxsize(ofdev);
+	grcan_sanitize_rxcode(ofdev);
+	grcan_sanitize_rxmask(ofdev);
+}
+
+/* These following sysfs entires provides additional statistics specific to
+ * GRCAN/GRHCAN
+ */
+
+#define GRCAN_GSTATS_ATTR(name)						\
+	GRCAN_READ_ATTR(name, priv->gstats.name, GRCAN_DECF)		\
+	GRCAN_RESET_ATTR(name, priv->gstats.name, 0)			\
+	static DEVICE_ATTR(stat_##name, S_IRUGO | S_IWUSR,		\
+			   grcan_show_##name, grcan_reset_##name)
+
+GRCAN_GSTATS_ATTR(ahberr_tx);	/* AMBA AHB errors on tx */
+GRCAN_GSTATS_ATTR(ahberr_rx);	/* AMBA AHB errors on rx */
+GRCAN_GSTATS_ATTR(hwfiltered);	/* Number of hardware filtered frames */
+
+static const struct attribute *const sysfs_grcan_attrs[] = {
+	/* Config attrs */
+	&dev_attr_enable0.attr,
+	&dev_attr_enable1.attr,
+	&dev_attr_selection.attr,
+	&dev_attr_bpr.attr,
+	&dev_attr_txsize.attr,
+	&dev_attr_rxsize.attr,
+	&dev_attr_rxcode.attr,
+	&dev_attr_rxmask.attr,
+	&dev_attr_rxcode_basic.attr,
+	&dev_attr_rxmask_basic.attr,
+	/* Statistics attrs */
+	&dev_attr_stat_ahberr_tx.attr,
+	&dev_attr_stat_ahberr_rx.attr,
+	&dev_attr_stat_hwfiltered.attr,
+	NULL,
+};
+
+static const struct attribute_group sysfs_grcan_group = {
+	.name = "grcan",
+	.attrs = (struct attribute **)sysfs_grcan_attrs,
+};
+
+
+/* ========== Setting up the driver ========== */
+
+static const struct net_device_ops grcan_netdev_ops = {
+	.ndo_open               = grcan_open,
+	.ndo_stop               = grcan_close,
+	.ndo_start_xmit         = grcan_start_xmit,
+};
+
+static int grcan_setup_netdev(struct platform_device *ofdev,
+			      void __iomem *base,
+			      int irq, u32 ambafreq, bool txbug)
+{
+	struct net_device *dev;
+	struct grcan_priv *priv;
+	struct grcan_registers __iomem *regs;
+	int err;
+
+	dev = alloc_candev(sizeof(struct grcan_priv), 0);
+	if (!dev)
+		return -ENOMEM;
+
+	dev->irq = irq;
+	dev->flags |= IFF_ECHO;
+	dev->netdev_ops = &grcan_netdev_ops;
+	dev->sysfs_groups[0] = &sysfs_grcan_group;
+
+	priv = netdev_priv(dev);
+	memcpy(&priv->config, &grcan_module_config,
+	       sizeof(struct grcan_device_config));
+	priv->dev = dev;
+	priv->regs = (struct grcan_registers *) base;
+	priv->can.bittiming_const     = &grcan_bittiming_const;
+	priv->can.do_set_bittiming    = grcan_set_bittiming;
+	priv->can.do_set_mode         = grcan_set_mode;
+	priv->can.do_get_berr_counter = grcan_get_berr_counter;
+	priv->ambafreq                = ambafreq;
+	priv->can.clock.freq          = ambafreq >> priv->config.bpr;
+	priv->can.ctrlmode_supported  =
+		CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_ONE_SHOT;
+	priv->gstats.ahberr_tx = 0;
+	priv->gstats.ahberr_rx = 0;
+	priv->gstats.hwfiltered = 0;
+	priv->need_txbug_workaround = txbug;
+
+	spin_lock_init(&priv->lock);
+
+	if (priv->need_txbug_workaround) {
+		init_timer(&priv->rr_timer);
+		priv->rr_timer.function = grcan_running_reset;
+		priv->rr_timer.data = (unsigned long)dev;
+
+		init_timer(&priv->hang_timer);
+		priv->hang_timer.function = grcan_initiate_running_reset;
+		priv->hang_timer.data = (unsigned long)dev;
+	}
+
+	netif_napi_add(dev, &priv->napi, grcan_poll, GRCAN_NAPI_WEIGHT);
+
+	SET_NETDEV_DEV(dev, &ofdev->dev);
+	regs = priv->regs;
+	dev_info(&ofdev->dev,
+		 "regs=0x%p, irq=%d, clock=%d\n",
+		 priv->regs, dev->irq, priv->can.clock.freq);
+
+	err = register_candev(dev);
+	if (err) {
+		dev_err(&ofdev->dev, "registering %s failed (err=%d)\n",
+			DRV_NAME, err);
+		goto exit_free_candev;
+	}
+	dev_set_drvdata(&ofdev->dev, dev);
+
+	/* Reset device to allow bit-timing to be set. No need to call
+	 * grcan_reset at this stage. That is done in grcan_open.
+	 */
+	grcan_write_reg(&regs->ctrl, GRCAN_CTRL_RESET);
+
+	return 0;
+exit_free_candev:
+	free_candev(dev);
+	return err;
+}
+
+static int __devinit grcan_probe(struct platform_device *ofdev)
+{
+	struct device_node *np = ofdev->dev.of_node;
+	struct resource *res;
+	u32 sysid, ambafreq;
+	int irq, err;
+	void __iomem *base;
+	bool txbug = true;
+
+	/* Compare GRLIB version number with the first that does not
+	 * have the tx bug (see start_xmit)
+	 */
+	err = of_property_read_u32(np, "systemid", &sysid);
+	if (!err && ((sysid & GRLIB_VERSION_MASK)
+		     >= GRCAN_TXBUG_SAFE_GRLIB_VERSION))
+		txbug = false;
+
+	err = of_property_read_u32(np, "freq", &ambafreq);
+	if (err) {
+		dev_err(&ofdev->dev, "unable to fetch \"freq\" property\n");
+		goto exit_error;
+	}
+
+	res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
+	base = devm_request_and_ioremap(&ofdev->dev, res);
+	if (!base) {
+		dev_err(&ofdev->dev, "couldn't map IO resource\n");
+		err = -EADDRNOTAVAIL;
+		goto exit_error;
+	}
+
+	irq = irq_of_parse_and_map(np, GRCAN_IRQIX_IRQ);
+	if (irq == NO_IRQ) {
+		dev_err(&ofdev->dev, "no irq found\n");
+		err = -ENODEV;
+		goto exit_error;
+	}
+
+	grcan_sanitize_module_config(ofdev);
+
+	err = grcan_setup_netdev(ofdev, base, irq, ambafreq, txbug);
+	if (err)
+		goto exit_dispose_irq;
+
+	return 0;
+
+exit_dispose_irq:
+	irq_dispose_mapping(irq);
+exit_error:
+	dev_err(&ofdev->dev,
+		"%s socket CAN driver initialization failed with error %d\n",
+		DRV_NAME, err);
+	return err;
+}
+
+static  int __devexit grcan_remove(struct platform_device *ofdev)
+{
+	struct net_device *dev = dev_get_drvdata(&ofdev->dev);
+	struct grcan_priv *priv = netdev_priv(dev);
+
+	unregister_candev(dev); /* Will in turn call grcan_close */
+
+	irq_dispose_mapping(dev->irq);
+	dev_set_drvdata(&ofdev->dev, NULL);
+	netif_napi_del(&priv->napi);
+	free_candev(dev);
+
+	dev_info(&ofdev->dev, "%s socket CAN driver removed\n", DRV_NAME);
+	return 0;
+}
+
+static struct of_device_id grcan_match[] = {
+	{.name = "GAISLER_GRCAN"},
+	{.name = "01_03d"},
+	{.name = "GAISLER_GRHCAN"},
+	{.name = "01_034"},
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, grcan_match);
+
+static struct platform_driver grcan_driver = {
+	.driver = {
+		.name = DRV_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = grcan_match,
+	},
+	.probe = grcan_probe,
+	.remove = __devexit_p(grcan_remove),
+};
+
+module_platform_driver(grcan_driver);
+
+MODULE_AUTHOR("Aeroflex Gaisler AB.");
+MODULE_DESCRIPTION("Socket CAN driver for Aeroflex Gaisler GRCAN");
+MODULE_LICENSE("GPL");
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* Re: [PATCH v2] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-10-23  9:57     ` [PATCH v2] " Andreas Larsson
@ 2012-10-23 16:26       ` Wolfgang Grandegger
  2012-10-24 13:31         ` Andreas Larsson
  0 siblings, 1 reply; 41+ messages in thread
From: Wolfgang Grandegger @ 2012-10-23 16:26 UTC (permalink / raw)
  To: Andreas Larsson; +Cc: linux-can, mkl, devicetree-discuss, software

Hi,

before I have a closer look I have some general questions, especially
about the heavy usage of SysFS for configuring the IP core module.
Generally, we are not allowed to use SysFS for CAN device configuration.

- Why may the user want to configure the resources on a per device base?

- Aren't there good default values which work just fine for 99% of the
  users?

- Why could the resources not be configured via device tree (or platform
  code)?

- Are there other IP cores already supported by mainline Linux, e.g.
  uart. How are they configured?

On 10/23/2012 11:57 AM, Andreas Larsson wrote:
> This driver supports GRCAN and CRHCAN CAN controllers available in the GRLIB
> VHDL IP core library.
> 
> Signed-off-by: Andreas Larsson <andreas@gaisler.com>
> ---
>  Documentation/ABI/testing/sysfs-class-net-grcan    |  136 ++
>  .../devicetree/bindings/net/can/grcan.txt          |   27 +
>  Documentation/kernel-parameters.txt                |   88 +-
>  drivers/net/can/Kconfig                            |    9 +
>  drivers/net/can/Makefile                           |    1 +
>  drivers/net/can/grcan.c                            | 1735 ++++++++++++++++++++
>  6 files changed, 1952 insertions(+), 44 deletions(-)
>  create mode 100644 Documentation/ABI/testing/sysfs-class-net-grcan
>  create mode 100644 Documentation/devicetree/bindings/net/can/grcan.txt
>  create mode 100644 drivers/net/can/grcan.c
> 
> diff --git a/Documentation/ABI/testing/sysfs-class-net-grcan b/Documentation/ABI/testing/sysfs-class-net-grcan
> new file mode 100644
> index 0000000..c6eed07
> --- /dev/null
> +++ b/Documentation/ABI/testing/sysfs-class-net-grcan
> @@ -0,0 +1,136 @@
> +
> +What:		/sys/class/net/<iface>/grcan/enable0
> +Date:		October 2012
> +KernelVersion:	3.8
> +Contact:	Andreas Larsson <andreas@gaisler.com>
> +Description:
> +		Hardware configuration of physical interface 0. This file reads
> +		and writes the "Enable 0" bit of the configuration register.
> +		Possible values: 0 or 1. See the GRCAN chapter of the GRLIB IP
> +		core library documentation for details.
> +		The default value is set by the module parameter enable0 and can
> +		be read at /sys/module/grcan/parameters/enable0.
> +
> +What:		/sys/class/net/<iface>/grcan/enable1
> +Date:		October 2012
> +KernelVersion:	3.8
> +Contact:	Andreas Larsson <andreas@gaisler.com>
> +Description:
> +		Hardware configuration of physical interface 1. This file reads
> +		and writes the "Enable 1" bit of the configuration register.
> +		Possible values: 0 or 1. See the GRCAN chapter of the GRLIB IP
> +		core library documentation for details.
> +		The default value is set by the module parameter enable1 and can
> +		be read at /sys/module/grcan/parameters/enable1.
> +
> +What:		/sys/class/net/<iface>/grcan/selection
> +Date:		October 2012
> +KernelVersion:	3.8
> +Contact:	Andreas Larsson <andreas@gaisler.com>
> +Description:
> +		Configuration of which physical interface to be used. Possible
> +		values: 0 or 1. See the GRCAN chapter of the GRLIB IP core
> +		library documentation for details.
> +		The default value is set by the module parameter selection and can
> +		be read at /sys/module/grcan/parameters/selection.
> +
> +What:		/sys/class/net/<iface>/grcan/bpr
> +Date:		October 2012
> +KernelVersion:	3.8
> +Contact:	Andreas Larsson <andreas@gaisler.com>
> +Description:
> +		Configuration of the bpr baud rate scaler (not to be confused
> +		with the "brp" concept which in grcan is called scaler). From
> +		the socket can layer's point of view, divides the external clock
> +		frequency by 1 << value. Possible values in [0, 3].
> +		The default value is set by the module parameter bpr and can
> +		be read at /sys/module/grcan/parameters/bpr.
> +
> +What:		/sys/class/net/<iface>/grcan/txsize
> +Date:		October 2012
> +KernelVersion:	3.8
> +Contact:	Andreas Larsson <andreas@gaisler.com>
> +Description:
> +		Configures the size of the tx buffer. Possible values: (value &
> +		0x1fffc0) == 0.
> +		The default value is set by the module parameter txsize and can
> +		be read at /sys/module/grcan/parameters/txsize.
> +
> +
> +What:		/sys/class/net/<iface>/grcan/rxsize
> +Date:		October 2012
> +KernelVersion:	3.8
> +Contact:	Andreas Larsson <andreas@gaisler.com>
> +Description:
> +		Configures the size of the rx buffer. Possible values: (value &
> +		0x1fffc0) == 0.
> +		The default value is set by the module parameter rxsize and can
> +		be read at /sys/module/grcan/parameters/rxsize.
> +
> +
> +What:		/sys/class/net/<iface>/grcan/rxcode
> +Date:		October 2012
> +KernelVersion:	3.8
> +Contact:	Andreas Larsson <andreas@gaisler.com>
> +Description:
> +		Configures the rxcode of the hardware filter. Received messages
> +		for which ((message_id ^ rxcode) & rxmask) != 0 holds will be
> +		filtered out in harware. Possible values in [0, 0x1fffffff].
> +		The default value is set by the module parameter rxcode and can
> +		be read at /sys/module/grcan/parameters/rxcode.
> +
> +What:		/sys/class/net/<iface>/grcan/rxmask
> +Date:		October 2012
> +KernelVersion:	3.8
> +Contact:	Andreas Larsson <andreas@gaisler.com>
> +Description:
> +		Configures the rxmask of the hardware filter. Received messages
> +		for which ((message_id ^ rxcode) & rxmask) != 0 holds will be
> +		filtered out in harware. Possible values in [0, 0x1fffffff].
> +		The default value is set by the module parameter rxmask and can
> +		be read at /sys/module/grcan/parameters/rxmask.

Hardware filters should definitely not be defined via SysFS. We do not
have an interface yet, mainly because it does not fit into a multi user
concept. Anyway, we need such an interface *sooner* than later. Needs
some further thoughts.

> +
> +What:		/sys/class/net/<iface>/grcan/rxcode_basic
> +Date:		October 2012
> +KernelVersion:	3.8
> +Contact:	Andreas Larsson <andreas@gaisler.com>
> +Description:
> +		Configures the rxcode of the hardware filter to match a basic
> +		id. Writable only. Result can be read in rxcode. Possible values
> +		in [0, 0x7ff].
> +
> +What:		/sys/class/net/<iface>/grcan/rxmask_basic
> +Date:		October 2012
> +KernelVersion:	3.8
> +Contact:	Andreas Larsson <andreas@gaisler.com>
> +Description:
> +		Configures the rxmask of the hardware filter to match a basic
> +		id. Writable only. Result can be read in rxcode. Possible values
> +		in [0, 0x7ff].
> +
> +What:		/sys/class/net/<iface>/grcan/stat_ahberr_tx
> +Date:		October 2012
> +KernelVersion:	3.8
> +Contact:	Andreas Larsson <andreas@gaisler.com>
> +Description:
> +		Statistics on number of AHB errors that has happened during tx
> +		(note that the device halts on AHB errors). Write anything to
> +		reset to 0.
> +
> +What:		/sys/class/net/<iface>/grcan/stat_ahberr_rx
> +Date:		October 2012
> +KernelVersion:	3.8
> +Contact:	Andreas Larsson <andreas@gaisler.com>
> +Description:
> +		Statistics on number of AHB errors that has happened during rx
> +		(note that the device halts on AHB errors). Write anything to
> +		reset to 0.
> +
> +What:		/sys/class/net/<iface>/grcan/stat_hwfiltered
> +Date:		October 2012
> +KernelVersion:	3.8
> +Contact:	Andreas Larsson <andreas@gaisler.com>
> +Description:
> +		Statistics on number of hardware-filtered messages. Write anything to
> +		reset to 0.
> diff --git a/Documentation/devicetree/bindings/net/can/grcan.txt b/Documentation/devicetree/bindings/net/can/grcan.txt
> new file mode 100644
> index 0000000..a7180f1
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/can/grcan.txt
> @@ -0,0 +1,27 @@
> +CAN controller for Aeroflex Gaisler GRCAN and GRHCAN.
> +
> +The GRCAN and CRHCAN CAN controllers are available in the GRLIB VHDL IP core
> +library.
> +
> +Note: These properties are built from the AMBA plug&play in a Leon SPARC
> +system (the ordinary environment for GRCAN and GRHCAN). There are no bsp
> +files for sparc.
> +
> +Required properties:
> +
> +- name : Should be "GAISLER_GRCAN", "01_03d", "GAISLER_GRHCAN" or "01_034"

A name should be "vendor,device", e.g. gaisler,grcan. It's also unusual
to add release numbers. Also, you do not distinguish between the devices
above. Then, just use one name and the others are compatible to that one
(even if they are named differently). Well, I realized that the device
tree police is less strict than it was 1..2 years ago... anyway, please
have a look to the many examples around, also for CAN.

> +- reg : Address and length of the register set for the device
> +
> +- freq : Frequency of the external oscillator clock in Hz (the frequency of
> +	the amba bus in the ordinary case)

Ditto. "clock-frequency" is a common name for that purpose.

> +
> +- interrupts : Interrupt number for this device
> +
> +Optional properties:
> +
> +- systemid : If not present or if the value of the least significant 16 bits
> +	of this 32-bit property is smaller than GRCAN_TXBUG_SAFE_GRLIB_VERSION
> +	a bug workaround is activated.

Why can't this be handled via compatible string?

> +
> +For further information look in the documentation for the GLIB IP core library.
> diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
> index 9776f06..32c924f 100644
> --- a/Documentation/kernel-parameters.txt
> +++ b/Documentation/kernel-parameters.txt
> @@ -905,6 +905,46 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
>  	gpt		[EFI] Forces disk with valid GPT signature but
>  			invalid Protective MBR to be treated as GPT.
>  
> +	grcan.enable0=	[HW] The "Enable 0" bit of the configuration
> +			register. For more documentation, see
> +			Documentation/ABI/testing/sysfs-class-net-grcan
> +			Format: 0 | 1
> +			Default: 0
> +	grcan.enable1=	[HW] The "Enable 1" bit of the configuration
> +			register. For more documentation, see
> +			Documentation/ABI/testing/sysfs-class-net-grcan.
> +			Format: 0 | 1
> +			Default: 0
> +	grcan.selection=
> +			[HW] Selection of which physical interface to be
> +			used. For more documentation, see
> +			Documentation/ABI/testing/sysfs-class-net-grcan.
> +			Format: 0 | 1
> +			Default: 0
> +	grcan.bpr=	[HW] Configuration of the bpr baud rate scaler. For
> +			more documentation, see
> +			Documentation/ABI/testing/sysfs-class-net-grcan.
> +			Format: 0 | 1 | 2 | 3
> +			Default: 0
> +	grcan.txsize=	[HW] The size of the tx buffer. For more documentation,
> +			see Documentation/ABI/testing/sysfs-class-net-grcan.
> +			Format: <value> such that (value & 0x1fffc0) == 0.
> +			Default: 1024
> +	grcan.rxsize=	[HW] The size of the rx buffer. For more documentation,
> +			see Documentation/ABI/testing/sysfs-class-net-grcan.
> +			Format: <value> such that (value & 0x1fffc0) == 0.
> +			Default: 1024
> +	grcan.rxcode=	[HW] The rxcode of the hardware filter. For more
> +			documentation, see
> +			Documentation/ABI/testing/sysfs-class-net-grcan.
> +			Format: <value> in the range [0, 0x1fffffff]
> +			Default: 0
> +	grcan.rxmask=	[HW] The rxmask of the hardware filter. For more
> +			documentation, see
> +			Documentation/ABI/testing/sysfs-class-net-grcan.
> +			Format: <value> in the range [0, 0x1fffffff]
> +			Default: 0
> +
>  	hashdist=	[KNL,NUMA] Large hashes allocated during boot
>  			are distributed across NUMA nodes.  Defaults on
>  			for 64-bit NUMA, off otherwise.
> @@ -1051,14 +1091,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
>  	ihash_entries=	[KNL]
>  			Set number of hash buckets for inode cache.
>  
> -	ima_appraise=	[IMA] appraise integrity measurements
> -			Format: { "off" | "enforce" | "fix" }
> -			default: "enforce"
> -
> -	ima_appraise_tcb [IMA]
> -			The builtin appraise policy appraises all files
> -			owned by uid=0.
> -

Hm, is this related? There are more below.

I will have a closer look to the driver code later this week.

Thanks,

Wolfgang.


^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v2] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-10-23 16:26       ` Wolfgang Grandegger
@ 2012-10-24 13:31         ` Andreas Larsson
  2012-10-30  9:06           ` [PATCH v3] " Andreas Larsson
  2012-10-30  9:29           ` [PATCH v2] " Wolfgang Grandegger
  0 siblings, 2 replies; 41+ messages in thread
From: Andreas Larsson @ 2012-10-24 13:31 UTC (permalink / raw)
  To: Wolfgang Grandegger; +Cc: linux-can, mkl, devicetree-discuss, software

On 10/23/2012 06:26 PM, Wolfgang Grandegger wrote:
> Hi,
>
> before I have a closer look I have some general questions, especially
> about the heavy usage of SysFS for configuring the IP core module.
> Generally, we are not allowed to use SysFS for CAN device configuration.
>
> - Why may the user want to configure the resources on a per device base?

The GRCAN core supports selecting between two different hardware interfaces. The 
parameters output0, output1 and selection configures these interfaces and 
selects which one to use. This can not be done in general. For output0 and 
output1 what value means what depends on what hardware is connected to the core. 
If a board has many GRCAN cores they might need different settings for these 
variables. In addition, switching between the two hardware interfaces is 
something that might be wanted to be done at runtime.

For the others module level configuration would work fine.


> - Aren't there good default values which work just fine for 99% of the
>   users?

For output0, output1 and selection, the answer is no due to the reasons pointed 
out above. For the bpr and buffer sizes, that is probably true.


> - Why could the resources not be configured via device tree (or platform
>   code)?
> - Are there other IP cores already supported by mainline Linux, e.g.
>   uart. How are they configured?

See further down on Documentation/devicetree/bindings/net/can/grcan.txt for 
discussion on the device tree matter, or do you something else than configuring 
via bsp files and the like?


>> +What:		/sys/class/net/<iface>/grcan/rxcode
>> +Date:		October 2012
>> +KernelVersion:	3.8
>> +Contact:	Andreas Larsson<andreas@gaisler.com>
>> +Description:
>> +		Configures the rxcode of the hardware filter. Received messages
>> +		for which ((message_id ^ rxcode) & rxmask) != 0 holds will be
>> +		filtered out in harware. Possible values in [0, 0x1fffffff].
>> +		The default value is set by the module parameter rxcode and can
>> +		be read at /sys/module/grcan/parameters/rxcode.
>> +
>> +What:		/sys/class/net/<iface>/grcan/rxmask
>> +Date:		October 2012
>> +KernelVersion:	3.8
>> +Contact:	Andreas Larsson<andreas@gaisler.com>
>> +Description:
>> +		Configures the rxmask of the hardware filter. Received messages
>> +		for which ((message_id ^ rxcode) & rxmask) != 0 holds will be
>> +		filtered out in harware. Possible values in [0, 0x1fffffff].
>> +		The default value is set by the module parameter rxmask and can
>> +		be read at /sys/module/grcan/parameters/rxmask.
>
> Hardware filters should definitely not be defined via SysFS. We do not
> have an interface yet, mainly because it does not fit into a multi user
> concept. Anyway, we need such an interface *sooner* than later. Needs
> some further thoughts.

OK, I'll get rid of that then and wait for such an interface in the future. It 
would be a pity if hardware filtering, that is a feature that would probably be 
used on an embedded system without multiple users, could never be realized 
because of the socket interface being a multi user concept. If root is the only 
one that can set it up it should be fine in my opinion. Nevertheless, I totally 
agree that a well defined API to enable it would be much nicer than going 
through SysFS.


>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/net/can/grcan.txt
>> @@ -0,0 +1,27 @@
>> +CAN controller for Aeroflex Gaisler GRCAN and GRHCAN.
>> +
>> +The GRCAN and CRHCAN CAN controllers are available in the GRLIB VHDL IP core
>> +library.
>> +
>> +Note: These properties are built from the AMBA plug&play in a Leon SPARC
>> +system (the ordinary environment for GRCAN and GRHCAN). There are no bsp
>> +files for sparc.
>> +
>> +Required properties:
>> +
>> +- name : Should be "GAISLER_GRCAN", "01_03d", "GAISLER_GRHCAN" or "01_034"
>
> A name should be "vendor,device", e.g. gaisler,grcan. It's also unusual
> to add release numbers. Also, you do not distinguish between the devices
> above. Then, just use one name and the others are compatible to that one
> (even if they are named differently). Well, I realized that the device
> tree police is less strict than it was 1..2 years ago... anyway, please
> have a look to the many examples around, also for CAN.

As I stated in the file, there are no bsp files for sparc. The device trees are 
generated by a boot loader or a prom. For a leon sparc system the boot loader 
gets information from the hardware, the AMBA plug&play, and generates the device 
trees accordingly.

As for 01_03d and 01_034, they are are the names, based on what is found in the 
plug&play, that are generated by a boot loader that does not have a mapping from 
the plug and play to a name. They are not release numbers. They are based on 
vendor and device numbers as found in the plug&play on a leon sparc system.

Compare with these drivers that all use these kind of names to match with the 
hardware:
- drivers/net/ethernet/aeroflex/greth.c
- drivers/tty/serial/apbuart.c
- drivers/usb/host/ehci-grlib.c
- drivers/usb/host/uhci-hcd.c
- drivers/video/grvga.c

The reason for adding Documentation/devicetree/bindings/net/can/grcan.txt in the 
first I guess is for someone that takes the IP core outside of a leon system and 
need to write a bsp file for the board. For a leon system (the ordinary 
environment for GRCAN and GRHCAN as pointed out in the file). nothing needs to 
be done for adding support for GRCAN for a new board. The bootloader takes care 
of that.


>> +- freq : Frequency of the external oscillator clock in Hz (the frequency of
>> +	the amba bus in the ordinary case)
>
> Ditto. "clock-frequency" is a common name for that purpose.

Once again, "freq" is the property name that is given by the boot loader. 
Compare with drivers/tty/serial/apbuart.c that also relies on "freq".


>> +
>> +- interrupts : Interrupt number for this device
>> +
>> +Optional properties:
>> +
>> +- systemid : If not present or if the value of the least significant 16 bits
>> +	of this 32-bit property is smaller than GRCAN_TXBUG_SAFE_GRLIB_VERSION
>> +	a bug workaround is activated.
>
> Why can't this be handled via compatible string?

This approach is used as the information is available from the boot loader in 
this form.


>> -	ima_appraise=	[IMA] appraise integrity measurements
>> -			Format: { "off" | "enforce" | "fix" }
>> -			default: "enforce"
>> -
>> -	ima_appraise_tcb [IMA]
>> -			The builtin appraise policy appraises all files
>> -			owned by uid=0.
>> -
> Hm, is this related? There are more below.

Oops, sorry. That is a mistake. I'll clean that up.


Thanks for the feedback!

Cheers,
Andreas Larsson

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH v3] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-10-24 13:31         ` Andreas Larsson
@ 2012-10-30  9:06           ` Andreas Larsson
  2012-10-30 10:07             ` Wolfgang Grandegger
  2012-10-30  9:29           ` [PATCH v2] " Wolfgang Grandegger
  1 sibling, 1 reply; 41+ messages in thread
From: Andreas Larsson @ 2012-10-30  9:06 UTC (permalink / raw)
  To: linux-can
  Cc: Wolfgang Grandegger, Marc Kleine-Budde, devicetree-discuss, software

This driver supports GRCAN and CRHCAN CAN controllers available in the GRLIB
VHDL IP core library.

Signed-off-by: Andreas Larsson <andreas@gaisler.com>
---
 Documentation/ABI/testing/sysfs-class-net-grcan    |   35 +
 .../devicetree/bindings/net/can/grcan.txt          |   27 +
 Documentation/kernel-parameters.txt                |   25 +
 drivers/net/can/Kconfig                            |    9 +
 drivers/net/can/Makefile                           |    1 +
 drivers/net/can/grcan.c                            | 1616 ++++++++++++++++++++
 6 files changed, 1713 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-class-net-grcan
 create mode 100644 Documentation/devicetree/bindings/net/can/grcan.txt
 create mode 100644 drivers/net/can/grcan.c

diff --git a/Documentation/ABI/testing/sysfs-class-net-grcan b/Documentation/ABI/testing/sysfs-class-net-grcan
new file mode 100644
index 0000000..8fa2f90
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-net-grcan
@@ -0,0 +1,35 @@
+
+What:		/sys/class/net/<iface>/grcan/enable0
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas@gaisler.com>
+Description:
+		Hardware configuration of physical interface 0. This file reads
+		and writes the "Enable 0" bit of the configuration register.
+		Possible values: 0 or 1. See the GRCAN chapter of the GRLIB IP
+		core library documentation for details.
+		The default value is set by the module parameter enable0 and can
+		be read at /sys/module/grcan/parameters/enable0.
+
+What:		/sys/class/net/<iface>/grcan/enable1
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas@gaisler.com>
+Description:
+		Hardware configuration of physical interface 1. This file reads
+		and writes the "Enable 1" bit of the configuration register.
+		Possible values: 0 or 1. See the GRCAN chapter of the GRLIB IP
+		core library documentation for details.
+		The default value is set by the module parameter enable1 and can
+		be read at /sys/module/grcan/parameters/enable1.
+
+What:		/sys/class/net/<iface>/grcan/selection
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas@gaisler.com>
+Description:
+		Configuration of which physical interface to be used. Possible
+		values: 0 or 1. See the GRCAN chapter of the GRLIB IP core
+		library documentation for details.
+		The default value is set by the module parameter selection and can
+		be read at /sys/module/grcan/parameters/selection.
diff --git a/Documentation/devicetree/bindings/net/can/grcan.txt b/Documentation/devicetree/bindings/net/can/grcan.txt
new file mode 100644
index 0000000..a7180f1
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/can/grcan.txt
@@ -0,0 +1,27 @@
+CAN controller for Aeroflex Gaisler GRCAN and GRHCAN.
+
+The GRCAN and CRHCAN CAN controllers are available in the GRLIB VHDL IP core
+library.
+
+Note: These properties are built from the AMBA plug&play in a Leon SPARC
+system (the ordinary environment for GRCAN and GRHCAN). There are no bsp
+files for sparc.
+
+Required properties:
+
+- name : Should be "GAISLER_GRCAN", "01_03d", "GAISLER_GRHCAN" or "01_034"
+
+- reg : Address and length of the register set for the device
+
+- freq : Frequency of the external oscillator clock in Hz (the frequency of
+	the amba bus in the ordinary case)
+
+- interrupts : Interrupt number for this device
+
+Optional properties:
+
+- systemid : If not present or if the value of the least significant 16 bits
+	of this 32-bit property is smaller than GRCAN_TXBUG_SAFE_GRLIB_VERSION
+	a bug workaround is activated.
+
+For further information look in the documentation for the GLIB IP core library.
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 9776f06..3a82433 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -905,6 +905,31 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 	gpt		[EFI] Forces disk with valid GPT signature but
 			invalid Protective MBR to be treated as GPT.
 
+	grcan.enable0=	[HW] The "Enable 0" bit of the configuration
+			register. For more documentation, see
+			Documentation/ABI/testing/sysfs-class-net-grcan
+			Format: 0 | 1
+			Default: 0
+	grcan.enable1=	[HW] The "Enable 1" bit of the configuration
+			register. For more documentation, see
+			Documentation/ABI/testing/sysfs-class-net-grcan.
+			Format: 0 | 1
+			Default: 0
+	grcan.selection=
+			[HW] Selection of which physical interface to be
+			used. For more documentation, see
+			Documentation/ABI/testing/sysfs-class-net-grcan.
+			Format: 0 | 1
+			Default: 0
+	grcan.txsize=	[HW] The size of the tx buffer. For more documentation,
+			see Documentation/ABI/testing/sysfs-class-net-grcan.
+			Format: <value> such that (value & 0x1fffc0) == 0.
+			Default: 1024
+	grcan.rxsize=	[HW] The size of the rx buffer. For more documentation,
+			see Documentation/ABI/testing/sysfs-class-net-grcan.
+			Format: <value> such that (value & 0x1fffc0) == 0.
+			Default: 1024
+
 	hashdist=	[KNL,NUMA] Large hashes allocated during boot
 			are distributed across NUMA nodes.  Defaults on
 			for 64-bit NUMA, off otherwise.
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
index bb709fd..b56bd9e 100644
--- a/drivers/net/can/Kconfig
+++ b/drivers/net/can/Kconfig
@@ -110,6 +110,15 @@ config PCH_CAN
 	  is an IOH for x86 embedded processor (Intel Atom E6xx series).
 	  This driver can access CAN bus.
 
+config CAN_GRCAN
+	tristate "Aeroflex Gaisler GRCAN and GRHCAN CAN devices"
+	depends on CAN_DEV && OF
+	---help---
+	  Say Y here if you want to use Aeroflex Gaisler GRCAN or GRHCAN.
+	  Note that the driver supports little endian, even though little
+	  endian syntheses of the cores would need some modifications on
+	  the hardware level to work.
+
 source "drivers/net/can/mscan/Kconfig"
 
 source "drivers/net/can/sja1000/Kconfig"
diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
index 938be37..7de5986 100644
--- a/drivers/net/can/Makefile
+++ b/drivers/net/can/Makefile
@@ -22,5 +22,6 @@ obj-$(CONFIG_CAN_BFIN)		+= bfin_can.o
 obj-$(CONFIG_CAN_JANZ_ICAN3)	+= janz-ican3.o
 obj-$(CONFIG_CAN_FLEXCAN)	+= flexcan.o
 obj-$(CONFIG_PCH_CAN)		+= pch_can.o
+obj-$(CONFIG_CAN_GRCAN)		+= grcan.o
 
 ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/grcan.c b/drivers/net/can/grcan.c
new file mode 100644
index 0000000..201914c
--- /dev/null
+++ b/drivers/net/can/grcan.c
@@ -0,0 +1,1616 @@
+/*
+ * Socket CAN driver for Aeroflex Gaisler GRCAN and GRHCAN.
+ *
+ * 2012 (c) Aeroflex Gaisler AB
+ *
+ * This driver supports GRCAN and CRHCAN CAN controllers available in the GRLIB
+ * VHDL IP core library.
+ *
+ * Full documentation of the GRCAN core can be found here:
+ * http://www.gaisler.com/products/grlib/grip.pdf
+ *
+ * See "Documentation/devicetree/bindings/net/can/grcan.txt" for information on
+ * open firmware properties.
+ *
+ * See "Documentation/ABI/testing/sysfs-class-net-grcan" for information on the
+ * sysfs interface.
+ *
+ * See "Documentation/kernel-parameters.txt" for information on the module
+ * parameters.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Contributors: Andreas Larsson <andreas@gaisler.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/can/dev.h>
+#include <linux/spinlock.h>
+
+#include <linux/of_platform.h>
+#include <asm/prom.h>
+
+#include <linux/of_irq.h>
+
+#include <linux/dma-mapping.h>
+
+#define DRV_NAME "grcan"
+
+#define GRCAN_NAPI_WEIGHT	16
+
+#define GRCAN_RESERVE_SIZE(slot1, slot2) (((slot2) - (slot1)) / 4 - 1)
+
+#define SPIN_LOCK(lock)						\
+	do { spin_lock(lock); priv->holder = __LINE__; } while (0)
+#define SPIN_LOCK_IRQSAVE(lock, flags)					\
+	do {spin_lock_irqsave(lock, flags); priv->holder = __LINE__; } while (0)
+#define SPIN_UNLOCK(lock)					\
+	do { priv->holder = 0; spin_unlock(lock); } while (0)
+#define SPIN_UNLOCK_IRQRESTORE(lock, flags)				\
+	do { priv->holder = 0; spin_unlock_irqrestore(lock, flags); } while (0)
+
+
+struct grcan_registers {
+	u32 conf;	/* 0x00 */
+	u32 stat;	/* 0x04 */
+	u32 ctrl;	/* 0x08 */
+	u32 __reserved1[GRCAN_RESERVE_SIZE(0x08, 0x18)];
+	u32 smask;	/* 0x18 - CanMASK */
+	u32 scode;	/* 0x1c - CanCODE */
+	u32 __reserved2[GRCAN_RESERVE_SIZE(0x1c, 0x100)];
+	u32 pimsr;	/* 0x100 */
+	u32 pimr;	/* 0x104 */
+	u32 pisr;	/* 0x108 */
+	u32 pir;	/* 0x10C */
+	u32 imr;	/* 0x110 */
+	u32 picr;	/* 0x114 */
+	u32 __reserved3[GRCAN_RESERVE_SIZE(0x114, 0x200)];
+	u32 txctrl;	/* 0x200 */
+	u32 txaddr;	/* 0x204 */
+	u32 txsize;	/* 0x208 */
+	u32 txwr;	/* 0x20C */
+	u32 txrd;	/* 0x210 */
+	u32 txirq;	/* 0x214 */
+	u32 __reserved4[GRCAN_RESERVE_SIZE(0x214, 0x300)];
+	u32 rxctrl;	/* 0x300 */
+	u32 rxaddr;	/* 0x304 */
+	u32 rxsize;	/* 0x308 */
+	u32 rxwr;	/* 0x30C */
+	u32 rxrd;	/* 0x310 */
+	u32 rxirq;	/* 0x314 */
+	u32 rxmask;	/* 0x318 */
+	u32 rxcode;	/* 0x31C */
+};
+
+#define GRCAN_CONF_ABORT      0x00000001
+#define GRCAN_CONF_ENABLE0    0x00000002
+#define GRCAN_CONF_ENABLE1    0x00000004
+#define GRCAN_CONF_SELECTION  0x00000008
+#define GRCAN_CONF_SILENT     0x00000010
+#define GRCAN_CONF_BPR        0x00000300  /* Note: not BRP */
+#define GRCAN_CONF_RSJ        0x00007000
+#define GRCAN_CONF_PS1        0x00f00000
+#define GRCAN_CONF_PS2        0x000f0000
+#define GRCAN_CONF_SCALER     0xff000000
+#define GRCAN_CONF_OPERATION						\
+	(GRCAN_CONF_ABORT | GRCAN_CONF_ENABLE0 | GRCAN_CONF_ENABLE1	\
+	 | GRCAN_CONF_SELECTION | GRCAN_CONF_SILENT)
+#define GRCAN_CONF_TIMING						\
+	(GRCAN_CONF_BPR | GRCAN_CONF_RSJ | GRCAN_CONF_PS1		\
+	 | GRCAN_CONF_PS2 | GRCAN_CONF_SCALER)
+
+#define GRCAN_CONF_RSJ_MIN    1
+#define GRCAN_CONF_RSJ_MAX    4
+#define GRCAN_CONF_PS1_MIN    1
+#define GRCAN_CONF_PS1_MAX    15
+#define GRCAN_CONF_PS2_MIN    2
+#define GRCAN_CONF_PS2_MAX    8
+#define GRCAN_CONF_SCALER_MIN 0
+#define GRCAN_CONF_SCALER_MAX 255
+#define GRCAN_CONF_SCALER_INC 1
+
+#define GRCAN_CONF_BPR_BIT    8
+#define GRCAN_CONF_RSJ_BIT    12
+#define GRCAN_CONF_PS1_BIT    20
+#define GRCAN_CONF_PS2_BIT    16
+#define GRCAN_CONF_SCALER_BIT 24
+
+#define GRCAN_STAT_PASS      0x000001
+#define GRCAN_STAT_OFF       0x000002
+#define GRCAN_STAT_OR        0x000004
+#define GRCAN_STAT_AHBERR    0x000008
+#define GRCAN_STAT_ACTIVE    0x000010
+#define GRCAN_STAT_RXERRCNT  0x00ff00
+#define GRCAN_STAT_TXERRCNT  0xff0000
+
+#define GRCAN_STAT_RXERRCNT_BIT  8
+#define GRCAN_STAT_TXERRCNT_BIT  16
+
+#define GRCAN_STAT_ERRCNT_WARNING_LIMIT 96
+#define GRCAN_STAT_ERRCNT_PASSIVE_LIMIT 127
+
+
+#define GRCAN_CTRL_RESET  0x2
+#define GRCAN_CTRL_ENABLE 0x1
+
+#define GRCAN_TXCTRL_ENABLE  0x1
+#define GRCAN_TXCTRL_ONGOING 0x2
+#define GRCAN_TXCTRL_SINGLE  0x4
+
+#define GRCAN_RXCTRL_ENABLE  0x1
+#define GRCAN_RXCTRL_ONGOING 0x2
+
+/* Relative offset of IRQ sources to AMBA Plug&Play */
+#define GRCAN_IRQIX_IRQ    0
+#define GRCAN_IRQIX_TXSYNC 1
+#define GRCAN_IRQIX_RXSYNC 2
+
+#define GRCAN_IRQ_PASS       0x00001
+#define GRCAN_IRQ_OFF        0x00002
+#define GRCAN_IRQ_OR         0x00004
+#define GRCAN_IRQ_RXAHBERR   0x00008
+#define GRCAN_IRQ_TXAHBERR   0x00010
+#define GRCAN_IRQ_RXIRQ      0x00020
+#define GRCAN_IRQ_TXIRQ      0x00040
+#define GRCAN_IRQ_RXFULL     0x00080
+#define GRCAN_IRQ_TXEMPTY    0x00100
+#define GRCAN_IRQ_RX         0x00200
+#define GRCAN_IRQ_TX         0x00400
+#define GRCAN_IRQ_RXSYNC     0x00800
+#define GRCAN_IRQ_TXSYNC     0x01000
+#define GRCAN_IRQ_RXERRCTR   0x02000
+#define GRCAN_IRQ_TXERRCTR   0x04000
+#define GRCAN_IRQ_RXMISS     0x08000
+#define GRCAN_IRQ_TXLOSS     0x10000
+
+#define GRCAN_IRQ_NONE 0
+#define GRCAN_IRQ_ALL \
+(GRCAN_IRQ_PASS | GRCAN_IRQ_OFF | GRCAN_IRQ_OR				\
+		       | GRCAN_IRQ_RXAHBERR | GRCAN_IRQ_TXAHBERR	\
+		       | GRCAN_IRQ_RXIRQ | GRCAN_IRQ_TXIRQ		\
+		       | GRCAN_IRQ_RXFULL | GRCAN_IRQ_TXEMPTY		\
+		       | GRCAN_IRQ_RX | GRCAN_IRQ_TX | GRCAN_IRQ_RXSYNC \
+		       | GRCAN_IRQ_TXSYNC | GRCAN_IRQ_RXERRCTR		\
+		       | GRCAN_IRQ_TXERRCTR | GRCAN_IRQ_RXMISS		\
+		       | GRCAN_IRQ_TXLOSS)
+
+#define GRCAN_IRQ_ERRCTR_RELATED (GRCAN_IRQ_RXERRCTR | GRCAN_IRQ_TXERRCTR \
+				  | GRCAN_IRQ_PASS | GRCAN_IRQ_OFF)
+#define GRCAN_IRQ_ERRORS (GRCAN_IRQ_ERRCTR_RELATED | GRCAN_IRQ_OR	\
+			  | GRCAN_IRQ_TXAHBERR | GRCAN_IRQ_RXAHBERR	\
+			  | GRCAN_IRQ_TXLOSS)
+#define GRCAN_IRQ_DEFAULT (GRCAN_IRQ_RX | GRCAN_IRQ_TX | GRCAN_IRQ_ERRORS)
+
+#define GRCAN_MSG_SIZE 16
+
+#define GRCAN_MSG_IDE 0x80000000
+#define GRCAN_MSG_RTR 0x40000000
+#define GRCAN_MSG_BID 0x1ffc0000
+#define GRCAN_MSG_EID 0x1fffffff
+#define GRCAN_MSG_IDE_BIT 31
+#define GRCAN_MSG_RTR_BIT 30
+#define GRCAN_MSG_BID_BIT 18
+#define GRCAN_MSG_EID_BIT 0
+
+#define GRCAN_MSG_DLC    0xf0000000
+#define GRCAN_MSG_TXERRC 0x00ff0000
+#define GRCAN_MSG_RXERRC 0x0000ff00
+#define GRCAN_MSG_DLC_BIT 28
+#define GRCAN_MSG_TXERRC_BIT 16
+#define GRCAN_MSG_RXERRC_BIT 8
+#define GRCAN_MSG_AHBERR 0x00000008
+#define GRCAN_MSG_OR     0x00000004
+#define GRCAN_MSG_OFF    0x00000002
+#define GRCAN_MSG_PASS   0x00000001
+
+#define GRCAN_MSG_DATA_SLOT_INDEX(i) (2 + (i) / 4)
+#define GRCAN_MSG_DATA_SHIFT(i) ((3 - (i) % 4) * 8)
+
+#define GRCAN_BUFFER_ALIGNMENT 1024
+#define GRCAN_DEFAULT_BUFFER_SIZE 1024
+
+#define GRCAN_VALID_TR_SIZE_MASK 0x001fffc0
+#define GRCAN_INVALID_BUFFER_SIZE(s)		\
+	((s) == 0 || ((s) & ~GRCAN_VALID_TR_SIZE_MASK))
+
+#if GRCAN_INVALID_BUFFER_SIZE(GRCAN_DEFAULT_BUFFER_SIZE)
+#error "Invalid default buffer size"
+#endif
+
+struct grcan_dma_buffer {
+	size_t size;
+	void *buf;
+	dma_addr_t handle;
+};
+
+struct grcan_dma {
+	size_t base_size;
+	void *base_buf;
+	dma_addr_t base_handle;
+	struct grcan_dma_buffer tx;
+	struct grcan_dma_buffer rx;
+};
+
+/* GRCAN configuration parameters */
+struct grcan_device_config {
+	unsigned short enable0;
+	unsigned short enable1;
+	unsigned short selection;
+	unsigned int txsize;
+	unsigned int rxsize;
+};
+
+#define GRCAN_DEFAULT_DEVICE_CONFIG {			\
+		.enable0 = 0,				\
+		.enable1 = 0,				\
+		.selection = 0,				\
+		.txsize = GRCAN_DEFAULT_BUFFER_SIZE,	\
+		.rxsize = GRCAN_DEFAULT_BUFFER_SIZE,	\
+		}
+
+#define GRCAN_TXBUG_SAFE_GRLIB_VERSION 0x4100
+#define GRLIB_VERSION_MASK 0xffff
+
+
+/* GRCAN private data structure */
+struct grcan_priv {
+	struct can_priv can;	/* must be the first member */
+	struct net_device *dev;
+	struct napi_struct napi;
+
+	struct grcan_registers __iomem *regs; /* ioremap'ed registers */
+	struct grcan_device_config config;
+	struct grcan_dma dma;
+	struct sk_buff **echo_skb;	/* We allocate this on our own */
+	u32 eskbp;			/* Pointer into echo_skb */
+	u8 *txdlc;			/* Length of queued frames */
+	u32 ambafreq;
+
+	/* Lock for stopping and waking the netif tx queue and for
+	 * accesses to eskbp
+	 */
+	spinlock_t lock;
+	int holder;
+
+	/* Whether a workaround is needed due to a bug in older hardware. */
+	bool need_txbug_workaround;
+
+	/* To trigger initization of running reset and to trigger running reset
+	 * respectively in the case of a hanged device due to a txbug.
+	 */
+	struct timer_list hang_timer;
+	struct timer_list rr_timer;
+
+	/* To avoid waking up the netif queue and restarting timers
+	 * when a reset is scheduled or when closing of the device is
+	 * undergoing
+	 */
+	bool resetting;
+	bool closing;
+};
+
+/* Wait time for a short wait for ongoing to clear */
+#define GRCAN_SHORTWAIT_USECS 10
+
+/* Waiting for a time corresponding to transmission of three can frames */
+#define GRCAN_EFF_FRAME_MAX_BITS (1+32+6+8*8+16+2+7)
+
+#if defined(__BIG_ENDIAN)
+static inline u32 grcan_read_reg(u32 __iomem *reg)
+{
+	return ioread32be(reg);
+}
+
+static inline void grcan_write_reg(u32 __iomem *reg, u32 val)
+{
+	iowrite32be(val, reg);
+}
+#else
+static inline u32 grcan_read_reg(u32 __iomem *reg)
+{
+	return ioread32(reg);
+}
+
+static inline void grcan_write_reg(u32 __iomem *reg, u32 val)
+{
+	iowrite32(val, reg);
+}
+#endif
+
+static inline void grcan_clear_bits(u32 __iomem *reg, u32 mask)
+{
+	grcan_write_reg(reg, grcan_read_reg(reg) & ~mask);
+}
+
+static inline void grcan_set_bits(u32 __iomem *reg, u32 mask)
+{
+	grcan_write_reg(reg, grcan_read_reg(reg) | mask);
+}
+
+static inline u32 grcan_read_bits(u32 __iomem *reg, u32 mask)
+{
+	return grcan_read_reg(reg) & mask;
+}
+
+static inline void grcan_write_bits(u32 __iomem *reg, u32 value, u32 mask)
+{
+	u32 old = grcan_read_reg(reg);
+	grcan_write_reg(reg, (old & ~mask) | (value & mask));
+}
+
+static inline u32 grcan_ring_add(u32 a, u32 b, u32 size)
+{
+	u32 sum = a + b;
+	if (sum < size)
+		return sum;
+	else
+		return sum - size;
+}
+
+static inline u32 grcan_ring_sub(u32 a, u32 b, u32 size)
+{
+	u32 diff = a - b;
+	if (a < b)
+		return diff + size;
+	else
+		return diff;
+}
+
+static inline u32 grcan_txspace(size_t txsize, u32 txwr, u32 eskbp)
+{
+	u32 slots = txsize / GRCAN_MSG_SIZE - 1;
+	u32 used = grcan_ring_sub(txwr, eskbp, txsize);
+	return slots - used;
+}
+
+/* Configuration parameters that can be set via module parameters */
+static struct grcan_device_config grcan_module_config =
+	GRCAN_DEFAULT_DEVICE_CONFIG;
+
+static struct can_bittiming_const grcan_bittiming_const = {
+	.name = DRV_NAME,
+	.tseg1_min = GRCAN_CONF_PS1_MIN + 1,
+	.tseg1_max = GRCAN_CONF_PS1_MAX + 1,
+	.tseg2_min = GRCAN_CONF_PS2_MIN,
+	.tseg2_max = GRCAN_CONF_PS2_MAX,
+	.sjw_max   = GRCAN_CONF_RSJ_MAX,
+	.brp_min   = GRCAN_CONF_SCALER_MIN + 1,
+	.brp_max   = GRCAN_CONF_SCALER_MAX + 1,
+	.brp_inc   = GRCAN_CONF_SCALER_INC,
+};
+
+static int grcan_set_bittiming(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct can_bittiming *bt = &priv->can.bittiming;
+	u32 timing = 0;
+	int bpr, rsj, ps1, ps2, scaler;
+
+	/* Should never happen - function will not be called when
+	 * device is up
+	 */
+	if (grcan_read_bits(&regs->ctrl, GRCAN_CTRL_ENABLE))
+		return -EBUSY;
+
+	bpr    = 0; /* Note bpr and brp are different concepts */
+	rsj    = bt->sjw;
+	ps1    = (bt->prop_seg + bt->phase_seg1) - 1; /* tseg1-1 */
+	ps2    = bt->phase_seg2;
+	scaler = (bt->brp - 1);
+	timing |= (bpr << GRCAN_CONF_BPR_BIT) & GRCAN_CONF_BPR;
+	timing |= (rsj << GRCAN_CONF_RSJ_BIT) & GRCAN_CONF_RSJ;
+	timing |= (ps1 << GRCAN_CONF_PS1_BIT) & GRCAN_CONF_PS1;
+	timing |= (ps2 << GRCAN_CONF_PS2_BIT) & GRCAN_CONF_PS2;
+	timing |= (scaler << GRCAN_CONF_SCALER_BIT) & GRCAN_CONF_SCALER;
+
+	dev_info(dev->dev.parent,
+		 "setting timing=0x%x\n", timing);
+	grcan_write_bits(&regs->conf, timing, GRCAN_CONF_TIMING);
+	return 0;
+}
+
+static int grcan_get_berr_counter(const struct net_device *dev,
+				  struct can_berr_counter *bec)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	u32 status = grcan_read_reg(&regs->stat);
+	bec->txerr = (status & GRCAN_STAT_TXERRCNT) >> GRCAN_STAT_TXERRCNT_BIT;
+	bec->rxerr = (status & GRCAN_STAT_RXERRCNT) >> GRCAN_STAT_RXERRCNT_BIT;
+	return 0;
+}
+
+static int grcan_poll(struct napi_struct *napi, int budget);
+
+/* Reset device, but keep timing information */
+static void grcan_reset(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+
+	u32 timing = grcan_read_bits(&regs->conf, GRCAN_CONF_TIMING);
+	grcan_set_bits(&regs->ctrl, GRCAN_CTRL_RESET);
+	grcan_write_bits(&regs->conf, timing, GRCAN_CONF_TIMING);
+
+	priv->eskbp = grcan_read_reg(&regs->txrd);
+	priv->can.state = CAN_STATE_STOPPED;
+
+	/* Turn off hardware filtering - regs->rxcode set to 0 by reset */
+	grcan_write_reg(&regs->rxmask, 0);
+}
+
+/* stop device without changing any configurations */
+static void grcan_stop(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	grcan_write_reg(&regs->imr, GRCAN_IRQ_NONE);
+	grcan_clear_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
+	grcan_clear_bits(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+	grcan_clear_bits(&regs->ctrl, GRCAN_CTRL_ENABLE);
+	priv->can.state = CAN_STATE_STOPPED;
+}
+
+/* Let priv->eskp catch up to regs->txrd and echo back the skbs if echo is true
+ * and free them otherwise.
+ *
+ * If budget is >= 0, stop after handling at most budget skbs. Otherwise,
+ * continue until priv->eskp catches up to regs->txrd.
+ *
+ * priv->lock *must* be held when calling this function
+ */
+static int catch_up_echo_skb(struct net_device *dev, int budget, bool echo)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	struct net_device_stats *stats = &dev->stats;
+	int i, work_done;
+
+	/* Updates to priv->eskbp and wake-ups of the queue needs to
+	 * be atomic towards the reads of priv->eskbp and shut-downs
+	 * of the queue in grcan_start_xmit.
+	 */
+	u32 txrd = grcan_read_reg(&regs->txrd);
+	for (work_done = 0; work_done < budget || budget < 0; work_done++) {
+		if (priv->eskbp == txrd)
+			break;
+		i = priv->eskbp / GRCAN_MSG_SIZE;
+		if (echo) {
+			/* Normal echo of messages */
+			stats->tx_packets++;
+			stats->tx_bytes += priv->txdlc[i];
+			priv->txdlc[i] = 0;
+			can_get_echo_skb(dev, i);
+		} else {
+			/* For cleanup of untransmitted messages */
+			can_free_echo_skb(dev, i);
+		}
+
+		priv->eskbp = grcan_ring_add(priv->eskbp, GRCAN_MSG_SIZE,
+					     dma->tx.size);
+		txrd = grcan_read_reg(&regs->txrd);
+	}
+	return work_done;
+}
+
+static void grcan_lost_one_shot_frame(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	u32 txrd;
+
+	SPIN_LOCK(&priv->lock);
+	priv->holder = 1;
+
+	catch_up_echo_skb(dev, -1, true);
+
+	if (unlikely(grcan_read_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE))) {
+		/* Should never happen */
+		netdev_err(dev, "TXCTRL enabled at TXLOSS in one shot mode\n");
+	} else {
+		/* By the time an GRCAN_IRQ_TXLOSS is generated in
+		 * one-shot mode there is no problem in writing
+		 * to TXRD even in versions of the hardware in
+		 * which GRCAN_TXCTRL_ONGOING is not cleared properly
+		 * in one-shot mode.
+		 */
+
+		/* Skip message and discard echo-skb */
+		txrd = grcan_read_reg(&regs->txrd);
+		txrd = grcan_ring_add(txrd, GRCAN_MSG_SIZE, dma->tx.size);
+		grcan_write_reg(&regs->txrd, txrd);
+		catch_up_echo_skb(dev, -1, false);
+
+		if (!priv->resetting && !priv->closing) {
+			if (netif_queue_stopped(dev))
+				netif_wake_queue(dev);
+			grcan_set_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
+		}
+	}
+
+	priv->holder = 0;
+	SPIN_UNLOCK(&priv->lock);
+}
+
+static void grcan_err(struct net_device *dev, u32 sources, u32 status)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct net_device_stats *stats = &dev->stats;
+	struct can_frame cf;
+
+	/* Zero potential error_frame */
+	memset(&cf, 0, sizeof(cf));
+
+	/* Arbitration lost interrupt */
+	if (sources & GRCAN_IRQ_TXLOSS) {
+		netdev_dbg(dev,
+			   "arbitration lost (or other comm failure)\n");
+		stats->tx_errors++;
+		priv->can.can_stats.arbitration_lost++;
+
+		/* Take care of failed one-shot transmit */
+		if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT)
+			grcan_lost_one_shot_frame(dev);
+
+		cf.can_id |= CAN_ERR_LOSTARB;
+	}
+
+	/* Conditions dealing with the error counters */
+	if (sources & GRCAN_IRQ_ERRCTR_RELATED) {
+		enum can_state state = priv->can.state;
+		enum can_state oldstate = state;
+		u32 txerr = (status & GRCAN_STAT_TXERRCNT)
+			>> GRCAN_STAT_TXERRCNT_BIT;
+		u32 rxerr = (status & GRCAN_STAT_RXERRCNT)
+			>> GRCAN_STAT_RXERRCNT_BIT;
+
+		if (status & GRCAN_STAT_OFF) {
+			netdev_dbg(dev, "Bus off condition\n");
+			state = CAN_STATE_BUS_OFF;
+			can_bus_off(dev);
+
+			cf.can_id |= CAN_ERR_BUSOFF;
+		} else if (status & GRCAN_STAT_PASS) {
+			netdev_dbg(dev, "Error passive condition\n");
+			state = CAN_STATE_ERROR_PASSIVE;
+			priv->can.can_stats.error_passive++;
+
+			cf.can_id |= CAN_ERR_CRTL;
+			if (txerr >= GRCAN_STAT_ERRCNT_PASSIVE_LIMIT)
+				cf.data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
+			if (rxerr >= GRCAN_STAT_ERRCNT_PASSIVE_LIMIT)
+				cf.data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
+		} else if (txerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT ||
+			   rxerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT) {
+			state = CAN_STATE_ERROR_WARNING;
+			priv->can.can_stats.error_warning++;
+			if (oldstate != state)
+				netdev_dbg(dev, "Error warning condition\n");
+
+			cf.can_id |= CAN_ERR_CRTL;
+			if (txerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT)
+				cf.data[1] |= CAN_ERR_CRTL_TX_WARNING;
+			if (rxerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT)
+				cf.data[1] |= CAN_ERR_CRTL_RX_WARNING;
+		} else {
+			state = CAN_STATE_ERROR_ACTIVE;
+			if (oldstate != state)
+				netdev_dbg(dev, "Error active condition\n");
+		}
+		if (state != CAN_STATE_ERROR_ACTIVE) {
+			cf.data[6] = txerr;
+			cf.data[7] = rxerr;
+		}
+		priv->can.state = state;
+	}
+
+	/* Data overrun interrupt */
+	if (sources & GRCAN_IRQ_OR) {
+		netdev_dbg(dev, "got data overrun interrupt\n");
+		stats->rx_over_errors++;
+		stats->rx_errors++;
+
+		cf.can_id  |= CAN_ERR_CRTL;
+		cf.data[1] |= CAN_ERR_CRTL_RX_OVERFLOW;
+	}
+
+	/* AHB bus error interrupts (not CAN bus errors) - shut down the
+	 * device.
+	 */
+	if (sources & (GRCAN_IRQ_TXAHBERR | GRCAN_IRQ_RXAHBERR)) {
+		if (sources & GRCAN_IRQ_TXAHBERR) {
+			netdev_err(dev, "got AHB bus error on tx\n");
+			stats->tx_errors++;
+		} else {
+			netdev_err(dev, "got AHB bus error on rx\n");
+			stats->rx_errors++;
+		}
+		netdev_err(dev, "halting device\n");
+
+		/* Prevent anything to be enabled again and halt device */
+		SPIN_LOCK(&priv->lock);
+		priv->closing = true;
+		netif_stop_queue(dev);
+		grcan_stop(dev);
+		SPIN_UNLOCK(&priv->lock);
+	}
+
+	/* Pass on error frame if something to report,
+	 * i.e. id contains some information
+	 */
+	if (cf.can_id) {
+		struct can_frame *skb_cf;
+		struct sk_buff *skb = alloc_can_err_skb(dev, &skb_cf);
+		if (skb == NULL)
+			netdev_dbg(dev, "could not allocate error frame\n");
+		skb_cf->can_id |= cf.can_id;
+		memcpy(skb_cf->data, cf.data, sizeof(cf.data));
+
+		netif_rx(skb);
+	}
+}
+
+static irqreturn_t grcan_interrupt(int irq, void *dev_id)
+{
+	struct net_device *dev = (struct net_device *)dev_id;
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	u32 sources, status;
+
+	/* Find out the source */
+	sources = grcan_read_reg(&regs->pimsr);
+	if (!sources)
+		return IRQ_NONE;
+	grcan_write_reg(&regs->picr, sources);
+	status = grcan_read_reg(&regs->stat);
+
+	/* If we got TX progress, the device has not hanged,
+	 * so disable the hang timer
+	 */
+	if (priv->need_txbug_workaround
+	    && (sources & (GRCAN_IRQ_TX | GRCAN_IRQ_TXLOSS))) {
+		SPIN_LOCK(&priv->lock);
+		if (timer_pending(&priv->hang_timer))
+			del_timer(&priv->hang_timer);
+		SPIN_UNLOCK(&priv->lock);
+	}
+
+	/* Frame(s) received or transmitted */
+	if (sources & (GRCAN_IRQ_TX | GRCAN_IRQ_RX)) {
+		/* Disable tx/rx interrupts and schedule poll() */
+		grcan_clear_bits(&regs->imr, GRCAN_IRQ_TX | GRCAN_IRQ_RX);
+		napi_schedule(&priv->napi);
+	}
+
+	/* (Potential) error conditions to take care of */
+	if (sources & GRCAN_IRQ_ERRORS)
+		grcan_err(dev, sources, status);
+
+	return IRQ_HANDLED;
+}
+
+/* Reset device and restart operations from where they were.
+ *
+ * This assumes that RXCTRL & RXCTRL is properly disabled and that RX
+ * is not ONGOING (TX might be stuck in ONGOING due to a harwrware bug
+ * for single shot)
+ */
+static void grcan_running_reset(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *) data;
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	u32 txwr, txrd, rxwr, rxrd, eskbp;
+	unsigned long flags;
+
+	/* This temporarily messes with eskbp, so we need to lock
+	 * priv->lock
+	 */
+	SPIN_LOCK_IRQSAVE(&priv->lock, flags);
+	if (!priv->closing && priv->resetting) {
+		txwr = grcan_read_reg(&regs->txwr);
+		txrd = grcan_read_reg(&regs->txrd);
+		rxwr = grcan_read_reg(&regs->rxwr);
+		rxrd = grcan_read_reg(&regs->rxrd);
+		eskbp = priv->eskbp;
+
+		grcan_reset(dev);
+
+		grcan_write_reg(&regs->txwr, txwr);
+		grcan_write_reg(&regs->txrd, txrd);
+		grcan_write_reg(&regs->rxwr, rxwr);
+		grcan_write_reg(&regs->rxrd, rxrd);
+		priv->eskbp = eskbp;
+
+		priv->can.state = CAN_STATE_ERROR_ACTIVE;
+		grcan_set_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE
+			      | (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT
+				 ? GRCAN_TXCTRL_SINGLE : 0));
+		grcan_set_bits(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+		/* Start queue if there is size */
+		if (grcan_txspace(priv->dma.tx.size, txwr, priv->eskbp))
+			netif_wake_queue(dev);
+
+		del_timer(&priv->hang_timer);
+		del_timer(&priv->rr_timer);
+
+		priv->resetting = false;
+	}
+	SPIN_UNLOCK_IRQRESTORE(&priv->lock, flags);
+	netdev_err(dev, "Device reset and restored\n");
+
+}
+
+/* A time in usecs within which the can controller have time to finish sending
+ * or receiving a frame with a good margin
+ */
+static inline u32 grcan_ongoing_wait_usecs(__u32 bitrate)
+{
+	return 1000000 * 3 * GRCAN_EFF_FRAME_MAX_BITS / bitrate;
+}
+
+/* Set timer so that it will not fire until after a period in which the can
+ * controller have a good margin to finish transmitting a frame unless it has
+ * hanged
+ */
+static inline void grcan_reset_timer(struct timer_list *timer, __u32 bitrate)
+{
+	u32 wait_jiffies = usecs_to_jiffies(grcan_ongoing_wait_usecs(bitrate));
+	mod_timer(timer, jiffies + wait_jiffies);
+}
+
+/* Disable channels and schedule a running reset */
+static void grcan_initiate_running_reset(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *)data;
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	unsigned long flags;
+
+	netdev_err(dev, "Device seems hanged - reset scheduled\n");
+
+
+	SPIN_LOCK_IRQSAVE(&priv->lock, flags);
+
+	/* The main body of this function must never be executed again
+	 * until after an execution of grcan_running_reset
+	 */
+	if (!priv->resetting && !priv->closing) {
+		priv->resetting = true;
+		netif_stop_queue(dev);
+		grcan_clear_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
+		grcan_clear_bits(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+		grcan_reset_timer(&priv->rr_timer, priv->can.bittiming.bitrate);
+	}
+
+	SPIN_UNLOCK_IRQRESTORE(&priv->lock, flags);
+}
+
+static void grcan_free_dma_buffers(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_dma *dma = &priv->dma;
+	dma_free_coherent(&dev->dev,
+			  dma->base_size,
+			  dma->base_buf,
+			  dma->base_handle);
+	dma->base_size = 0;
+	dma->base_buf = NULL;
+	dma->base_handle = 0;
+	dma->rx.size = 0;
+	dma->rx.buf = NULL;
+	dma->rx.handle = 0;
+	dma->tx.size = 0;
+	dma->tx.buf = NULL;
+	dma->tx.handle = 0;
+}
+
+static int grcan_allocate_dma_buffers(struct net_device *dev,
+				      size_t tsize, size_t rsize)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_dma *dma = &priv->dma;
+	struct grcan_dma_buffer *large = rsize > tsize ? &dma->rx : &dma->tx;
+	struct grcan_dma_buffer *small = rsize > tsize ? &dma->tx : &dma->rx;
+	size_t shift;
+
+	/* Need a whole number of GRCAN_BUFFER_ALIGNMENT for the large,
+	 * i.e. first buffer
+	 */
+	size_t maxs  = max(tsize, rsize);
+	size_t lsize = ALIGN(maxs, GRCAN_BUFFER_ALIGNMENT);
+
+	/* Put the small buffer after that */
+	size_t ssize = min(tsize, rsize);
+
+	/* Extra GRCAN_BUFFER_ALIGNMENT to allow for alignment */
+	dma->base_size = lsize + ssize + GRCAN_BUFFER_ALIGNMENT;
+	dma->base_buf = dma_alloc_coherent(&dev->dev,
+					   dma->base_size,
+					   &dma->base_handle,
+					   GFP_KERNEL);
+
+	if (!dma->base_buf)
+		return -ENOMEM;
+
+	dma->tx.size = tsize;
+	dma->rx.size = rsize;
+
+	large->handle = ALIGN(dma->base_handle, GRCAN_BUFFER_ALIGNMENT);
+	small->handle = large->handle + lsize;
+	shift = large->handle - dma->base_handle;
+
+	large->buf = dma->base_buf + shift;
+	small->buf = large->buf + lsize;
+
+	return 0;
+}
+
+
+/* priv->lock *must* be held when calling this function */
+static int grcan_start(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+
+	grcan_reset(dev);
+
+	grcan_write_reg(&regs->txaddr, priv->dma.tx.handle);
+	grcan_write_reg(&regs->txsize, priv->dma.tx.size);
+	/* regs->txwr and regs->txrd already set to 0 by reset */
+
+	grcan_write_reg(&regs->rxaddr, priv->dma.rx.handle);
+	grcan_write_reg(&regs->rxsize, priv->dma.rx.size);
+	/* regs->rxwr and regs->rxrd already set to 0 by reset */
+
+	/* Enable interrupts */
+	grcan_read_reg(&regs->pir);
+	grcan_write_reg(&regs->imr, GRCAN_IRQ_DEFAULT);
+
+	/* Enable interfaces, channels and device */
+	grcan_set_bits(&regs->conf,
+		      ((priv->config.enable0 ? GRCAN_CONF_ENABLE0 : 0)
+		       | (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY ?
+			  GRCAN_CONF_SILENT : 0)
+		       | (priv->config.enable1 ? GRCAN_CONF_ENABLE1 : 0)
+		       | (priv->config.selection ? GRCAN_CONF_SELECTION : 0)
+		       | GRCAN_CONF_ABORT));
+	grcan_set_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE
+		      | (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT
+			 ? GRCAN_TXCTRL_SINGLE : 0));
+	grcan_set_bits(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+	grcan_set_bits(&regs->ctrl, GRCAN_CTRL_ENABLE);
+
+	priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+	return 0;
+}
+
+static int grcan_set_mode(struct net_device *dev, enum can_mode mode)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+	int err;
+
+	if (mode == CAN_MODE_START) {
+		/* This might be called to restart the device to recover from
+		 * bus off errors
+		 */
+		SPIN_LOCK_IRQSAVE(&priv->lock, flags);
+		if (priv->closing || priv->resetting) {
+			err = -EBUSY;
+		} else {
+			netdev_info(dev, "Restarting device\n");
+			grcan_start(dev);
+			if (netif_queue_stopped(dev))
+				netif_wake_queue(dev);
+			err = 0;
+		}
+		SPIN_UNLOCK_IRQRESTORE(&priv->lock, flags);
+		return err;
+	}
+	return -EOPNOTSUPP;
+}
+
+static int grcan_open(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_dma *dma = &priv->dma;
+	unsigned long flags;
+	int err;
+
+	SPIN_LOCK_IRQSAVE(&priv->lock, flags);
+
+	/* Allocate memory */
+	if (GRCAN_INVALID_BUFFER_SIZE(priv->config.txsize)
+	    || GRCAN_INVALID_BUFFER_SIZE(priv->config.rxsize)) {
+		/* Should never be able go this far with invalid sizes */
+		netdev_err(dev, "Invalid buffer size pair 0x%x 0x%x\n",
+			   priv->config.txsize, priv->config.rxsize);
+		err = -EINVAL;
+		goto exit_unlock;
+	}
+	err = grcan_allocate_dma_buffers(dev, priv->config.txsize,
+					 priv->config.rxsize);
+	if (err) {
+		netdev_err(dev, "could not allocate DMA buffers\n");
+		goto exit_unlock;
+	}
+
+	priv->echo_skb = devm_kzalloc(&dev->dev,
+				      dma->tx.size * sizeof(*priv->echo_skb),
+				      GFP_KERNEL);
+	if (!priv->echo_skb) {
+		err = -ENOMEM;
+		goto exit_free_dma_buffers;
+	}
+	priv->can.echo_skb_max = dma->tx.size;
+	priv->can.echo_skb = priv->echo_skb;
+
+	priv->txdlc = devm_kzalloc(&dev->dev,
+				   dma->tx.size * sizeof(*priv->txdlc),
+				   GFP_KERNEL);
+	if (!priv->txdlc) {
+		err = -ENOMEM;
+		goto exit_free_echo_skb;
+	}
+
+	/* Get can device up */
+	err = open_candev(dev);
+	if (err)
+		goto exit_free_txdlc;
+
+	err = devm_request_irq(&dev->dev, dev->irq, grcan_interrupt,
+			       IRQF_SHARED, dev->name, (void *)dev);
+	if (err)
+		goto exit_close_candev;
+
+	grcan_start(dev);
+	napi_enable(&priv->napi);
+	netif_start_queue(dev);
+
+	priv->resetting = false;
+	priv->closing = false;
+
+	SPIN_UNLOCK_IRQRESTORE(&priv->lock, flags);
+	return 0;
+
+exit_close_candev:
+	close_candev(dev);
+exit_free_txdlc:
+	devm_kfree(&dev->dev, priv->txdlc);
+exit_free_echo_skb:
+	devm_kfree(&dev->dev, priv->echo_skb);
+exit_free_dma_buffers:
+	grcan_free_dma_buffers(dev);
+exit_unlock:
+	SPIN_UNLOCK_IRQRESTORE(&priv->lock, flags);
+	return err;
+}
+
+static int grcan_close(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+
+	napi_disable(&priv->napi);
+
+	SPIN_LOCK_IRQSAVE(&priv->lock, flags);
+
+	priv->closing = true;
+	if (priv->need_txbug_workaround) {
+		del_timer_sync(&priv->hang_timer);
+		del_timer_sync(&priv->rr_timer);
+	}
+	netif_stop_queue(dev);
+	grcan_stop(dev);
+
+	SPIN_UNLOCK_IRQRESTORE(&priv->lock, flags);
+
+	devm_free_irq(&dev->dev, dev->irq, (void *)dev);
+	close_candev(dev);
+
+	grcan_free_dma_buffers(dev);
+	priv->can.echo_skb_max = 0;
+	priv->can.echo_skb = NULL;
+	devm_kfree(&dev->dev, priv->echo_skb);
+	devm_kfree(&dev->dev, priv->txdlc);
+
+	return 0;
+}
+
+static int grcan_transmit_catch_up(struct net_device *dev, int budget)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+	int work_done;
+
+	SPIN_LOCK_IRQSAVE(&priv->lock, flags);
+
+	work_done = catch_up_echo_skb(dev, budget, true);
+	if (work_done) {
+		if (!priv->resetting && !priv->closing
+		    && netif_queue_stopped(dev))
+			netif_wake_queue(dev);
+
+		/* With napi we don't get TX interrupts for a while,
+		 * so prevent a running reset while catching up
+		 */
+		if (priv->need_txbug_workaround
+		    && timer_pending(&priv->hang_timer))
+			del_timer(&priv->hang_timer);
+	}
+
+	SPIN_UNLOCK_IRQRESTORE(&priv->lock, flags);
+
+	return work_done;
+}
+
+static int grcan_receive(struct net_device *dev, int budget)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	struct net_device_stats *stats = &dev->stats;
+	struct can_frame *cf;
+	struct sk_buff *skb;
+	u32 wr, rd, startrd;
+	u32 *slot;
+	u32 i, rtr, eff, j, shift;
+	int work_done = 0;
+
+	rd = grcan_read_reg(&regs->rxrd);
+	startrd = rd;
+	for (work_done = 0; work_done < budget; work_done++) {
+		/* Check for packet to receive */
+		wr = grcan_read_reg(&regs->rxwr);
+		if (rd == wr)
+			break;
+
+		/* Take care of packet */
+		skb = alloc_can_skb(dev, &cf);
+		if (skb == NULL) {
+			netdev_dbg(dev,
+				   "dropping frame: skb allocation failed\n");
+			stats->rx_dropped++;
+			continue;
+		}
+
+		slot = dma->rx.buf + rd;
+		eff = slot[0] & GRCAN_MSG_IDE;
+		rtr = slot[0] & GRCAN_MSG_RTR;
+		if (eff) {
+			cf->can_id = ((slot[0] & GRCAN_MSG_EID)
+				      >> GRCAN_MSG_EID_BIT);
+			cf->can_id |= CAN_EFF_FLAG;
+		} else {
+			cf->can_id = ((slot[0] & GRCAN_MSG_BID)
+				      >> GRCAN_MSG_BID_BIT);
+		}
+		cf->can_dlc = get_can_dlc((slot[1] & GRCAN_MSG_DLC)
+					  >> GRCAN_MSG_DLC_BIT);
+		if (rtr) {
+			cf->can_id |= CAN_RTR_FLAG;
+		} else {
+			for (i = 0; i < cf->can_dlc; i++) {
+				j = GRCAN_MSG_DATA_SLOT_INDEX(i);
+				shift = GRCAN_MSG_DATA_SHIFT(i);
+				cf->data[i] = (u8)((slot[j] >> shift) & 0xff);
+			}
+		}
+		netif_receive_skb(skb);
+
+		/* Update statistics and read pointer */
+		stats->rx_packets++;
+		stats->rx_bytes += cf->can_dlc;
+		rd = grcan_ring_add(rd, GRCAN_MSG_SIZE, dma->rx.size);
+	}
+
+	/* Make sure everything is read before allowing hardware to
+	 * use the memory
+	 */
+	mb();
+
+	/* Update read pointer - no need to check for ongoing */
+	if (likely(rd != startrd))
+		grcan_write_reg(&regs->rxrd, rd);
+
+	return work_done;
+}
+
+static int grcan_poll(struct napi_struct *napi, int budget)
+{
+	struct grcan_priv *priv = container_of(napi, struct grcan_priv, napi);
+	struct net_device *dev = priv->dev;
+	struct grcan_registers __iomem *regs = priv->regs;
+	int rx_work_done = grcan_receive(dev, budget);
+	int tx_work_done = grcan_transmit_catch_up(dev, budget);
+	if (rx_work_done < budget && tx_work_done < budget) {
+		napi_complete(napi);
+		/* Enable tx and rx interrupts again */
+		if (!priv->closing)
+			grcan_set_bits(&regs->imr, GRCAN_IRQ_TX | GRCAN_IRQ_RX);
+	}
+	return rx_work_done;
+}
+
+/* Work tx bug by waiting while for the risky situation to clear. If that fails,
+ * drop a frame in one-shot mode or indicate a busy device otherwise.
+ *
+ * Returns 0 on successful wait. Otherwise it sets *netdev_tx_status to the
+ * value that should be returned by grcan_start_xmit when aborting the xmit.
+ */
+static int grcan_txbug_workaround(struct net_device *dev, struct sk_buff *skb,
+				  u32 txwr, u32 oneshotmode,
+				  netdev_tx_t *netdev_tx_status)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	int i;
+	unsigned long flags;
+
+	/* Wait a while for ongoing to be cleared or read pointer to catch up to
+	 * write pointer. The latter is needed due to a bug in older versions of
+	 * GRCAN in which ONGOING is not cleared properly one-shot mode when a
+	 * transmission fails.
+	 */
+	for (i = 0; i < GRCAN_SHORTWAIT_USECS; i++) {
+		udelay(1);
+		if (!grcan_read_bits(&regs->txctrl, GRCAN_TXCTRL_ONGOING)
+		    || grcan_read_reg(&regs->txrd) == txwr) {
+			return 0;
+		}
+	}
+
+	/* Clean up, in case the situation was not resolved */
+	SPIN_LOCK_IRQSAVE(&priv->lock, flags);
+	if (!priv->resetting && !priv->closing) {
+		/* Queue might have been stopped earlier in grcan_start_xmit */
+		if (grcan_txspace(dma->tx.size, txwr, priv->eskbp))
+			if (netif_queue_stopped(dev))
+				netif_wake_queue(dev);
+		/* Set a timer to resolve a hanged tx controller */
+		if (!timer_pending(&priv->hang_timer))
+			grcan_reset_timer(&priv->hang_timer,
+					  priv->can.bittiming.bitrate);
+	}
+	SPIN_UNLOCK_IRQRESTORE(&priv->lock, flags);
+
+	if (oneshotmode) {
+		/* In one-shot mode we should never end up here because
+		 * then the interrupt handler increases txrd on TXLOSS,
+		 * but it is consistent with one-shot mode to drop the
+		 * frame in this case.
+		 */
+		kfree_skb(skb);
+		*netdev_tx_status = NETDEV_TX_OK;
+	} else {
+		/* In normal mode the socket-can transmission queue get
+		 * to keep the frame so that it can be retransmitted
+		 * later
+		 */
+		*netdev_tx_status = NETDEV_TX_BUSY;
+	}
+	return -EBUSY;
+}
+
+/* Notes on the tx cyclic buffer handling:
+ *
+ * regs->txwr	- the next slot for the driver to put data to be sent
+ * regs->txrd	- the next slot for the device to read data
+ * priv->eskbp	- the next slot for the driver to call can_put_echo_skb for
+ *
+ * grcan_start_xmit can enter more messages as long as regs->txwr does
+ * not reach priv->eskbp (within 1 message gap)
+ *
+ * The device sends messages until regs->txrd reaches regs->txwr
+ *
+ * The interrupt calls handler calls can_put_echo_skb until
+ * priv->eskbp reaches regs->txrd
+ */
+static netdev_tx_t grcan_start_xmit(struct sk_buff *skb,
+				    struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	struct can_frame *cf = (struct can_frame *)skb->data;
+	u32 id, txwr, txrd, space, txctrl;
+	int slotindex;
+	u32 *slot;
+	u32 i, rtr, eff, dlc, tmp, err;
+	int j, shift;
+	unsigned long flags;
+	u32 oneshotmode = priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT;
+
+	if (can_dropped_invalid_skb(dev, skb))
+		return NETDEV_TX_OK;
+
+	/* Trying to transmit in silent mode will generate error interrupts */
+	if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
+		return NETDEV_TX_BUSY;
+
+	/* Reads of priv->eskbp and shut-downs of the queue needs to
+	 * be atomic towards the updates to priv->eskbp and wake-ups
+	 * of the queue in the interrupt handler.
+	 */
+	SPIN_LOCK_IRQSAVE(&priv->lock, flags);
+
+	txwr = grcan_read_reg(&regs->txwr);
+	space = grcan_txspace(dma->tx.size, txwr, priv->eskbp);
+
+	slotindex = txwr / GRCAN_MSG_SIZE;
+	slot = dma->tx.buf + txwr;
+
+	if (unlikely(space == 1))
+		netif_stop_queue(dev);
+
+	SPIN_UNLOCK_IRQRESTORE(&priv->lock, flags);
+	/* End of critical section*/
+
+	/* This should never happen. If circular buffer is full, the
+	 * netif_stop_queue should have been stopped already.
+	 */
+	if (unlikely(!space)) {
+		netdev_err(dev, "No buffer space, but queue is non-stopped.\n");
+		return NETDEV_TX_BUSY;
+	}
+
+	/* Convert and write CAN message to DMA buffer */
+	eff = cf->can_id & CAN_EFF_FLAG;
+	rtr = cf->can_id & CAN_RTR_FLAG;
+	id  = cf->can_id & (eff ? CAN_EFF_MASK : CAN_SFF_MASK);
+	dlc = cf->can_dlc;
+	if (eff)
+		tmp = (id << GRCAN_MSG_EID_BIT) & GRCAN_MSG_EID;
+	else
+		tmp = (id << GRCAN_MSG_BID_BIT) & GRCAN_MSG_BID;
+	slot[0] = (eff ? GRCAN_MSG_IDE : 0) | (rtr ? GRCAN_MSG_RTR : 0) | tmp;
+
+	slot[1] = ((dlc << GRCAN_MSG_DLC_BIT) & GRCAN_MSG_DLC);
+	slot[2] = 0;
+	slot[3] = 0;
+	for (i = 0; i < dlc; i++) {
+		j = GRCAN_MSG_DATA_SLOT_INDEX(i);
+		shift = GRCAN_MSG_DATA_SHIFT(i);
+		slot[j] |= cf->data[i] << shift;
+	}
+
+	/* Checking that channel has not been disabled. These cases
+	 * should never happen
+	 */
+	txctrl = grcan_read_reg(&regs->txctrl);
+	if (!(txctrl & GRCAN_TXCTRL_ENABLE))
+		netdev_err(dev, "tx channel spuriously disabled\n");
+
+	if (oneshotmode && !(txctrl & GRCAN_TXCTRL_SINGLE))
+		netdev_err(dev, "one-shot mode spuriously disabled\n");
+
+	/* Bug workaround for old version of grcan where updating txwr
+	 * in the same clock cycle as the controller updates txrd to
+	 * the current txwr could hang the can controller
+	 */
+	if (priv->need_txbug_workaround) {
+		txrd = grcan_read_reg(&regs->txrd) ;
+		if (unlikely(grcan_ring_sub(txwr, txrd, dma->tx.size) == 1)) {
+			netdev_tx_t txstatus;
+			err = grcan_txbug_workaround(dev, skb, txwr,
+						     oneshotmode, &txstatus);
+			if (err)
+				return txstatus;
+		}
+	}
+
+	/* Prepare skb for echoing. This must be after the bug workaround above
+	 * as ownership of the skb is passed on by calling can_put_echo_skb.
+	 * Returning NETDEV_TX_BUSY or accessing skb or cf after a call to
+	 * can_put_echo_skb would be an error unless other measures are
+	 * taken.
+	 */
+	priv->txdlc[slotindex] = cf->can_dlc; /* Store dlc for statistics */
+	can_put_echo_skb(skb, dev, slotindex);
+
+	/* Make sure everything is written before allowing hardware to
+	 * read from the memory
+	 */
+	wmb();
+
+	/* Update write pointer to start transmission */
+	grcan_write_reg(&regs->txwr,
+			grcan_ring_add(txwr, GRCAN_MSG_SIZE, dma->tx.size));
+
+	return NETDEV_TX_OK;
+}
+
+
+/* ========== Setting up sysfs interface and module parameters  ========== */
+
+
+#define GRCAN_NOT_BOOL(val) ((val) < 0 || (val) > 1)
+
+#define GRCAN_MODULE_PARAM(name, mtype, valcheckf)			\
+	static void grcan_sanitize_##name(struct platform_device *pd)	\
+	{								\
+		struct grcan_device_config grcan_default_config		\
+			= GRCAN_DEFAULT_DEVICE_CONFIG;			\
+		if (valcheckf(grcan_module_config.name)) {		\
+			dev_err(&pd->dev,				\
+				"Invalid module parameter value for "	\
+				#name " - setting default\n");		\
+			grcan_module_config.name =			\
+				grcan_default_config.name;		\
+		}							\
+	}								\
+	module_param_named(name, grcan_module_config.name,		\
+			   mtype, S_IRUGO)
+
+#define GRCAN_CONFIG_ATTR(name)						\
+	static ssize_t grcan_store_##name(struct device *sdev,		\
+					  struct device_attribute *att,	\
+					  const char *buf,		\
+					  size_t count)			\
+	{								\
+		struct net_device *dev = to_net_dev(sdev);		\
+		struct grcan_priv *priv = netdev_priv(dev);		\
+		u8 val;							\
+		int ret;						\
+		if (dev->flags & IFF_UP)				\
+			return -EBUSY;					\
+		ret = kstrtou8(buf, 0, &val);				\
+		if (ret < 0 || val < 0 || val > 1)			\
+			return -EINVAL;					\
+		priv->config.name = val;				\
+		return count;						\
+	}								\
+	static ssize_t grcan_show_##name(struct device *sdev,		\
+					 struct device_attribute *att,	\
+					 char *buf)			\
+	{								\
+		struct net_device *dev = to_net_dev(sdev);		\
+		struct grcan_priv *priv = netdev_priv(dev);		\
+		return sprintf(buf, "%d\n", priv->config.name);		\
+	}								\
+	static DEVICE_ATTR(name, S_IRUGO | S_IWUSR,			\
+			   grcan_show_##name,				\
+			   grcan_store_##name);				\
+	GRCAN_MODULE_PARAM(name, ushort, GRCAN_NOT_BOOL)
+
+/* The following configuration options are made available both via module
+ * parameters and writable sysfs files. See the chapter about GRCAN in the
+ * documentation for the GRLIB VHDL library for further details.
+ */
+
+/* Configure enable0 - Configuration for interface 0. */
+GRCAN_CONFIG_ATTR(enable0);
+
+/* Configure enable1 - Configuration for interface 0  */
+GRCAN_CONFIG_ATTR(enable1);
+
+/* Configure selection - Selection on which interface to use */
+GRCAN_CONFIG_ATTR(selection);
+
+
+/* The following configuration options are only available via module
+ * parameters.
+ */
+
+/* Configure size of tx buffer */
+GRCAN_MODULE_PARAM(txsize, uint, GRCAN_INVALID_BUFFER_SIZE);
+
+/* Configure size of rx buffer */
+GRCAN_MODULE_PARAM(rxsize, uint, GRCAN_INVALID_BUFFER_SIZE);
+
+
+/* Function that makes sure that configuration done using
+ * module parameters are set to valid values
+ */
+static void grcan_sanitize_module_config(struct platform_device *ofdev)
+{
+	grcan_sanitize_enable0(ofdev);
+	grcan_sanitize_enable1(ofdev);
+	grcan_sanitize_selection(ofdev);
+	grcan_sanitize_txsize(ofdev);
+	grcan_sanitize_rxsize(ofdev);
+}
+
+static const struct attribute *const sysfs_grcan_attrs[] = {
+	/* Config attrs */
+	&dev_attr_enable0.attr,
+	&dev_attr_enable1.attr,
+	&dev_attr_selection.attr,
+	NULL,
+};
+
+static const struct attribute_group sysfs_grcan_group = {
+	.name = "grcan",
+	.attrs = (struct attribute **)sysfs_grcan_attrs,
+};
+
+
+/* ========== Setting up the driver ========== */
+
+static const struct net_device_ops grcan_netdev_ops = {
+	.ndo_open               = grcan_open,
+	.ndo_stop               = grcan_close,
+	.ndo_start_xmit         = grcan_start_xmit,
+};
+
+static int grcan_setup_netdev(struct platform_device *ofdev,
+			      void __iomem *base,
+			      int irq, u32 ambafreq, bool txbug)
+{
+	struct net_device *dev;
+	struct grcan_priv *priv;
+	struct grcan_registers __iomem *regs;
+	int err;
+
+	dev = alloc_candev(sizeof(struct grcan_priv), 0);
+	if (!dev)
+		return -ENOMEM;
+
+	dev->irq = irq;
+	dev->flags |= IFF_ECHO;
+	dev->netdev_ops = &grcan_netdev_ops;
+	dev->sysfs_groups[0] = &sysfs_grcan_group;
+
+	priv = netdev_priv(dev);
+	memcpy(&priv->config, &grcan_module_config,
+	       sizeof(struct grcan_device_config));
+	priv->dev = dev;
+	priv->regs = (struct grcan_registers *) base;
+	priv->can.bittiming_const     = &grcan_bittiming_const;
+	priv->can.do_set_bittiming    = grcan_set_bittiming;
+	priv->can.do_set_mode         = grcan_set_mode;
+	priv->can.do_get_berr_counter = grcan_get_berr_counter;
+	priv->can.clock.freq          = ambafreq;
+	priv->can.ctrlmode_supported  =
+		CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_ONE_SHOT;
+	priv->need_txbug_workaround = txbug;
+
+	spin_lock_init(&priv->lock);
+
+	if (priv->need_txbug_workaround) {
+		init_timer(&priv->rr_timer);
+		priv->rr_timer.function = grcan_running_reset;
+		priv->rr_timer.data = (unsigned long)dev;
+
+		init_timer(&priv->hang_timer);
+		priv->hang_timer.function = grcan_initiate_running_reset;
+		priv->hang_timer.data = (unsigned long)dev;
+	}
+
+	netif_napi_add(dev, &priv->napi, grcan_poll, GRCAN_NAPI_WEIGHT);
+
+	SET_NETDEV_DEV(dev, &ofdev->dev);
+	regs = priv->regs;
+	dev_info(&ofdev->dev,
+		 "regs=0x%p, irq=%d, clock=%d\n",
+		 priv->regs, dev->irq, priv->can.clock.freq);
+
+	err = register_candev(dev);
+	if (err) {
+		dev_err(&ofdev->dev, "registering %s failed (err=%d)\n",
+			DRV_NAME, err);
+		goto exit_free_candev;
+	}
+	dev_set_drvdata(&ofdev->dev, dev);
+
+	/* Reset device to allow bit-timing to be set. No need to call
+	 * grcan_reset at this stage. That is done in grcan_open.
+	 */
+	grcan_write_reg(&regs->ctrl, GRCAN_CTRL_RESET);
+
+	return 0;
+exit_free_candev:
+	free_candev(dev);
+	return err;
+}
+
+static int __devinit grcan_probe(struct platform_device *ofdev)
+{
+	struct device_node *np = ofdev->dev.of_node;
+	struct resource *res;
+	u32 sysid, ambafreq;
+	int irq, err;
+	void __iomem *base;
+	bool txbug = true;
+
+	/* Compare GRLIB version number with the first that does not
+	 * have the tx bug (see start_xmit)
+	 */
+	err = of_property_read_u32(np, "systemid", &sysid);
+	if (!err && ((sysid & GRLIB_VERSION_MASK)
+		     >= GRCAN_TXBUG_SAFE_GRLIB_VERSION))
+		txbug = false;
+
+	err = of_property_read_u32(np, "freq", &ambafreq);
+	if (err) {
+		dev_err(&ofdev->dev, "unable to fetch \"freq\" property\n");
+		goto exit_error;
+	}
+
+	res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
+	base = devm_request_and_ioremap(&ofdev->dev, res);
+	if (!base) {
+		dev_err(&ofdev->dev, "couldn't map IO resource\n");
+		err = -EADDRNOTAVAIL;
+		goto exit_error;
+	}
+
+	irq = irq_of_parse_and_map(np, GRCAN_IRQIX_IRQ);
+	if (irq == NO_IRQ) {
+		dev_err(&ofdev->dev, "no irq found\n");
+		err = -ENODEV;
+		goto exit_error;
+	}
+
+	grcan_sanitize_module_config(ofdev);
+
+	err = grcan_setup_netdev(ofdev, base, irq, ambafreq, txbug);
+	if (err)
+		goto exit_dispose_irq;
+
+	return 0;
+
+exit_dispose_irq:
+	irq_dispose_mapping(irq);
+exit_error:
+	dev_err(&ofdev->dev,
+		"%s socket CAN driver initialization failed with error %d\n",
+		DRV_NAME, err);
+	return err;
+}
+
+static  int __devexit grcan_remove(struct platform_device *ofdev)
+{
+	struct net_device *dev = dev_get_drvdata(&ofdev->dev);
+	struct grcan_priv *priv = netdev_priv(dev);
+
+	unregister_candev(dev); /* Will in turn call grcan_close */
+
+	irq_dispose_mapping(dev->irq);
+	dev_set_drvdata(&ofdev->dev, NULL);
+	netif_napi_del(&priv->napi);
+	free_candev(dev);
+
+	dev_info(&ofdev->dev, "%s socket CAN driver removed\n", DRV_NAME);
+	return 0;
+}
+
+static struct of_device_id grcan_match[] = {
+	{.name = "GAISLER_GRCAN"},
+	{.name = "01_03d"},
+	{.name = "GAISLER_GRHCAN"},
+	{.name = "01_034"},
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, grcan_match);
+
+static struct platform_driver grcan_driver = {
+	.driver = {
+		.name = DRV_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = grcan_match,
+	},
+	.probe = grcan_probe,
+	.remove = __devexit_p(grcan_remove),
+};
+
+module_platform_driver(grcan_driver);
+
+MODULE_AUTHOR("Aeroflex Gaisler AB.");
+MODULE_DESCRIPTION("Socket CAN driver for Aeroflex Gaisler GRCAN");
+MODULE_LICENSE("GPL");
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* Re: [PATCH v2] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-10-24 13:31         ` Andreas Larsson
  2012-10-30  9:06           ` [PATCH v3] " Andreas Larsson
@ 2012-10-30  9:29           ` Wolfgang Grandegger
  1 sibling, 0 replies; 41+ messages in thread
From: Wolfgang Grandegger @ 2012-10-30  9:29 UTC (permalink / raw)
  To: Andreas Larsson; +Cc: linux-can, mkl, devicetree-discuss, software

Hi Andreas,

sorry for late answer. Other duties are keeping me busy. Your v3
triggered a closer look...

On 10/24/2012 03:31 PM, Andreas Larsson wrote:
> On 10/23/2012 06:26 PM, Wolfgang Grandegger wrote:
>> Hi,
>>
>> before I have a closer look I have some general questions, especially
>> about the heavy usage of SysFS for configuring the IP core module.
>> Generally, we are not allowed to use SysFS for CAN device configuration.
>>
>> - Why may the user want to configure the resources on a per device base?
> 
> The GRCAN core supports selecting between two different hardware
> interfaces. The parameters output0, output1 and selection configures
> these interfaces and selects which one to use. This can not be done in
> general. For output0 and output1 what value means what depends on what
> hardware is connected to the core. If a board has many GRCAN cores they
> might need different settings for these variables. In addition,
> switching between the two hardware interfaces is something that might be
> wanted to be done at runtime.
> 
> For the others module level configuration would work fine.

OK.

>
>> - Aren't there good default values which work just fine for 99% of the
>>   users?
>
> For output0, output1 and selection, the answer is no due to the reasons
> pointed out above. For the bpr and buffer sizes, that is probably
true.

OK, reducing the number of SysFS files to a really useful number (for
end users) would be nice.

...

>>> +What:        /sys/class/net/<iface>/grcan/rxmask
>>> +Date:        October 2012
>>> +KernelVersion:    3.8
>>> +Contact:    Andreas Larsson<andreas@gaisler.com>
>>> +Description:
>>> +        Configures the rxmask of the hardware filter. Received messages
>>> +        for which ((message_id ^ rxcode) & rxmask) != 0 holds will be
>>> +        filtered out in harware. Possible values in [0, 0x1fffffff].
>>> +        The default value is set by the module parameter rxmask and can
>>> +        be read at /sys/module/grcan/parameters/rxmask.
>>
>> Hardware filters should definitely not be defined via SysFS. We do not
>> have an interface yet, mainly because it does not fit into a multi user
>> concept. Anyway, we need such an interface *sooner* than later. Needs
>> some further thoughts.
> 
> OK, I'll get rid of that then and wait for such an interface in the
> future. It would be a pity if hardware filtering, that is a feature that
> would probably be used on an embedded system without multiple users,
> could never be realized because of the socket interface being a multi
> user concept. If root is the only one that can set it up it should be
> fine in my opinion. Nevertheless, I totally agree that a well defined
> API to enable it would be much nicer than going through SysFS.

Yes, we definitely need a generic interface to support hardware filters.
I put it on top of my Linux-CAN-TODO-List.


>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/net/can/grcan.txt
>>> @@ -0,0 +1,27 @@
>>> +CAN controller for Aeroflex Gaisler GRCAN and GRHCAN.
>>> +
>>> +The GRCAN and CRHCAN CAN controllers are available in the GRLIB VHDL
>>> IP core
>>> +library.
>>> +
>>> +Note: These properties are built from the AMBA plug&play in a Leon
>>> SPARC
>>> +system (the ordinary environment for GRCAN and GRHCAN). There are no
>>> bsp
>>> +files for sparc.
>>> +
>>> +Required properties:
>>> +
>>> +- name : Should be "GAISLER_GRCAN", "01_03d", "GAISLER_GRHCAN" or
>>> "01_034"
>>
>> A name should be "vendor,device", e.g. gaisler,grcan. It's also unusual
>> to add release numbers. Also, you do not distinguish between the devices
>> above. Then, just use one name and the others are compatible to that one
>> (even if they are named differently). Well, I realized that the device
>> tree police is less strict than it was 1..2 years ago... anyway, please
>> have a look to the many examples around, also for CAN.
> 
> As I stated in the file, there are no bsp files for sparc. The device
> trees are generated by a boot loader or a prom. For a leon sparc system
> the boot loader gets information from the hardware, the AMBA plug&play,
> and generates the device trees accordingly.

Ah, the system uses good old classic OpenFirmware. Sorry, I missed that.
This makes a lot of my questions obsolete.




^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v3] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-10-30  9:06           ` [PATCH v3] " Andreas Larsson
@ 2012-10-30 10:07             ` Wolfgang Grandegger
  2012-10-30 16:24               ` Andreas Larsson
  0 siblings, 1 reply; 41+ messages in thread
From: Wolfgang Grandegger @ 2012-10-30 10:07 UTC (permalink / raw)
  To: Andreas Larsson
  Cc: linux-can, Marc Kleine-Budde, devicetree-discuss, software

Finally, here come my review. As I'm at it I'm also reporting coding
style issues.

On 10/30/2012 10:06 AM, Andreas Larsson wrote:
> This driver supports GRCAN and CRHCAN CAN controllers available in the GRLIB
> VHDL IP core library.
> 
> Signed-off-by: Andreas Larsson <andreas@gaisler.com>
> ---
>  Documentation/ABI/testing/sysfs-class-net-grcan    |   35 +
>  .../devicetree/bindings/net/can/grcan.txt          |   27 +
>  Documentation/kernel-parameters.txt                |   25 +
>  drivers/net/can/Kconfig                            |    9 +
>  drivers/net/can/Makefile                           |    1 +
>  drivers/net/can/grcan.c                            | 1616 ++++++++++++++++++++
>  6 files changed, 1713 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/ABI/testing/sysfs-class-net-grcan
>  create mode 100644 Documentation/devicetree/bindings/net/can/grcan.txt
>  create mode 100644 drivers/net/can/grcan.c
> 
> diff --git a/Documentation/ABI/testing/sysfs-class-net-grcan b/Documentation/ABI/testing/sysfs-class-net-grcan
> new file mode 100644
> index 0000000..8fa2f90
> --- /dev/null
> +++ b/Documentation/ABI/testing/sysfs-class-net-grcan
> @@ -0,0 +1,35 @@
> +
> +What:		/sys/class/net/<iface>/grcan/enable0
> +Date:		October 2012
> +KernelVersion:	3.8
> +Contact:	Andreas Larsson <andreas@gaisler.com>
> +Description:
> +		Hardware configuration of physical interface 0. This file reads
> +		and writes the "Enable 0" bit of the configuration register.
> +		Possible values: 0 or 1. See the GRCAN chapter of the GRLIB IP
> +		core library documentation for details.
> +		The default value is set by the module parameter enable0 and can
> +		be read at /sys/module/grcan/parameters/enable0.
> +
> +What:		/sys/class/net/<iface>/grcan/enable1
> +Date:		October 2012
> +KernelVersion:	3.8
> +Contact:	Andreas Larsson <andreas@gaisler.com>
> +Description:
> +		Hardware configuration of physical interface 1. This file reads
> +		and writes the "Enable 1" bit of the configuration register.
> +		Possible values: 0 or 1. See the GRCAN chapter of the GRLIB IP
> +		core library documentation for details.
> +		The default value is set by the module parameter enable1 and can
> +		be read at /sys/module/grcan/parameters/enable1.
> +
> +What:		/sys/class/net/<iface>/grcan/selection
> +Date:		October 2012
> +KernelVersion:	3.8
> +Contact:	Andreas Larsson <andreas@gaisler.com>
> +Description:
> +		Configuration of which physical interface to be used. Possible
> +		values: 0 or 1. See the GRCAN chapter of the GRLIB IP core
> +		library documentation for details.
> +		The default value is set by the module parameter selection and can
> +		be read at /sys/module/grcan/parameters/selection.
> diff --git a/Documentation/devicetree/bindings/net/can/grcan.txt b/Documentation/devicetree/bindings/net/can/grcan.txt
> new file mode 100644
> index 0000000..a7180f1
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/can/grcan.txt
> @@ -0,0 +1,27 @@
> +CAN controller for Aeroflex Gaisler GRCAN and GRHCAN.
> +
> +The GRCAN and CRHCAN CAN controllers are available in the GRLIB VHDL IP core
> +library.
> +
> +Note: These properties are built from the AMBA plug&play in a Leon SPARC
> +system (the ordinary environment for GRCAN and GRHCAN). There are no bsp
> +files for sparc.
> +
> +Required properties:
> +
> +- name : Should be "GAISLER_GRCAN", "01_03d", "GAISLER_GRHCAN" or "01_034"
> +
> +- reg : Address and length of the register set for the device
> +
> +- freq : Frequency of the external oscillator clock in Hz (the frequency of
> +	the amba bus in the ordinary case)
> +
> +- interrupts : Interrupt number for this device
> +
> +Optional properties:
> +
> +- systemid : If not present or if the value of the least significant 16 bits
> +	of this 32-bit property is smaller than GRCAN_TXBUG_SAFE_GRLIB_VERSION
> +	a bug workaround is activated.
> +
> +For further information look in the documentation for the GLIB IP core library.
> diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
> index 9776f06..3a82433 100644
> --- a/Documentation/kernel-parameters.txt
> +++ b/Documentation/kernel-parameters.txt
> @@ -905,6 +905,31 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
>  	gpt		[EFI] Forces disk with valid GPT signature but
>  			invalid Protective MBR to be treated as GPT.
>  
> +	grcan.enable0=	[HW] The "Enable 0" bit of the configuration
> +			register. For more documentation, see
> +			Documentation/ABI/testing/sysfs-class-net-grcan
> +			Format: 0 | 1
> +			Default: 0
> +	grcan.enable1=	[HW] The "Enable 1" bit of the configuration
> +			register. For more documentation, see
> +			Documentation/ABI/testing/sysfs-class-net-grcan.
> +			Format: 0 | 1
> +			Default: 0
> +	grcan.selection=
> +			[HW] Selection of which physical interface to be
> +			used. For more documentation, see
> +			Documentation/ABI/testing/sysfs-class-net-grcan.
> +			Format: 0 | 1
> +			Default: 0
> +	grcan.txsize=	[HW] The size of the tx buffer. For more documentation,
> +			see Documentation/ABI/testing/sysfs-class-net-grcan.
> +			Format: <value> such that (value & 0x1fffc0) == 0.
> +			Default: 1024
> +	grcan.rxsize=	[HW] The size of the rx buffer. For more documentation,
> +			see Documentation/ABI/testing/sysfs-class-net-grcan.
> +			Format: <value> such that (value & 0x1fffc0) == 0.
> +			Default: 1024
> +
>  	hashdist=	[KNL,NUMA] Large hashes allocated during boot
>  			are distributed across NUMA nodes.  Defaults on
>  			for 64-bit NUMA, off otherwise.
> diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
> index bb709fd..b56bd9e 100644
> --- a/drivers/net/can/Kconfig
> +++ b/drivers/net/can/Kconfig
> @@ -110,6 +110,15 @@ config PCH_CAN
>  	  is an IOH for x86 embedded processor (Intel Atom E6xx series).
>  	  This driver can access CAN bus.
>  
> +config CAN_GRCAN
> +	tristate "Aeroflex Gaisler GRCAN and GRHCAN CAN devices"
> +	depends on CAN_DEV && OF
> +	---help---
> +	  Say Y here if you want to use Aeroflex Gaisler GRCAN or GRHCAN.
> +	  Note that the driver supports little endian, even though little
> +	  endian syntheses of the cores would need some modifications on
> +	  the hardware level to work.
> +
>  source "drivers/net/can/mscan/Kconfig"
>  
>  source "drivers/net/can/sja1000/Kconfig"
> diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
> index 938be37..7de5986 100644
> --- a/drivers/net/can/Makefile
> +++ b/drivers/net/can/Makefile
> @@ -22,5 +22,6 @@ obj-$(CONFIG_CAN_BFIN)		+= bfin_can.o
>  obj-$(CONFIG_CAN_JANZ_ICAN3)	+= janz-ican3.o
>  obj-$(CONFIG_CAN_FLEXCAN)	+= flexcan.o
>  obj-$(CONFIG_PCH_CAN)		+= pch_can.o
> +obj-$(CONFIG_CAN_GRCAN)		+= grcan.o
>  
>  ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
> diff --git a/drivers/net/can/grcan.c b/drivers/net/can/grcan.c
> new file mode 100644
> index 0000000..201914c
> --- /dev/null
> +++ b/drivers/net/can/grcan.c
> @@ -0,0 +1,1616 @@
> +/*
> + * Socket CAN driver for Aeroflex Gaisler GRCAN and GRHCAN.
> + *
> + * 2012 (c) Aeroflex Gaisler AB
> + *
> + * This driver supports GRCAN and CRHCAN CAN controllers available in the GRLIB
> + * VHDL IP core library.
> + *
> + * Full documentation of the GRCAN core can be found here:
> + * http://www.gaisler.com/products/grlib/grip.pdf
> + *
> + * See "Documentation/devicetree/bindings/net/can/grcan.txt" for information on
> + * open firmware properties.
> + *
> + * See "Documentation/ABI/testing/sysfs-class-net-grcan" for information on the
> + * sysfs interface.
> + *
> + * See "Documentation/kernel-parameters.txt" for information on the module
> + * parameters.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as published by the
> + * Free Software Foundation; either version 2 of the License, or (at your
> + * option) any later version.
> + *
> + * Contributors: Andreas Larsson <andreas@gaisler.com>
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/interrupt.h>
> +#include <linux/netdevice.h>
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/can/dev.h>
> +#include <linux/spinlock.h>
> +
> +#include <linux/of_platform.h>
> +#include <asm/prom.h>
> +
> +#include <linux/of_irq.h>
> +
> +#include <linux/dma-mapping.h>
> +
> +#define DRV_NAME "grcan"
> +
> +#define GRCAN_NAPI_WEIGHT	16
> +
> +#define GRCAN_RESERVE_SIZE(slot1, slot2) (((slot2) - (slot1)) / 4 - 1)
> +
> +#define SPIN_LOCK(lock)						\
> +	do { spin_lock(lock); priv->holder = __LINE__; } while (0)
> +#define SPIN_LOCK_IRQSAVE(lock, flags)					\
> +	do {spin_lock_irqsave(lock, flags); priv->holder = __LINE__; } while (0)
> +#define SPIN_UNLOCK(lock)					\
> +	do { priv->holder = 0; spin_unlock(lock); } while (0)
> +#define SPIN_UNLOCK_IRQRESTORE(lock, flags)				\
> +	do { priv->holder = 0; spin_unlock_irqrestore(lock, flags); } while (0)

What are the macro definitions good for? Please remove them?

> +
> +struct grcan_registers {
> +	u32 conf;	/* 0x00 */
> +	u32 stat;	/* 0x04 */
> +	u32 ctrl;	/* 0x08 */
> +	u32 __reserved1[GRCAN_RESERVE_SIZE(0x08, 0x18)];
> +	u32 smask;	/* 0x18 - CanMASK */
> +	u32 scode;	/* 0x1c - CanCODE */
> +	u32 __reserved2[GRCAN_RESERVE_SIZE(0x1c, 0x100)];
> +	u32 pimsr;	/* 0x100 */
> +	u32 pimr;	/* 0x104 */
> +	u32 pisr;	/* 0x108 */
> +	u32 pir;	/* 0x10C */
> +	u32 imr;	/* 0x110 */
> +	u32 picr;	/* 0x114 */
> +	u32 __reserved3[GRCAN_RESERVE_SIZE(0x114, 0x200)];
> +	u32 txctrl;	/* 0x200 */
> +	u32 txaddr;	/* 0x204 */
> +	u32 txsize;	/* 0x208 */
> +	u32 txwr;	/* 0x20C */
> +	u32 txrd;	/* 0x210 */
> +	u32 txirq;	/* 0x214 */
> +	u32 __reserved4[GRCAN_RESERVE_SIZE(0x214, 0x300)];
> +	u32 rxctrl;	/* 0x300 */
> +	u32 rxaddr;	/* 0x304 */
> +	u32 rxsize;	/* 0x308 */
> +	u32 rxwr;	/* 0x30C */
> +	u32 rxrd;	/* 0x310 */
> +	u32 rxirq;	/* 0x314 */
> +	u32 rxmask;	/* 0x318 */
> +	u32 rxcode;	/* 0x31C */
> +};

Using a struct is nice!

> +#define GRCAN_CONF_ABORT      0x00000001
> +#define GRCAN_CONF_ENABLE0    0x00000002
> +#define GRCAN_CONF_ENABLE1    0x00000004
> +#define GRCAN_CONF_SELECTION  0x00000008
> +#define GRCAN_CONF_SILENT     0x00000010
> +#define GRCAN_CONF_BPR        0x00000300  /* Note: not BRP */
> +#define GRCAN_CONF_RSJ        0x00007000
> +#define GRCAN_CONF_PS1        0x00f00000
> +#define GRCAN_CONF_PS2        0x000f0000
> +#define GRCAN_CONF_SCALER     0xff000000
> +#define GRCAN_CONF_OPERATION						\
> +	(GRCAN_CONF_ABORT | GRCAN_CONF_ENABLE0 | GRCAN_CONF_ENABLE1	\
> +	 | GRCAN_CONF_SELECTION | GRCAN_CONF_SILENT)
> +#define GRCAN_CONF_TIMING						\
> +	(GRCAN_CONF_BPR | GRCAN_CONF_RSJ | GRCAN_CONF_PS1		\
> +	 | GRCAN_CONF_PS2 | GRCAN_CONF_SCALER)
> +
> +#define GRCAN_CONF_RSJ_MIN    1
> +#define GRCAN_CONF_RSJ_MAX    4
> +#define GRCAN_CONF_PS1_MIN    1
> +#define GRCAN_CONF_PS1_MAX    15
> +#define GRCAN_CONF_PS2_MIN    2
> +#define GRCAN_CONF_PS2_MAX    8
> +#define GRCAN_CONF_SCALER_MIN 0
> +#define GRCAN_CONF_SCALER_MAX 255
> +#define GRCAN_CONF_SCALER_INC 1
> +
> +#define GRCAN_CONF_BPR_BIT    8
> +#define GRCAN_CONF_RSJ_BIT    12
> +#define GRCAN_CONF_PS1_BIT    20
> +#define GRCAN_CONF_PS2_BIT    16
> +#define GRCAN_CONF_SCALER_BIT 24
> +
> +#define GRCAN_STAT_PASS      0x000001
> +#define GRCAN_STAT_OFF       0x000002
> +#define GRCAN_STAT_OR        0x000004
> +#define GRCAN_STAT_AHBERR    0x000008
> +#define GRCAN_STAT_ACTIVE    0x000010
> +#define GRCAN_STAT_RXERRCNT  0x00ff00
> +#define GRCAN_STAT_TXERRCNT  0xff0000
> +
> +#define GRCAN_STAT_RXERRCNT_BIT  8
> +#define GRCAN_STAT_TXERRCNT_BIT  16
> +
> +#define GRCAN_STAT_ERRCNT_WARNING_LIMIT 96
> +#define GRCAN_STAT_ERRCNT_PASSIVE_LIMIT 127
> +
> +
> +#define GRCAN_CTRL_RESET  0x2
> +#define GRCAN_CTRL_ENABLE 0x1
> +
> +#define GRCAN_TXCTRL_ENABLE  0x1
> +#define GRCAN_TXCTRL_ONGOING 0x2
> +#define GRCAN_TXCTRL_SINGLE  0x4
> +
> +#define GRCAN_RXCTRL_ENABLE  0x1
> +#define GRCAN_RXCTRL_ONGOING 0x2
> +
> +/* Relative offset of IRQ sources to AMBA Plug&Play */
> +#define GRCAN_IRQIX_IRQ    0
> +#define GRCAN_IRQIX_TXSYNC 1
> +#define GRCAN_IRQIX_RXSYNC 2
> +
> +#define GRCAN_IRQ_PASS       0x00001
> +#define GRCAN_IRQ_OFF        0x00002
> +#define GRCAN_IRQ_OR         0x00004
> +#define GRCAN_IRQ_RXAHBERR   0x00008
> +#define GRCAN_IRQ_TXAHBERR   0x00010
> +#define GRCAN_IRQ_RXIRQ      0x00020
> +#define GRCAN_IRQ_TXIRQ      0x00040
> +#define GRCAN_IRQ_RXFULL     0x00080
> +#define GRCAN_IRQ_TXEMPTY    0x00100
> +#define GRCAN_IRQ_RX         0x00200
> +#define GRCAN_IRQ_TX         0x00400
> +#define GRCAN_IRQ_RXSYNC     0x00800
> +#define GRCAN_IRQ_TXSYNC     0x01000
> +#define GRCAN_IRQ_RXERRCTR   0x02000
> +#define GRCAN_IRQ_TXERRCTR   0x04000
> +#define GRCAN_IRQ_RXMISS     0x08000
> +#define GRCAN_IRQ_TXLOSS     0x10000
> +
> +#define GRCAN_IRQ_NONE 0
> +#define GRCAN_IRQ_ALL \
> +(GRCAN_IRQ_PASS | GRCAN_IRQ_OFF | GRCAN_IRQ_OR				\
> +		       | GRCAN_IRQ_RXAHBERR | GRCAN_IRQ_TXAHBERR	\
> +		       | GRCAN_IRQ_RXIRQ | GRCAN_IRQ_TXIRQ		\
> +		       | GRCAN_IRQ_RXFULL | GRCAN_IRQ_TXEMPTY		\
> +		       | GRCAN_IRQ_RX | GRCAN_IRQ_TX | GRCAN_IRQ_RXSYNC \
> +		       | GRCAN_IRQ_TXSYNC | GRCAN_IRQ_RXERRCTR		\
> +		       | GRCAN_IRQ_TXERRCTR | GRCAN_IRQ_RXMISS		\
> +		       | GRCAN_IRQ_TXLOSS)
> +
> +#define GRCAN_IRQ_ERRCTR_RELATED (GRCAN_IRQ_RXERRCTR | GRCAN_IRQ_TXERRCTR \
> +				  | GRCAN_IRQ_PASS | GRCAN_IRQ_OFF)
> +#define GRCAN_IRQ_ERRORS (GRCAN_IRQ_ERRCTR_RELATED | GRCAN_IRQ_OR	\
> +			  | GRCAN_IRQ_TXAHBERR | GRCAN_IRQ_RXAHBERR	\
> +			  | GRCAN_IRQ_TXLOSS)
> +#define GRCAN_IRQ_DEFAULT (GRCAN_IRQ_RX | GRCAN_IRQ_TX | GRCAN_IRQ_ERRORS)
> +
> +#define GRCAN_MSG_SIZE 16
> +
> +#define GRCAN_MSG_IDE 0x80000000
> +#define GRCAN_MSG_RTR 0x40000000
> +#define GRCAN_MSG_BID 0x1ffc0000
> +#define GRCAN_MSG_EID 0x1fffffff
> +#define GRCAN_MSG_IDE_BIT 31
> +#define GRCAN_MSG_RTR_BIT 30
> +#define GRCAN_MSG_BID_BIT 18
> +#define GRCAN_MSG_EID_BIT 0
> +
> +#define GRCAN_MSG_DLC    0xf0000000
> +#define GRCAN_MSG_TXERRC 0x00ff0000
> +#define GRCAN_MSG_RXERRC 0x0000ff00
> +#define GRCAN_MSG_DLC_BIT 28
> +#define GRCAN_MSG_TXERRC_BIT 16
> +#define GRCAN_MSG_RXERRC_BIT 8

Sometimes you align definitions, sometimes not. Please use a consistant
style.

> +#define GRCAN_MSG_AHBERR 0x00000008
> +#define GRCAN_MSG_OR     0x00000004
> +#define GRCAN_MSG_OFF    0x00000002
> +#define GRCAN_MSG_PASS   0x00000001
> +
> +#define GRCAN_MSG_DATA_SLOT_INDEX(i) (2 + (i) / 4)
> +#define GRCAN_MSG_DATA_SHIFT(i) ((3 - (i) % 4) * 8)
> +
> +#define GRCAN_BUFFER_ALIGNMENT 1024
> +#define GRCAN_DEFAULT_BUFFER_SIZE 1024
> +
> +#define GRCAN_VALID_TR_SIZE_MASK 0x001fffc0
> +#define GRCAN_INVALID_BUFFER_SIZE(s)		\
> +	((s) == 0 || ((s) & ~GRCAN_VALID_TR_SIZE_MASK))
> +
> +#if GRCAN_INVALID_BUFFER_SIZE(GRCAN_DEFAULT_BUFFER_SIZE)
> +#error "Invalid default buffer size"
> +#endif
> +
> +struct grcan_dma_buffer {
> +	size_t size;
> +	void *buf;
> +	dma_addr_t handle;
> +};
> +
> +struct grcan_dma {
> +	size_t base_size;
> +	void *base_buf;
> +	dma_addr_t base_handle;
> +	struct grcan_dma_buffer tx;
> +	struct grcan_dma_buffer rx;
> +};
> +
> +/* GRCAN configuration parameters */
> +struct grcan_device_config {
> +	unsigned short enable0;
> +	unsigned short enable1;
> +	unsigned short selection;
> +	unsigned int txsize;
> +	unsigned int rxsize;
> +};
> +
> +#define GRCAN_DEFAULT_DEVICE_CONFIG {			\
> +		.enable0 = 0,				\
> +		.enable1 = 0,				\
> +		.selection = 0,				\
> +		.txsize = GRCAN_DEFAULT_BUFFER_SIZE,	\
> +		.rxsize = GRCAN_DEFAULT_BUFFER_SIZE,	\
> +		}
> +
> +#define GRCAN_TXBUG_SAFE_GRLIB_VERSION 0x4100
> +#define GRLIB_VERSION_MASK 0xffff
> +
> +
> +/* GRCAN private data structure */
> +struct grcan_priv {
> +	struct can_priv can;	/* must be the first member */
> +	struct net_device *dev;
> +	struct napi_struct napi;
> +
> +	struct grcan_registers __iomem *regs; /* ioremap'ed registers */
> +	struct grcan_device_config config;
> +	struct grcan_dma dma;
> +	struct sk_buff **echo_skb;	/* We allocate this on our own */
> +	u32 eskbp;			/* Pointer into echo_skb */
> +	u8 *txdlc;			/* Length of queued frames */
> +	u32 ambafreq;
> +
> +	/* Lock for stopping and waking the netif tx queue and for
> +	 * accesses to eskbp
> +	 */
> +	spinlock_t lock;

What does eskbp mean? Your locking is quite complex and a few word here
woudl be nice.

> +	int holder;
> +
> +	/* Whether a workaround is needed due to a bug in older hardware. */
> +	bool need_txbug_workaround;
> +
> +	/* To trigger initization of running reset and to trigger running reset
> +	 * respectively in the case of a hanged device due to a txbug.
> +	 */
> +	struct timer_list hang_timer;
> +	struct timer_list rr_timer;
> +
> +	/* To avoid waking up the netif queue and restarting timers
> +	 * when a reset is scheduled or when closing of the device is
> +	 * undergoing
> +	 */
> +	bool resetting;
> +	bool closing;
> +};
> +
> +/* Wait time for a short wait for ongoing to clear */
> +#define GRCAN_SHORTWAIT_USECS 10
> +
> +/* Waiting for a time corresponding to transmission of three can frames */
> +#define GRCAN_EFF_FRAME_MAX_BITS (1+32+6+8*8+16+2+7)

You know what it means but for me it's magic. Either be more verbose by
using macro definitons or add more comment or just put the sum.

> +
> +#if defined(__BIG_ENDIAN)
> +static inline u32 grcan_read_reg(u32 __iomem *reg)
> +{
> +	return ioread32be(reg);
> +}
> +
> +static inline void grcan_write_reg(u32 __iomem *reg, u32 val)
> +{
> +	iowrite32be(val, reg);
> +}
> +#else
> +static inline u32 grcan_read_reg(u32 __iomem *reg)
> +{
> +	return ioread32(reg);
> +}
> +
> +static inline void grcan_write_reg(u32 __iomem *reg, u32 val)
> +{
> +	iowrite32(val, reg);
> +}
> +#endif
> +
> +static inline void grcan_clear_bits(u32 __iomem *reg, u32 mask)
> +{
> +	grcan_write_reg(reg, grcan_read_reg(reg) & ~mask);
> +}
> +
> +static inline void grcan_set_bits(u32 __iomem *reg, u32 mask)
> +{
> +	grcan_write_reg(reg, grcan_read_reg(reg) | mask);
> +}
> +
> +static inline u32 grcan_read_bits(u32 __iomem *reg, u32 mask)
> +{
> +	return grcan_read_reg(reg) & mask;
> +}
> +
> +static inline void grcan_write_bits(u32 __iomem *reg, u32 value, u32 mask)
> +{
> +	u32 old = grcan_read_reg(reg);

Empty line please.

> +	grcan_write_reg(reg, (old & ~mask) | (value & mask));
> +}
> +
> +static inline u32 grcan_ring_add(u32 a, u32 b, u32 size)
> +{
> +	u32 sum = a + b;

Ditto.


> +	if (sum < size)
> +		return sum;
> +	else
> +		return sum - size;
> +}
> +
> +static inline u32 grcan_ring_sub(u32 a, u32 b, u32 size)
> +{
> +	u32 diff = a - b;

Ditto.

> +	if (a < b)
> +		return diff + size;
> +	else
> +		return diff;
> +}
> +
> +static inline u32 grcan_txspace(size_t txsize, u32 txwr, u32 eskbp)
> +{
> +	u32 slots = txsize / GRCAN_MSG_SIZE - 1;
> +	u32 used = grcan_ring_sub(txwr, eskbp, txsize);

Ditto.

> +	return slots - used;
> +}
> +
> +/* Configuration parameters that can be set via module parameters */
> +static struct grcan_device_config grcan_module_config =
> +	GRCAN_DEFAULT_DEVICE_CONFIG;
> +
> +static struct can_bittiming_const grcan_bittiming_const = {
> +	.name = DRV_NAME,
> +	.tseg1_min = GRCAN_CONF_PS1_MIN + 1,
> +	.tseg1_max = GRCAN_CONF_PS1_MAX + 1,
> +	.tseg2_min = GRCAN_CONF_PS2_MIN,
> +	.tseg2_max = GRCAN_CONF_PS2_MAX,
> +	.sjw_max   = GRCAN_CONF_RSJ_MAX,
> +	.brp_min   = GRCAN_CONF_SCALER_MIN + 1,
> +	.brp_max   = GRCAN_CONF_SCALER_MAX + 1,
> +	.brp_inc   = GRCAN_CONF_SCALER_INC,
> +};
> +
> +static int grcan_set_bittiming(struct net_device *dev)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	struct can_bittiming *bt = &priv->can.bittiming;
> +	u32 timing = 0;
> +	int bpr, rsj, ps1, ps2, scaler;
> +
> +	/* Should never happen - function will not be called when
> +	 * device is up
> +	 */
> +	if (grcan_read_bits(&regs->ctrl, GRCAN_CTRL_ENABLE))
> +		return -EBUSY;
> +
> +	bpr    = 0; /* Note bpr and brp are different concepts */
> +	rsj    = bt->sjw;
> +	ps1    = (bt->prop_seg + bt->phase_seg1) - 1; /* tseg1-1 */
> +	ps2    = bt->phase_seg2;

Please use just *one* space before and after the "=", here and in other
places as well.

> +	scaler = (bt->brp - 1);
> +	timing |= (bpr << GRCAN_CONF_BPR_BIT) & GRCAN_CONF_BPR;
> +	timing |= (rsj << GRCAN_CONF_RSJ_BIT) & GRCAN_CONF_RSJ;
> +	timing |= (ps1 << GRCAN_CONF_PS1_BIT) & GRCAN_CONF_PS1;
> +	timing |= (ps2 << GRCAN_CONF_PS2_BIT) & GRCAN_CONF_PS2;
> +	timing |= (scaler << GRCAN_CONF_SCALER_BIT) & GRCAN_CONF_SCALER;
> +
> +	dev_info(dev->dev.parent,
> +		 "setting timing=0x%x\n", timing);
> +	grcan_write_bits(&regs->conf, timing, GRCAN_CONF_TIMING);
> +	return 0;
> +}
> +
> +static int grcan_get_berr_counter(const struct net_device *dev,
> +				  struct can_berr_counter *bec)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	u32 status = grcan_read_reg(&regs->stat);

Empty line here and in many other places.

> +	bec->txerr = (status & GRCAN_STAT_TXERRCNT) >> GRCAN_STAT_TXERRCNT_BIT;
> +	bec->rxerr = (status & GRCAN_STAT_RXERRCNT) >> GRCAN_STAT_RXERRCNT_BIT;
> +	return 0;
> +}
> +
> +static int grcan_poll(struct napi_struct *napi, int budget);
> +
> +/* Reset device, but keep timing information */
> +static void grcan_reset(struct net_device *dev)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +

Remove empty line.

> +	u32 timing = grcan_read_bits(&regs->conf, GRCAN_CONF_TIMING);

Add empty line.

> +	grcan_set_bits(&regs->ctrl, GRCAN_CTRL_RESET);
> +	grcan_write_bits(&regs->conf, timing, GRCAN_CONF_TIMING);
> +
> +	priv->eskbp = grcan_read_reg(&regs->txrd);
> +	priv->can.state = CAN_STATE_STOPPED;
> +
> +	/* Turn off hardware filtering - regs->rxcode set to 0 by reset */
> +	grcan_write_reg(&regs->rxmask, 0);
> +}
> +
> +/* stop device without changing any configurations */
> +static void grcan_stop(struct net_device *dev)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;

Ditto.

> +	grcan_write_reg(&regs->imr, GRCAN_IRQ_NONE);
> +	grcan_clear_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
> +	grcan_clear_bits(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
> +	grcan_clear_bits(&regs->ctrl, GRCAN_CTRL_ENABLE);
> +	priv->can.state = CAN_STATE_STOPPED;
> +}
> +
> +/* Let priv->eskp catch up to regs->txrd and echo back the skbs if echo is true
> + * and free them otherwise.
> + *
> + * If budget is >= 0, stop after handling at most budget skbs. Otherwise,
> + * continue until priv->eskp catches up to regs->txrd.
> + *
> + * priv->lock *must* be held when calling this function
> + */
> +static int catch_up_echo_skb(struct net_device *dev, int budget, bool echo)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	struct grcan_dma *dma = &priv->dma;
> +	struct net_device_stats *stats = &dev->stats;
> +	int i, work_done;
> +
> +	/* Updates to priv->eskbp and wake-ups of the queue needs to
> +	 * be atomic towards the reads of priv->eskbp and shut-downs
> +	 * of the queue in grcan_start_xmit.
> +	 */
> +	u32 txrd = grcan_read_reg(&regs->txrd);

Ditto

> +	for (work_done = 0; work_done < budget || budget < 0; work_done++) {
> +		if (priv->eskbp == txrd)
> +			break;
> +		i = priv->eskbp / GRCAN_MSG_SIZE;
> +		if (echo) {
> +			/* Normal echo of messages */
> +			stats->tx_packets++;
> +			stats->tx_bytes += priv->txdlc[i];
> +			priv->txdlc[i] = 0;
> +			can_get_echo_skb(dev, i);
> +		} else {
> +			/* For cleanup of untransmitted messages */
> +			can_free_echo_skb(dev, i);
> +		}
> +
> +		priv->eskbp = grcan_ring_add(priv->eskbp, GRCAN_MSG_SIZE,
> +					     dma->tx.size);
> +		txrd = grcan_read_reg(&regs->txrd);
> +	}
> +	return work_done;
> +}
> +
> +static void grcan_lost_one_shot_frame(struct net_device *dev)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	struct grcan_dma *dma = &priv->dma;
> +	u32 txrd;
> +
> +	SPIN_LOCK(&priv->lock);
> +	priv->holder = 1;
> +
> +	catch_up_echo_skb(dev, -1, true);
> +
> +	if (unlikely(grcan_read_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE))) {
> +		/* Should never happen */
> +		netdev_err(dev, "TXCTRL enabled at TXLOSS in one shot mode\n");
> +	} else {
> +		/* By the time an GRCAN_IRQ_TXLOSS is generated in
> +		 * one-shot mode there is no problem in writing
> +		 * to TXRD even in versions of the hardware in
> +		 * which GRCAN_TXCTRL_ONGOING is not cleared properly
> +		 * in one-shot mode.
> +		 */
> +
> +		/* Skip message and discard echo-skb */
> +		txrd = grcan_read_reg(&regs->txrd);
> +		txrd = grcan_ring_add(txrd, GRCAN_MSG_SIZE, dma->tx.size);
> +		grcan_write_reg(&regs->txrd, txrd);
> +		catch_up_echo_skb(dev, -1, false);
> +
> +		if (!priv->resetting && !priv->closing) {
> +			if (netif_queue_stopped(dev))
> +				netif_wake_queue(dev);

IIRC, netif_wake_queue(dev) can be called directly, Marc? Here and in
other places.

> +			grcan_set_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
> +		}
> +	}
> +
> +	priv->holder = 0;
> +	SPIN_UNLOCK(&priv->lock);
> +}
> +
> +static void grcan_err(struct net_device *dev, u32 sources, u32 status)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct net_device_stats *stats = &dev->stats;
> +	struct can_frame cf;
> +
> +	/* Zero potential error_frame */
> +	memset(&cf, 0, sizeof(cf));
> +
> +	/* Arbitration lost interrupt */
> +	if (sources & GRCAN_IRQ_TXLOSS) {
> +		netdev_dbg(dev,
> +			   "arbitration lost (or other comm failure)\n");

Does fit on one line?

> +		stats->tx_errors++;
> +		priv->can.can_stats.arbitration_lost++;
> +
> +		/* Take care of failed one-shot transmit */
> +		if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT)
> +			grcan_lost_one_shot_frame(dev);
> +
> +		cf.can_id |= CAN_ERR_LOSTARB;
> +	}
> +
> +	/* Conditions dealing with the error counters */
> +	if (sources & GRCAN_IRQ_ERRCTR_RELATED) {
> +		enum can_state state = priv->can.state;
> +		enum can_state oldstate = state;
> +		u32 txerr = (status & GRCAN_STAT_TXERRCNT)
> +			>> GRCAN_STAT_TXERRCNT_BIT;
> +		u32 rxerr = (status & GRCAN_STAT_RXERRCNT)
> +			>> GRCAN_STAT_RXERRCNT_BIT;
> +
> +		if (status & GRCAN_STAT_OFF) {
> +			netdev_dbg(dev, "Bus off condition\n");
> +			state = CAN_STATE_BUS_OFF;
> +			can_bus_off(dev);
> +
> +			cf.can_id |= CAN_ERR_BUSOFF;
> +		} else if (status & GRCAN_STAT_PASS) {
> +			netdev_dbg(dev, "Error passive condition\n");
> +			state = CAN_STATE_ERROR_PASSIVE;
> +			priv->can.can_stats.error_passive++;
> +
> +			cf.can_id |= CAN_ERR_CRTL;
> +			if (txerr >= GRCAN_STAT_ERRCNT_PASSIVE_LIMIT)
> +				cf.data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
> +			if (rxerr >= GRCAN_STAT_ERRCNT_PASSIVE_LIMIT)
> +				cf.data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
> +		} else if (txerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT ||
> +			   rxerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT) {
> +			state = CAN_STATE_ERROR_WARNING;
> +			priv->can.can_stats.error_warning++;
> +			if (oldstate != state)
> +				netdev_dbg(dev, "Error warning condition\n");
> +
> +			cf.can_id |= CAN_ERR_CRTL;
> +			if (txerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT)
> +				cf.data[1] |= CAN_ERR_CRTL_TX_WARNING;
> +			if (rxerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT)
> +				cf.data[1] |= CAN_ERR_CRTL_RX_WARNING;
> +		} else {
> +			state = CAN_STATE_ERROR_ACTIVE;
> +			if (oldstate != state)
> +				netdev_dbg(dev, "Error active condition\n");
> +		}
> +		if (state != CAN_STATE_ERROR_ACTIVE) {
> +			cf.data[6] = txerr;
> +			cf.data[7] = rxerr;
> +		}

The errors are also of interest when the state is still error active.
Therefore please remove the if block.

> +		priv->can.state = state;
> +	}
> +
> +	/* Data overrun interrupt */
> +	if (sources & GRCAN_IRQ_OR) {
> +		netdev_dbg(dev, "got data overrun interrupt\n");
> +		stats->rx_over_errors++;
> +		stats->rx_errors++;
> +
> +		cf.can_id  |= CAN_ERR_CRTL;
> +		cf.data[1] |= CAN_ERR_CRTL_RX_OVERFLOW;
> +	}
> +
> +	/* AHB bus error interrupts (not CAN bus errors) - shut down the
> +	 * device.
> +	 */
> +	if (sources & (GRCAN_IRQ_TXAHBERR | GRCAN_IRQ_RXAHBERR)) {
> +		if (sources & GRCAN_IRQ_TXAHBERR) {
> +			netdev_err(dev, "got AHB bus error on tx\n");
> +			stats->tx_errors++;
> +		} else {
> +			netdev_err(dev, "got AHB bus error on rx\n");
> +			stats->rx_errors++;
> +		}
> +		netdev_err(dev, "halting device\n");
> +
> +		/* Prevent anything to be enabled again and halt device */
> +		SPIN_LOCK(&priv->lock);
> +		priv->closing = true;
> +		netif_stop_queue(dev);
> +		grcan_stop(dev);
> +		SPIN_UNLOCK(&priv->lock);

Hm, does that really happen? How can the user/app realized the problem
and recover?

Furthermore, why is a spin_clock enough here? THe interrupt may run a
thread.

> +	}
> +
> +	/* Pass on error frame if something to report,
> +	 * i.e. id contains some information
> +	 */
> +	if (cf.can_id) {
> +		struct can_frame *skb_cf;
> +		struct sk_buff *skb = alloc_can_err_skb(dev, &skb_cf);

Empty line.

> +		if (skb == NULL)
> +			netdev_dbg(dev, "could not allocate error frame\n");

You don't want to continue in case of error but return?

> +		skb_cf->can_id |= cf.can_id;
> +		memcpy(skb_cf->data, cf.data, sizeof(cf.data));
> +
> +		netif_rx(skb);
> +	}
> +}
> +
> +static irqreturn_t grcan_interrupt(int irq, void *dev_id)
> +{
> +	struct net_device *dev = (struct net_device *)dev_id;
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	u32 sources, status;
> +
> +	/* Find out the source */
> +	sources = grcan_read_reg(&regs->pimsr);
> +	if (!sources)
> +		return IRQ_NONE;
> +	grcan_write_reg(&regs->picr, sources);
> +	status = grcan_read_reg(&regs->stat);
> +
> +	/* If we got TX progress, the device has not hanged,
> +	 * so disable the hang timer
> +	 */
> +	if (priv->need_txbug_workaround
> +	    && (sources & (GRCAN_IRQ_TX | GRCAN_IRQ_TXLOSS))) {
> +		SPIN_LOCK(&priv->lock);
> +		if (timer_pending(&priv->hang_timer))
> +			del_timer(&priv->hang_timer);
> +		SPIN_UNLOCK(&priv->lock);

del_timer() works on both active and inactive timers. Therefore you can
remove the timer_pending() and even the locking. Here and in other
places as well.

> +	}
> +
> +	/* Frame(s) received or transmitted */
> +	if (sources & (GRCAN_IRQ_TX | GRCAN_IRQ_RX)) {
> +		/* Disable tx/rx interrupts and schedule poll() */
> +		grcan_clear_bits(&regs->imr, GRCAN_IRQ_TX | GRCAN_IRQ_RX);
> +		napi_schedule(&priv->napi);
> +	}
> +
> +	/* (Potential) error conditions to take care of */
> +	if (sources & GRCAN_IRQ_ERRORS)
> +		grcan_err(dev, sources, status);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +/* Reset device and restart operations from where they were.
> + *
> + * This assumes that RXCTRL & RXCTRL is properly disabled and that RX
> + * is not ONGOING (TX might be stuck in ONGOING due to a harwrware bug
> + * for single shot)
> + */
> +static void grcan_running_reset(unsigned long data)
> +{
> +	struct net_device *dev = (struct net_device *) data;
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	u32 txwr, txrd, rxwr, rxrd, eskbp;
> +	unsigned long flags;
> +
> +	/* This temporarily messes with eskbp, so we need to lock
> +	 * priv->lock
> +	 */
> +	SPIN_LOCK_IRQSAVE(&priv->lock, flags);
> +	if (!priv->closing && priv->resetting) {
> +		txwr = grcan_read_reg(&regs->txwr);
> +		txrd = grcan_read_reg(&regs->txrd);
> +		rxwr = grcan_read_reg(&regs->rxwr);
> +		rxrd = grcan_read_reg(&regs->rxrd);
> +		eskbp = priv->eskbp;
> +
> +		grcan_reset(dev);
> +
> +		grcan_write_reg(&regs->txwr, txwr);
> +		grcan_write_reg(&regs->txrd, txrd);
> +		grcan_write_reg(&regs->rxwr, rxwr);
> +		grcan_write_reg(&regs->rxrd, rxrd);
> +		priv->eskbp = eskbp;
> +
> +		priv->can.state = CAN_STATE_ERROR_ACTIVE;
> +		grcan_set_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE
> +			      | (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT
> +				 ? GRCAN_TXCTRL_SINGLE : 0));
> +		grcan_set_bits(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
> +		/* Start queue if there is size */
> +		if (grcan_txspace(priv->dma.tx.size, txwr, priv->eskbp))
> +			netif_wake_queue(dev);
> +
> +		del_timer(&priv->hang_timer);
> +		del_timer(&priv->rr_timer);
> +
> +		priv->resetting = false;
> +	}
> +	SPIN_UNLOCK_IRQRESTORE(&priv->lock, flags);
> +	netdev_err(dev, "Device reset and restored\n");
> +
> +}
> +
> +/* A time in usecs within which the can controller have time to finish sending
> + * or receiving a frame with a good margin
> + */
> +static inline u32 grcan_ongoing_wait_usecs(__u32 bitrate)
> +{
> +	return 1000000 * 3 * GRCAN_EFF_FRAME_MAX_BITS / bitrate;
> +}

Magic!

> +/* Set timer so that it will not fire until after a period in which the can
> + * controller have a good margin to finish transmitting a frame unless it has
> + * hanged
> + */
> +static inline void grcan_reset_timer(struct timer_list *timer, __u32 bitrate)
> +{
> +	u32 wait_jiffies = usecs_to_jiffies(grcan_ongoing_wait_usecs(bitrate));

Empty line.

> +	mod_timer(timer, jiffies + wait_jiffies);
> +}
> +
> +/* Disable channels and schedule a running reset */
> +static void grcan_initiate_running_reset(unsigned long data)
> +{
> +	struct net_device *dev = (struct net_device *)data;
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	unsigned long flags;
> +
> +	netdev_err(dev, "Device seems hanged - reset scheduled\n");
> +
> +

Remove one line, please.

> +	SPIN_LOCK_IRQSAVE(&priv->lock, flags);
> +
> +	/* The main body of this function must never be executed again
> +	 * until after an execution of grcan_running_reset
> +	 */
> +	if (!priv->resetting && !priv->closing) {
> +		priv->resetting = true;
> +		netif_stop_queue(dev);
> +		grcan_clear_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
> +		grcan_clear_bits(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
> +		grcan_reset_timer(&priv->rr_timer, priv->can.bittiming.bitrate);
> +	}
> +
> +	SPIN_UNLOCK_IRQRESTORE(&priv->lock, flags);
> +}
> +
> +static void grcan_free_dma_buffers(struct net_device *dev)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_dma *dma = &priv->dma;

Empty line.

> +	dma_free_coherent(&dev->dev,
> +			  dma->base_size,
> +			  dma->base_buf,
> +			  dma->base_handle);

Does fit on less lines.


> +	dma->base_size = 0;
> +	dma->base_buf = NULL;
> +	dma->base_handle = 0;
> +	dma->rx.size = 0;
> +	dma->rx.buf = NULL;
> +	dma->rx.handle = 0;
> +	dma->tx.size = 0;
> +	dma->tx.buf = NULL;
> +	dma->tx.handle = 0;

Why not memset?

> +}
> +
> +static int grcan_allocate_dma_buffers(struct net_device *dev,
> +				      size_t tsize, size_t rsize)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_dma *dma = &priv->dma;
> +	struct grcan_dma_buffer *large = rsize > tsize ? &dma->rx : &dma->tx;
> +	struct grcan_dma_buffer *small = rsize > tsize ? &dma->tx : &dma->rx;
> +	size_t shift;
> +
> +	/* Need a whole number of GRCAN_BUFFER_ALIGNMENT for the large,
> +	 * i.e. first buffer
> +	 */
> +	size_t maxs  = max(tsize, rsize);

s/  / /

> +	size_t lsize = ALIGN(maxs, GRCAN_BUFFER_ALIGNMENT);
> +
> +	/* Put the small buffer after that */
> +	size_t ssize = min(tsize, rsize);
> +
> +	/* Extra GRCAN_BUFFER_ALIGNMENT to allow for alignment */
> +	dma->base_size = lsize + ssize + GRCAN_BUFFER_ALIGNMENT;
> +	dma->base_buf = dma_alloc_coherent(&dev->dev,
> +					   dma->base_size,
> +					   &dma->base_handle,
> +					   GFP_KERNEL);
> +
> +	if (!dma->base_buf)
> +		return -ENOMEM;
> +
> +	dma->tx.size = tsize;
> +	dma->rx.size = rsize;
> +
> +	large->handle = ALIGN(dma->base_handle, GRCAN_BUFFER_ALIGNMENT);
> +	small->handle = large->handle + lsize;
> +	shift = large->handle - dma->base_handle;
> +
> +	large->buf = dma->base_buf + shift;
> +	small->buf = large->buf + lsize;
> +
> +	return 0;
> +}
> +
> +
> +/* priv->lock *must* be held when calling this function */
> +static int grcan_start(struct net_device *dev)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +
> +	grcan_reset(dev);
> +
> +	grcan_write_reg(&regs->txaddr, priv->dma.tx.handle);
> +	grcan_write_reg(&regs->txsize, priv->dma.tx.size);
> +	/* regs->txwr and regs->txrd already set to 0 by reset */
> +
> +	grcan_write_reg(&regs->rxaddr, priv->dma.rx.handle);
> +	grcan_write_reg(&regs->rxsize, priv->dma.rx.size);
> +	/* regs->rxwr and regs->rxrd already set to 0 by reset */
> +
> +	/* Enable interrupts */
> +	grcan_read_reg(&regs->pir);
> +	grcan_write_reg(&regs->imr, GRCAN_IRQ_DEFAULT);
> +
> +	/* Enable interfaces, channels and device */
> +	grcan_set_bits(&regs->conf,
> +		      ((priv->config.enable0 ? GRCAN_CONF_ENABLE0 : 0)
> +		       | (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY ?
> +			  GRCAN_CONF_SILENT : 0)
> +		       | (priv->config.enable1 ? GRCAN_CONF_ENABLE1 : 0)
> +		       | (priv->config.selection ? GRCAN_CONF_SELECTION : 0)
> +		       | GRCAN_CONF_ABORT));
> +	grcan_set_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE
> +		      | (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT
> +			 ? GRCAN_TXCTRL_SINGLE : 0));
> +	grcan_set_bits(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
> +	grcan_set_bits(&regs->ctrl, GRCAN_CTRL_ENABLE);
> +
> +	priv->can.state = CAN_STATE_ERROR_ACTIVE;
> +
> +	return 0;
> +}
> +
> +static int grcan_set_mode(struct net_device *dev, enum can_mode mode)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	unsigned long flags;
> +	int err;
> +
> +	if (mode == CAN_MODE_START) {
> +		/* This might be called to restart the device to recover from
> +		 * bus off errors
> +		 */
> +		SPIN_LOCK_IRQSAVE(&priv->lock, flags);
> +		if (priv->closing || priv->resetting) {
> +			err = -EBUSY;
> +		} else {
> +			netdev_info(dev, "Restarting device\n");
> +			grcan_start(dev);
> +			if (netif_queue_stopped(dev))
> +				netif_wake_queue(dev);
> +			err = 0;
> +		}
> +		SPIN_UNLOCK_IRQRESTORE(&priv->lock, flags);
> +		return err;
> +	}
> +	return -EOPNOTSUPP;
> +}
> +
> +static int grcan_open(struct net_device *dev)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_dma *dma = &priv->dma;
> +	unsigned long flags;
> +	int err;
> +
> +	SPIN_LOCK_IRQSAVE(&priv->lock, flags);
> +
> +	/* Allocate memory */
> +	if (GRCAN_INVALID_BUFFER_SIZE(priv->config.txsize)
> +	    || GRCAN_INVALID_BUFFER_SIZE(priv->config.rxsize)) {
> +		/* Should never be able go this far with invalid sizes */
> +		netdev_err(dev, "Invalid buffer size pair 0x%x 0x%x\n",
> +			   priv->config.txsize, priv->config.rxsize);
> +		err = -EINVAL;
> +		goto exit_unlock;
> +	}
> +	err = grcan_allocate_dma_buffers(dev, priv->config.txsize,
> +					 priv->config.rxsize);
> +	if (err) {
> +		netdev_err(dev, "could not allocate DMA buffers\n");
> +		goto exit_unlock;
> +	}
> +
> +	priv->echo_skb = devm_kzalloc(&dev->dev,
> +				      dma->tx.size * sizeof(*priv->echo_skb),
> +				      GFP_KERNEL);
> +	if (!priv->echo_skb) {
> +		err = -ENOMEM;
> +		goto exit_free_dma_buffers;
> +	}
> +	priv->can.echo_skb_max = dma->tx.size;
> +	priv->can.echo_skb = priv->echo_skb;
> +
> +	priv->txdlc = devm_kzalloc(&dev->dev,
> +				   dma->tx.size * sizeof(*priv->txdlc),
> +				   GFP_KERNEL);
> +	if (!priv->txdlc) {
> +		err = -ENOMEM;
> +		goto exit_free_echo_skb;
> +	}
> +
> +	/* Get can device up */
> +	err = open_candev(dev);
> +	if (err)
> +		goto exit_free_txdlc;
> +
> +	err = devm_request_irq(&dev->dev, dev->irq, grcan_interrupt,
> +			       IRQF_SHARED, dev->name, (void *)dev);
> +	if (err)
> +		goto exit_close_candev;
> +
> +	grcan_start(dev);
> +	napi_enable(&priv->napi);
> +	netif_start_queue(dev);
> +
> +	priv->resetting = false;
> +	priv->closing = false;
> +
> +	SPIN_UNLOCK_IRQRESTORE(&priv->lock, flags);

This is a rather big lock. Please shorten the critical section if possible.

> +	return 0;
> +
> +exit_close_candev:
> +	close_candev(dev);
> +exit_free_txdlc:
> +	devm_kfree(&dev->dev, priv->txdlc);
> +exit_free_echo_skb:
> +	devm_kfree(&dev->dev, priv->echo_skb);
> +exit_free_dma_buffers:
> +	grcan_free_dma_buffers(dev);
> +exit_unlock:
> +	SPIN_UNLOCK_IRQRESTORE(&priv->lock, flags);
> +	return err;
> +}
> +
> +static int grcan_close(struct net_device *dev)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	unsigned long flags;
> +
> +	napi_disable(&priv->napi);
> +
> +	SPIN_LOCK_IRQSAVE(&priv->lock, flags);
> +
> +	priv->closing = true;
> +	if (priv->need_txbug_workaround) {
> +		del_timer_sync(&priv->hang_timer);
> +		del_timer_sync(&priv->rr_timer);
> +	}
> +	netif_stop_queue(dev);
> +	grcan_stop(dev);
> +
> +	SPIN_UNLOCK_IRQRESTORE(&priv->lock, flags);
> +
> +	devm_free_irq(&dev->dev, dev->irq, (void *)dev);
> +	close_candev(dev);
> +
> +	grcan_free_dma_buffers(dev);
> +	priv->can.echo_skb_max = 0;
> +	priv->can.echo_skb = NULL;
> +	devm_kfree(&dev->dev, priv->echo_skb);
> +	devm_kfree(&dev->dev, priv->txdlc);
> +
> +	return 0;
> +}
> +
> +static int grcan_transmit_catch_up(struct net_device *dev, int budget)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	unsigned long flags;
> +	int work_done;
> +
> +	SPIN_LOCK_IRQSAVE(&priv->lock, flags);
> +
> +	work_done = catch_up_echo_skb(dev, budget, true);
> +	if (work_done) {
> +		if (!priv->resetting && !priv->closing
> +		    && netif_queue_stopped(dev))
> +			netif_wake_queue(dev);
> +
> +		/* With napi we don't get TX interrupts for a while,
> +		 * so prevent a running reset while catching up
> +		 */
> +		if (priv->need_txbug_workaround
> +		    && timer_pending(&priv->hang_timer))
> +			del_timer(&priv->hang_timer);

timer_pending() not needed as mentioned above.

> +	}
> +
> +	SPIN_UNLOCK_IRQRESTORE(&priv->lock, flags);
> +
> +	return work_done;
> +}
> +
> +static int grcan_receive(struct net_device *dev, int budget)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	struct grcan_dma *dma = &priv->dma;
> +	struct net_device_stats *stats = &dev->stats;
> +	struct can_frame *cf;
> +	struct sk_buff *skb;
> +	u32 wr, rd, startrd;
> +	u32 *slot;
> +	u32 i, rtr, eff, j, shift;
> +	int work_done = 0;
> +
> +	rd = grcan_read_reg(&regs->rxrd);
> +	startrd = rd;
> +	for (work_done = 0; work_done < budget; work_done++) {
> +		/* Check for packet to receive */
> +		wr = grcan_read_reg(&regs->rxwr);
> +		if (rd == wr)
> +			break;
> +
> +		/* Take care of packet */
> +		skb = alloc_can_skb(dev, &cf);
> +		if (skb == NULL) {
> +			netdev_dbg(dev,
> +				   "dropping frame: skb allocation failed\n");
> +			stats->rx_dropped++;
> +			continue;
> +		}
> +
> +		slot = dma->rx.buf + rd;
> +		eff = slot[0] & GRCAN_MSG_IDE;
> +		rtr = slot[0] & GRCAN_MSG_RTR;
> +		if (eff) {
> +			cf->can_id = ((slot[0] & GRCAN_MSG_EID)
> +				      >> GRCAN_MSG_EID_BIT);
> +			cf->can_id |= CAN_EFF_FLAG;
> +		} else {
> +			cf->can_id = ((slot[0] & GRCAN_MSG_BID)
> +				      >> GRCAN_MSG_BID_BIT);
> +		}
> +		cf->can_dlc = get_can_dlc((slot[1] & GRCAN_MSG_DLC)
> +					  >> GRCAN_MSG_DLC_BIT);
> +		if (rtr) {
> +			cf->can_id |= CAN_RTR_FLAG;
> +		} else {
> +			for (i = 0; i < cf->can_dlc; i++) {
> +				j = GRCAN_MSG_DATA_SLOT_INDEX(i);
> +				shift = GRCAN_MSG_DATA_SHIFT(i);
> +				cf->data[i] = (u8)((slot[j] >> shift) & 0xff);
> +			}
> +		}
> +		netif_receive_skb(skb);
> +
> +		/* Update statistics and read pointer */
> +		stats->rx_packets++;
> +		stats->rx_bytes += cf->can_dlc;
> +		rd = grcan_ring_add(rd, GRCAN_MSG_SIZE, dma->rx.size);
> +	}
> +
> +	/* Make sure everything is read before allowing hardware to
> +	 * use the memory
> +	 */
> +	mb();
> +
> +	/* Update read pointer - no need to check for ongoing */
> +	if (likely(rd != startrd))
> +		grcan_write_reg(&regs->rxrd, rd);
> +
> +	return work_done;
> +}
> +
> +static int grcan_poll(struct napi_struct *napi, int budget)
> +{
> +	struct grcan_priv *priv = container_of(napi, struct grcan_priv, napi);
> +	struct net_device *dev = priv->dev;
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	int rx_work_done = grcan_receive(dev, budget);
> +	int tx_work_done = grcan_transmit_catch_up(dev, budget);

Empty line.

> +	if (rx_work_done < budget && tx_work_done < budget) {
> +		napi_complete(napi);
> +		/* Enable tx and rx interrupts again */
> +		if (!priv->closing)
> +			grcan_set_bits(&regs->imr, GRCAN_IRQ_TX | GRCAN_IRQ_RX);
> +	}
> +	return rx_work_done;
> +}
> +
> +/* Work tx bug by waiting while for the risky situation to clear. If that fails,
> + * drop a frame in one-shot mode or indicate a busy device otherwise.
> + *
> + * Returns 0 on successful wait. Otherwise it sets *netdev_tx_status to the
> + * value that should be returned by grcan_start_xmit when aborting the xmit.
> + */
> +static int grcan_txbug_workaround(struct net_device *dev, struct sk_buff *skb,
> +				  u32 txwr, u32 oneshotmode,
> +				  netdev_tx_t *netdev_tx_status)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	struct grcan_dma *dma = &priv->dma;
> +	int i;
> +	unsigned long flags;
> +
> +	/* Wait a while for ongoing to be cleared or read pointer to catch up to
> +	 * write pointer. The latter is needed due to a bug in older versions of
> +	 * GRCAN in which ONGOING is not cleared properly one-shot mode when a
> +	 * transmission fails.
> +	 */
> +	for (i = 0; i < GRCAN_SHORTWAIT_USECS; i++) {
> +		udelay(1);
> +		if (!grcan_read_bits(&regs->txctrl, GRCAN_TXCTRL_ONGOING)
> +		    || grcan_read_reg(&regs->txrd) == txwr) {
> +			return 0;
> +		}
> +	}
> +
> +	/* Clean up, in case the situation was not resolved */
> +	SPIN_LOCK_IRQSAVE(&priv->lock, flags);
> +	if (!priv->resetting && !priv->closing) {
> +		/* Queue might have been stopped earlier in grcan_start_xmit */
> +		if (grcan_txspace(dma->tx.size, txwr, priv->eskbp))
> +			if (netif_queue_stopped(dev))
> +				netif_wake_queue(dev);
> +		/* Set a timer to resolve a hanged tx controller */
> +		if (!timer_pending(&priv->hang_timer))
> +			grcan_reset_timer(&priv->hang_timer,
> +					  priv->can.bittiming.bitrate);
> +	}
> +	SPIN_UNLOCK_IRQRESTORE(&priv->lock, flags);
> +
> +	if (oneshotmode) {
> +		/* In one-shot mode we should never end up here because
> +		 * then the interrupt handler increases txrd on TXLOSS,
> +		 * but it is consistent with one-shot mode to drop the
> +		 * frame in this case.
> +		 */
> +		kfree_skb(skb);
> +		*netdev_tx_status = NETDEV_TX_OK;
> +	} else {
> +		/* In normal mode the socket-can transmission queue get
> +		 * to keep the frame so that it can be retransmitted
> +		 * later
> +		 */
> +		*netdev_tx_status = NETDEV_TX_BUSY;
> +	}
> +	return -EBUSY;
> +}
> +
> +/* Notes on the tx cyclic buffer handling:
> + *
> + * regs->txwr	- the next slot for the driver to put data to be sent
> + * regs->txrd	- the next slot for the device to read data
> + * priv->eskbp	- the next slot for the driver to call can_put_echo_skb for
> + *
> + * grcan_start_xmit can enter more messages as long as regs->txwr does
> + * not reach priv->eskbp (within 1 message gap)
> + *
> + * The device sends messages until regs->txrd reaches regs->txwr
> + *
> + * The interrupt calls handler calls can_put_echo_skb until
> + * priv->eskbp reaches regs->txrd
> + */
> +static netdev_tx_t grcan_start_xmit(struct sk_buff *skb,
> +				    struct net_device *dev)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	struct grcan_dma *dma = &priv->dma;
> +	struct can_frame *cf = (struct can_frame *)skb->data;
> +	u32 id, txwr, txrd, space, txctrl;
> +	int slotindex;
> +	u32 *slot;
> +	u32 i, rtr, eff, dlc, tmp, err;
> +	int j, shift;
> +	unsigned long flags;
> +	u32 oneshotmode = priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT;
> +
> +	if (can_dropped_invalid_skb(dev, skb))
> +		return NETDEV_TX_OK;
> +
> +	/* Trying to transmit in silent mode will generate error interrupts */
> +	if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
> +		return NETDEV_TX_BUSY;

Good point. Other driver may have this issues as well. To avoid entering
the xmit routine, netif_start_queue should never be called.

> +
> +	/* Reads of priv->eskbp and shut-downs of the queue needs to
> +	 * be atomic towards the updates to priv->eskbp and wake-ups
> +	 * of the queue in the interrupt handler.
> +	 */
> +	SPIN_LOCK_IRQSAVE(&priv->lock, flags);
> +
> +	txwr = grcan_read_reg(&regs->txwr);
> +	space = grcan_txspace(dma->tx.size, txwr, priv->eskbp);
> +
> +	slotindex = txwr / GRCAN_MSG_SIZE;
> +	slot = dma->tx.buf + txwr;
> +
> +	if (unlikely(space == 1))
> +		netif_stop_queue(dev);
> +
> +	SPIN_UNLOCK_IRQRESTORE(&priv->lock, flags);
> +	/* End of critical section*/
> +
> +	/* This should never happen. If circular buffer is full, the
> +	 * netif_stop_queue should have been stopped already.
> +	 */
> +	if (unlikely(!space)) {
> +		netdev_err(dev, "No buffer space, but queue is non-stopped.\n");
> +		return NETDEV_TX_BUSY;
> +	}
> +
> +	/* Convert and write CAN message to DMA buffer */
> +	eff = cf->can_id & CAN_EFF_FLAG;
> +	rtr = cf->can_id & CAN_RTR_FLAG;
> +	id  = cf->can_id & (eff ? CAN_EFF_MASK : CAN_SFF_MASK);
> +	dlc = cf->can_dlc;
> +	if (eff)
> +		tmp = (id << GRCAN_MSG_EID_BIT) & GRCAN_MSG_EID;
> +	else
> +		tmp = (id << GRCAN_MSG_BID_BIT) & GRCAN_MSG_BID;
> +	slot[0] = (eff ? GRCAN_MSG_IDE : 0) | (rtr ? GRCAN_MSG_RTR : 0) | tmp;
> +
> +	slot[1] = ((dlc << GRCAN_MSG_DLC_BIT) & GRCAN_MSG_DLC);
> +	slot[2] = 0;
> +	slot[3] = 0;
> +	for (i = 0; i < dlc; i++) {
> +		j = GRCAN_MSG_DATA_SLOT_INDEX(i);
> +		shift = GRCAN_MSG_DATA_SHIFT(i);
> +		slot[j] |= cf->data[i] << shift;
> +	}
> +
> +	/* Checking that channel has not been disabled. These cases
> +	 * should never happen
> +	 */
> +	txctrl = grcan_read_reg(&regs->txctrl);
> +	if (!(txctrl & GRCAN_TXCTRL_ENABLE))
> +		netdev_err(dev, "tx channel spuriously disabled\n");
> +
> +	if (oneshotmode && !(txctrl & GRCAN_TXCTRL_SINGLE))
> +		netdev_err(dev, "one-shot mode spuriously disabled\n");
> +
> +	/* Bug workaround for old version of grcan where updating txwr
> +	 * in the same clock cycle as the controller updates txrd to
> +	 * the current txwr could hang the can controller
> +	 */
> +	if (priv->need_txbug_workaround) {
> +		txrd = grcan_read_reg(&regs->txrd) ;
> +		if (unlikely(grcan_ring_sub(txwr, txrd, dma->tx.size) == 1)) {
> +			netdev_tx_t txstatus;
> +			err = grcan_txbug_workaround(dev, skb, txwr,
> +						     oneshotmode, &txstatus);
> +			if (err)
> +				return txstatus;
> +		}
> +	}
> +
> +	/* Prepare skb for echoing. This must be after the bug workaround above
> +	 * as ownership of the skb is passed on by calling can_put_echo_skb.
> +	 * Returning NETDEV_TX_BUSY or accessing skb or cf after a call to
> +	 * can_put_echo_skb would be an error unless other measures are
> +	 * taken.
> +	 */
> +	priv->txdlc[slotindex] = cf->can_dlc; /* Store dlc for statistics */
> +	can_put_echo_skb(skb, dev, slotindex);
> +
> +	/* Make sure everything is written before allowing hardware to
> +	 * read from the memory
> +	 */
> +	wmb();
> +
> +	/* Update write pointer to start transmission */
> +	grcan_write_reg(&regs->txwr,
> +			grcan_ring_add(txwr, GRCAN_MSG_SIZE, dma->tx.size));
> +
> +	return NETDEV_TX_OK;
> +}
> +
> +
> +/* ========== Setting up sysfs interface and module parameters  ========== */
> +
> +
> +#define GRCAN_NOT_BOOL(val) ((val) < 0 || (val) > 1)
> +
> +#define GRCAN_MODULE_PARAM(name, mtype, valcheckf)			\
> +	static void grcan_sanitize_##name(struct platform_device *pd)	\
> +	{								\
> +		struct grcan_device_config grcan_default_config		\
> +			= GRCAN_DEFAULT_DEVICE_CONFIG;			\
> +		if (valcheckf(grcan_module_config.name)) {		\
> +			dev_err(&pd->dev,				\
> +				"Invalid module parameter value for "	\
> +				#name " - setting default\n");		\
> +			grcan_module_config.name =			\
> +				grcan_default_config.name;		\
> +		}							\
> +	}								\
> +	module_param_named(name, grcan_module_config.name,		\
> +			   mtype, S_IRUGO)
> +
> +#define GRCAN_CONFIG_ATTR(name)						\
> +	static ssize_t grcan_store_##name(struct device *sdev,		\
> +					  struct device_attribute *att,	\
> +					  const char *buf,		\
> +					  size_t count)			\
> +	{								\
> +		struct net_device *dev = to_net_dev(sdev);		\
> +		struct grcan_priv *priv = netdev_priv(dev);		\
> +		u8 val;							\
> +		int ret;						\
> +		if (dev->flags & IFF_UP)				\
> +			return -EBUSY;					\
> +		ret = kstrtou8(buf, 0, &val);				\
> +		if (ret < 0 || val < 0 || val > 1)			\
> +			return -EINVAL;					\
> +		priv->config.name = val;				\
> +		return count;						\
> +	}								\
> +	static ssize_t grcan_show_##name(struct device *sdev,		\
> +					 struct device_attribute *att,	\
> +					 char *buf)			\
> +	{								\
> +		struct net_device *dev = to_net_dev(sdev);		\
> +		struct grcan_priv *priv = netdev_priv(dev);		\
> +		return sprintf(buf, "%d\n", priv->config.name);		\
> +	}								\
> +	static DEVICE_ATTR(name, S_IRUGO | S_IWUSR,			\
> +			   grcan_show_##name,				\
> +			   grcan_store_##name);				\
> +	GRCAN_MODULE_PARAM(name, ushort, GRCAN_NOT_BOOL)
> +
> +/* The following configuration options are made available both via module
> + * parameters and writable sysfs files. See the chapter about GRCAN in the
> + * documentation for the GRLIB VHDL library for further details.
> + */
> +
> +/* Configure enable0 - Configuration for interface 0. */
> +GRCAN_CONFIG_ATTR(enable0);
> +
> +/* Configure enable1 - Configuration for interface 0  */
> +GRCAN_CONFIG_ATTR(enable1);
> +
> +/* Configure selection - Selection on which interface to use */
> +GRCAN_CONFIG_ATTR(selection);
> +
> +
> +/* The following configuration options are only available via module
> + * parameters.
> + */
> +
> +/* Configure size of tx buffer */
> +GRCAN_MODULE_PARAM(txsize, uint, GRCAN_INVALID_BUFFER_SIZE);
> +
> +/* Configure size of rx buffer */
> +GRCAN_MODULE_PARAM(rxsize, uint, GRCAN_INVALID_BUFFER_SIZE);
> +
> +
> +/* Function that makes sure that configuration done using
> + * module parameters are set to valid values
> + */
> +static void grcan_sanitize_module_config(struct platform_device *ofdev)
> +{
> +	grcan_sanitize_enable0(ofdev);
> +	grcan_sanitize_enable1(ofdev);
> +	grcan_sanitize_selection(ofdev);
> +	grcan_sanitize_txsize(ofdev);
> +	grcan_sanitize_rxsize(ofdev);
> +}
> +
> +static const struct attribute *const sysfs_grcan_attrs[] = {
> +	/* Config attrs */
> +	&dev_attr_enable0.attr,
> +	&dev_attr_enable1.attr,
> +	&dev_attr_selection.attr,
> +	NULL,
> +};
> +
> +static const struct attribute_group sysfs_grcan_group = {
> +	.name = "grcan",
> +	.attrs = (struct attribute **)sysfs_grcan_attrs,
> +};
> +
> +
> +/* ========== Setting up the driver ========== */
> +
> +static const struct net_device_ops grcan_netdev_ops = {
> +	.ndo_open               = grcan_open,
> +	.ndo_stop               = grcan_close,
> +	.ndo_start_xmit         = grcan_start_xmit,
> +};
> +
> +static int grcan_setup_netdev(struct platform_device *ofdev,
> +			      void __iomem *base,
> +			      int irq, u32 ambafreq, bool txbug)
> +{
> +	struct net_device *dev;
> +	struct grcan_priv *priv;
> +	struct grcan_registers __iomem *regs;
> +	int err;
> +
> +	dev = alloc_candev(sizeof(struct grcan_priv), 0);
> +	if (!dev)
> +		return -ENOMEM;
> +
> +	dev->irq = irq;
> +	dev->flags |= IFF_ECHO;
> +	dev->netdev_ops = &grcan_netdev_ops;
> +	dev->sysfs_groups[0] = &sysfs_grcan_group;
> +
> +	priv = netdev_priv(dev);
> +	memcpy(&priv->config, &grcan_module_config,
> +	       sizeof(struct grcan_device_config));
> +	priv->dev = dev;
> +	priv->regs = (struct grcan_registers *) base;
> +	priv->can.bittiming_const     = &grcan_bittiming_const;
> +	priv->can.do_set_bittiming    = grcan_set_bittiming;
> +	priv->can.do_set_mode         = grcan_set_mode;
> +	priv->can.do_get_berr_counter = grcan_get_berr_counter;
> +	priv->can.clock.freq          = ambafreq;

As mentioned above, just *one* space before an after the "=".

> +	priv->can.ctrlmode_supported  =
> +		CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_ONE_SHOT;

What about triple-sampling?

> +	priv->need_txbug_workaround = txbug;
> +
> +	spin_lock_init(&priv->lock);
> +
> +	if (priv->need_txbug_workaround) {
> +		init_timer(&priv->rr_timer);
> +		priv->rr_timer.function = grcan_running_reset;
> +		priv->rr_timer.data = (unsigned long)dev;
> +
> +		init_timer(&priv->hang_timer);
> +		priv->hang_timer.function = grcan_initiate_running_reset;
> +		priv->hang_timer.data = (unsigned long)dev;
> +	}
> +
> +	netif_napi_add(dev, &priv->napi, grcan_poll, GRCAN_NAPI_WEIGHT);
> +
> +	SET_NETDEV_DEV(dev, &ofdev->dev);
> +	regs = priv->regs;
> +	dev_info(&ofdev->dev,
> +		 "regs=0x%p, irq=%d, clock=%d\n",
> +		 priv->regs, dev->irq, priv->can.clock.freq);

Does fit on two lines?

> +
> +	err = register_candev(dev);
> +	if (err) {
> +		dev_err(&ofdev->dev, "registering %s failed (err=%d)\n",
> +			DRV_NAME, err);
> +		goto exit_free_candev;
> +	}
> +	dev_set_drvdata(&ofdev->dev, dev);
> +
> +	/* Reset device to allow bit-timing to be set. No need to call
> +	 * grcan_reset at this stage. That is done in grcan_open.
> +	 */
> +	grcan_write_reg(&regs->ctrl, GRCAN_CTRL_RESET);
> +
> +	return 0;
> +exit_free_candev:
> +	free_candev(dev);
> +	return err;
> +}
> +
> +static int __devinit grcan_probe(struct platform_device *ofdev)
> +{
> +	struct device_node *np = ofdev->dev.of_node;
> +	struct resource *res;
> +	u32 sysid, ambafreq;
> +	int irq, err;
> +	void __iomem *base;
> +	bool txbug = true;
> +
> +	/* Compare GRLIB version number with the first that does not
> +	 * have the tx bug (see start_xmit)
> +	 */
> +	err = of_property_read_u32(np, "systemid", &sysid);
> +	if (!err && ((sysid & GRLIB_VERSION_MASK)
> +		     >= GRCAN_TXBUG_SAFE_GRLIB_VERSION))
> +		txbug = false;
> +
> +	err = of_property_read_u32(np, "freq", &ambafreq);
> +	if (err) {
> +		dev_err(&ofdev->dev, "unable to fetch \"freq\" property\n");
> +		goto exit_error;
> +	}
> +
> +	res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
> +	base = devm_request_and_ioremap(&ofdev->dev, res);
> +	if (!base) {
> +		dev_err(&ofdev->dev, "couldn't map IO resource\n");
> +		err = -EADDRNOTAVAIL;
> +		goto exit_error;
> +	}
> +
> +	irq = irq_of_parse_and_map(np, GRCAN_IRQIX_IRQ);
> +	if (irq == NO_IRQ) {
> +		dev_err(&ofdev->dev, "no irq found\n");
> +		err = -ENODEV;
> +		goto exit_error;
> +	}
> +
> +	grcan_sanitize_module_config(ofdev);
> +
> +	err = grcan_setup_netdev(ofdev, base, irq, ambafreq, txbug);
> +	if (err)
> +		goto exit_dispose_irq;
> +
> +	return 0;
> +
> +exit_dispose_irq:
> +	irq_dispose_mapping(irq);
> +exit_error:
> +	dev_err(&ofdev->dev,
> +		"%s socket CAN driver initialization failed with error %d\n",
> +		DRV_NAME, err);
> +	return err;
> +}
> +
> +static  int __devexit grcan_remove(struct platform_device *ofdev)
> +{
> +	struct net_device *dev = dev_get_drvdata(&ofdev->dev);
> +	struct grcan_priv *priv = netdev_priv(dev);
> +
> +	unregister_candev(dev); /* Will in turn call grcan_close */
> +
> +	irq_dispose_mapping(dev->irq);
> +	dev_set_drvdata(&ofdev->dev, NULL);
> +	netif_napi_del(&priv->napi);
> +	free_candev(dev);
> +
> +	dev_info(&ofdev->dev, "%s socket CAN driver removed\n", DRV_NAME);
> +	return 0;
> +}
> +
> +static struct of_device_id grcan_match[] = {
> +	{.name = "GAISLER_GRCAN"},
> +	{.name = "01_03d"},
> +	{.name = "GAISLER_GRHCAN"},
> +	{.name = "01_034"},
> +	{},
> +};
> +
> +MODULE_DEVICE_TABLE(of, grcan_match);
> +
> +static struct platform_driver grcan_driver = {
> +	.driver = {
> +		.name = DRV_NAME,
> +		.owner = THIS_MODULE,
> +		.of_match_table = grcan_match,
> +	},
> +	.probe = grcan_probe,
> +	.remove = __devexit_p(grcan_remove),
> +};
> +
> +module_platform_driver(grcan_driver);
> +
> +MODULE_AUTHOR("Aeroflex Gaisler AB.");
> +MODULE_DESCRIPTION("Socket CAN driver for Aeroflex Gaisler GRCAN");
> +MODULE_LICENSE("GPL");

I curious how the device behaves on bus errors and state changes. Could
you please show the output of "candump -e any,0:0,#FFFFFFFF" while
sending a CAN message with no other node on the bus (not connected) and
with going bus off (by short-circuiting CAN high and low).

Thanks,

Wolfgang.


^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v3] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-10-30 10:07             ` Wolfgang Grandegger
@ 2012-10-30 16:24               ` Andreas Larsson
  2012-10-31 12:51                 ` Wolfgang Grandegger
  0 siblings, 1 reply; 41+ messages in thread
From: Andreas Larsson @ 2012-10-30 16:24 UTC (permalink / raw)
  To: Wolfgang Grandegger
  Cc: linux-can, Marc Kleine-Budde, devicetree-discuss, software

On 10/30/2012 11:07 AM, Wolfgang Grandegger wrote:
>> +	/* AHB bus error interrupts (not CAN bus errors) - shut down the
>> +	 * device.
>> +	 */
>> +	if (sources & (GRCAN_IRQ_TXAHBERR | GRCAN_IRQ_RXAHBERR)) {
>> +		if (sources & GRCAN_IRQ_TXAHBERR) {
>> +			netdev_err(dev, "got AHB bus error on tx\n");
>> +			stats->tx_errors++;
>> +		} else {
>> +			netdev_err(dev, "got AHB bus error on rx\n");
>> +			stats->rx_errors++;
>> +		}
>> +		netdev_err(dev, "halting device\n");
>> +
>> +		/* Prevent anything to be enabled again and halt device */
>> +		SPIN_LOCK(&priv->lock);
>> +		priv->closing = true;
>> +		netif_stop_queue(dev);
>> +		grcan_stop(dev);
>> +		SPIN_UNLOCK(&priv->lock);
>
> Hm, does that really happen? How can the user/app realized the problem
> and recover?

My understanding of it is that if you get amba bus errors something is seriously 
wrong and nothing can be done at driver level to recover. Shutting down the 
device is to prevent the driver from spamming console messages. I used to have a 
sysfs indication of such errors. Now dmesg is the way to find out about the 
problem. The user can always bring the interface down and up again and try again 
after such an error.


> Furthermore, why is a spin_clock enough here? THe interrupt may run a
> thread.

It should be enough because the function is only called
directly from the interrupt handler, right? Or did I miss something?


>> +	priv->can.ctrlmode_supported  =
>> +		CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_ONE_SHOT;
>
> What about triple-sampling?

That is not supported by the hardware.


> I curious how the device behaves on bus errors and state changes. Could
> you please show the output of "candump -e any,0:0,#FFFFFFFF" while
> sending a CAN message with no other node on the bus (not connected) and
> with going bus off (by short-circuiting CAN high and low).


Here is the output (with long sequences of similar error frames
where only one counter is increasing cut out) from the the upcoming v4. let me 
know if you see any problems with this.

   can0  20000006  [8] 00 00 00 00 00 00 10 00   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{}
         error-counter-tx-rx{{16}{0}}
   can0  20000004  [8] 00 20 00 00 00 00 88 00   ERRORFRAME
         controller-problem{tx-error-passive}
         error-counter-tx-rx{{136}{0}}
   can0  20000006  [8] 00 20 00 00 00 00 90 00   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{tx-error-passive}
         error-counter-tx-rx{{144}{0}}
   [...]
   can0  20000006  [8] 00 20 00 00 00 00 F0 00   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{tx-error-passive}
         error-counter-tx-rx{{240}{0}}
   can0  20000006  [8] 00 20 00 00 00 00 F8 00   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{tx-error-passive}
         error-counter-tx-rx{{248}{0}}
   can0  20000042  [8] 00 00 00 00 00 00 80 00   ERRORFRAME
         lost-arbitration{at bit 0}
         bus-off
         error-counter-tx-rx{{128}{0}}
   can0  20000006  [8] 00 00 00 00 00 00 18 00   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{}
         error-counter-tx-rx{{24}{0}}
   can0  20000004  [8] 00 10 00 00 00 00 4F 80   ERRORFRAME
         controller-problem{rx-error-passive}
         error-counter-tx-rx{{79}{128}}
   [...]
   can0  20000006  [8] 00 10 00 00 00 00 77 80   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{rx-error-passive}
         error-counter-tx-rx{{119}{128}}
   can0  20000006  [8] 00 30 00 00 00 00 7F 80   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{rx-error-passive,tx-error-passive}
         error-counter-tx-rx{{127}{128}}
   can0  20000006  [8] 00 30 00 00 00 00 87 80   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{rx-error-passive,tx-error-passive}
         error-counter-tx-rx{{135}{128}}
   [...]
   can0  20000006  [8] 00 30 00 00 00 00 F7 80   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{rx-error-passive,tx-error-passive}
         error-counter-tx-rx{{247}{128}}
   can0  20000006  [8] 00 30 00 00 00 00 FF 80   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{rx-error-passive,tx-error-passive}
         error-counter-tx-rx{{255}{128}}
   can0  20000042  [8] 00 00 00 00 00 00 80 00   ERRORFRAME
         lost-arbitration{at bit 0}
         bus-off
         error-counter-tx-rx{{128}{0}}
   can0  20000006  [8] 00 00 00 00 00 00 18 00   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{}
         error-counter-tx-rx{{24}{0}}
   can0  20000004  [8] 00 10 00 00 00 00 4F 80   ERRORFRAME
         controller-problem{rx-error-passive}
         error-counter-tx-rx{{79}{128}}
   can0  20000006  [8] 00 10 00 00 00 00 57 80   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{rx-error-passive}
         error-counter-tx-rx{{87}{128}}
   [...]



Thanks a lot for all the feedback!

I'll send in v4 tomorrow.

Cheers,
Andreas


^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v3] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-10-30 16:24               ` Andreas Larsson
@ 2012-10-31 12:51                 ` Wolfgang Grandegger
  2012-10-31 16:33                   ` Andreas Larsson
  0 siblings, 1 reply; 41+ messages in thread
From: Wolfgang Grandegger @ 2012-10-31 12:51 UTC (permalink / raw)
  To: Andreas Larsson
  Cc: linux-can, Marc Kleine-Budde, devicetree-discuss, software

On 10/30/2012 05:24 PM, Andreas Larsson wrote:
> On 10/30/2012 11:07 AM, Wolfgang Grandegger wrote:
>>> +    /* AHB bus error interrupts (not CAN bus errors) - shut down the
>>> +     * device.
>>> +     */
>>> +    if (sources & (GRCAN_IRQ_TXAHBERR | GRCAN_IRQ_RXAHBERR)) {
>>> +        if (sources & GRCAN_IRQ_TXAHBERR) {
>>> +            netdev_err(dev, "got AHB bus error on tx\n");
>>> +            stats->tx_errors++;
>>> +        } else {
>>> +            netdev_err(dev, "got AHB bus error on rx\n");
>>> +            stats->rx_errors++;
>>> +        }
>>> +        netdev_err(dev, "halting device\n");
>>> +
>>> +        /* Prevent anything to be enabled again and halt device */
>>> +        SPIN_LOCK(&priv->lock);
>>> +        priv->closing = true;
>>> +        netif_stop_queue(dev);
>>> +        grcan_stop(dev);
>>> +        SPIN_UNLOCK(&priv->lock);
>>
>> Hm, does that really happen? How can the user/app realized the problem
>> and recover?
> 
> My understanding of it is that if you get amba bus errors something is
> seriously wrong and nothing can be done at driver level to recover.
> Shutting down the device is to prevent the driver from spamming console
> messages. I used to have a sysfs indication of such errors. Now dmesg is
> the way to find out about the problem. The user can always bring the
> interface down and up again and try again after such an error.

Well, sounds like a fatal error. Did you ever saw it? If that happens
frequently, or even once, the device/system seems not really usable.

>> Furthermore, why is a spin_clock enough here? THe interrupt may run a
>> thread.
> 
> It should be enough because the function is only called
> directly from the interrupt handler, right? Or did I miss something?

The interrupt handler may run as thread, e.g. if the -rt patch has been
applied. Therefore it's safer to use the irqsave/restore variants of the
spin_lock functions. At least that's my understanding. See also
"Documentation/spinlock.txt".

>>> +    priv->can.ctrlmode_supported  =
>>> +        CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_ONE_SHOT;
>>
>> What about triple-sampling?
> 
> That is not supported by the hardware.
> 
> 
>> I curious how the device behaves on bus errors and state changes. Could
>> you please show the output of "candump -e any,0:0,#FFFFFFFF" while
>> sending a CAN message with no other node on the bus (not connected) and
>> with going bus off (by short-circuiting CAN high and low).
> 
> 
> Here is the output (with long sequences of similar error frames
> where only one counter is increasing cut out) from the the upcoming v4.
> let me know if you see any problems with this.

How did your trigger that sequence? Short-circuit or not cable
connected? The latter, I assume, as bus-off is not reached.

> 
>   can0  20000006  [8] 00 00 00 00 00 00 10 00   ERRORFRAME
>         lost-arbitration{at bit 0}
>         controller-problem{}
>         error-counter-tx-rx{{16}{0}}

This is most probably an ack slot bus error similar to. You seem not to
handle bus errors and it's not a controller problem as the state did not
change.

http://lxr.linux.no/#linux+v3.6.4/drivers/net/can/flexcan.c#L353

>   can0  20000004  [8] 00 20 00 00 00 00 88 00   ERRORFRAME
>         controller-problem{tx-error-passive}
>         error-counter-tx-rx{{136}{0}}

OK, a state change to error passive. The device seems not to report
changes to error warning.

>   can0  20000006  [8] 00 20 00 00 00 00 90 00   ERRORFRAME
>         lost-arbitration{at bit 0}
>         controller-problem{tx-error-passive}
>         error-counter-tx-rx{{144}{0}}

State changes should be reported only once. But it did not change. This
is then a bus error (CAN_ERR_PROT | CAN_ERR_BUSERROR). See also above.

>   [...]
>   can0  20000006  [8] 00 20 00 00 00 00 F0 00   ERRORFRAME
>         lost-arbitration{at bit 0}
>         controller-problem{tx-error-passive}
>         error-counter-tx-rx{{240}{0}}
>   can0  20000006  [8] 00 20 00 00 00 00 F8 00   ERRORFRAME
>         lost-arbitration{at bit 0}
>         controller-problem{tx-error-passive}
>         error-counter-tx-rx{{248}{0}}
>   can0  20000042  [8] 00 00 00 00 00 00 80 00   ERRORFRAME
>         lost-arbitration{at bit 0}
>         bus-off
>         error-counter-tx-rx{{128}{0}}
>   can0  20000006  [8] 00 00 00 00 00 00 18 00   ERRORFRAME
>         lost-arbitration{at bit 0}
>         controller-problem{}
>         error-counter-tx-rx{{24}{0}}
>   can0  20000004  [8] 00 10 00 00 00 00 4F 80   ERRORFRAME
>         controller-problem{rx-error-passive}
>         error-counter-tx-rx{{79}{128}}
>   [...]
>   can0  20000006  [8] 00 10 00 00 00 00 77 80   ERRORFRAME
>         lost-arbitration{at bit 0}
>         controller-problem{rx-error-passive}
>         error-counter-tx-rx{{119}{128}}
>   can0  20000006  [8] 00 30 00 00 00 00 7F 80   ERRORFRAME
>         lost-arbitration{at bit 0}
>         controller-problem{rx-error-passive,tx-error-passive}
>         error-counter-tx-rx{{127}{128}}
>   can0  20000006  [8] 00 30 00 00 00 00 87 80   ERRORFRAME
>         lost-arbitration{at bit 0}
>         controller-problem{rx-error-passive,tx-error-passive}
>         error-counter-tx-rx{{135}{128}}
>   [...]
>   can0  20000006  [8] 00 30 00 00 00 00 F7 80   ERRORFRAME
>         lost-arbitration{at bit 0}
>         controller-problem{rx-error-passive,tx-error-passive}
>         error-counter-tx-rx{{247}{128}}
>   can0  20000006  [8] 00 30 00 00 00 00 FF 80   ERRORFRAME
>         lost-arbitration{at bit 0}
>         controller-problem{rx-error-passive,tx-error-passive}
>         error-counter-tx-rx{{255}{128}}
>   can0  20000042  [8] 00 00 00 00 00 00 80 00   ERRORFRAME
>         lost-arbitration{at bit 0}
>         bus-off
>         error-counter-tx-rx{{128}{0}}
>   can0  20000006  [8] 00 00 00 00 00 00 18 00   ERRORFRAME
>         lost-arbitration{at bit 0}
>         controller-problem{}
>         error-counter-tx-rx{{24}{0}}
>   can0  20000004  [8] 00 10 00 00 00 00 4F 80   ERRORFRAME
>         controller-problem{rx-error-passive}
>         error-counter-tx-rx{{79}{128}}
>   can0  20000006  [8] 00 10 00 00 00 00 57 80   ERRORFRAME
>         lost-arbitration{at bit 0}
>         controller-problem{rx-error-passive}
>         error-counter-tx-rx{{87}{128}}
>   [...]

Also a sequence to bus-off including the recovery would be nice.

Wolfgang.


^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v3] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-10-31 12:51                 ` Wolfgang Grandegger
@ 2012-10-31 16:33                   ` Andreas Larsson
  2012-10-31 16:39                     ` [PATCH v4] " Andreas Larsson
  2012-10-31 20:21                     ` [PATCH v3] " Wolfgang Grandegger
  0 siblings, 2 replies; 41+ messages in thread
From: Andreas Larsson @ 2012-10-31 16:33 UTC (permalink / raw)
  To: Wolfgang Grandegger
  Cc: linux-can, Marc Kleine-Budde, devicetree-discuss, software

On 2012-10-31 13:51, Wolfgang Grandegger wrote:
> On 10/30/2012 05:24 PM, Andreas Larsson wrote:
>> On 10/30/2012 11:07 AM, Wolfgang Grandegger wrote:
>>>> +    /* AHB bus error interrupts (not CAN bus errors) - shut down the
>>>> +     * device.
>>>> +     */
>>>> +    if (sources & (GRCAN_IRQ_TXAHBERR | GRCAN_IRQ_RXAHBERR)) {
>>>> +        if (sources & GRCAN_IRQ_TXAHBERR) {
>>>> +            netdev_err(dev, "got AHB bus error on tx\n");
>>>> +            stats->tx_errors++;
>>>> +        } else {
>>>> +            netdev_err(dev, "got AHB bus error on rx\n");
>>>> +            stats->rx_errors++;
>>>> +        }
>>>> +        netdev_err(dev, "halting device\n");
>>>> +
>>>> +        /* Prevent anything to be enabled again and halt device */
>>>> +        SPIN_LOCK(&priv->lock);
>>>> +        priv->closing = true;
>>>> +        netif_stop_queue(dev);
>>>> +        grcan_stop(dev);
>>>> +        SPIN_UNLOCK(&priv->lock);
>>>
>>> Hm, does that really happen? How can the user/app realized the problem
>>> and recover?
>>
>> My understanding of it is that if you get amba bus errors something is
>> seriously wrong and nothing can be done at driver level to recover.
>> Shutting down the device is to prevent the driver from spamming console
>> messages. I used to have a sysfs indication of such errors. Now dmesg is
>> the way to find out about the problem. The user can always bring the
>> interface down and up again and try again after such an error.
>
> Well, sounds like a fatal error. Did you ever saw it? If that happens
> frequently, or even once, the device/system seems not really usable.

Fatal and yes if this is ever seen something is very bad with the system. I have 
never seen it. However the hardware reports if it would happen, so why not try 
to take care of it in some manner. If this is seen the can device is probably 
useless but it is possible that the rest of the system might be usable. I don't 
really know in what circumstances this would trigger.


>>> Furthermore, why is a spin_clock enough here? THe interrupt may run a
>>> thread.
>>
>> It should be enough because the function is only called
>> directly from the interrupt handler, right? Or did I miss something?
>
> The interrupt handler may run as thread, e.g. if the -rt patch has been
> applied. Therefore it's safer to use the irqsave/restore variants of the
> spin_lock functions. At least that's my understanding. See also
> "Documentation/spinlock.txt".

I'll look into this. Seems strange if the same cpu can be interrupted in an 
interrupt handler to run the very same interrupt handler. Sounds like a horrible 
situation for any driver that does not lock down most of its interrupt handler. 
Or maybe there is some situation that I don't foresee.


>>>> +    priv->can.ctrlmode_supported  =
>>>> +        CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_ONE_SHOT;
>>>
>>> What about triple-sampling?
>>
>> That is not supported by the hardware.

Well, now it will be in future versions of the controller, so support is added 
to the driver.


>>> I curious how the device behaves on bus errors and state changes. Could
>>> you please show the output of "candump -e any,0:0,#FFFFFFFF" while
>>> sending a CAN message with no other node on the bus (not connected) and
>>> with going bus off (by short-circuiting CAN high and low).
>>
>>
>> Here is the output (with long sequences of similar error frames
>> where only one counter is increasing cut out) from the the upcoming v4.
>> let me know if you see any problems with this.
>
> How did your trigger that sequence? Short-circuit or not cable
> connected? The latter, I assume, as bus-off is not reached.

Triggered by short-circuiting, just as asked.


>>
>>    can0  20000006  [8] 00 00 00 00 00 00 10 00   ERRORFRAME
>>          lost-arbitration{at bit 0}
>>          controller-problem{}
>>          error-counter-tx-rx{{16}{0}}
>
> This is most probably an ack slot bus error similar to. You seem not to
> handle bus errors and it's not a controller problem as the state did not
> change.

No, the hardware has no support for can-bus error reporting.


> http://lxr.linux.no/#linux+v3.6.4/drivers/net/can/flexcan.c#L353
>
>>    can0  20000004  [8] 00 20 00 00 00 00 88 00   ERRORFRAME
>>          controller-problem{tx-error-passive}
>>          error-counter-tx-rx{{136}{0}}
>
> OK, a state change to error passive. The device seems not to report
> changes to error warning.

No, there is no interrupts or anything that alert about the error states. That 
is why I set the sate based on the error counters in the error handler.


>>    can0  20000006  [8] 00 20 00 00 00 00 90 00   ERRORFRAME
>>          lost-arbitration{at bit 0}
>>          controller-problem{tx-error-passive}
>>          error-counter-tx-rx{{144}{0}}
>
> State changes should be reported only once.

Do you mean that an error message should only be sent on state change?


> But it did not change. This
> is then a bus error (CAN_ERR_PROT | CAN_ERR_BUSERROR). See also above.
>
>>    [...]
>>    can0  20000006  [8] 00 20 00 00 00 00 F0 00   ERRORFRAME
>>          lost-arbitration{at bit 0}
>>          controller-problem{tx-error-passive}
>>          error-counter-tx-rx{{240}{0}}
>>    can0  20000006  [8] 00 20 00 00 00 00 F8 00   ERRORFRAME
>>          lost-arbitration{at bit 0}
>>          controller-problem{tx-error-passive}
>>          error-counter-tx-rx{{248}{0}}
>>    can0  20000042  [8] 00 00 00 00 00 00 80 00   ERRORFRAME
>>          lost-arbitration{at bit 0}
>>          bus-off
>>          error-counter-tx-rx{{128}{0}}
>>    can0  20000006  [8] 00 00 00 00 00 00 18 00   ERRORFRAME
>>          lost-arbitration{at bit 0}
>>          controller-problem{}
>>          error-counter-tx-rx{{24}{0}}
>>    can0  20000004  [8] 00 10 00 00 00 00 4F 80   ERRORFRAME
>>          controller-problem{rx-error-passive}
>>          error-counter-tx-rx{{79}{128}}
>>    [...]
>>    can0  20000006  [8] 00 10 00 00 00 00 77 80   ERRORFRAME
>>          lost-arbitration{at bit 0}
>>          controller-problem{rx-error-passive}
>>          error-counter-tx-rx{{119}{128}}
>>    can0  20000006  [8] 00 30 00 00 00 00 7F 80   ERRORFRAME
>>          lost-arbitration{at bit 0}
>>          controller-problem{rx-error-passive,tx-error-passive}
>>          error-counter-tx-rx{{127}{128}}
>>    can0  20000006  [8] 00 30 00 00 00 00 87 80   ERRORFRAME
>>          lost-arbitration{at bit 0}
>>          controller-problem{rx-error-passive,tx-error-passive}
>>          error-counter-tx-rx{{135}{128}}
>>    [...]
>>    can0  20000006  [8] 00 30 00 00 00 00 F7 80   ERRORFRAME
>>          lost-arbitration{at bit 0}
>>          controller-problem{rx-error-passive,tx-error-passive}
>>          error-counter-tx-rx{{247}{128}}
>>    can0  20000006  [8] 00 30 00 00 00 00 FF 80   ERRORFRAME
>>          lost-arbitration{at bit 0}
>>          controller-problem{rx-error-passive,tx-error-passive}
>>          error-counter-tx-rx{{255}{128}}
>>    can0  20000042  [8] 00 00 00 00 00 00 80 00   ERRORFRAME
>>          lost-arbitration{at bit 0}
>>          bus-off
>>          error-counter-tx-rx{{128}{0}}
>>    can0  20000006  [8] 00 00 00 00 00 00 18 00   ERRORFRAME
>>          lost-arbitration{at bit 0}
>>          controller-problem{}
>>          error-counter-tx-rx{{24}{0}}
>>    can0  20000004  [8] 00 10 00 00 00 00 4F 80   ERRORFRAME
>>          controller-problem{rx-error-passive}
>>          error-counter-tx-rx{{79}{128}}
>>    can0  20000006  [8] 00 10 00 00 00 00 57 80   ERRORFRAME
>>          lost-arbitration{at bit 0}
>>          controller-problem{rx-error-passive}
>>          error-counter-tx-rx{{87}{128}}
>>    [...]
>
> Also a sequence to bus-off including the recovery would be nice.

Here is a longer unedited run up to the second bus-off (also with 
short-circuited bus)

   can0  20000006  [8] 00 00 00 00 00 00 20 00   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{}
         error-counter-tx-rx{{32}{0}}
   can0  20000004  [8] 00 20 00 00 00 00 88 00   ERRORFRAME
         controller-problem{tx-error-passive}
         error-counter-tx-rx{{136}{0}}
   can0  20000006  [8] 00 20 00 00 00 00 90 00   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{tx-error-passive}
         error-counter-tx-rx{{144}{0}}
   can0  20000006  [8] 00 20 00 00 00 00 98 00   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{tx-error-passive}
         error-counter-tx-rx{{152}{0}}
   can0  20000006  [8] 00 20 00 00 00 00 A0 00   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{tx-error-passive}
         error-counter-tx-rx{{160}{0}}
   can0  20000006  [8] 00 20 00 00 00 00 A8 00   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{tx-error-passive}
         error-counter-tx-rx{{168}{0}}
   can0  20000006  [8] 00 20 00 00 00 00 B0 00   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{tx-error-passive}
         error-counter-tx-rx{{176}{0}}
   can0  20000006  [8] 00 20 00 00 00 00 B8 00   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{tx-error-passive}
         error-counter-tx-rx{{184}{0}}
   can0  20000006  [8] 00 20 00 00 00 00 C0 00   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{tx-error-passive}
         error-counter-tx-rx{{192}{0}}
   can0  20000006  [8] 00 20 00 00 00 00 C8 00   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{tx-error-passive}
         error-counter-tx-rx{{200}{0}}
   can0  20000006  [8] 00 20 00 00 00 00 D0 00   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{tx-error-passive}
         error-counter-tx-rx{{208}{0}}
   can0  20000006  [8] 00 20 00 00 00 00 D8 00   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{tx-error-passive}
         error-counter-tx-rx{{216}{0}}
   can0  20000006  [8] 00 20 00 00 00 00 E0 00   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{tx-error-passive}
         error-counter-tx-rx{{224}{0}}
   can0  20000006  [8] 00 20 00 00 00 00 E8 00   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{tx-error-passive}
         error-counter-tx-rx{{232}{0}}
   can0  20000006  [8] 00 20 00 00 00 00 F0 00   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{tx-error-passive}
         error-counter-tx-rx{{240}{0}}
   can0  20000006  [8] 00 20 00 00 00 00 F8 00   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{tx-error-passive}
         error-counter-tx-rx{{248}{0}}
   can0  20000042  [8] 00 00 00 00 00 00 80 00   ERRORFRAME
         lost-arbitration{at bit 0}
         bus-off
         error-counter-tx-rx{{128}{0}}
   can0  20000006  [8] 00 00 00 00 00 00 20 00   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{}
         error-counter-tx-rx{{32}{0}}
   can0  20000006  [8] 00 10 00 00 00 00 57 80   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{rx-error-passive}
         error-counter-tx-rx{{87}{128}}
   can0  20000006  [8] 00 10 00 00 00 00 5F 80   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{rx-error-passive}
         error-counter-tx-rx{{95}{128}}
   can0  20000006  [8] 00 10 00 00 00 00 67 80   ERRORFRAME
         lost-arbitration{at bit 0}
         error-counter-tx-rx{{103}{128}}
   can0  20000006  [8] 00 10 00 00 00 00 6F 80   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{rx-error-passive}
         error-counter-tx-rx{{111}{128}}
   can0  20000006  [8] 00 10 00 00 00 00 77 80   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{rx-error-passive}
         error-counter-tx-rx{{119}{128}}
   can0  20000006  [8] 00 30 00 00 00 00 7F 80   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{rx-error-passive,tx-error-passive}
         error-counter-tx-rx{{127}{128}}
   can0  20000006  [8] 00 30 00 00 00 00 87 80   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{rx-error-passive,tx-error-passive}
         error-counter-tx-rx{{135}{128}}
   can0  20000006  [8] 00 30 00 00 00 00 8F 80   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{rx-error-passive,tx-error-passive}
         error-counter-tx-rx{{143}{128}}
   can0  20000006  [8] 00 30 00 00 00 00 97 80   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{rx-error-passive,tx-error-passive}
         error-counter-tx-rx{{151}{128}}
   can0  20000006  [8] 00 30 00 00 00 00 9F 80   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{rx-error-passive,tx-error-passive}
         error-counter-tx-rx{{159}{128}}
   can0  20000006  [8] 00 30 00 00 00 00 A7 80   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{rx-error-passive,tx-error-passive}
         error-counter-tx-rx{{167}{128}}
   can0  20000006  [8] 00 30 00 00 00 00 AF 80   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{rx-error-passive,tx-error-passive}
         error-counter-tx-rx{{175}{128}}
   can0  20000006  [8] 00 30 00 00 00 00 B7 80   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{rx-error-passive,tx-error-passive}
         error-counter-tx-rx{{183}{128}}
   can0  20000006  [8] 00 30 00 00 00 00 BF 80   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{rx-error-passive,tx-error-passive}
         error-counter-tx-rx{{191}{128}}
   can0  20000006  [8] 00 30 00 00 00 00 C7 80   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{rx-error-passive,tx-error-passive}
         error-counter-tx-rx{{199}{128}}
   can0  20000006  [8] 00 30 00 00 00 00 CF 80   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{rx-error-passive,tx-error-passive}
         error-counter-tx-rx{{207}{128}}
   can0  20000006  [8] 00 30 00 00 00 00 D7 80   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{rx-error-passive,tx-error-passive}
         error-counter-tx-rx{{215}{128}}
   can0  20000006  [8] 00 30 00 00 00 00 DF 80   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{rx-error-passive,tx-error-passive}
         error-counter-tx-rx{{223}{128}}
   can0  20000006  [8] 00 30 00 00 00 00 E7 80   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{rx-error-passive,tx-error-passive}
         error-counter-tx-rx{{231}{128}}
   can0  20000006  [8] 00 30 00 00 00 00 EF 80   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{rx-error-passive,tx-error-passive}
         error-counter-tx-rx{{239}{128}}
   can0  20000006  [8] 00 30 00 00 00 00 F7 80   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{rx-error-passive,tx-error-passive}
         error-counter-tx-rx{{247}{128}}
   can0  20000006  [8] 00 30 00 00 00 00 FF 80   ERRORFRAME
         lost-arbitration{at bit 0}
         controller-problem{rx-error-passive,tx-error-passive}
         error-counter-tx-rx{{255}{128}}
   can0  20000042  [8] 00 00 00 00 00 00 80 00   ERRORFRAME
         lost-arbitration{at bit 0}
         bus-off
         error-counter-tx-rx{{128}{0}}


Thanks for the input! I'll send in v4 so you can see what the code that 
generated the above.

Cheers,
Andreas


^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH v4] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-10-31 16:33                   ` Andreas Larsson
@ 2012-10-31 16:39                     ` Andreas Larsson
  2012-10-31 20:21                     ` [PATCH v3] " Wolfgang Grandegger
  1 sibling, 0 replies; 41+ messages in thread
From: Andreas Larsson @ 2012-10-31 16:39 UTC (permalink / raw)
  To: wg, linux-can; +Cc: mkl, devicetree-discuss, software

This driver supports GRCAN and CRHCAN CAN controllers available in the GRLIB
VHDL IP core library.

Signed-off-by: Andreas Larsson <andreas@gaisler.com>
---
 Documentation/ABI/testing/sysfs-class-net-grcan    |   35 +
 .../devicetree/bindings/net/can/grcan.txt          |   27 +
 Documentation/kernel-parameters.txt                |   25 +
 drivers/net/can/Kconfig                            |    9 +
 drivers/net/can/Makefile                           |    1 +
 drivers/net/can/grcan.c                            | 1667 ++++++++++++++++++++
 6 files changed, 1764 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-class-net-grcan
 create mode 100644 Documentation/devicetree/bindings/net/can/grcan.txt
 create mode 100644 drivers/net/can/grcan.c

diff --git a/Documentation/ABI/testing/sysfs-class-net-grcan b/Documentation/ABI/testing/sysfs-class-net-grcan
new file mode 100644
index 0000000..8fa2f90
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-net-grcan
@@ -0,0 +1,35 @@
+
+What:		/sys/class/net/<iface>/grcan/enable0
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas@gaisler.com>
+Description:
+		Hardware configuration of physical interface 0. This file reads
+		and writes the "Enable 0" bit of the configuration register.
+		Possible values: 0 or 1. See the GRCAN chapter of the GRLIB IP
+		core library documentation for details.
+		The default value is set by the module parameter enable0 and can
+		be read at /sys/module/grcan/parameters/enable0.
+
+What:		/sys/class/net/<iface>/grcan/enable1
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas@gaisler.com>
+Description:
+		Hardware configuration of physical interface 1. This file reads
+		and writes the "Enable 1" bit of the configuration register.
+		Possible values: 0 or 1. See the GRCAN chapter of the GRLIB IP
+		core library documentation for details.
+		The default value is set by the module parameter enable1 and can
+		be read at /sys/module/grcan/parameters/enable1.
+
+What:		/sys/class/net/<iface>/grcan/selection
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas@gaisler.com>
+Description:
+		Configuration of which physical interface to be used. Possible
+		values: 0 or 1. See the GRCAN chapter of the GRLIB IP core
+		library documentation for details.
+		The default value is set by the module parameter selection and can
+		be read at /sys/module/grcan/parameters/selection.
diff --git a/Documentation/devicetree/bindings/net/can/grcan.txt b/Documentation/devicetree/bindings/net/can/grcan.txt
new file mode 100644
index 0000000..a7180f1
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/can/grcan.txt
@@ -0,0 +1,27 @@
+CAN controller for Aeroflex Gaisler GRCAN and GRHCAN.
+
+The GRCAN and CRHCAN CAN controllers are available in the GRLIB VHDL IP core
+library.
+
+Note: These properties are built from the AMBA plug&play in a Leon SPARC
+system (the ordinary environment for GRCAN and GRHCAN). There are no bsp
+files for sparc.
+
+Required properties:
+
+- name : Should be "GAISLER_GRCAN", "01_03d", "GAISLER_GRHCAN" or "01_034"
+
+- reg : Address and length of the register set for the device
+
+- freq : Frequency of the external oscillator clock in Hz (the frequency of
+	the amba bus in the ordinary case)
+
+- interrupts : Interrupt number for this device
+
+Optional properties:
+
+- systemid : If not present or if the value of the least significant 16 bits
+	of this 32-bit property is smaller than GRCAN_TXBUG_SAFE_GRLIB_VERSION
+	a bug workaround is activated.
+
+For further information look in the documentation for the GLIB IP core library.
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 9776f06..3a82433 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -905,6 +905,31 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 	gpt		[EFI] Forces disk with valid GPT signature but
 			invalid Protective MBR to be treated as GPT.
 
+	grcan.enable0=	[HW] The "Enable 0" bit of the configuration
+			register. For more documentation, see
+			Documentation/ABI/testing/sysfs-class-net-grcan
+			Format: 0 | 1
+			Default: 0
+	grcan.enable1=	[HW] The "Enable 1" bit of the configuration
+			register. For more documentation, see
+			Documentation/ABI/testing/sysfs-class-net-grcan.
+			Format: 0 | 1
+			Default: 0
+	grcan.selection=
+			[HW] Selection of which physical interface to be
+			used. For more documentation, see
+			Documentation/ABI/testing/sysfs-class-net-grcan.
+			Format: 0 | 1
+			Default: 0
+	grcan.txsize=	[HW] The size of the tx buffer. For more documentation,
+			see Documentation/ABI/testing/sysfs-class-net-grcan.
+			Format: <value> such that (value & 0x1fffc0) == 0.
+			Default: 1024
+	grcan.rxsize=	[HW] The size of the rx buffer. For more documentation,
+			see Documentation/ABI/testing/sysfs-class-net-grcan.
+			Format: <value> such that (value & 0x1fffc0) == 0.
+			Default: 1024
+
 	hashdist=	[KNL,NUMA] Large hashes allocated during boot
 			are distributed across NUMA nodes.  Defaults on
 			for 64-bit NUMA, off otherwise.
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
index bb709fd..b56bd9e 100644
--- a/drivers/net/can/Kconfig
+++ b/drivers/net/can/Kconfig
@@ -110,6 +110,15 @@ config PCH_CAN
 	  is an IOH for x86 embedded processor (Intel Atom E6xx series).
 	  This driver can access CAN bus.
 
+config CAN_GRCAN
+	tristate "Aeroflex Gaisler GRCAN and GRHCAN CAN devices"
+	depends on CAN_DEV && OF
+	---help---
+	  Say Y here if you want to use Aeroflex Gaisler GRCAN or GRHCAN.
+	  Note that the driver supports little endian, even though little
+	  endian syntheses of the cores would need some modifications on
+	  the hardware level to work.
+
 source "drivers/net/can/mscan/Kconfig"
 
 source "drivers/net/can/sja1000/Kconfig"
diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
index 938be37..7de5986 100644
--- a/drivers/net/can/Makefile
+++ b/drivers/net/can/Makefile
@@ -22,5 +22,6 @@ obj-$(CONFIG_CAN_BFIN)		+= bfin_can.o
 obj-$(CONFIG_CAN_JANZ_ICAN3)	+= janz-ican3.o
 obj-$(CONFIG_CAN_FLEXCAN)	+= flexcan.o
 obj-$(CONFIG_PCH_CAN)		+= pch_can.o
+obj-$(CONFIG_CAN_GRCAN)		+= grcan.o
 
 ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/grcan.c b/drivers/net/can/grcan.c
new file mode 100644
index 0000000..3f0102e
--- /dev/null
+++ b/drivers/net/can/grcan.c
@@ -0,0 +1,1667 @@
+/*
+ * Socket CAN driver for Aeroflex Gaisler GRCAN and GRHCAN.
+ *
+ * 2012 (c) Aeroflex Gaisler AB
+ *
+ * This driver supports GRCAN and GRHCAN CAN controllers available in the GRLIB
+ * VHDL IP core library.
+ *
+ * Full documentation of the GRCAN core can be found here:
+ * http://www.gaisler.com/products/grlib/grip.pdf
+ *
+ * See "Documentation/devicetree/bindings/net/can/grcan.txt" for information on
+ * open firmware properties.
+ *
+ * See "Documentation/ABI/testing/sysfs-class-net-grcan" for information on the
+ * sysfs interface.
+ *
+ * See "Documentation/kernel-parameters.txt" for information on the module
+ * parameters.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Contributors: Andreas Larsson <andreas@gaisler.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/can/dev.h>
+#include <linux/spinlock.h>
+
+#include <linux/of_platform.h>
+#include <asm/prom.h>
+
+#include <linux/of_irq.h>
+
+#include <linux/dma-mapping.h>
+
+#define DRV_NAME	"grcan"
+
+#define GRCAN_NAPI_WEIGHT	16
+
+#define GRCAN_RESERVE_SIZE(slot1, slot2) (((slot2) - (slot1)) / 4 - 1)
+
+struct grcan_registers {
+	u32 conf;	/* 0x00 */
+	u32 stat;	/* 0x04 */
+	u32 ctrl;	/* 0x08 */
+	u32 __reserved1[GRCAN_RESERVE_SIZE(0x08, 0x18)];
+	u32 smask;	/* 0x18 - CanMASK */
+	u32 scode;	/* 0x1c - CanCODE */
+	u32 __reserved2[GRCAN_RESERVE_SIZE(0x1c, 0x100)];
+	u32 pimsr;	/* 0x100 */
+	u32 pimr;	/* 0x104 */
+	u32 pisr;	/* 0x108 */
+	u32 pir;	/* 0x10C */
+	u32 imr;	/* 0x110 */
+	u32 picr;	/* 0x114 */
+	u32 __reserved3[GRCAN_RESERVE_SIZE(0x114, 0x200)];
+	u32 txctrl;	/* 0x200 */
+	u32 txaddr;	/* 0x204 */
+	u32 txsize;	/* 0x208 */
+	u32 txwr;	/* 0x20C */
+	u32 txrd;	/* 0x210 */
+	u32 txirq;	/* 0x214 */
+	u32 __reserved4[GRCAN_RESERVE_SIZE(0x214, 0x300)];
+	u32 rxctrl;	/* 0x300 */
+	u32 rxaddr;	/* 0x304 */
+	u32 rxsize;	/* 0x308 */
+	u32 rxwr;	/* 0x30C */
+	u32 rxrd;	/* 0x310 */
+	u32 rxirq;	/* 0x314 */
+	u32 rxmask;	/* 0x318 */
+	u32 rxcode;	/* 0x31C */
+};
+
+#define GRCAN_CONF_ABORT	0x00000001
+#define GRCAN_CONF_ENABLE0	0x00000002
+#define GRCAN_CONF_ENABLE1	0x00000004
+#define GRCAN_CONF_SELECTION	0x00000008
+#define GRCAN_CONF_SILENT	0x00000010
+#define GRCAN_CONF_TRIPLESAMP	0x00000020 /* Available in some hardware */
+#define GRCAN_CONF_BPR		0x00000300 /* Note: not BRP */
+#define GRCAN_CONF_RSJ		0x00007000
+#define GRCAN_CONF_PS1		0x00f00000
+#define GRCAN_CONF_PS2		0x000f0000
+#define GRCAN_CONF_SCALER	0xff000000
+#define GRCAN_CONF_OPERATION						\
+	(GRCAN_CONF_ABORT | GRCAN_CONF_ENABLE0 | GRCAN_CONF_ENABLE1	\
+	 | GRCAN_CONF_SELECTION | GRCAN_CONF_SILENT			\
+	 | GRCAN_CONF_TRIPLESAMP)
+#define GRCAN_CONF_TIMING						\
+	(GRCAN_CONF_BPR | GRCAN_CONF_RSJ | GRCAN_CONF_PS1		\
+	 | GRCAN_CONF_PS2 | GRCAN_CONF_SCALER)
+
+#define GRCAN_CONF_RSJ_MIN	1
+#define GRCAN_CONF_RSJ_MAX	4
+#define GRCAN_CONF_PS1_MIN	1
+#define GRCAN_CONF_PS1_MAX	15
+#define GRCAN_CONF_PS2_MIN	2
+#define GRCAN_CONF_PS2_MAX	8
+#define GRCAN_CONF_SCALER_MIN	0
+#define GRCAN_CONF_SCALER_MAX	255
+#define GRCAN_CONF_SCALER_INC	1
+
+#define GRCAN_CONF_BPR_BIT	8
+#define GRCAN_CONF_RSJ_BIT	12
+#define GRCAN_CONF_PS1_BIT	20
+#define GRCAN_CONF_PS2_BIT	16
+#define GRCAN_CONF_SCALER_BIT	24
+
+#define GRCAN_STAT_PASS		0x000001
+#define GRCAN_STAT_OFF		0x000002
+#define GRCAN_STAT_OR		0x000004
+#define GRCAN_STAT_AHBERR	0x000008
+#define GRCAN_STAT_ACTIVE	0x000010
+#define GRCAN_STAT_RXERRCNT	0x00ff00
+#define GRCAN_STAT_TXERRCNT	0xff0000
+
+#define GRCAN_STAT_RXERRCNT_BIT	8
+#define GRCAN_STAT_TXERRCNT_BIT	16
+
+#define GRCAN_STAT_ERRCNT_WARNING_LIMIT	96
+#define GRCAN_STAT_ERRCNT_PASSIVE_LIMIT	127
+
+
+#define GRCAN_CTRL_RESET	0x2
+#define GRCAN_CTRL_ENABLE	0x1
+
+#define GRCAN_TXCTRL_ENABLE	0x1
+#define GRCAN_TXCTRL_ONGOING	0x2
+#define GRCAN_TXCTRL_SINGLE	0x4
+
+#define GRCAN_RXCTRL_ENABLE	0x1
+#define GRCAN_RXCTRL_ONGOING	0x2
+
+/* Relative offset of IRQ sources to AMBA Plug&Play */
+#define GRCAN_IRQIX_IRQ		0
+#define GRCAN_IRQIX_TXSYNC	1
+#define GRCAN_IRQIX_RXSYNC	2
+
+#define GRCAN_IRQ_PASS		0x00001
+#define GRCAN_IRQ_OFF		0x00002
+#define GRCAN_IRQ_OR		0x00004
+#define GRCAN_IRQ_RXAHBERR	0x00008
+#define GRCAN_IRQ_TXAHBERR	0x00010
+#define GRCAN_IRQ_RXIRQ		0x00020
+#define GRCAN_IRQ_TXIRQ		0x00040
+#define GRCAN_IRQ_RXFULL	0x00080
+#define GRCAN_IRQ_TXEMPTY	0x00100
+#define GRCAN_IRQ_RX		0x00200
+#define GRCAN_IRQ_TX		0x00400
+#define GRCAN_IRQ_RXSYNC	0x00800
+#define GRCAN_IRQ_TXSYNC	0x01000
+#define GRCAN_IRQ_RXERRCTR	0x02000
+#define GRCAN_IRQ_TXERRCTR	0x04000
+#define GRCAN_IRQ_RXMISS	0x08000
+#define GRCAN_IRQ_TXLOSS	0x10000
+
+#define GRCAN_IRQ_NONE	0
+#define GRCAN_IRQ_ALL							\
+	(GRCAN_IRQ_PASS | GRCAN_IRQ_OFF | GRCAN_IRQ_OR			\
+	 | GRCAN_IRQ_RXAHBERR | GRCAN_IRQ_TXAHBERR			\
+	 | GRCAN_IRQ_RXIRQ | GRCAN_IRQ_TXIRQ				\
+	 | GRCAN_IRQ_RXFULL | GRCAN_IRQ_TXEMPTY				\
+	 | GRCAN_IRQ_RX | GRCAN_IRQ_TX | GRCAN_IRQ_RXSYNC		\
+	 | GRCAN_IRQ_TXSYNC | GRCAN_IRQ_RXERRCTR			\
+	 | GRCAN_IRQ_TXERRCTR | GRCAN_IRQ_RXMISS			\
+	 | GRCAN_IRQ_TXLOSS)
+
+#define GRCAN_IRQ_ERRCTR_RELATED (GRCAN_IRQ_RXERRCTR | GRCAN_IRQ_TXERRCTR \
+				  | GRCAN_IRQ_PASS | GRCAN_IRQ_OFF)
+#define GRCAN_IRQ_ERRORS (GRCAN_IRQ_ERRCTR_RELATED | GRCAN_IRQ_OR	\
+			  | GRCAN_IRQ_TXAHBERR | GRCAN_IRQ_RXAHBERR	\
+			  | GRCAN_IRQ_TXLOSS)
+#define GRCAN_IRQ_DEFAULT (GRCAN_IRQ_RX | GRCAN_IRQ_TX | GRCAN_IRQ_ERRORS)
+
+#define GRCAN_MSG_SIZE		16
+
+#define GRCAN_MSG_IDE		0x80000000
+#define GRCAN_MSG_RTR		0x40000000
+#define GRCAN_MSG_BID		0x1ffc0000
+#define GRCAN_MSG_EID		0x1fffffff
+#define GRCAN_MSG_IDE_BIT	31
+#define GRCAN_MSG_RTR_BIT	30
+#define GRCAN_MSG_BID_BIT	18
+#define GRCAN_MSG_EID_BIT	0
+
+#define GRCAN_MSG_DLC		0xf0000000
+#define GRCAN_MSG_TXERRC	0x00ff0000
+#define GRCAN_MSG_RXERRC	0x0000ff00
+#define GRCAN_MSG_DLC_BIT	28
+#define GRCAN_MSG_TXERRC_BIT	16
+#define GRCAN_MSG_RXERRC_BIT	8
+#define GRCAN_MSG_AHBERR	0x00000008
+#define GRCAN_MSG_OR		0x00000004
+#define GRCAN_MSG_OFF		0x00000002
+#define GRCAN_MSG_PASS		0x00000001
+
+#define GRCAN_MSG_DATA_SLOT_INDEX(i) (2 + (i) / 4)
+#define GRCAN_MSG_DATA_SHIFT(i) ((3 - (i) % 4) * 8)
+
+#define GRCAN_BUFFER_ALIGNMENT		1024
+#define GRCAN_DEFAULT_BUFFER_SIZE	1024
+#define GRCAN_VALID_TR_SIZE_MASK	0x001fffc0
+
+#define GRCAN_INVALID_BUFFER_SIZE(s)			\
+	((s) == 0 || ((s) & ~GRCAN_VALID_TR_SIZE_MASK))
+
+#if GRCAN_INVALID_BUFFER_SIZE(GRCAN_DEFAULT_BUFFER_SIZE)
+#error "Invalid default buffer size"
+#endif
+
+struct grcan_dma_buffer {
+	size_t size;
+	void *buf;
+	dma_addr_t handle;
+};
+
+struct grcan_dma {
+	size_t base_size;
+	void *base_buf;
+	dma_addr_t base_handle;
+	struct grcan_dma_buffer tx;
+	struct grcan_dma_buffer rx;
+};
+
+/* GRCAN configuration parameters */
+struct grcan_device_config {
+	unsigned short enable0;
+	unsigned short enable1;
+	unsigned short selection;
+	unsigned int txsize;
+	unsigned int rxsize;
+};
+
+#define GRCAN_DEFAULT_DEVICE_CONFIG {				\
+		.enable0	= 0,				\
+		.enable1	= 0,				\
+		.selection	= 0,				\
+		.txsize		= GRCAN_DEFAULT_BUFFER_SIZE,	\
+		.rxsize		= GRCAN_DEFAULT_BUFFER_SIZE,	\
+		}
+
+#define GRCAN_TXBUG_SAFE_GRLIB_VERSION	0x4100
+#define GRLIB_VERSION_MASK		0xffff
+
+
+/* GRCAN private data structure */
+struct grcan_priv {
+	struct can_priv can;	/* must be the first member */
+	struct net_device *dev;
+	struct napi_struct napi;
+
+	struct grcan_registers __iomem *regs;	/* ioremap'ed registers */
+	struct grcan_device_config config;
+	struct grcan_dma dma;
+
+	struct sk_buff **echo_skb;	/* We allocate this on our own */
+	u8 *txdlc;			/* Length of queued frames */
+
+	/* The echo skb pointer, pointing into echo_skb and indicating which
+	 * frames can be echoed back. See the "Notes on the tx cyclic buffer
+	 * handling"-comment for grcan_start_xmit for more details.
+	 */
+	u32 eskbp;
+
+	/* Lock for controlling changes to the netif tx queue state, accesses to
+	 * the echo_skb pointer eskbp and for making sure that a running reset
+	 * and/or a close of the interface is done without interference from
+	 * other parts of the code.
+	 *
+	 * The echo_skb pointer, eskbp, should only be accessed under this lock
+	 * as it can be changed in several places and together with decisions on
+	 * whether to wake up the tx queue.
+	 *
+	 * The tx queue must never be woken up if there is a running reset or
+	 * close in progress.
+	 *
+	 * A running reset (see below on need_txbug_workaround) should never be
+	 * done if the interface is closing down and several running resets
+	 * should never be scheduled simultaneously.
+	 */
+	spinlock_t lock;
+
+	/* Whether a workaround is needed due to a bug in older hardware. In
+	 * this case, the driver both tries to prevent the bug from being
+	 * triggered and recovers, if the bug nevertheless happens, by doing a
+	 * running reset. A running reset, resets the device and continues from
+	 * where it were without being noticeable from outside the driver (apart
+	 * from slight delays).
+	 */
+	bool need_txbug_workaround;
+
+	/* To trigger initization of running reset and to trigger running reset
+	 * respectively in the case of a hanged device due to a txbug.
+	 */
+	struct timer_list hang_timer;
+	struct timer_list rr_timer;
+
+	/* To avoid waking up the netif queue and restarting timers
+	 * when a reset is scheduled or when closing of the device is
+	 * undergoing
+	 */
+	bool resetting;
+	bool closing;
+};
+
+/* Wait time for a short wait for ongoing to clear */
+#define GRCAN_SHORTWAIT_USECS	10
+
+/* Limit on the number of transmitted bits of an eff frame according to the CAN
+ * specification: 1 bit start of frame, 32 bits arbitration field, 6 bits
+ * control field, 8 bytes data field, 16 bits crc field, 2 bits ACK field and 7
+ * bits end of frame
+ */
+#define GRCAN_EFF_FRAME_MAX_BITS	(1+32+6+8*8+16+2+7)
+
+#if defined(__BIG_ENDIAN)
+static inline u32 grcan_read_reg(u32 __iomem *reg)
+{
+	return ioread32be(reg);
+}
+
+static inline void grcan_write_reg(u32 __iomem *reg, u32 val)
+{
+	iowrite32be(val, reg);
+}
+#else
+static inline u32 grcan_read_reg(u32 __iomem *reg)
+{
+	return ioread32(reg);
+}
+
+static inline void grcan_write_reg(u32 __iomem *reg, u32 val)
+{
+	iowrite32(val, reg);
+}
+#endif
+
+static inline void grcan_clear_bits(u32 __iomem *reg, u32 mask)
+{
+	grcan_write_reg(reg, grcan_read_reg(reg) & ~mask);
+}
+
+static inline void grcan_set_bits(u32 __iomem *reg, u32 mask)
+{
+	grcan_write_reg(reg, grcan_read_reg(reg) | mask);
+}
+
+static inline u32 grcan_read_bits(u32 __iomem *reg, u32 mask)
+{
+	return grcan_read_reg(reg) & mask;
+}
+
+static inline void grcan_write_bits(u32 __iomem *reg, u32 value, u32 mask)
+{
+	u32 old = grcan_read_reg(reg);
+
+	grcan_write_reg(reg, (old & ~mask) | (value & mask));
+}
+
+/* a and b should both be in [0,size] and a == b == size should not hold */
+static inline u32 grcan_ring_add(u32 a, u32 b, u32 size)
+{
+	u32 sum = a + b;
+
+	if (sum < size)
+		return sum;
+	else
+		return sum - size;
+}
+
+/* a and b should both be in [0,size) */
+static inline u32 grcan_ring_sub(u32 a, u32 b, u32 size)
+{
+	return grcan_ring_add(a, size - b, size);
+}
+
+/* Available slots for new transmissions */
+static inline u32 grcan_txspace(size_t txsize, u32 txwr, u32 eskbp)
+{
+	u32 slots = txsize / GRCAN_MSG_SIZE - 1;
+	u32 used = grcan_ring_sub(txwr, eskbp, txsize) / GRCAN_MSG_SIZE;
+
+	return slots - used;
+}
+
+/* Configuration parameters that can be set via module parameters */
+static struct grcan_device_config grcan_module_config =
+	GRCAN_DEFAULT_DEVICE_CONFIG;
+
+static struct can_bittiming_const grcan_bittiming_const = {
+	.name		= DRV_NAME,
+	.tseg1_min	= GRCAN_CONF_PS1_MIN + 1,
+	.tseg1_max	= GRCAN_CONF_PS1_MAX + 1,
+	.tseg2_min	= GRCAN_CONF_PS2_MIN,
+	.tseg2_max	= GRCAN_CONF_PS2_MAX,
+	.sjw_max	= GRCAN_CONF_RSJ_MAX,
+	.brp_min	= GRCAN_CONF_SCALER_MIN + 1,
+	.brp_max	= GRCAN_CONF_SCALER_MAX + 1,
+	.brp_inc	= GRCAN_CONF_SCALER_INC,
+};
+
+static int grcan_set_bittiming(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct can_bittiming *bt = &priv->can.bittiming;
+	u32 timing = 0;
+	int bpr, rsj, ps1, ps2, scaler;
+
+	/* Should never happen - function will not be called when
+	 * device is up
+	 */
+	if (grcan_read_bits(&regs->ctrl, GRCAN_CTRL_ENABLE))
+		return -EBUSY;
+
+	bpr = 0; /* Note bpr and brp are different concepts */
+	rsj = bt->sjw;
+	ps1 = (bt->prop_seg + bt->phase_seg1) - 1; /* tseg1 - 1 */
+	ps2 = bt->phase_seg2;
+	scaler = (bt->brp - 1);
+	timing |= (bpr << GRCAN_CONF_BPR_BIT) & GRCAN_CONF_BPR;
+	timing |= (rsj << GRCAN_CONF_RSJ_BIT) & GRCAN_CONF_RSJ;
+	timing |= (ps1 << GRCAN_CONF_PS1_BIT) & GRCAN_CONF_PS1;
+	timing |= (ps2 << GRCAN_CONF_PS2_BIT) & GRCAN_CONF_PS2;
+	timing |= (scaler << GRCAN_CONF_SCALER_BIT) & GRCAN_CONF_SCALER;
+
+	dev_info(dev->dev.parent,
+		 "setting timing=0x%x\n", timing);
+	grcan_write_bits(&regs->conf, timing, GRCAN_CONF_TIMING);
+	return 0;
+}
+
+static int grcan_get_berr_counter(const struct net_device *dev,
+				  struct can_berr_counter *bec)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	u32 status = grcan_read_reg(&regs->stat);
+
+	bec->txerr = (status & GRCAN_STAT_TXERRCNT) >> GRCAN_STAT_TXERRCNT_BIT;
+	bec->rxerr = (status & GRCAN_STAT_RXERRCNT) >> GRCAN_STAT_RXERRCNT_BIT;
+	return 0;
+}
+
+static int grcan_poll(struct napi_struct *napi, int budget);
+
+/* Reset device, but keep configuration information */
+static void grcan_reset(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	u32 config = grcan_read_reg(&regs->conf);
+
+	grcan_set_bits(&regs->ctrl, GRCAN_CTRL_RESET);
+	grcan_write_reg(&regs->conf, config);
+
+	priv->eskbp = grcan_read_reg(&regs->txrd);
+	priv->can.state = CAN_STATE_STOPPED;
+
+	/* Turn off hardware filtering - regs->rxcode set to 0 by reset */
+	grcan_write_reg(&regs->rxmask, 0);
+}
+
+/* stop device without changing any configurations */
+static void grcan_stop(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+
+	grcan_write_reg(&regs->imr, GRCAN_IRQ_NONE);
+	grcan_clear_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
+	grcan_clear_bits(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+	grcan_clear_bits(&regs->ctrl, GRCAN_CTRL_ENABLE);
+	priv->can.state = CAN_STATE_STOPPED;
+}
+
+/* Let priv->eskbp catch up to regs->txrd and echo back the skbs if echo
+ * is true and free them otherwise.
+ *
+ * If budget is >= 0, stop after handling at most budget skbs. Otherwise,
+ * continue until priv->eskbp catches up to regs->txrd.
+ *
+ * priv->lock *must* be held when calling this function
+ */
+static int catch_up_echo_skb(struct net_device *dev, int budget, bool echo)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	struct net_device_stats *stats = &dev->stats;
+	int i, work_done;
+
+	/* Updates to priv->eskbp and wake-ups of the queue needs to
+	 * be atomic towards the reads of priv->eskbp and shut-downs
+	 * of the queue in grcan_start_xmit.
+	 */
+	u32 txrd = grcan_read_reg(&regs->txrd);
+
+	for (work_done = 0; work_done < budget || budget < 0; work_done++) {
+		if (priv->eskbp == txrd)
+			break;
+		i = priv->eskbp / GRCAN_MSG_SIZE;
+		if (echo) {
+			/* Normal echo of messages */
+			stats->tx_packets++;
+			stats->tx_bytes += priv->txdlc[i];
+			priv->txdlc[i] = 0;
+			can_get_echo_skb(dev, i);
+		} else {
+			/* For cleanup of untransmitted messages */
+			can_free_echo_skb(dev, i);
+		}
+
+		priv->eskbp = grcan_ring_add(priv->eskbp, GRCAN_MSG_SIZE,
+					     dma->tx.size);
+		txrd = grcan_read_reg(&regs->txrd);
+	}
+	return work_done;
+}
+
+static void grcan_lost_one_shot_frame(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	u32 txrd;
+
+	spin_lock(&priv->lock);
+
+	catch_up_echo_skb(dev, -1, true);
+
+	if (unlikely(grcan_read_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE))) {
+		/* Should never happen */
+		netdev_err(dev, "TXCTRL enabled at TXLOSS in one shot mode\n");
+	} else {
+		/* By the time an GRCAN_IRQ_TXLOSS is generated in
+		 * one-shot mode there is no problem in writing
+		 * to TXRD even in versions of the hardware in
+		 * which GRCAN_TXCTRL_ONGOING is not cleared properly
+		 * in one-shot mode.
+		 */
+
+		/* Skip message and discard echo-skb */
+		txrd = grcan_read_reg(&regs->txrd);
+		txrd = grcan_ring_add(txrd, GRCAN_MSG_SIZE, dma->tx.size);
+		grcan_write_reg(&regs->txrd, txrd);
+		catch_up_echo_skb(dev, -1, false);
+
+		if (!priv->resetting && !priv->closing &&
+		    !(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)) {
+			netif_wake_queue(dev);
+			grcan_set_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
+		}
+	}
+
+	spin_unlock(&priv->lock);
+}
+
+static void grcan_err(struct net_device *dev, u32 sources, u32 status)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct net_device_stats *stats = &dev->stats;
+	struct can_frame cf;
+
+	/* Zero potential error_frame */
+	memset(&cf, 0, sizeof(cf));
+
+	/* Arbitration lost interrupt */
+	if (sources & GRCAN_IRQ_TXLOSS) {
+		netdev_dbg(dev, "arbitration lost (or other comm failure)\n");
+		stats->tx_errors++;
+		priv->can.can_stats.arbitration_lost++;
+
+		/* Take care of failed one-shot transmit */
+		if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT)
+			grcan_lost_one_shot_frame(dev);
+
+		cf.can_id |= CAN_ERR_LOSTARB;
+	}
+
+	/* Conditions dealing with the error counters */
+	if (sources & GRCAN_IRQ_ERRCTR_RELATED) {
+		enum can_state state = priv->can.state;
+		enum can_state oldstate = state;
+		u32 txerr = (status & GRCAN_STAT_TXERRCNT)
+			>> GRCAN_STAT_TXERRCNT_BIT;
+		u32 rxerr = (status & GRCAN_STAT_RXERRCNT)
+			>> GRCAN_STAT_RXERRCNT_BIT;
+
+		if (status & GRCAN_STAT_OFF) {
+			state = CAN_STATE_BUS_OFF;
+			if (oldstate != state)
+				netdev_dbg(dev, "Bus off condition\n");
+			can_bus_off(dev);
+
+			cf.can_id |= CAN_ERR_BUSOFF;
+		} else if (status & GRCAN_STAT_PASS) {
+			priv->can.can_stats.error_passive++;
+			state = CAN_STATE_ERROR_PASSIVE;
+			if (oldstate != state)
+				netdev_dbg(dev, "Error passive condition\n");
+
+			cf.can_id |= CAN_ERR_CRTL;
+			if (txerr >= GRCAN_STAT_ERRCNT_PASSIVE_LIMIT)
+				cf.data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
+			if (rxerr >= GRCAN_STAT_ERRCNT_PASSIVE_LIMIT)
+				cf.data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
+		} else if (txerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT ||
+			   rxerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT) {
+			priv->can.can_stats.error_warning++;
+			state = CAN_STATE_ERROR_WARNING;
+			if (oldstate != state)
+				netdev_dbg(dev, "Error warning condition\n");
+
+			cf.can_id |= CAN_ERR_CRTL;
+			if (txerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT)
+				cf.data[1] |= CAN_ERR_CRTL_TX_WARNING;
+			if (rxerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT)
+				cf.data[1] |= CAN_ERR_CRTL_RX_WARNING;
+		} else {
+			state = CAN_STATE_ERROR_ACTIVE;
+			if (oldstate != state)
+				netdev_dbg(dev, "Error active condition\n");
+
+			cf.can_id |= CAN_ERR_CRTL;
+		}
+		cf.data[6] = txerr;
+		cf.data[7] = rxerr;
+		priv->can.state = state;
+	}
+
+	/* Data overrun interrupt */
+	if (sources & GRCAN_IRQ_OR) {
+		netdev_dbg(dev, "got data overrun interrupt\n");
+		stats->rx_over_errors++;
+		stats->rx_errors++;
+
+		cf.can_id |= CAN_ERR_CRTL;
+		cf.data[1] |= CAN_ERR_CRTL_RX_OVERFLOW;
+	}
+
+	/* AHB bus error interrupts (not CAN bus errors) - shut down the
+	 * device.
+	 */
+	if (sources & (GRCAN_IRQ_TXAHBERR | GRCAN_IRQ_RXAHBERR)) {
+		if (sources & GRCAN_IRQ_TXAHBERR) {
+			netdev_err(dev, "got AHB bus error on tx\n");
+			stats->tx_errors++;
+		} else {
+			netdev_err(dev, "got AHB bus error on rx\n");
+			stats->rx_errors++;
+		}
+		netdev_err(dev, "halting device\n");
+
+		/* Prevent anything to be enabled again and halt device */
+		spin_lock(&priv->lock);
+		priv->closing = true;
+		netif_stop_queue(dev);
+		grcan_stop(dev);
+		spin_unlock(&priv->lock);
+	}
+
+	/* Pass on error frame if something to report,
+	 * i.e. id contains some information
+	 */
+	if (cf.can_id) {
+		struct can_frame *skb_cf;
+		struct sk_buff *skb = alloc_can_err_skb(dev, &skb_cf);
+
+		if (skb == NULL) {
+			netdev_dbg(dev, "could not allocate error frame\n");
+			return;
+		}
+		skb_cf->can_id |= cf.can_id;
+		memcpy(skb_cf->data, cf.data, sizeof(cf.data));
+
+		netif_rx(skb);
+	}
+}
+
+static irqreturn_t grcan_interrupt(int irq, void *dev_id)
+{
+	struct net_device *dev = (struct net_device *)dev_id;
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	u32 sources, status;
+
+	/* Find out the source */
+	sources = grcan_read_reg(&regs->pimsr);
+	if (!sources)
+		return IRQ_NONE;
+	grcan_write_reg(&regs->picr, sources);
+	status = grcan_read_reg(&regs->stat);
+
+	/* If we got TX progress, the device has not hanged,
+	 * so disable the hang timer
+	 */
+	if (priv->need_txbug_workaround
+	    && (sources & (GRCAN_IRQ_TX | GRCAN_IRQ_TXLOSS))) {
+		del_timer(&priv->hang_timer);
+	}
+
+	/* Frame(s) received or transmitted */
+	if (sources & (GRCAN_IRQ_TX | GRCAN_IRQ_RX)) {
+		/* Disable tx/rx interrupts and schedule poll() */
+		grcan_clear_bits(&regs->imr, GRCAN_IRQ_TX | GRCAN_IRQ_RX);
+		napi_schedule(&priv->napi);
+	}
+
+	/* (Potential) error conditions to take care of */
+	if (sources & GRCAN_IRQ_ERRORS)
+		grcan_err(dev, sources, status);
+
+	return IRQ_HANDLED;
+}
+
+/* Reset device and restart operations from where they were.
+ *
+ * This assumes that RXCTRL & RXCTRL is properly disabled and that RX
+ * is not ONGOING (TX might be stuck in ONGOING due to a harwrware bug
+ * for single shot)
+ */
+static void grcan_running_reset(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *) data;
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	unsigned long flags;
+
+	/* This temporarily messes with eskbp, so we need to lock
+	 * priv->lock
+	 */
+	spin_lock_irqsave(&priv->lock, flags);
+
+	priv->resetting = false;
+	del_timer(&priv->hang_timer);
+	del_timer(&priv->rr_timer);
+
+	if (!priv->closing) {
+		/* Save and reset - config register preserved by grcan_reset */
+		u32 imr = grcan_read_reg(&regs->imr);
+
+		u32 txaddr = grcan_read_reg(&regs->txaddr);
+		u32 txsize = grcan_read_reg(&regs->txsize);
+		u32 txwr = grcan_read_reg(&regs->txwr);
+		u32 txrd = grcan_read_reg(&regs->txrd);
+		u32 eskbp = priv->eskbp;
+
+		u32 rxaddr = grcan_read_reg(&regs->rxaddr);
+		u32 rxsize = grcan_read_reg(&regs->rxsize);
+		u32 rxwr = grcan_read_reg(&regs->rxwr);
+		u32 rxrd = grcan_read_reg(&regs->rxrd);
+
+		grcan_reset(dev);
+
+		/* Restore */
+		grcan_write_reg(&regs->txaddr, txaddr);
+		grcan_write_reg(&regs->txsize, txsize);
+		grcan_write_reg(&regs->txwr, txwr);
+		grcan_write_reg(&regs->txrd, txrd);
+		priv->eskbp = eskbp;
+
+		grcan_write_reg(&regs->rxaddr, rxaddr);
+		grcan_write_reg(&regs->rxsize, rxsize);
+		grcan_write_reg(&regs->rxwr, rxwr);
+		grcan_write_reg(&regs->rxrd, rxrd);
+
+		/* Turn on device again */
+		grcan_write_reg(&regs->imr, imr);
+		priv->can.state = CAN_STATE_ERROR_ACTIVE;
+		grcan_write_reg(&regs->txctrl, GRCAN_TXCTRL_ENABLE
+				| (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT
+				   ? GRCAN_TXCTRL_SINGLE : 0));
+		grcan_write_reg(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+		grcan_write_reg(&regs->ctrl, GRCAN_CTRL_ENABLE);
+
+		/* Start queue if there is size and listen-onle mode is not
+		 * enabled
+		 */
+		if (grcan_txspace(priv->dma.tx.size, txwr, priv->eskbp) &&
+		    !(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
+			netif_wake_queue(dev);
+
+
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	netdev_err(dev, "Device reset and restored\n");
+}
+
+/* Waiting time in usecs corresponding to the transmission of three maximum
+ * sized can frames in the given bitrate (in bits/sec). Waiting for this amount
+ * of time makes sure that the can controller have time to finish sending or
+ * receiving a frame with a good margin.
+ *
+ * usecs/sec * number of frames * bits/frame / bits/sec
+ */
+static inline u32 grcan_ongoing_wait_usecs(__u32 bitrate)
+{
+	return 1000000 * 3 * GRCAN_EFF_FRAME_MAX_BITS / bitrate;
+}
+
+/* Set timer so that it will not fire until after a period in which the can
+ * controller have a good margin to finish transmitting a frame unless it has
+ * hanged
+ */
+static inline void grcan_reset_timer(struct timer_list *timer, __u32 bitrate)
+{
+	u32 wait_jiffies = usecs_to_jiffies(grcan_ongoing_wait_usecs(bitrate));
+
+	mod_timer(timer, jiffies + wait_jiffies);
+}
+
+/* Disable channels and schedule a running reset */
+static void grcan_initiate_running_reset(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *)data;
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	unsigned long flags;
+
+	netdev_err(dev, "Device seems hanged - reset scheduled\n");
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	/* The main body of this function must never be executed again
+	 * until after an execution of grcan_running_reset
+	 */
+	if (!priv->resetting && !priv->closing) {
+		priv->resetting = true;
+		netif_stop_queue(dev);
+		grcan_clear_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
+		grcan_clear_bits(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+		grcan_reset_timer(&priv->rr_timer, priv->can.bittiming.bitrate);
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static void grcan_free_dma_buffers(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_dma *dma = &priv->dma;
+
+	dma_free_coherent(&dev->dev, dma->base_size, dma->base_buf,
+			  dma->base_handle);
+	memset(dma, 0, sizeof(*dma));
+}
+
+static int grcan_allocate_dma_buffers(struct net_device *dev,
+				      size_t tsize, size_t rsize)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_dma *dma = &priv->dma;
+	struct grcan_dma_buffer *large = rsize > tsize ? &dma->rx : &dma->tx;
+	struct grcan_dma_buffer *small = rsize > tsize ? &dma->tx : &dma->rx;
+	size_t shift;
+
+	/* Need a whole number of GRCAN_BUFFER_ALIGNMENT for the large,
+	 * i.e. first buffer
+	 */
+	size_t maxs = max(tsize, rsize);
+	size_t lsize = ALIGN(maxs, GRCAN_BUFFER_ALIGNMENT);
+
+	/* Put the small buffer after that */
+	size_t ssize = min(tsize, rsize);
+
+	/* Extra GRCAN_BUFFER_ALIGNMENT to allow for alignment */
+	dma->base_size = lsize + ssize + GRCAN_BUFFER_ALIGNMENT;
+	dma->base_buf = dma_alloc_coherent(&dev->dev,
+					   dma->base_size,
+					   &dma->base_handle,
+					   GFP_KERNEL);
+
+	if (!dma->base_buf)
+		return -ENOMEM;
+
+	dma->tx.size = tsize;
+	dma->rx.size = rsize;
+
+	large->handle = ALIGN(dma->base_handle, GRCAN_BUFFER_ALIGNMENT);
+	small->handle = large->handle + lsize;
+	shift = large->handle - dma->base_handle;
+
+	large->buf = dma->base_buf + shift;
+	small->buf = large->buf + lsize;
+
+	return 0;
+}
+
+
+/* priv->lock *must* be held when calling this function */
+static int grcan_start(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	u32 confop, txctrl;
+
+	grcan_reset(dev);
+
+	grcan_write_reg(&regs->txaddr, priv->dma.tx.handle);
+	grcan_write_reg(&regs->txsize, priv->dma.tx.size);
+	/* regs->txwr and regs->txrd already set to 0 by reset */
+
+	grcan_write_reg(&regs->rxaddr, priv->dma.rx.handle);
+	grcan_write_reg(&regs->rxsize, priv->dma.rx.size);
+	/* regs->rxwr and regs->rxrd already set to 0 by reset */
+
+	/* Enable interrupts */
+	grcan_read_reg(&regs->pir);
+	grcan_write_reg(&regs->imr, GRCAN_IRQ_DEFAULT);
+
+	/* Enable interfaces, channels and device */
+	confop = GRCAN_CONF_ABORT
+		| (priv->config.enable0 ? GRCAN_CONF_ENABLE0 : 0)
+		| (priv->config.enable1 ? GRCAN_CONF_ENABLE1 : 0)
+		| (priv->config.selection ? GRCAN_CONF_SELECTION : 0)
+		| (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY ?
+		   GRCAN_CONF_SILENT : 0)
+		| (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES ?
+		   GRCAN_CONF_TRIPLESAMP : 0);
+	grcan_write_bits(&regs->conf, confop, GRCAN_CONF_OPERATION);
+	txctrl = GRCAN_TXCTRL_ENABLE
+		| (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT
+		   ? GRCAN_TXCTRL_SINGLE : 0);
+	grcan_write_reg(&regs->txctrl, txctrl);
+	grcan_write_reg(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+	grcan_write_reg(&regs->ctrl, GRCAN_CTRL_ENABLE);
+
+	priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+	return 0;
+}
+
+static int grcan_set_mode(struct net_device *dev, enum can_mode mode)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+	int err = 0;
+
+	if (mode == CAN_MODE_START) {
+		/* This might be called to restart the device to recover from
+		 * bus off errors
+		 */
+		spin_lock_irqsave(&priv->lock, flags);
+		if (priv->closing || priv->resetting) {
+			err = -EBUSY;
+		} else {
+			netdev_info(dev, "Restarting device\n");
+			grcan_start(dev);
+			if (!(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
+				netif_wake_queue(dev);
+		}
+		spin_unlock_irqrestore(&priv->lock, flags);
+		return err;
+	}
+	return -EOPNOTSUPP;
+}
+
+static int grcan_open(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_dma *dma = &priv->dma;
+	unsigned long flags;
+	int err;
+
+	/* Allocate memory */
+	if (GRCAN_INVALID_BUFFER_SIZE(priv->config.txsize)
+	    || GRCAN_INVALID_BUFFER_SIZE(priv->config.rxsize)) {
+		/* Should never be able go this far with invalid sizes */
+		netdev_err(dev, "Invalid buffer size pair 0x%x 0x%x\n",
+			   priv->config.txsize, priv->config.rxsize);
+		return -EINVAL;
+	}
+	err = grcan_allocate_dma_buffers(dev, priv->config.txsize,
+					 priv->config.rxsize);
+	if (err) {
+		netdev_err(dev, "could not allocate DMA buffers\n");
+		return err;
+	}
+
+	priv->echo_skb = devm_kzalloc(&dev->dev,
+				      dma->tx.size * sizeof(*priv->echo_skb),
+				      GFP_KERNEL);
+	if (!priv->echo_skb) {
+		err = -ENOMEM;
+		goto exit_free_dma_buffers;
+	}
+	priv->can.echo_skb_max = dma->tx.size;
+	priv->can.echo_skb = priv->echo_skb;
+
+	priv->txdlc = devm_kzalloc(&dev->dev,
+				   dma->tx.size * sizeof(*priv->txdlc),
+				   GFP_KERNEL);
+	if (!priv->txdlc) {
+		err = -ENOMEM;
+		goto exit_free_echo_skb;
+	}
+
+	/* Get can device up */
+	err = open_candev(dev);
+	if (err)
+		goto exit_free_txdlc;
+
+	err = devm_request_irq(&dev->dev, dev->irq, grcan_interrupt,
+			       IRQF_SHARED, dev->name, (void *)dev);
+	if (err)
+		goto exit_close_candev;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	grcan_start(dev);
+	napi_enable(&priv->napi);
+	if (!(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
+		netif_start_queue(dev);
+	priv->resetting = false;
+	priv->closing = false;
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return 0;
+
+exit_close_candev:
+	close_candev(dev);
+exit_free_txdlc:
+	devm_kfree(&dev->dev, priv->txdlc);
+exit_free_echo_skb:
+	devm_kfree(&dev->dev, priv->echo_skb);
+exit_free_dma_buffers:
+	grcan_free_dma_buffers(dev);
+	return err;
+}
+
+static int grcan_close(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+
+	napi_disable(&priv->napi);
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	priv->closing = true;
+	if (priv->need_txbug_workaround) {
+		del_timer_sync(&priv->hang_timer);
+		del_timer_sync(&priv->rr_timer);
+	}
+	netif_stop_queue(dev);
+	grcan_stop(dev);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	devm_free_irq(&dev->dev, dev->irq, (void *)dev);
+	close_candev(dev);
+
+	grcan_free_dma_buffers(dev);
+	priv->can.echo_skb_max = 0;
+	priv->can.echo_skb = NULL;
+	devm_kfree(&dev->dev, priv->echo_skb);
+	devm_kfree(&dev->dev, priv->txdlc);
+
+	return 0;
+}
+
+static int grcan_transmit_catch_up(struct net_device *dev, int budget)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+	int work_done;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	work_done = catch_up_echo_skb(dev, budget, true);
+	if (work_done) {
+		if (!priv->resetting && !priv->closing &&
+		    !(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
+			netif_wake_queue(dev);
+
+		/* With napi we don't get TX interrupts for a while,
+		 * so prevent a running reset while catching up
+		 */
+		if (priv->need_txbug_workaround)
+			del_timer(&priv->hang_timer);
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return work_done;
+}
+
+static int grcan_receive(struct net_device *dev, int budget)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	struct net_device_stats *stats = &dev->stats;
+	struct can_frame *cf;
+	struct sk_buff *skb;
+	u32 wr, rd, startrd;
+	u32 *slot;
+	u32 i, rtr, eff, j, shift;
+	int work_done = 0;
+
+	rd = grcan_read_reg(&regs->rxrd);
+	startrd = rd;
+	for (work_done = 0; work_done < budget; work_done++) {
+		/* Check for packet to receive */
+		wr = grcan_read_reg(&regs->rxwr);
+		if (rd == wr)
+			break;
+
+		/* Take care of packet */
+		skb = alloc_can_skb(dev, &cf);
+		if (skb == NULL) {
+			netdev_dbg(dev,
+				   "dropping frame: skb allocation failed\n");
+			stats->rx_dropped++;
+			continue;
+		}
+
+		slot = dma->rx.buf + rd;
+		eff = slot[0] & GRCAN_MSG_IDE;
+		rtr = slot[0] & GRCAN_MSG_RTR;
+		if (eff) {
+			cf->can_id = ((slot[0] & GRCAN_MSG_EID)
+				      >> GRCAN_MSG_EID_BIT);
+			cf->can_id |= CAN_EFF_FLAG;
+		} else {
+			cf->can_id = ((slot[0] & GRCAN_MSG_BID)
+				      >> GRCAN_MSG_BID_BIT);
+		}
+		cf->can_dlc = get_can_dlc((slot[1] & GRCAN_MSG_DLC)
+					  >> GRCAN_MSG_DLC_BIT);
+		if (rtr) {
+			cf->can_id |= CAN_RTR_FLAG;
+		} else {
+			for (i = 0; i < cf->can_dlc; i++) {
+				j = GRCAN_MSG_DATA_SLOT_INDEX(i);
+				shift = GRCAN_MSG_DATA_SHIFT(i);
+				cf->data[i] = (u8)((slot[j] >> shift) & 0xff);
+			}
+		}
+		netif_receive_skb(skb);
+
+		/* Update statistics and read pointer */
+		stats->rx_packets++;
+		stats->rx_bytes += cf->can_dlc;
+		rd = grcan_ring_add(rd, GRCAN_MSG_SIZE, dma->rx.size);
+	}
+
+	/* Make sure everything is read before allowing hardware to
+	 * use the memory
+	 */
+	mb();
+
+	/* Update read pointer - no need to check for ongoing */
+	if (likely(rd != startrd))
+		grcan_write_reg(&regs->rxrd, rd);
+
+	return work_done;
+}
+
+static int grcan_poll(struct napi_struct *napi, int budget)
+{
+	struct grcan_priv *priv = container_of(napi, struct grcan_priv, napi);
+	struct net_device *dev = priv->dev;
+	struct grcan_registers __iomem *regs = priv->regs;
+	int rx_work_done = grcan_receive(dev, budget);
+	int tx_work_done = grcan_transmit_catch_up(dev, budget);
+
+	if (rx_work_done < budget && tx_work_done < budget) {
+		napi_complete(napi);
+		/* Enable tx and rx interrupts again */
+		if (!priv->closing)
+			grcan_set_bits(&regs->imr, GRCAN_IRQ_TX | GRCAN_IRQ_RX);
+	}
+	return rx_work_done;
+}
+
+/* Work tx bug by waiting while for the risky situation to clear. If that fails,
+ * drop a frame in one-shot mode or indicate a busy device otherwise.
+ *
+ * Returns 0 on successful wait. Otherwise it sets *netdev_tx_status to the
+ * value that should be returned by grcan_start_xmit when aborting the xmit.
+ */
+static int grcan_txbug_workaround(struct net_device *dev, struct sk_buff *skb,
+				  u32 txwr, u32 oneshotmode,
+				  netdev_tx_t *netdev_tx_status)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	int i;
+	unsigned long flags;
+
+	/* Wait a while for ongoing to be cleared or read pointer to catch up to
+	 * write pointer. The latter is needed due to a bug in older versions of
+	 * GRCAN in which ONGOING is not cleared properly one-shot mode when a
+	 * transmission fails.
+	 */
+	for (i = 0; i < GRCAN_SHORTWAIT_USECS; i++) {
+		udelay(1);
+		if (!grcan_read_bits(&regs->txctrl, GRCAN_TXCTRL_ONGOING)
+		    || grcan_read_reg(&regs->txrd) == txwr) {
+			return 0;
+		}
+	}
+
+	/* Clean up, in case the situation was not resolved */
+	spin_lock_irqsave(&priv->lock, flags);
+	if (!priv->resetting && !priv->closing) {
+		/* Queue might have been stopped earlier in grcan_start_xmit */
+		if (grcan_txspace(dma->tx.size, txwr, priv->eskbp))
+			netif_wake_queue(dev);
+		/* Set a timer to resolve a hanged tx controller */
+		if (!timer_pending(&priv->hang_timer))
+			grcan_reset_timer(&priv->hang_timer,
+					  priv->can.bittiming.bitrate);
+	}
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	if (oneshotmode) {
+		/* In one-shot mode we should never end up here because
+		 * then the interrupt handler increases txrd on TXLOSS,
+		 * but it is consistent with one-shot mode to drop the
+		 * frame in this case.
+		 */
+		kfree_skb(skb);
+		*netdev_tx_status = NETDEV_TX_OK;
+	} else {
+		/* In normal mode the socket-can transmission queue get
+		 * to keep the frame so that it can be retransmitted
+		 * later
+		 */
+		*netdev_tx_status = NETDEV_TX_BUSY;
+	}
+	return -EBUSY;
+}
+
+/* Notes on the tx cyclic buffer handling:
+ *
+ * regs->txwr	- the next slot for the driver to put data to be sent
+ * regs->txrd	- the next slot for the device to read data
+ * priv->eskbp	- the next slot for the driver to call can_put_echo_skb for
+ *
+ * grcan_start_xmit can enter more messages as long as regs->txwr does
+ * not reach priv->eskbp (within 1 message gap)
+ *
+ * The device sends messages until regs->txrd reaches regs->txwr
+ *
+ * The interrupt calls handler calls can_put_echo_skb until
+ * priv->eskbp reaches regs->txrd
+ */
+static netdev_tx_t grcan_start_xmit(struct sk_buff *skb,
+				    struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	struct can_frame *cf = (struct can_frame *)skb->data;
+	u32 id, txwr, txrd, space, txctrl;
+	int slotindex;
+	u32 *slot;
+	u32 i, rtr, eff, dlc, tmp, err;
+	int j, shift;
+	unsigned long flags;
+	u32 oneshotmode = priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT;
+
+	if (can_dropped_invalid_skb(dev, skb))
+		return NETDEV_TX_OK;
+
+	/* Trying to transmit in silent mode will generate error interrupts, but
+	 * this should never happen - the queue should not have been started.
+	 */
+	if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
+		return NETDEV_TX_BUSY;
+
+	/* Reads of priv->eskbp and shut-downs of the queue needs to
+	 * be atomic towards the updates to priv->eskbp and wake-ups
+	 * of the queue in the interrupt handler.
+	 */
+	spin_lock_irqsave(&priv->lock, flags);
+
+	txwr = grcan_read_reg(&regs->txwr);
+	space = grcan_txspace(dma->tx.size, txwr, priv->eskbp);
+
+	slotindex = txwr / GRCAN_MSG_SIZE;
+	slot = dma->tx.buf + txwr;
+
+	if (unlikely(space == 1))
+		netif_stop_queue(dev);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+	/* End of critical section*/
+
+	/* This should never happen. If circular buffer is full, the
+	 * netif_stop_queue should have been stopped already.
+	 */
+	if (unlikely(!space)) {
+		netdev_err(dev, "No buffer space, but queue is non-stopped.\n");
+		return NETDEV_TX_BUSY;
+	}
+
+	/* Convert and write CAN message to DMA buffer */
+	eff = cf->can_id & CAN_EFF_FLAG;
+	rtr = cf->can_id & CAN_RTR_FLAG;
+	id = cf->can_id & (eff ? CAN_EFF_MASK : CAN_SFF_MASK);
+	dlc = cf->can_dlc;
+	if (eff)
+		tmp = (id << GRCAN_MSG_EID_BIT) & GRCAN_MSG_EID;
+	else
+		tmp = (id << GRCAN_MSG_BID_BIT) & GRCAN_MSG_BID;
+	slot[0] = (eff ? GRCAN_MSG_IDE : 0) | (rtr ? GRCAN_MSG_RTR : 0) | tmp;
+
+	slot[1] = ((dlc << GRCAN_MSG_DLC_BIT) & GRCAN_MSG_DLC);
+	slot[2] = 0;
+	slot[3] = 0;
+	for (i = 0; i < dlc; i++) {
+		j = GRCAN_MSG_DATA_SLOT_INDEX(i);
+		shift = GRCAN_MSG_DATA_SHIFT(i);
+		slot[j] |= cf->data[i] << shift;
+	}
+
+	/* Checking that channel has not been disabled. These cases
+	 * should never happen
+	 */
+	txctrl = grcan_read_reg(&regs->txctrl);
+	if (!(txctrl & GRCAN_TXCTRL_ENABLE))
+		netdev_err(dev, "tx channel spuriously disabled\n");
+
+	if (oneshotmode && !(txctrl & GRCAN_TXCTRL_SINGLE))
+		netdev_err(dev, "one-shot mode spuriously disabled\n");
+
+	/* Bug workaround for old version of grcan where updating txwr
+	 * in the same clock cycle as the controller updates txrd to
+	 * the current txwr could hang the can controller
+	 */
+	if (priv->need_txbug_workaround) {
+		txrd = grcan_read_reg(&regs->txrd) ;
+		if (unlikely(grcan_ring_sub(txwr, txrd, dma->tx.size) == 1)) {
+			netdev_tx_t txstatus;
+
+			err = grcan_txbug_workaround(dev, skb, txwr,
+						     oneshotmode, &txstatus);
+			if (err)
+				return txstatus;
+		}
+	}
+
+	/* Prepare skb for echoing. This must be after the bug workaround above
+	 * as ownership of the skb is passed on by calling can_put_echo_skb.
+	 * Returning NETDEV_TX_BUSY or accessing skb or cf after a call to
+	 * can_put_echo_skb would be an error unless other measures are
+	 * taken.
+	 */
+	priv->txdlc[slotindex] = cf->can_dlc; /* Store dlc for statistics */
+	can_put_echo_skb(skb, dev, slotindex);
+
+	/* Make sure everything is written before allowing hardware to
+	 * read from the memory
+	 */
+	wmb();
+
+	/* Update write pointer to start transmission */
+	grcan_write_reg(&regs->txwr,
+			grcan_ring_add(txwr, GRCAN_MSG_SIZE, dma->tx.size));
+
+	return NETDEV_TX_OK;
+}
+
+
+/* ========== Setting up sysfs interface and module parameters ========== */
+
+
+#define GRCAN_NOT_BOOL(val) ((val) < 0 || (val) > 1)
+
+#define GRCAN_MODULE_PARAM(name, mtype, valcheckf)			\
+	static void grcan_sanitize_##name(struct platform_device *pd)	\
+	{								\
+		struct grcan_device_config grcan_default_config		\
+			= GRCAN_DEFAULT_DEVICE_CONFIG;			\
+		if (valcheckf(grcan_module_config.name)) {		\
+			dev_err(&pd->dev,				\
+				"Invalid module parameter value for "	\
+				#name " - setting default\n");		\
+			grcan_module_config.name =			\
+				grcan_default_config.name;		\
+		}							\
+	}								\
+	module_param_named(name, grcan_module_config.name,		\
+			   mtype, S_IRUGO)
+
+#define GRCAN_CONFIG_ATTR(name)						\
+	static ssize_t grcan_store_##name(struct device *sdev,		\
+					  struct device_attribute *att,	\
+					  const char *buf,		\
+					  size_t count)			\
+	{								\
+		struct net_device *dev = to_net_dev(sdev);		\
+		struct grcan_priv *priv = netdev_priv(dev);		\
+		u8 val;							\
+		int ret;						\
+		if (dev->flags & IFF_UP)				\
+			return -EBUSY;					\
+		ret = kstrtou8(buf, 0, &val);				\
+		if (ret < 0 || val < 0 || val > 1)			\
+			return -EINVAL;					\
+		priv->config.name = val;				\
+		return count;						\
+	}								\
+	static ssize_t grcan_show_##name(struct device *sdev,		\
+					 struct device_attribute *att,	\
+					 char *buf)			\
+	{								\
+		struct net_device *dev = to_net_dev(sdev);		\
+		struct grcan_priv *priv = netdev_priv(dev);		\
+		return sprintf(buf, "%d\n", priv->config.name);		\
+	}								\
+	static DEVICE_ATTR(name, S_IRUGO | S_IWUSR,			\
+			   grcan_show_##name,				\
+			   grcan_store_##name);				\
+	GRCAN_MODULE_PARAM(name, ushort, GRCAN_NOT_BOOL)
+
+/* The following configuration options are made available both via module
+ * parameters and writable sysfs files. See the chapter about GRCAN in the
+ * documentation for the GRLIB VHDL library for further details.
+ */
+
+/* Configure enable0 - Hardware configuration for interface 0 */
+GRCAN_CONFIG_ATTR(enable0);
+
+/* Configure enable1 - Hardware configuration for interface 1 */
+GRCAN_CONFIG_ATTR(enable1);
+
+/* Configure selection - Selection on which interface to use */
+GRCAN_CONFIG_ATTR(selection);
+
+
+/* The following configuration options are only available via module
+ * parameters.
+ */
+
+/* Configure size of tx buffer */
+GRCAN_MODULE_PARAM(txsize, uint, GRCAN_INVALID_BUFFER_SIZE);
+
+/* Configure size of rx buffer */
+GRCAN_MODULE_PARAM(rxsize, uint, GRCAN_INVALID_BUFFER_SIZE);
+
+
+/* Function that makes sure that configuration done using
+ * module parameters are set to valid values
+ */
+static void grcan_sanitize_module_config(struct platform_device *ofdev)
+{
+	grcan_sanitize_enable0(ofdev);
+	grcan_sanitize_enable1(ofdev);
+	grcan_sanitize_selection(ofdev);
+	grcan_sanitize_txsize(ofdev);
+	grcan_sanitize_rxsize(ofdev);
+}
+
+static const struct attribute *const sysfs_grcan_attrs[] = {
+	/* Config attrs */
+	&dev_attr_enable0.attr,
+	&dev_attr_enable1.attr,
+	&dev_attr_selection.attr,
+	NULL,
+};
+
+static const struct attribute_group sysfs_grcan_group = {
+	.name	= "grcan",
+	.attrs	= (struct attribute **)sysfs_grcan_attrs,
+};
+
+
+/* ========== Setting up the driver ========== */
+
+static const struct net_device_ops grcan_netdev_ops = {
+	.ndo_open	= grcan_open,
+	.ndo_stop	= grcan_close,
+	.ndo_start_xmit	= grcan_start_xmit,
+};
+
+static int grcan_setup_netdev(struct platform_device *ofdev,
+			      void __iomem *base,
+			      int irq, u32 ambafreq, bool txbug)
+{
+	struct net_device *dev;
+	struct grcan_priv *priv;
+	struct grcan_registers __iomem *regs;
+	int err;
+
+	dev = alloc_candev(sizeof(struct grcan_priv), 0);
+	if (!dev)
+		return -ENOMEM;
+
+	dev->irq = irq;
+	dev->flags |= IFF_ECHO;
+	dev->netdev_ops = &grcan_netdev_ops;
+	dev->sysfs_groups[0] = &sysfs_grcan_group;
+
+	priv = netdev_priv(dev);
+	memcpy(&priv->config, &grcan_module_config,
+	       sizeof(struct grcan_device_config));
+	priv->dev = dev;
+	priv->regs = (struct grcan_registers *) base;
+	priv->can.bittiming_const = &grcan_bittiming_const;
+	priv->can.do_set_bittiming = grcan_set_bittiming;
+	priv->can.do_set_mode = grcan_set_mode;
+	priv->can.do_get_berr_counter = grcan_get_berr_counter;
+	priv->can.clock.freq = ambafreq;
+	priv->can.ctrlmode_supported =
+		CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_ONE_SHOT;
+	priv->need_txbug_workaround = txbug;
+
+	/* Discover if triple sampling is supported by hardware */
+	regs = priv->regs;
+	grcan_set_bits(&regs->ctrl, GRCAN_CTRL_RESET);
+	grcan_set_bits(&regs->conf, GRCAN_CONF_TRIPLESAMP);
+	if (grcan_read_bits(&regs->conf, GRCAN_CONF_TRIPLESAMP)) {
+		priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES;
+		dev_info(&ofdev->dev, "Hardware supports triple-sampling\n");
+	}
+
+	spin_lock_init(&priv->lock);
+
+	if (priv->need_txbug_workaround) {
+		init_timer(&priv->rr_timer);
+		priv->rr_timer.function = grcan_running_reset;
+		priv->rr_timer.data = (unsigned long)dev;
+
+		init_timer(&priv->hang_timer);
+		priv->hang_timer.function = grcan_initiate_running_reset;
+		priv->hang_timer.data = (unsigned long)dev;
+	}
+
+	netif_napi_add(dev, &priv->napi, grcan_poll, GRCAN_NAPI_WEIGHT);
+
+	SET_NETDEV_DEV(dev, &ofdev->dev);
+	dev_info(&ofdev->dev, "regs=0x%p, irq=%d, clock=%d\n",
+		 priv->regs, dev->irq, priv->can.clock.freq);
+
+	err = register_candev(dev);
+	if (err) {
+		dev_err(&ofdev->dev, "registering %s failed (err=%d)\n",
+			DRV_NAME, err);
+		goto exit_free_candev;
+	}
+	dev_set_drvdata(&ofdev->dev, dev);
+
+	/* Reset device to allow bit-timing to be set. No need to call
+	 * grcan_reset at this stage. That is done in grcan_open.
+	 */
+	grcan_write_reg(&regs->ctrl, GRCAN_CTRL_RESET);
+
+	return 0;
+exit_free_candev:
+	free_candev(dev);
+	return err;
+}
+
+static int __devinit grcan_probe(struct platform_device *ofdev)
+{
+	struct device_node *np = ofdev->dev.of_node;
+	struct resource *res;
+	u32 sysid, ambafreq;
+	int irq, err;
+	void __iomem *base;
+	bool txbug = true;
+
+	/* Compare GRLIB version number with the first that does not
+	 * have the tx bug (see start_xmit)
+	 */
+	err = of_property_read_u32(np, "systemid", &sysid);
+	if (!err && ((sysid & GRLIB_VERSION_MASK)
+		     >= GRCAN_TXBUG_SAFE_GRLIB_VERSION))
+		txbug = false;
+
+	err = of_property_read_u32(np, "freq", &ambafreq);
+	if (err) {
+		dev_err(&ofdev->dev, "unable to fetch \"freq\" property\n");
+		goto exit_error;
+	}
+
+	res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
+	base = devm_request_and_ioremap(&ofdev->dev, res);
+	if (!base) {
+		dev_err(&ofdev->dev, "couldn't map IO resource\n");
+		err = -EADDRNOTAVAIL;
+		goto exit_error;
+	}
+
+	irq = irq_of_parse_and_map(np, GRCAN_IRQIX_IRQ);
+	if (irq == NO_IRQ) {
+		dev_err(&ofdev->dev, "no irq found\n");
+		err = -ENODEV;
+		goto exit_error;
+	}
+
+	grcan_sanitize_module_config(ofdev);
+
+	err = grcan_setup_netdev(ofdev, base, irq, ambafreq, txbug);
+	if (err)
+		goto exit_dispose_irq;
+
+	return 0;
+
+exit_dispose_irq:
+	irq_dispose_mapping(irq);
+exit_error:
+	dev_err(&ofdev->dev,
+		"%s socket CAN driver initialization failed with error %d\n",
+		DRV_NAME, err);
+	return err;
+}
+
+static int __devexit grcan_remove(struct platform_device *ofdev)
+{
+	struct net_device *dev = dev_get_drvdata(&ofdev->dev);
+	struct grcan_priv *priv = netdev_priv(dev);
+
+	unregister_candev(dev); /* Will in turn call grcan_close */
+
+	irq_dispose_mapping(dev->irq);
+	dev_set_drvdata(&ofdev->dev, NULL);
+	netif_napi_del(&priv->napi);
+	free_candev(dev);
+
+	dev_info(&ofdev->dev, "%s socket CAN driver removed\n", DRV_NAME);
+	return 0;
+}
+
+static struct of_device_id grcan_match[] = {
+	{.name = "GAISLER_GRCAN"},
+	{.name = "01_03d"},
+	{.name = "GAISLER_GRHCAN"},
+	{.name = "01_034"},
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, grcan_match);
+
+static struct platform_driver grcan_driver = {
+	.driver = {
+		.name = DRV_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = grcan_match,
+	},
+	.probe = grcan_probe,
+	.remove = __devexit_p(grcan_remove),
+};
+
+module_platform_driver(grcan_driver);
+
+MODULE_AUTHOR("Aeroflex Gaisler AB.");
+MODULE_DESCRIPTION("Socket CAN driver for Aeroflex Gaisler GRCAN");
+MODULE_LICENSE("GPL");
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* Re: [PATCH v3] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-10-31 16:33                   ` Andreas Larsson
  2012-10-31 16:39                     ` [PATCH v4] " Andreas Larsson
@ 2012-10-31 20:21                     ` Wolfgang Grandegger
  2012-11-01 16:08                       ` Andreas Larsson
  1 sibling, 1 reply; 41+ messages in thread
From: Wolfgang Grandegger @ 2012-10-31 20:21 UTC (permalink / raw)
  To: Andreas Larsson
  Cc: linux-can, Marc Kleine-Budde, devicetree-discuss, software

On 10/31/2012 05:33 PM, Andreas Larsson wrote:
> On 2012-10-31 13:51, Wolfgang Grandegger wrote:
>> On 10/30/2012 05:24 PM, Andreas Larsson wrote:
>>> On 10/30/2012 11:07 AM, Wolfgang Grandegger wrote:
>>>>> +    /* AHB bus error interrupts (not CAN bus errors) - shut down the
>>>>> +     * device.
>>>>> +     */
>>>>> +    if (sources & (GRCAN_IRQ_TXAHBERR | GRCAN_IRQ_RXAHBERR)) {
>>>>> +        if (sources & GRCAN_IRQ_TXAHBERR) {
>>>>> +            netdev_err(dev, "got AHB bus error on tx\n");
>>>>> +            stats->tx_errors++;
>>>>> +        } else {
>>>>> +            netdev_err(dev, "got AHB bus error on rx\n");
>>>>> +            stats->rx_errors++;
>>>>> +        }
>>>>> +        netdev_err(dev, "halting device\n");
>>>>> +
>>>>> +        /* Prevent anything to be enabled again and halt device */
>>>>> +        SPIN_LOCK(&priv->lock);
>>>>> +        priv->closing = true;
>>>>> +        netif_stop_queue(dev);
>>>>> +        grcan_stop(dev);
>>>>> +        SPIN_UNLOCK(&priv->lock);
>>>>
>>>> Hm, does that really happen? How can the user/app realized the problem
>>>> and recover?
>>>
>>> My understanding of it is that if you get amba bus errors something is
>>> seriously wrong and nothing can be done at driver level to recover.
>>> Shutting down the device is to prevent the driver from spamming console
>>> messages. I used to have a sysfs indication of such errors. Now dmesg is
>>> the way to find out about the problem. The user can always bring the
>>> interface down and up again and try again after such an error.
>>
>> Well, sounds like a fatal error. Did you ever saw it? If that happens
>> frequently, or even once, the device/system seems not really usable.
> 
> Fatal and yes if this is ever seen something is very bad with the
> system. I have never seen it. However the hardware reports if it would
> happen, so why not try to take care of it in some manner. If this is
> seen the can device is probably useless but it is possible that the rest
> of the system might be usable. I don't really know in what circumstances
> this would trigger.

OK, maybe a more serious message would just be fine.

>>>> Furthermore, why is a spin_clock enough here? THe interrupt may run a
>>>> thread.
>>>
>>> It should be enough because the function is only called
>>> directly from the interrupt handler, right? Or did I miss something?
>>
>> The interrupt handler may run as thread, e.g. if the -rt patch has been
>> applied. Therefore it's safer to use the irqsave/restore variants of the
>> spin_lock functions. At least that's my understanding. See also
>> "Documentation/spinlock.txt".
> 
> I'll look into this. Seems strange if the same cpu can be interrupted in
> an interrupt handler to run the very same interrupt handler. Sounds like
> a horrible situation for any driver that does not lock down most of its
> interrupt handler. Or maybe there is some situation that I don't foresee.

As I said, if you use CONFIG_PREEMPT_RT all interrupt isr will be
threaded (running by threads).

>>>>> +    priv->can.ctrlmode_supported  =
>>>>> +        CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_ONE_SHOT;
>>>>
>>>> What about triple-sampling?
>>>
>>> That is not supported by the hardware.
> 
> Well, now it will be in future versions of the controller, so support is
> added to the driver.
> 
> 
>>>> I curious how the device behaves on bus errors and state changes. Could
>>>> you please show the output of "candump -e any,0:0,#FFFFFFFF" while
>>>> sending a CAN message with no other node on the bus (not connected) and
>>>> with going bus off (by short-circuiting CAN high and low).
>>>
>>>
>>> Here is the output (with long sequences of similar error frames
>>> where only one counter is increasing cut out) from the the upcoming v4.
>>> let me know if you see any problems with this.
>>
>> How did your trigger that sequence? Short-circuit or not cable
>> connected? The latter, I assume, as bus-off is not reached.
> 
> Triggered by short-circuiting, just as asked.

I ask for both tests but I missed the bus-off forther down.

>>>
>>>    can0  20000006  [8] 00 00 00 00 00 00 10 00   ERRORFRAME
>>>          lost-arbitration{at bit 0}
>>>          controller-problem{}
>>>          error-counter-tx-rx{{16}{0}}
>>
>> This is most probably an ack slot bus error similar to. You seem not to
>> handle bus errors and it's not a controller problem as the state did not
>> change.
> 
> No, the hardware has no support for can-bus error reporting.

OK, but why is CAN_ERR_CRTL set?

>> http://lxr.linux.no/#linux+v3.6.4/drivers/net/can/flexcan.c#L353
>>
>>>    can0  20000004  [8] 00 20 00 00 00 00 88 00   ERRORFRAME
>>>          controller-problem{tx-error-passive}
>>>          error-counter-tx-rx{{136}{0}}
>>
>> OK, a state change to error passive. The device seems not to report
>> changes to error warning.
> 
> No, there is no interrupts or anything that alert about the error
> states. That is why I set the sate based on the error counters in the
> error handler.

Who does trigger the message above?

>>>    can0  20000006  [8] 00 20 00 00 00 00 90 00   ERRORFRAME
>>>          lost-arbitration{at bit 0}
>>>          controller-problem{tx-error-passive}
>>>          error-counter-tx-rx{{144}{0}}
>>
>> State changes should be reported only once.
> 
> Do you mean that an error message should only be sent on state change?

Yes. On state change or another error, e.g. the lost-arbitration above.

>> But it did not change. This
>> is then a bus error (CAN_ERR_PROT | CAN_ERR_BUSERROR). See also above.
>>
>>>    [...]
>>>    can0  20000006  [8] 00 20 00 00 00 00 F0 00   ERRORFRAME
>>>          lost-arbitration{at bit 0}
>>>          controller-problem{tx-error-passive}
>>>          error-counter-tx-rx{{240}{0}}
>>>    can0  20000006  [8] 00 20 00 00 00 00 F8 00   ERRORFRAME
>>>          lost-arbitration{at bit 0}
>>>          controller-problem{tx-error-passive}
>>>          error-counter-tx-rx{{248}{0}}
>>>    can0  20000042  [8] 00 00 00 00 00 00 80 00   ERRORFRAME
>>>          lost-arbitration{at bit 0}
>>>          bus-off
>>>          error-counter-tx-rx{{128}{0}}
>>>    can0  20000006  [8] 00 00 00 00 00 00 18 00   ERRORFRAME
>>>          lost-arbitration{at bit 0}
>>>          controller-problem{}

Obviously the device restarts automatically after bus-off. Can this be
switched off. The normal procedure is to call "ip ... type can restart"
or to set "restart-ms" for automatic restart after the specified delay.

>> Also a sequence to bus-off including the recovery would be nice.

The sequence with no cable connected would be nice as well.

...

> Thanks for the input! I'll send in v4 so you can see what the code that
> generated the above.

Please fix the error handling first.

Thanks,

Wolfgang.


^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v3] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-10-31 20:21                     ` [PATCH v3] " Wolfgang Grandegger
@ 2012-11-01 16:08                       ` Andreas Larsson
  2012-11-02 14:23                         ` [PATCH v5] " Andreas Larsson
  2012-11-05  9:28                         ` [PATCH v3] " Wolfgang Grandegger
  0 siblings, 2 replies; 41+ messages in thread
From: Andreas Larsson @ 2012-11-01 16:08 UTC (permalink / raw)
  To: Wolfgang Grandegger
  Cc: linux-can, Marc Kleine-Budde, devicetree-discuss, software

On 2012-10-31 21:21, Wolfgang Grandegger wrote:
 >>> Well, sounds like a fatal error. Did you ever saw it? If that happens
 >>> frequently, or even once, the device/system seems not really usable.
 >>
 >> Fatal and yes if this is ever seen something is very bad with the
 >> system. I have never seen it. However the hardware reports if it would
 >> happen, so why not try to take care of it in some manner. If this is
 >> seen the can device is probably useless but it is possible that the rest
 >> of the system might be usable. I don't really know in what circumstances
 >> this would trigger.
 >
 > OK, maybe a more serious message would just be fine.

Yes, I have now made it clearer that this is a very serious error.


>>>>> Furthermore, why is a spin_clock enough here? THe interrupt may run a
>>>>> thread.
>>>>
>>>> It should be enough because the function is only called
>>>> directly from the interrupt handler, right? Or did I miss something?
>>>
>>> The interrupt handler may run as thread, e.g. if the -rt patch has been
>>> applied. Therefore it's safer to use the irqsave/restore variants of the
>>> spin_lock functions. At least that's my understanding. See also
>>> "Documentation/spinlock.txt".
>>
>> I'll look into this. Seems strange if the same cpu can be interrupted in
>> an interrupt handler to run the very same interrupt handler. Sounds like
>> a horrible situation for any driver that does not lock down most of its
>> interrupt handler. Or maybe there is some situation that I don't foresee.
>
> As I said, if you use CONFIG_PREEMPT_RT all interrupt isr will be
> threaded (running by threads).

I have now added it, even though I am still not sure if it is needed. Under 
CONFIG_PREEMPT_RT_FULL a spin_lock_irqsave is just a plain spin_lock anyway 
(plus type checking on the flags argument).


>>> This is most probably an ack slot bus error similar to. You seem not to
>>> handle bus errors and it's not a controller problem as the state did not
>>> change.
>>
>> No, the hardware has no support for can-bus error reporting.
>
> OK, but why is CAN_ERR_CRTL set?

Maybe I am just confused with the terminology. What I mean is that the only 
error reporting that is supported by the hardware (apart from AMBA bus errors, 
but that is unrelated to the discussion) is the error counter related errors.

 From what I can see CAN_ERR_BUSERROR is not reported in the error counter 
related cases by the other drivers I looked in. The grcan hardware does not 
support reporting errors like form and stuff errors and which bits the errors 
occured in and the like.

Have I understood it correctly that reporting about protocol errors like that is 
what it is to support CAN_CTRLMODE_BERR_REPORTING? This seems to be the case but 
the janz-ican3 driver connects CAN_CTRLMODE_BERR_REPORTING to all error frame 
reporting, so I am not entirely sure.


>>> http://lxr.linux.no/#linux+v3.6.4/drivers/net/can/flexcan.c#L353
>>>
>>>>     can0  20000004  [8] 00 20 00 00 00 00 88 00   ERRORFRAME
>>>>           controller-problem{tx-error-passive}
>>>>           error-counter-tx-rx{{136}{0}}
>>>
>>> OK, a state change to error passive. The device seems not to report
>>> changes to error warning.
>>
>> No, there is no interrupts or anything that alert about the error
>> states. That is why I set the sate based on the error counters in the
>> error handler.
>
> Who does trigger the message above?

Sorry for confusing the matter. There is no interrupt for error warning, but 
there are interrupts for increases of the error counters and the other state 
changes. So to be able to report on error warning I check the error counters and 
do it manually.


> Obviously the device restarts automatically after bus-off. Can this be
> switched off. The normal procedure is to call "ip ... type can restart"
> or to set "restart-ms" for automatic restart after the specified delay.

Yes, the hardware becomes error active after having monitored 11 consecutive 
recessive bits on the bus 128 times (as allowed by the 2.0 CAN spec). There is 
no way of turning this off, so to conform to the normal linux procedure of not 
doing this, I shut down the device on bus off interrupt.

In addition I have thrown out the arbitration lost error frame generation as 
arbitration errors can not be singled out. The TXLOSS interrupt might be due to 
arbitration error, but is also triggered in great numbers when there is no one 
else on the can bus or when there is a problem with the hardware interface or 
the bus itself.

This is how things look currently with no one else on the bus:
~ # cansend can0 123#45
   can0  20000004  [8] 00 08 00 00 00 00 60 00   ERRORFRAME
         controller-problem{tx-error-warning}
         error-counter-tx-rx{{96}{0}}
   can0  20000004  [8] 00 20 00 00 00 00 80 00   ERRORFRAME
         controller-problem{tx-error-passive}
         error-counter-tx-rx{{128}{0}}
~ #

And this is how it looks with a short-circuited bus:
~ # cansend can0 123#45
   can0  20000004  [8] 00 08 00 00 00 00 90 00   ERRORFRAME
         controller-problem{tx-error-warning}
         error-counter-tx-rx{{144}{0}}
   can0  20000004  [8] 00 20 00 00 00 00 98 00   ERRORFRAME
         controller-problem{tx-error-passive}
         error-counter-tx-rx{{152}{0}}
   can0  20000040  [8] 00 00 00 00 00 00 00 00   ERRORFRAME
         bus-off
~ #


Thanks a lot for the input! Much appreciated!

Cheers,
Andreas


^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH v5] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-11-01 16:08                       ` Andreas Larsson
@ 2012-11-02 14:23                         ` Andreas Larsson
  2012-11-05  9:28                         ` [PATCH v3] " Wolfgang Grandegger
  1 sibling, 0 replies; 41+ messages in thread
From: Andreas Larsson @ 2012-11-02 14:23 UTC (permalink / raw)
  To: Wolfgang Grandegger
  Cc: linux-can, Marc Kleine-Budde, devicetree-discuss, software

This driver supports GRCAN and CRHCAN CAN controllers available in the GRLIB
VHDL IP core library.

Signed-off-by: Andreas Larsson <andreas@gaisler.com>
---
 Documentation/ABI/testing/sysfs-class-net-grcan    |   35 +
 .../devicetree/bindings/net/can/grcan.txt          |   27 +
 Documentation/kernel-parameters.txt                |   25 +
 drivers/net/can/Kconfig                            |    9 +
 drivers/net/can/Makefile                           |    1 +
 drivers/net/can/grcan.c                            | 1712 ++++++++++++++++++++
 6 files changed, 1809 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-class-net-grcan
 create mode 100644 Documentation/devicetree/bindings/net/can/grcan.txt
 create mode 100644 drivers/net/can/grcan.c

diff --git a/Documentation/ABI/testing/sysfs-class-net-grcan b/Documentation/ABI/testing/sysfs-class-net-grcan
new file mode 100644
index 0000000..8fa2f90
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-net-grcan
@@ -0,0 +1,35 @@
+
+What:		/sys/class/net/<iface>/grcan/enable0
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas@gaisler.com>
+Description:
+		Hardware configuration of physical interface 0. This file reads
+		and writes the "Enable 0" bit of the configuration register.
+		Possible values: 0 or 1. See the GRCAN chapter of the GRLIB IP
+		core library documentation for details.
+		The default value is set by the module parameter enable0 and can
+		be read at /sys/module/grcan/parameters/enable0.
+
+What:		/sys/class/net/<iface>/grcan/enable1
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas@gaisler.com>
+Description:
+		Hardware configuration of physical interface 1. This file reads
+		and writes the "Enable 1" bit of the configuration register.
+		Possible values: 0 or 1. See the GRCAN chapter of the GRLIB IP
+		core library documentation for details.
+		The default value is set by the module parameter enable1 and can
+		be read at /sys/module/grcan/parameters/enable1.
+
+What:		/sys/class/net/<iface>/grcan/selection
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas@gaisler.com>
+Description:
+		Configuration of which physical interface to be used. Possible
+		values: 0 or 1. See the GRCAN chapter of the GRLIB IP core
+		library documentation for details.
+		The default value is set by the module parameter selection and can
+		be read at /sys/module/grcan/parameters/selection.
diff --git a/Documentation/devicetree/bindings/net/can/grcan.txt b/Documentation/devicetree/bindings/net/can/grcan.txt
new file mode 100644
index 0000000..a7180f1
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/can/grcan.txt
@@ -0,0 +1,27 @@
+CAN controller for Aeroflex Gaisler GRCAN and GRHCAN.
+
+The GRCAN and CRHCAN CAN controllers are available in the GRLIB VHDL IP core
+library.
+
+Note: These properties are built from the AMBA plug&play in a Leon SPARC
+system (the ordinary environment for GRCAN and GRHCAN). There are no bsp
+files for sparc.
+
+Required properties:
+
+- name : Should be "GAISLER_GRCAN", "01_03d", "GAISLER_GRHCAN" or "01_034"
+
+- reg : Address and length of the register set for the device
+
+- freq : Frequency of the external oscillator clock in Hz (the frequency of
+	the amba bus in the ordinary case)
+
+- interrupts : Interrupt number for this device
+
+Optional properties:
+
+- systemid : If not present or if the value of the least significant 16 bits
+	of this 32-bit property is smaller than GRCAN_TXBUG_SAFE_GRLIB_VERSION
+	a bug workaround is activated.
+
+For further information look in the documentation for the GLIB IP core library.
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 9776f06..3a82433 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -905,6 +905,31 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 	gpt		[EFI] Forces disk with valid GPT signature but
 			invalid Protective MBR to be treated as GPT.
 
+	grcan.enable0=	[HW] The "Enable 0" bit of the configuration
+			register. For more documentation, see
+			Documentation/ABI/testing/sysfs-class-net-grcan
+			Format: 0 | 1
+			Default: 0
+	grcan.enable1=	[HW] The "Enable 1" bit of the configuration
+			register. For more documentation, see
+			Documentation/ABI/testing/sysfs-class-net-grcan.
+			Format: 0 | 1
+			Default: 0
+	grcan.selection=
+			[HW] Selection of which physical interface to be
+			used. For more documentation, see
+			Documentation/ABI/testing/sysfs-class-net-grcan.
+			Format: 0 | 1
+			Default: 0
+	grcan.txsize=	[HW] The size of the tx buffer. For more documentation,
+			see Documentation/ABI/testing/sysfs-class-net-grcan.
+			Format: <value> such that (value & 0x1fffc0) == 0.
+			Default: 1024
+	grcan.rxsize=	[HW] The size of the rx buffer. For more documentation,
+			see Documentation/ABI/testing/sysfs-class-net-grcan.
+			Format: <value> such that (value & 0x1fffc0) == 0.
+			Default: 1024
+
 	hashdist=	[KNL,NUMA] Large hashes allocated during boot
 			are distributed across NUMA nodes.  Defaults on
 			for 64-bit NUMA, off otherwise.
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
index bb709fd..b56bd9e 100644
--- a/drivers/net/can/Kconfig
+++ b/drivers/net/can/Kconfig
@@ -110,6 +110,15 @@ config PCH_CAN
 	  is an IOH for x86 embedded processor (Intel Atom E6xx series).
 	  This driver can access CAN bus.
 
+config CAN_GRCAN
+	tristate "Aeroflex Gaisler GRCAN and GRHCAN CAN devices"
+	depends on CAN_DEV && OF
+	---help---
+	  Say Y here if you want to use Aeroflex Gaisler GRCAN or GRHCAN.
+	  Note that the driver supports little endian, even though little
+	  endian syntheses of the cores would need some modifications on
+	  the hardware level to work.
+
 source "drivers/net/can/mscan/Kconfig"
 
 source "drivers/net/can/sja1000/Kconfig"
diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
index 938be37..7de5986 100644
--- a/drivers/net/can/Makefile
+++ b/drivers/net/can/Makefile
@@ -22,5 +22,6 @@ obj-$(CONFIG_CAN_BFIN)		+= bfin_can.o
 obj-$(CONFIG_CAN_JANZ_ICAN3)	+= janz-ican3.o
 obj-$(CONFIG_CAN_FLEXCAN)	+= flexcan.o
 obj-$(CONFIG_PCH_CAN)		+= pch_can.o
+obj-$(CONFIG_CAN_GRCAN)		+= grcan.o
 
 ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/grcan.c b/drivers/net/can/grcan.c
new file mode 100644
index 0000000..c6e7a67
--- /dev/null
+++ b/drivers/net/can/grcan.c
@@ -0,0 +1,1712 @@
+/*
+ * Socket CAN driver for Aeroflex Gaisler GRCAN and GRHCAN.
+ *
+ * 2012 (c) Aeroflex Gaisler AB
+ *
+ * This driver supports GRCAN and GRHCAN CAN controllers available in the GRLIB
+ * VHDL IP core library.
+ *
+ * Full documentation of the GRCAN core can be found here:
+ * http://www.gaisler.com/products/grlib/grip.pdf
+ *
+ * See "Documentation/devicetree/bindings/net/can/grcan.txt" for information on
+ * open firmware properties.
+ *
+ * See "Documentation/ABI/testing/sysfs-class-net-grcan" for information on the
+ * sysfs interface.
+ *
+ * See "Documentation/kernel-parameters.txt" for information on the module
+ * parameters.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Contributors: Andreas Larsson <andreas@gaisler.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/can/dev.h>
+#include <linux/spinlock.h>
+
+#include <linux/of_platform.h>
+#include <asm/prom.h>
+
+#include <linux/of_irq.h>
+
+#include <linux/dma-mapping.h>
+
+#define DRV_NAME	"grcan"
+
+#define GRCAN_NAPI_WEIGHT	16
+
+#define GRCAN_RESERVE_SIZE(slot1, slot2) (((slot2) - (slot1)) / 4 - 1)
+
+struct grcan_registers {
+	u32 conf;	/* 0x00 */
+	u32 stat;	/* 0x04 */
+	u32 ctrl;	/* 0x08 */
+	u32 __reserved1[GRCAN_RESERVE_SIZE(0x08, 0x18)];
+	u32 smask;	/* 0x18 - CanMASK */
+	u32 scode;	/* 0x1c - CanCODE */
+	u32 __reserved2[GRCAN_RESERVE_SIZE(0x1c, 0x100)];
+	u32 pimsr;	/* 0x100 */
+	u32 pimr;	/* 0x104 */
+	u32 pisr;	/* 0x108 */
+	u32 pir;	/* 0x10C */
+	u32 imr;	/* 0x110 */
+	u32 picr;	/* 0x114 */
+	u32 __reserved3[GRCAN_RESERVE_SIZE(0x114, 0x200)];
+	u32 txctrl;	/* 0x200 */
+	u32 txaddr;	/* 0x204 */
+	u32 txsize;	/* 0x208 */
+	u32 txwr;	/* 0x20C */
+	u32 txrd;	/* 0x210 */
+	u32 txirq;	/* 0x214 */
+	u32 __reserved4[GRCAN_RESERVE_SIZE(0x214, 0x300)];
+	u32 rxctrl;	/* 0x300 */
+	u32 rxaddr;	/* 0x304 */
+	u32 rxsize;	/* 0x308 */
+	u32 rxwr;	/* 0x30C */
+	u32 rxrd;	/* 0x310 */
+	u32 rxirq;	/* 0x314 */
+	u32 rxmask;	/* 0x318 */
+	u32 rxcode;	/* 0x31C */
+};
+
+#define GRCAN_CONF_ABORT	0x00000001
+#define GRCAN_CONF_ENABLE0	0x00000002
+#define GRCAN_CONF_ENABLE1	0x00000004
+#define GRCAN_CONF_SELECTION	0x00000008
+#define GRCAN_CONF_SILENT	0x00000010
+#define GRCAN_CONF_TRIPLESAMP	0x00000020 /* Available in some hardware */
+#define GRCAN_CONF_BPR		0x00000300 /* Note: not BRP */
+#define GRCAN_CONF_RSJ		0x00007000
+#define GRCAN_CONF_PS1		0x00f00000
+#define GRCAN_CONF_PS2		0x000f0000
+#define GRCAN_CONF_SCALER	0xff000000
+#define GRCAN_CONF_OPERATION						\
+	(GRCAN_CONF_ABORT | GRCAN_CONF_ENABLE0 | GRCAN_CONF_ENABLE1	\
+	 | GRCAN_CONF_SELECTION | GRCAN_CONF_SILENT			\
+	 | GRCAN_CONF_TRIPLESAMP)
+#define GRCAN_CONF_TIMING						\
+	(GRCAN_CONF_BPR | GRCAN_CONF_RSJ | GRCAN_CONF_PS1		\
+	 | GRCAN_CONF_PS2 | GRCAN_CONF_SCALER)
+
+#define GRCAN_CONF_RSJ_MIN	1
+#define GRCAN_CONF_RSJ_MAX	4
+#define GRCAN_CONF_PS1_MIN	1
+#define GRCAN_CONF_PS1_MAX	15
+#define GRCAN_CONF_PS2_MIN	2
+#define GRCAN_CONF_PS2_MAX	8
+#define GRCAN_CONF_SCALER_MIN	0
+#define GRCAN_CONF_SCALER_MAX	255
+#define GRCAN_CONF_SCALER_INC	1
+
+#define GRCAN_CONF_BPR_BIT	8
+#define GRCAN_CONF_RSJ_BIT	12
+#define GRCAN_CONF_PS1_BIT	20
+#define GRCAN_CONF_PS2_BIT	16
+#define GRCAN_CONF_SCALER_BIT	24
+
+#define GRCAN_STAT_PASS		0x000001
+#define GRCAN_STAT_OFF		0x000002
+#define GRCAN_STAT_OR		0x000004
+#define GRCAN_STAT_AHBERR	0x000008
+#define GRCAN_STAT_ACTIVE	0x000010
+#define GRCAN_STAT_RXERRCNT	0x00ff00
+#define GRCAN_STAT_TXERRCNT	0xff0000
+
+#define GRCAN_STAT_ERRCTR_RELATED	(GRCAN_STAT_PASS | GRCAN_STAT_OFF)
+
+#define GRCAN_STAT_RXERRCNT_BIT	8
+#define GRCAN_STAT_TXERRCNT_BIT	16
+
+#define GRCAN_STAT_ERRCNT_WARNING_LIMIT	96
+#define GRCAN_STAT_ERRCNT_PASSIVE_LIMIT	127
+
+
+#define GRCAN_CTRL_RESET	0x2
+#define GRCAN_CTRL_ENABLE	0x1
+
+#define GRCAN_TXCTRL_ENABLE	0x1
+#define GRCAN_TXCTRL_ONGOING	0x2
+#define GRCAN_TXCTRL_SINGLE	0x4
+
+#define GRCAN_RXCTRL_ENABLE	0x1
+#define GRCAN_RXCTRL_ONGOING	0x2
+
+/* Relative offset of IRQ sources to AMBA Plug&Play */
+#define GRCAN_IRQIX_IRQ		0
+#define GRCAN_IRQIX_TXSYNC	1
+#define GRCAN_IRQIX_RXSYNC	2
+
+#define GRCAN_IRQ_PASS		0x00001
+#define GRCAN_IRQ_OFF		0x00002
+#define GRCAN_IRQ_OR		0x00004
+#define GRCAN_IRQ_RXAHBERR	0x00008
+#define GRCAN_IRQ_TXAHBERR	0x00010
+#define GRCAN_IRQ_RXIRQ		0x00020
+#define GRCAN_IRQ_TXIRQ		0x00040
+#define GRCAN_IRQ_RXFULL	0x00080
+#define GRCAN_IRQ_TXEMPTY	0x00100
+#define GRCAN_IRQ_RX		0x00200
+#define GRCAN_IRQ_TX		0x00400
+#define GRCAN_IRQ_RXSYNC	0x00800
+#define GRCAN_IRQ_TXSYNC	0x01000
+#define GRCAN_IRQ_RXERRCTR	0x02000
+#define GRCAN_IRQ_TXERRCTR	0x04000
+#define GRCAN_IRQ_RXMISS	0x08000
+#define GRCAN_IRQ_TXLOSS	0x10000
+
+#define GRCAN_IRQ_NONE	0
+#define GRCAN_IRQ_ALL							\
+	(GRCAN_IRQ_PASS | GRCAN_IRQ_OFF | GRCAN_IRQ_OR			\
+	 | GRCAN_IRQ_RXAHBERR | GRCAN_IRQ_TXAHBERR			\
+	 | GRCAN_IRQ_RXIRQ | GRCAN_IRQ_TXIRQ				\
+	 | GRCAN_IRQ_RXFULL | GRCAN_IRQ_TXEMPTY				\
+	 | GRCAN_IRQ_RX | GRCAN_IRQ_TX | GRCAN_IRQ_RXSYNC		\
+	 | GRCAN_IRQ_TXSYNC | GRCAN_IRQ_RXERRCTR			\
+	 | GRCAN_IRQ_TXERRCTR | GRCAN_IRQ_RXMISS			\
+	 | GRCAN_IRQ_TXLOSS)
+
+#define GRCAN_IRQ_ERRCTR_RELATED (GRCAN_IRQ_RXERRCTR | GRCAN_IRQ_TXERRCTR \
+				  | GRCAN_IRQ_PASS | GRCAN_IRQ_OFF)
+#define GRCAN_IRQ_ERRORS (GRCAN_IRQ_ERRCTR_RELATED | GRCAN_IRQ_OR	\
+			  | GRCAN_IRQ_TXAHBERR | GRCAN_IRQ_RXAHBERR	\
+			  | GRCAN_IRQ_TXLOSS)
+#define GRCAN_IRQ_DEFAULT (GRCAN_IRQ_RX | GRCAN_IRQ_TX | GRCAN_IRQ_ERRORS)
+
+#define GRCAN_MSG_SIZE		16
+
+#define GRCAN_MSG_IDE		0x80000000
+#define GRCAN_MSG_RTR		0x40000000
+#define GRCAN_MSG_BID		0x1ffc0000
+#define GRCAN_MSG_EID		0x1fffffff
+#define GRCAN_MSG_IDE_BIT	31
+#define GRCAN_MSG_RTR_BIT	30
+#define GRCAN_MSG_BID_BIT	18
+#define GRCAN_MSG_EID_BIT	0
+
+#define GRCAN_MSG_DLC		0xf0000000
+#define GRCAN_MSG_TXERRC	0x00ff0000
+#define GRCAN_MSG_RXERRC	0x0000ff00
+#define GRCAN_MSG_DLC_BIT	28
+#define GRCAN_MSG_TXERRC_BIT	16
+#define GRCAN_MSG_RXERRC_BIT	8
+#define GRCAN_MSG_AHBERR	0x00000008
+#define GRCAN_MSG_OR		0x00000004
+#define GRCAN_MSG_OFF		0x00000002
+#define GRCAN_MSG_PASS		0x00000001
+
+#define GRCAN_MSG_DATA_SLOT_INDEX(i) (2 + (i) / 4)
+#define GRCAN_MSG_DATA_SHIFT(i) ((3 - (i) % 4) * 8)
+
+#define GRCAN_BUFFER_ALIGNMENT		1024
+#define GRCAN_DEFAULT_BUFFER_SIZE	1024
+#define GRCAN_VALID_TR_SIZE_MASK	0x001fffc0
+
+#define GRCAN_INVALID_BUFFER_SIZE(s)			\
+	((s) == 0 || ((s) & ~GRCAN_VALID_TR_SIZE_MASK))
+
+#if GRCAN_INVALID_BUFFER_SIZE(GRCAN_DEFAULT_BUFFER_SIZE)
+#error "Invalid default buffer size"
+#endif
+
+struct grcan_dma_buffer {
+	size_t size;
+	void *buf;
+	dma_addr_t handle;
+};
+
+struct grcan_dma {
+	size_t base_size;
+	void *base_buf;
+	dma_addr_t base_handle;
+	struct grcan_dma_buffer tx;
+	struct grcan_dma_buffer rx;
+};
+
+/* GRCAN configuration parameters */
+struct grcan_device_config {
+	unsigned short enable0;
+	unsigned short enable1;
+	unsigned short selection;
+	unsigned int txsize;
+	unsigned int rxsize;
+};
+
+#define GRCAN_DEFAULT_DEVICE_CONFIG {				\
+		.enable0	= 0,				\
+		.enable1	= 0,				\
+		.selection	= 0,				\
+		.txsize		= GRCAN_DEFAULT_BUFFER_SIZE,	\
+		.rxsize		= GRCAN_DEFAULT_BUFFER_SIZE,	\
+		}
+
+#define GRCAN_TXBUG_SAFE_GRLIB_VERSION	0x4100
+#define GRLIB_VERSION_MASK		0xffff
+
+
+/* GRCAN private data structure */
+struct grcan_priv {
+	struct can_priv can;	/* must be the first member */
+	struct net_device *dev;
+	struct napi_struct napi;
+
+	struct grcan_registers __iomem *regs;	/* ioremap'ed registers */
+	struct grcan_device_config config;
+	struct grcan_dma dma;
+
+	struct sk_buff **echo_skb;	/* We allocate this on our own */
+	u8 *txdlc;			/* Length of queued frames */
+
+	/* The echo skb pointer, pointing into echo_skb and indicating which
+	 * frames can be echoed back. See the "Notes on the tx cyclic buffer
+	 * handling"-comment for grcan_start_xmit for more details.
+	 */
+	u32 eskbp;
+
+	/* Lock for controlling changes to the netif tx queue state, accesses to
+	 * the echo_skb pointer eskbp and for making sure that a running reset
+	 * and/or a close of the interface is done without interference from
+	 * other parts of the code.
+	 *
+	 * The echo_skb pointer, eskbp, should only be accessed under this lock
+	 * as it can be changed in several places and together with decisions on
+	 * whether to wake up the tx queue.
+	 *
+	 * The tx queue must never be woken up if there is a running reset or
+	 * close in progress.
+	 *
+	 * A running reset (see below on need_txbug_workaround) should never be
+	 * done if the interface is closing down and several running resets
+	 * should never be scheduled simultaneously.
+	 */
+	spinlock_t lock;
+
+	/* Whether a workaround is needed due to a bug in older hardware. In
+	 * this case, the driver both tries to prevent the bug from being
+	 * triggered and recovers, if the bug nevertheless happens, by doing a
+	 * running reset. A running reset, resets the device and continues from
+	 * where it were without being noticeable from outside the driver (apart
+	 * from slight delays).
+	 */
+	bool need_txbug_workaround;
+
+	/* To trigger initization of running reset and to trigger running reset
+	 * respectively in the case of a hanged device due to a txbug.
+	 */
+	struct timer_list hang_timer;
+	struct timer_list rr_timer;
+
+	/* To avoid waking up the netif queue and restarting timers
+	 * when a reset is scheduled or when closing of the device is
+	 * undergoing
+	 */
+	bool resetting;
+	bool closing;
+};
+
+/* Wait time for a short wait for ongoing to clear */
+#define GRCAN_SHORTWAIT_USECS	10
+
+/* Limit on the number of transmitted bits of an eff frame according to the CAN
+ * specification: 1 bit start of frame, 32 bits arbitration field, 6 bits
+ * control field, 8 bytes data field, 16 bits crc field, 2 bits ACK field and 7
+ * bits end of frame
+ */
+#define GRCAN_EFF_FRAME_MAX_BITS	(1+32+6+8*8+16+2+7)
+
+#if defined(__BIG_ENDIAN)
+static inline u32 grcan_read_reg(u32 __iomem *reg)
+{
+	return ioread32be(reg);
+}
+
+static inline void grcan_write_reg(u32 __iomem *reg, u32 val)
+{
+	iowrite32be(val, reg);
+}
+#else
+static inline u32 grcan_read_reg(u32 __iomem *reg)
+{
+	return ioread32(reg);
+}
+
+static inline void grcan_write_reg(u32 __iomem *reg, u32 val)
+{
+	iowrite32(val, reg);
+}
+#endif
+
+static inline void grcan_clear_bits(u32 __iomem *reg, u32 mask)
+{
+	grcan_write_reg(reg, grcan_read_reg(reg) & ~mask);
+}
+
+static inline void grcan_set_bits(u32 __iomem *reg, u32 mask)
+{
+	grcan_write_reg(reg, grcan_read_reg(reg) | mask);
+}
+
+static inline u32 grcan_read_bits(u32 __iomem *reg, u32 mask)
+{
+	return grcan_read_reg(reg) & mask;
+}
+
+static inline void grcan_write_bits(u32 __iomem *reg, u32 value, u32 mask)
+{
+	u32 old = grcan_read_reg(reg);
+
+	grcan_write_reg(reg, (old & ~mask) | (value & mask));
+}
+
+/* a and b should both be in [0,size] and a == b == size should not hold */
+static inline u32 grcan_ring_add(u32 a, u32 b, u32 size)
+{
+	u32 sum = a + b;
+
+	if (sum < size)
+		return sum;
+	else
+		return sum - size;
+}
+
+/* a and b should both be in [0,size) */
+static inline u32 grcan_ring_sub(u32 a, u32 b, u32 size)
+{
+	return grcan_ring_add(a, size - b, size);
+}
+
+/* Available slots for new transmissions */
+static inline u32 grcan_txspace(size_t txsize, u32 txwr, u32 eskbp)
+{
+	u32 slots = txsize / GRCAN_MSG_SIZE - 1;
+	u32 used = grcan_ring_sub(txwr, eskbp, txsize) / GRCAN_MSG_SIZE;
+
+	return slots - used;
+}
+
+/* Configuration parameters that can be set via module parameters */
+static struct grcan_device_config grcan_module_config =
+	GRCAN_DEFAULT_DEVICE_CONFIG;
+
+static struct can_bittiming_const grcan_bittiming_const = {
+	.name		= DRV_NAME,
+	.tseg1_min	= GRCAN_CONF_PS1_MIN + 1,
+	.tseg1_max	= GRCAN_CONF_PS1_MAX + 1,
+	.tseg2_min	= GRCAN_CONF_PS2_MIN,
+	.tseg2_max	= GRCAN_CONF_PS2_MAX,
+	.sjw_max	= GRCAN_CONF_RSJ_MAX,
+	.brp_min	= GRCAN_CONF_SCALER_MIN + 1,
+	.brp_max	= GRCAN_CONF_SCALER_MAX + 1,
+	.brp_inc	= GRCAN_CONF_SCALER_INC,
+};
+
+static int grcan_set_bittiming(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct can_bittiming *bt = &priv->can.bittiming;
+	u32 timing = 0;
+	int bpr, rsj, ps1, ps2, scaler;
+
+	/* Should never happen - function will not be called when
+	 * device is up
+	 */
+	if (grcan_read_bits(&regs->ctrl, GRCAN_CTRL_ENABLE))
+		return -EBUSY;
+
+	bpr = 0; /* Note bpr and brp are different concepts */
+	rsj = bt->sjw;
+	ps1 = (bt->prop_seg + bt->phase_seg1) - 1; /* tseg1 - 1 */
+	ps2 = bt->phase_seg2;
+	scaler = (bt->brp - 1);
+	timing |= (bpr << GRCAN_CONF_BPR_BIT) & GRCAN_CONF_BPR;
+	timing |= (rsj << GRCAN_CONF_RSJ_BIT) & GRCAN_CONF_RSJ;
+	timing |= (ps1 << GRCAN_CONF_PS1_BIT) & GRCAN_CONF_PS1;
+	timing |= (ps2 << GRCAN_CONF_PS2_BIT) & GRCAN_CONF_PS2;
+	timing |= (scaler << GRCAN_CONF_SCALER_BIT) & GRCAN_CONF_SCALER;
+
+	dev_info(dev->dev.parent,
+		 "setting timing=0x%x\n", timing);
+	grcan_write_bits(&regs->conf, timing, GRCAN_CONF_TIMING);
+	return 0;
+}
+
+static int grcan_get_berr_counter(const struct net_device *dev,
+				  struct can_berr_counter *bec)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	u32 status = grcan_read_reg(&regs->stat);
+
+	bec->txerr = (status & GRCAN_STAT_TXERRCNT) >> GRCAN_STAT_TXERRCNT_BIT;
+	bec->rxerr = (status & GRCAN_STAT_RXERRCNT) >> GRCAN_STAT_RXERRCNT_BIT;
+	return 0;
+}
+
+static int grcan_poll(struct napi_struct *napi, int budget);
+
+/* Reset device, but keep configuration information */
+static void grcan_reset(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	u32 config = grcan_read_reg(&regs->conf);
+
+	grcan_set_bits(&regs->ctrl, GRCAN_CTRL_RESET);
+	grcan_write_reg(&regs->conf, config);
+
+	priv->eskbp = grcan_read_reg(&regs->txrd);
+	priv->can.state = CAN_STATE_STOPPED;
+
+	/* Turn off hardware filtering - regs->rxcode set to 0 by reset */
+	grcan_write_reg(&regs->rxmask, 0);
+}
+
+/* stop device without changing any configurations */
+static void grcan_stop_hardware(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+
+	grcan_write_reg(&regs->imr, GRCAN_IRQ_NONE);
+	grcan_clear_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
+	grcan_clear_bits(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+	grcan_clear_bits(&regs->ctrl, GRCAN_CTRL_ENABLE);
+}
+
+/* Let priv->eskbp catch up to regs->txrd and echo back the skbs if echo
+ * is true and free them otherwise.
+ *
+ * If budget is >= 0, stop after handling at most budget skbs. Otherwise,
+ * continue until priv->eskbp catches up to regs->txrd.
+ *
+ * priv->lock *must* be held when calling this function
+ */
+static int catch_up_echo_skb(struct net_device *dev, int budget, bool echo)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	struct net_device_stats *stats = &dev->stats;
+	int i, work_done;
+
+	/* Updates to priv->eskbp and wake-ups of the queue needs to
+	 * be atomic towards the reads of priv->eskbp and shut-downs
+	 * of the queue in grcan_start_xmit.
+	 */
+	u32 txrd = grcan_read_reg(&regs->txrd);
+
+	for (work_done = 0; work_done < budget || budget < 0; work_done++) {
+		if (priv->eskbp == txrd)
+			break;
+		i = priv->eskbp / GRCAN_MSG_SIZE;
+		if (echo) {
+			/* Normal echo of messages */
+			stats->tx_packets++;
+			stats->tx_bytes += priv->txdlc[i];
+			priv->txdlc[i] = 0;
+			can_get_echo_skb(dev, i);
+		} else {
+			/* For cleanup of untransmitted messages */
+			can_free_echo_skb(dev, i);
+		}
+
+		priv->eskbp = grcan_ring_add(priv->eskbp, GRCAN_MSG_SIZE,
+					     dma->tx.size);
+		txrd = grcan_read_reg(&regs->txrd);
+	}
+	return work_done;
+}
+
+static void grcan_lost_one_shot_frame(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	u32 txrd;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	catch_up_echo_skb(dev, -1, true);
+
+	if (unlikely(grcan_read_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE))) {
+		/* Should never happen */
+		netdev_err(dev, "TXCTRL enabled at TXLOSS in one shot mode\n");
+	} else {
+		/* By the time an GRCAN_IRQ_TXLOSS is generated in
+		 * one-shot mode there is no problem in writing
+		 * to TXRD even in versions of the hardware in
+		 * which GRCAN_TXCTRL_ONGOING is not cleared properly
+		 * in one-shot mode.
+		 */
+
+		/* Skip message and discard echo-skb */
+		txrd = grcan_read_reg(&regs->txrd);
+		txrd = grcan_ring_add(txrd, GRCAN_MSG_SIZE, dma->tx.size);
+		grcan_write_reg(&regs->txrd, txrd);
+		catch_up_echo_skb(dev, -1, false);
+
+		if (!priv->resetting && !priv->closing &&
+		    !(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)) {
+			netif_wake_queue(dev);
+			grcan_set_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
+		}
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static void grcan_err(struct net_device *dev, u32 sources, u32 status)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct net_device_stats *stats = &dev->stats;
+	struct can_frame cf;
+
+	/* Zero potential error_frame */
+	memset(&cf, 0, sizeof(cf));
+
+	/* Message lost interrupt. This might be due to arbitration error, but
+	 * is also triggered when there is no one else on the can bus or when
+	 * there is a problem with the hardware interface or the bus itself. As
+	 * arbitration errors can not be singled out, no error frames are
+	 * generated reporting this event as an arbitration error.
+	 */
+	if (sources & GRCAN_IRQ_TXLOSS) {
+		/* Take care of failed one-shot transmit */
+		if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT)
+			grcan_lost_one_shot_frame(dev);
+
+		/* When not in one-shot mode, GRCAN_IRQ_TXLOSS gets triggered
+		 * over and over again even if controller is error passive.
+		 */
+		if (!(status & GRCAN_STAT_ERRCTR_RELATED)) {
+			netdev_dbg(dev, "tx message lost due to an arbitration error or some other comm error)\n");
+			stats->tx_errors++;
+		}
+	}
+
+	/* Conditions dealing with the error counters. There is no interrupt for
+	 * error warning, but there are interrupts for increases of the error
+	 * counters.
+	 */
+	if ((sources & GRCAN_IRQ_ERRCTR_RELATED)
+	    || (status & GRCAN_STAT_ERRCTR_RELATED)) {
+		enum can_state state = priv->can.state;
+		enum can_state oldstate = state;
+		u32 txerr = (status & GRCAN_STAT_TXERRCNT)
+			>> GRCAN_STAT_TXERRCNT_BIT;
+		u32 rxerr = (status & GRCAN_STAT_RXERRCNT)
+			>> GRCAN_STAT_RXERRCNT_BIT;
+
+		/* Figure out current state */
+		if (status & GRCAN_STAT_OFF) {
+			state = CAN_STATE_BUS_OFF;
+		} else if (status & GRCAN_STAT_PASS) {
+			state = CAN_STATE_ERROR_PASSIVE;
+		} else if (txerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT ||
+			   rxerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT) {
+			state = CAN_STATE_ERROR_WARNING;
+		} else {
+			state = CAN_STATE_ERROR_ACTIVE;
+		}
+
+		/* Handle and report state changes */
+		if (state != oldstate) {
+			switch (state) {
+			case CAN_STATE_BUS_OFF:
+				netdev_dbg(dev, "Bus off condition\n");
+				cf.can_id |= CAN_ERR_BUSOFF;
+
+				can_bus_off(dev);
+
+				/* The hardware can recover from bus off on its
+				 * own. To give the control to linux, we have to
+				 * stop the hardware here.
+				 */
+				 grcan_stop_hardware(dev);
+				 break;
+
+			case CAN_STATE_ERROR_PASSIVE:
+				netdev_dbg(dev, "Error passive condition\n");
+				priv->can.can_stats.error_passive++;
+
+				cf.can_id |= CAN_ERR_CRTL;
+				if (txerr >= GRCAN_STAT_ERRCNT_PASSIVE_LIMIT)
+					cf.data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
+				if (rxerr >= GRCAN_STAT_ERRCNT_PASSIVE_LIMIT)
+					cf.data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
+				break;
+
+			case CAN_STATE_ERROR_WARNING:
+				netdev_dbg(dev, "Error warning condition\n");
+				priv->can.can_stats.error_warning++;
+
+				cf.can_id |= CAN_ERR_CRTL;
+				if (txerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT)
+					cf.data[1] |= CAN_ERR_CRTL_TX_WARNING;
+				if (rxerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT)
+					cf.data[1] |= CAN_ERR_CRTL_RX_WARNING;
+				break;
+
+			case CAN_STATE_ERROR_ACTIVE:
+				netdev_dbg(dev, "Error active condition\n");
+				cf.can_id |= CAN_ERR_CRTL;
+				break;
+
+			default:
+				/* There are no others at this point */
+				break;
+			}
+			cf.data[6] = txerr;
+			cf.data[7] = rxerr;
+			priv->can.state = state;
+		}
+	}
+
+	/* Data overrun interrupt */
+	if ((sources & GRCAN_IRQ_OR) || (status & GRCAN_STAT_OR)) {
+		netdev_dbg(dev, "got data overrun interrupt\n");
+		stats->rx_over_errors++;
+		stats->rx_errors++;
+
+		cf.can_id |= CAN_ERR_CRTL;
+		cf.data[1] |= CAN_ERR_CRTL_RX_OVERFLOW;
+	}
+
+	/* AHB bus error interrupts (not CAN bus errors) - shut down the
+	 * device.
+	 */
+	if (sources & (GRCAN_IRQ_TXAHBERR | GRCAN_IRQ_RXAHBERR)
+	    || (status & GRCAN_STAT_AHBERR)) {
+		char *txrx = "";
+		unsigned long flags;
+
+		if (sources & GRCAN_IRQ_TXAHBERR) {
+			txrx = "on tx " ;
+			stats->tx_errors++;
+		} else if (sources & GRCAN_IRQ_RXAHBERR) {
+			txrx = "on rx " ;
+			stats->rx_errors++;
+		}
+		netdev_err(dev, "Fatal AHB buss error %s- halting device\n",
+			   txrx);
+
+		spin_lock_irqsave(&priv->lock, flags);
+
+		/* Prevent anything to be enabled again and halt device */
+		priv->closing = true;
+		netif_stop_queue(dev);
+		grcan_stop_hardware(dev);
+		priv->can.state = CAN_STATE_STOPPED;
+
+		spin_unlock_irqrestore(&priv->lock, flags);
+	}
+
+	/* Pass on error frame if something to report,
+	 * i.e. id contains some information
+	 */
+	if (cf.can_id) {
+		struct can_frame *skb_cf;
+		struct sk_buff *skb = alloc_can_err_skb(dev, &skb_cf);
+
+		if (skb == NULL) {
+			netdev_dbg(dev, "could not allocate error frame\n");
+			return;
+		}
+		skb_cf->can_id |= cf.can_id;
+		memcpy(skb_cf->data, cf.data, sizeof(cf.data));
+
+		netif_rx(skb);
+	}
+}
+
+static irqreturn_t grcan_interrupt(int irq, void *dev_id)
+{
+	struct net_device *dev = (struct net_device *)dev_id;
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	u32 sources, status;
+
+	/* Find out the source */
+	sources = grcan_read_reg(&regs->pimsr);
+	if (!sources)
+		return IRQ_NONE;
+	grcan_write_reg(&regs->picr, sources);
+	status = grcan_read_reg(&regs->stat);
+
+	/* If we got TX progress, the device has not hanged,
+	 * so disable the hang timer
+	 */
+	if (priv->need_txbug_workaround
+	    && (sources & (GRCAN_IRQ_TX | GRCAN_IRQ_TXLOSS))) {
+		del_timer(&priv->hang_timer);
+	}
+
+	/* Frame(s) received or transmitted */
+	if (sources & (GRCAN_IRQ_TX | GRCAN_IRQ_RX)) {
+		/* Disable tx/rx interrupts and schedule poll() */
+		grcan_clear_bits(&regs->imr, GRCAN_IRQ_TX | GRCAN_IRQ_RX);
+		napi_schedule(&priv->napi);
+	}
+
+	/* (Potential) error conditions to take care of */
+	if (sources & GRCAN_IRQ_ERRORS)
+		grcan_err(dev, sources, status);
+
+	return IRQ_HANDLED;
+}
+
+/* Reset device and restart operations from where they were.
+ *
+ * This assumes that RXCTRL & RXCTRL is properly disabled and that RX
+ * is not ONGOING (TX might be stuck in ONGOING due to a harwrware bug
+ * for single shot)
+ */
+static void grcan_running_reset(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *) data;
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	unsigned long flags;
+
+	/* This temporarily messes with eskbp, so we need to lock
+	 * priv->lock
+	 */
+	spin_lock_irqsave(&priv->lock, flags);
+
+	priv->resetting = false;
+	del_timer(&priv->hang_timer);
+	del_timer(&priv->rr_timer);
+
+	if (!priv->closing) {
+		/* Save and reset - config register preserved by grcan_reset */
+		u32 imr = grcan_read_reg(&regs->imr);
+
+		u32 txaddr = grcan_read_reg(&regs->txaddr);
+		u32 txsize = grcan_read_reg(&regs->txsize);
+		u32 txwr = grcan_read_reg(&regs->txwr);
+		u32 txrd = grcan_read_reg(&regs->txrd);
+		u32 eskbp = priv->eskbp;
+
+		u32 rxaddr = grcan_read_reg(&regs->rxaddr);
+		u32 rxsize = grcan_read_reg(&regs->rxsize);
+		u32 rxwr = grcan_read_reg(&regs->rxwr);
+		u32 rxrd = grcan_read_reg(&regs->rxrd);
+
+		grcan_reset(dev);
+
+		/* Restore */
+		grcan_write_reg(&regs->txaddr, txaddr);
+		grcan_write_reg(&regs->txsize, txsize);
+		grcan_write_reg(&regs->txwr, txwr);
+		grcan_write_reg(&regs->txrd, txrd);
+		priv->eskbp = eskbp;
+
+		grcan_write_reg(&regs->rxaddr, rxaddr);
+		grcan_write_reg(&regs->rxsize, rxsize);
+		grcan_write_reg(&regs->rxwr, rxwr);
+		grcan_write_reg(&regs->rxrd, rxrd);
+
+		/* Turn on device again */
+		grcan_write_reg(&regs->imr, imr);
+		priv->can.state = CAN_STATE_ERROR_ACTIVE;
+		grcan_write_reg(&regs->txctrl, GRCAN_TXCTRL_ENABLE
+				| (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT
+				   ? GRCAN_TXCTRL_SINGLE : 0));
+		grcan_write_reg(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+		grcan_write_reg(&regs->ctrl, GRCAN_CTRL_ENABLE);
+
+		/* Start queue if there is size and listen-onle mode is not
+		 * enabled
+		 */
+		if (grcan_txspace(priv->dma.tx.size, txwr, priv->eskbp) &&
+		    !(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
+			netif_wake_queue(dev);
+
+
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	netdev_err(dev, "Device reset and restored\n");
+}
+
+/* Waiting time in usecs corresponding to the transmission of three maximum
+ * sized can frames in the given bitrate (in bits/sec). Waiting for this amount
+ * of time makes sure that the can controller have time to finish sending or
+ * receiving a frame with a good margin.
+ *
+ * usecs/sec * number of frames * bits/frame / bits/sec
+ */
+static inline u32 grcan_ongoing_wait_usecs(__u32 bitrate)
+{
+	return 1000000 * 3 * GRCAN_EFF_FRAME_MAX_BITS / bitrate;
+}
+
+/* Set timer so that it will not fire until after a period in which the can
+ * controller have a good margin to finish transmitting a frame unless it has
+ * hanged
+ */
+static inline void grcan_reset_timer(struct timer_list *timer, __u32 bitrate)
+{
+	u32 wait_jiffies = usecs_to_jiffies(grcan_ongoing_wait_usecs(bitrate));
+
+	mod_timer(timer, jiffies + wait_jiffies);
+}
+
+/* Disable channels and schedule a running reset */
+static void grcan_initiate_running_reset(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *)data;
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	unsigned long flags;
+
+	netdev_err(dev, "Device seems hanged - reset scheduled\n");
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	/* The main body of this function must never be executed again
+	 * until after an execution of grcan_running_reset
+	 */
+	if (!priv->resetting && !priv->closing) {
+		priv->resetting = true;
+		netif_stop_queue(dev);
+		grcan_clear_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
+		grcan_clear_bits(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+		grcan_reset_timer(&priv->rr_timer, priv->can.bittiming.bitrate);
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static void grcan_free_dma_buffers(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_dma *dma = &priv->dma;
+
+	dma_free_coherent(&dev->dev, dma->base_size, dma->base_buf,
+			  dma->base_handle);
+	memset(dma, 0, sizeof(*dma));
+}
+
+static int grcan_allocate_dma_buffers(struct net_device *dev,
+				      size_t tsize, size_t rsize)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_dma *dma = &priv->dma;
+	struct grcan_dma_buffer *large = rsize > tsize ? &dma->rx : &dma->tx;
+	struct grcan_dma_buffer *small = rsize > tsize ? &dma->tx : &dma->rx;
+	size_t shift;
+
+	/* Need a whole number of GRCAN_BUFFER_ALIGNMENT for the large,
+	 * i.e. first buffer
+	 */
+	size_t maxs = max(tsize, rsize);
+	size_t lsize = ALIGN(maxs, GRCAN_BUFFER_ALIGNMENT);
+
+	/* Put the small buffer after that */
+	size_t ssize = min(tsize, rsize);
+
+	/* Extra GRCAN_BUFFER_ALIGNMENT to allow for alignment */
+	dma->base_size = lsize + ssize + GRCAN_BUFFER_ALIGNMENT;
+	dma->base_buf = dma_alloc_coherent(&dev->dev,
+					   dma->base_size,
+					   &dma->base_handle,
+					   GFP_KERNEL);
+
+	if (!dma->base_buf)
+		return -ENOMEM;
+
+	dma->tx.size = tsize;
+	dma->rx.size = rsize;
+
+	large->handle = ALIGN(dma->base_handle, GRCAN_BUFFER_ALIGNMENT);
+	small->handle = large->handle + lsize;
+	shift = large->handle - dma->base_handle;
+
+	large->buf = dma->base_buf + shift;
+	small->buf = large->buf + lsize;
+
+	return 0;
+}
+
+
+/* priv->lock *must* be held when calling this function */
+static int grcan_start(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	u32 confop, txctrl;
+
+	grcan_reset(dev);
+
+	grcan_write_reg(&regs->txaddr, priv->dma.tx.handle);
+	grcan_write_reg(&regs->txsize, priv->dma.tx.size);
+	/* regs->txwr and regs->txrd already set to 0 by reset */
+
+	grcan_write_reg(&regs->rxaddr, priv->dma.rx.handle);
+	grcan_write_reg(&regs->rxsize, priv->dma.rx.size);
+	/* regs->rxwr and regs->rxrd already set to 0 by reset */
+
+	/* Enable interrupts */
+	grcan_read_reg(&regs->pir);
+	grcan_write_reg(&regs->imr, GRCAN_IRQ_DEFAULT);
+
+	/* Enable interfaces, channels and device */
+	confop = GRCAN_CONF_ABORT
+		| (priv->config.enable0 ? GRCAN_CONF_ENABLE0 : 0)
+		| (priv->config.enable1 ? GRCAN_CONF_ENABLE1 : 0)
+		| (priv->config.selection ? GRCAN_CONF_SELECTION : 0)
+		| (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY ?
+		   GRCAN_CONF_SILENT : 0)
+		| (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES ?
+		   GRCAN_CONF_TRIPLESAMP : 0);
+	grcan_write_bits(&regs->conf, confop, GRCAN_CONF_OPERATION);
+	txctrl = GRCAN_TXCTRL_ENABLE
+		| (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT
+		   ? GRCAN_TXCTRL_SINGLE : 0);
+	grcan_write_reg(&regs->txctrl, txctrl);
+	grcan_write_reg(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+	grcan_write_reg(&regs->ctrl, GRCAN_CTRL_ENABLE);
+
+	priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+	return 0;
+}
+
+static int grcan_set_mode(struct net_device *dev, enum can_mode mode)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+	int err = 0;
+
+	if (mode == CAN_MODE_START) {
+		/* This might be called to restart the device to recover from
+		 * bus off errors
+		 */
+		spin_lock_irqsave(&priv->lock, flags);
+		if (priv->closing || priv->resetting) {
+			err = -EBUSY;
+		} else {
+			netdev_info(dev, "Restarting device\n");
+			grcan_start(dev);
+			if (!(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
+				netif_wake_queue(dev);
+		}
+		spin_unlock_irqrestore(&priv->lock, flags);
+		return err;
+	}
+	return -EOPNOTSUPP;
+}
+
+static int grcan_open(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_dma *dma = &priv->dma;
+	unsigned long flags;
+	int err;
+
+	/* Allocate memory */
+	if (GRCAN_INVALID_BUFFER_SIZE(priv->config.txsize)
+	    || GRCAN_INVALID_BUFFER_SIZE(priv->config.rxsize)) {
+		/* Should never be able go this far with invalid sizes */
+		netdev_err(dev, "Invalid buffer size pair 0x%x 0x%x\n",
+			   priv->config.txsize, priv->config.rxsize);
+		return -EINVAL;
+	}
+	err = grcan_allocate_dma_buffers(dev, priv->config.txsize,
+					 priv->config.rxsize);
+	if (err) {
+		netdev_err(dev, "could not allocate DMA buffers\n");
+		return err;
+	}
+
+	priv->echo_skb = devm_kzalloc(&dev->dev,
+				      dma->tx.size * sizeof(*priv->echo_skb),
+				      GFP_KERNEL);
+	if (!priv->echo_skb) {
+		err = -ENOMEM;
+		goto exit_free_dma_buffers;
+	}
+	priv->can.echo_skb_max = dma->tx.size;
+	priv->can.echo_skb = priv->echo_skb;
+
+	priv->txdlc = devm_kzalloc(&dev->dev,
+				   dma->tx.size * sizeof(*priv->txdlc),
+				   GFP_KERNEL);
+	if (!priv->txdlc) {
+		err = -ENOMEM;
+		goto exit_free_echo_skb;
+	}
+
+	/* Get can device up */
+	err = open_candev(dev);
+	if (err)
+		goto exit_free_txdlc;
+
+	err = devm_request_irq(&dev->dev, dev->irq, grcan_interrupt,
+			       IRQF_SHARED, dev->name, (void *)dev);
+	if (err)
+		goto exit_close_candev;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	grcan_start(dev);
+	napi_enable(&priv->napi);
+	if (!(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
+		netif_start_queue(dev);
+	priv->resetting = false;
+	priv->closing = false;
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return 0;
+
+exit_close_candev:
+	close_candev(dev);
+exit_free_txdlc:
+	devm_kfree(&dev->dev, priv->txdlc);
+exit_free_echo_skb:
+	devm_kfree(&dev->dev, priv->echo_skb);
+exit_free_dma_buffers:
+	grcan_free_dma_buffers(dev);
+	return err;
+}
+
+static int grcan_close(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+
+	napi_disable(&priv->napi);
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	priv->closing = true;
+	if (priv->need_txbug_workaround) {
+		del_timer_sync(&priv->hang_timer);
+		del_timer_sync(&priv->rr_timer);
+	}
+	netif_stop_queue(dev);
+	grcan_stop_hardware(dev);
+	priv->can.state = CAN_STATE_STOPPED;
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	devm_free_irq(&dev->dev, dev->irq, (void *)dev);
+	close_candev(dev);
+
+	grcan_free_dma_buffers(dev);
+	priv->can.echo_skb_max = 0;
+	priv->can.echo_skb = NULL;
+	devm_kfree(&dev->dev, priv->echo_skb);
+	devm_kfree(&dev->dev, priv->txdlc);
+
+	return 0;
+}
+
+static int grcan_transmit_catch_up(struct net_device *dev, int budget)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+	int work_done;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	work_done = catch_up_echo_skb(dev, budget, true);
+	if (work_done) {
+		if (!priv->resetting && !priv->closing &&
+		    !(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
+			netif_wake_queue(dev);
+
+		/* With napi we don't get TX interrupts for a while,
+		 * so prevent a running reset while catching up
+		 */
+		if (priv->need_txbug_workaround)
+			del_timer(&priv->hang_timer);
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return work_done;
+}
+
+static int grcan_receive(struct net_device *dev, int budget)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	struct net_device_stats *stats = &dev->stats;
+	struct can_frame *cf;
+	struct sk_buff *skb;
+	u32 wr, rd, startrd;
+	u32 *slot;
+	u32 i, rtr, eff, j, shift;
+	int work_done = 0;
+
+	rd = grcan_read_reg(&regs->rxrd);
+	startrd = rd;
+	for (work_done = 0; work_done < budget; work_done++) {
+		/* Check for packet to receive */
+		wr = grcan_read_reg(&regs->rxwr);
+		if (rd == wr)
+			break;
+
+		/* Take care of packet */
+		skb = alloc_can_skb(dev, &cf);
+		if (skb == NULL) {
+			netdev_err(dev,
+				   "dropping frame: skb allocation failed\n");
+			stats->rx_dropped++;
+			continue;
+		}
+
+		slot = dma->rx.buf + rd;
+		eff = slot[0] & GRCAN_MSG_IDE;
+		rtr = slot[0] & GRCAN_MSG_RTR;
+		if (eff) {
+			cf->can_id = ((slot[0] & GRCAN_MSG_EID)
+				      >> GRCAN_MSG_EID_BIT);
+			cf->can_id |= CAN_EFF_FLAG;
+		} else {
+			cf->can_id = ((slot[0] & GRCAN_MSG_BID)
+				      >> GRCAN_MSG_BID_BIT);
+		}
+		cf->can_dlc = get_can_dlc((slot[1] & GRCAN_MSG_DLC)
+					  >> GRCAN_MSG_DLC_BIT);
+		if (rtr) {
+			cf->can_id |= CAN_RTR_FLAG;
+		} else {
+			for (i = 0; i < cf->can_dlc; i++) {
+				j = GRCAN_MSG_DATA_SLOT_INDEX(i);
+				shift = GRCAN_MSG_DATA_SHIFT(i);
+				cf->data[i] = (u8)((slot[j] >> shift) & 0xff);
+			}
+		}
+		netif_receive_skb(skb);
+
+		/* Update statistics and read pointer */
+		stats->rx_packets++;
+		stats->rx_bytes += cf->can_dlc;
+		rd = grcan_ring_add(rd, GRCAN_MSG_SIZE, dma->rx.size);
+	}
+
+	/* Make sure everything is read before allowing hardware to
+	 * use the memory
+	 */
+	mb();
+
+	/* Update read pointer - no need to check for ongoing */
+	if (likely(rd != startrd))
+		grcan_write_reg(&regs->rxrd, rd);
+
+	return work_done;
+}
+
+static int grcan_poll(struct napi_struct *napi, int budget)
+{
+	struct grcan_priv *priv = container_of(napi, struct grcan_priv, napi);
+	struct net_device *dev = priv->dev;
+	struct grcan_registers __iomem *regs = priv->regs;
+	int rx_work_done = grcan_receive(dev, budget);
+	int tx_work_done = grcan_transmit_catch_up(dev, budget);
+
+	if (rx_work_done < budget && tx_work_done < budget) {
+		napi_complete(napi);
+		/* Enable tx and rx interrupts again */
+		if (!priv->closing)
+			grcan_set_bits(&regs->imr, GRCAN_IRQ_TX | GRCAN_IRQ_RX);
+	}
+	return rx_work_done;
+}
+
+/* Work tx bug by waiting while for the risky situation to clear. If that fails,
+ * drop a frame in one-shot mode or indicate a busy device otherwise.
+ *
+ * Returns 0 on successful wait. Otherwise it sets *netdev_tx_status to the
+ * value that should be returned by grcan_start_xmit when aborting the xmit.
+ */
+static int grcan_txbug_workaround(struct net_device *dev, struct sk_buff *skb,
+				  u32 txwr, u32 oneshotmode,
+				  netdev_tx_t *netdev_tx_status)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	int i;
+	unsigned long flags;
+
+	/* Wait a while for ongoing to be cleared or read pointer to catch up to
+	 * write pointer. The latter is needed due to a bug in older versions of
+	 * GRCAN in which ONGOING is not cleared properly one-shot mode when a
+	 * transmission fails.
+	 */
+	for (i = 0; i < GRCAN_SHORTWAIT_USECS; i++) {
+		udelay(1);
+		if (!grcan_read_bits(&regs->txctrl, GRCAN_TXCTRL_ONGOING)
+		    || grcan_read_reg(&regs->txrd) == txwr) {
+			return 0;
+		}
+	}
+
+	/* Clean up, in case the situation was not resolved */
+	spin_lock_irqsave(&priv->lock, flags);
+	if (!priv->resetting && !priv->closing) {
+		/* Queue might have been stopped earlier in grcan_start_xmit */
+		if (grcan_txspace(dma->tx.size, txwr, priv->eskbp))
+			netif_wake_queue(dev);
+		/* Set a timer to resolve a hanged tx controller */
+		if (!timer_pending(&priv->hang_timer))
+			grcan_reset_timer(&priv->hang_timer,
+					  priv->can.bittiming.bitrate);
+	}
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	if (oneshotmode) {
+		/* In one-shot mode we should never end up here because
+		 * then the interrupt handler increases txrd on TXLOSS,
+		 * but it is consistent with one-shot mode to drop the
+		 * frame in this case.
+		 */
+		kfree_skb(skb);
+		*netdev_tx_status = NETDEV_TX_OK;
+	} else {
+		/* In normal mode the socket-can transmission queue get
+		 * to keep the frame so that it can be retransmitted
+		 * later
+		 */
+		*netdev_tx_status = NETDEV_TX_BUSY;
+	}
+	return -EBUSY;
+}
+
+/* Notes on the tx cyclic buffer handling:
+ *
+ * regs->txwr	- the next slot for the driver to put data to be sent
+ * regs->txrd	- the next slot for the device to read data
+ * priv->eskbp	- the next slot for the driver to call can_put_echo_skb for
+ *
+ * grcan_start_xmit can enter more messages as long as regs->txwr does
+ * not reach priv->eskbp (within 1 message gap)
+ *
+ * The device sends messages until regs->txrd reaches regs->txwr
+ *
+ * The interrupt calls handler calls can_put_echo_skb until
+ * priv->eskbp reaches regs->txrd
+ */
+static netdev_tx_t grcan_start_xmit(struct sk_buff *skb,
+				    struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	struct can_frame *cf = (struct can_frame *)skb->data;
+	u32 id, txwr, txrd, space, txctrl;
+	int slotindex;
+	u32 *slot;
+	u32 i, rtr, eff, dlc, tmp, err;
+	int j, shift;
+	unsigned long flags;
+	u32 oneshotmode = priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT;
+
+	if (can_dropped_invalid_skb(dev, skb))
+		return NETDEV_TX_OK;
+
+	/* Trying to transmit in silent mode will generate error interrupts, but
+	 * this should never happen - the queue should not have been started.
+	 */
+	if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
+		return NETDEV_TX_BUSY;
+
+	/* Reads of priv->eskbp and shut-downs of the queue needs to
+	 * be atomic towards the updates to priv->eskbp and wake-ups
+	 * of the queue in the interrupt handler.
+	 */
+	spin_lock_irqsave(&priv->lock, flags);
+
+	txwr = grcan_read_reg(&regs->txwr);
+	space = grcan_txspace(dma->tx.size, txwr, priv->eskbp);
+
+	slotindex = txwr / GRCAN_MSG_SIZE;
+	slot = dma->tx.buf + txwr;
+
+	if (unlikely(space == 1))
+		netif_stop_queue(dev);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+	/* End of critical section*/
+
+	/* This should never happen. If circular buffer is full, the
+	 * netif_stop_queue should have been stopped already.
+	 */
+	if (unlikely(!space)) {
+		netdev_err(dev, "No buffer space, but queue is non-stopped.\n");
+		return NETDEV_TX_BUSY;
+	}
+
+	/* Convert and write CAN message to DMA buffer */
+	eff = cf->can_id & CAN_EFF_FLAG;
+	rtr = cf->can_id & CAN_RTR_FLAG;
+	id = cf->can_id & (eff ? CAN_EFF_MASK : CAN_SFF_MASK);
+	dlc = cf->can_dlc;
+	if (eff)
+		tmp = (id << GRCAN_MSG_EID_BIT) & GRCAN_MSG_EID;
+	else
+		tmp = (id << GRCAN_MSG_BID_BIT) & GRCAN_MSG_BID;
+	slot[0] = (eff ? GRCAN_MSG_IDE : 0) | (rtr ? GRCAN_MSG_RTR : 0) | tmp;
+
+	slot[1] = ((dlc << GRCAN_MSG_DLC_BIT) & GRCAN_MSG_DLC);
+	slot[2] = 0;
+	slot[3] = 0;
+	for (i = 0; i < dlc; i++) {
+		j = GRCAN_MSG_DATA_SLOT_INDEX(i);
+		shift = GRCAN_MSG_DATA_SHIFT(i);
+		slot[j] |= cf->data[i] << shift;
+	}
+
+	/* Checking that channel has not been disabled. These cases
+	 * should never happen
+	 */
+	txctrl = grcan_read_reg(&regs->txctrl);
+	if (!(txctrl & GRCAN_TXCTRL_ENABLE))
+		netdev_err(dev, "tx channel spuriously disabled\n");
+
+	if (oneshotmode && !(txctrl & GRCAN_TXCTRL_SINGLE))
+		netdev_err(dev, "one-shot mode spuriously disabled\n");
+
+	/* Bug workaround for old version of grcan where updating txwr
+	 * in the same clock cycle as the controller updates txrd to
+	 * the current txwr could hang the can controller
+	 */
+	if (priv->need_txbug_workaround) {
+		txrd = grcan_read_reg(&regs->txrd) ;
+		if (unlikely(grcan_ring_sub(txwr, txrd, dma->tx.size) == 1)) {
+			netdev_tx_t txstatus;
+
+			err = grcan_txbug_workaround(dev, skb, txwr,
+						     oneshotmode, &txstatus);
+			if (err)
+				return txstatus;
+		}
+	}
+
+	/* Prepare skb for echoing. This must be after the bug workaround above
+	 * as ownership of the skb is passed on by calling can_put_echo_skb.
+	 * Returning NETDEV_TX_BUSY or accessing skb or cf after a call to
+	 * can_put_echo_skb would be an error unless other measures are
+	 * taken.
+	 */
+	priv->txdlc[slotindex] = cf->can_dlc; /* Store dlc for statistics */
+	can_put_echo_skb(skb, dev, slotindex);
+
+	/* Make sure everything is written before allowing hardware to
+	 * read from the memory
+	 */
+	wmb();
+
+	/* Update write pointer to start transmission */
+	grcan_write_reg(&regs->txwr,
+			grcan_ring_add(txwr, GRCAN_MSG_SIZE, dma->tx.size));
+
+	return NETDEV_TX_OK;
+}
+
+
+/* ========== Setting up sysfs interface and module parameters ========== */
+
+
+#define GRCAN_NOT_BOOL(val) ((val) < 0 || (val) > 1)
+
+#define GRCAN_MODULE_PARAM(name, mtype, valcheckf)			\
+	static void grcan_sanitize_##name(struct platform_device *pd)	\
+	{								\
+		struct grcan_device_config grcan_default_config		\
+			= GRCAN_DEFAULT_DEVICE_CONFIG;			\
+		if (valcheckf(grcan_module_config.name)) {		\
+			dev_err(&pd->dev,				\
+				"Invalid module parameter value for "	\
+				#name " - setting default\n");		\
+			grcan_module_config.name =			\
+				grcan_default_config.name;		\
+		}							\
+	}								\
+	module_param_named(name, grcan_module_config.name,		\
+			   mtype, S_IRUGO)
+
+#define GRCAN_CONFIG_ATTR(name)						\
+	static ssize_t grcan_store_##name(struct device *sdev,		\
+					  struct device_attribute *att,	\
+					  const char *buf,		\
+					  size_t count)			\
+	{								\
+		struct net_device *dev = to_net_dev(sdev);		\
+		struct grcan_priv *priv = netdev_priv(dev);		\
+		u8 val;							\
+		int ret;						\
+		if (dev->flags & IFF_UP)				\
+			return -EBUSY;					\
+		ret = kstrtou8(buf, 0, &val);				\
+		if (ret < 0 || val < 0 || val > 1)			\
+			return -EINVAL;					\
+		priv->config.name = val;				\
+		return count;						\
+	}								\
+	static ssize_t grcan_show_##name(struct device *sdev,		\
+					 struct device_attribute *att,	\
+					 char *buf)			\
+	{								\
+		struct net_device *dev = to_net_dev(sdev);		\
+		struct grcan_priv *priv = netdev_priv(dev);		\
+		return sprintf(buf, "%d\n", priv->config.name);		\
+	}								\
+	static DEVICE_ATTR(name, S_IRUGO | S_IWUSR,			\
+			   grcan_show_##name,				\
+			   grcan_store_##name);				\
+	GRCAN_MODULE_PARAM(name, ushort, GRCAN_NOT_BOOL)
+
+/* The following configuration options are made available both via module
+ * parameters and writable sysfs files. See the chapter about GRCAN in the
+ * documentation for the GRLIB VHDL library for further details.
+ */
+
+/* Configure enable0 - Hardware configuration for interface 0 */
+GRCAN_CONFIG_ATTR(enable0);
+
+/* Configure enable1 - Hardware configuration for interface 1 */
+GRCAN_CONFIG_ATTR(enable1);
+
+/* Configure selection - Selection on which interface to use */
+GRCAN_CONFIG_ATTR(selection);
+
+
+/* The following configuration options are only available via module
+ * parameters.
+ */
+
+/* Configure size of tx buffer */
+GRCAN_MODULE_PARAM(txsize, uint, GRCAN_INVALID_BUFFER_SIZE);
+
+/* Configure size of rx buffer */
+GRCAN_MODULE_PARAM(rxsize, uint, GRCAN_INVALID_BUFFER_SIZE);
+
+
+/* Function that makes sure that configuration done using
+ * module parameters are set to valid values
+ */
+static void grcan_sanitize_module_config(struct platform_device *ofdev)
+{
+	grcan_sanitize_enable0(ofdev);
+	grcan_sanitize_enable1(ofdev);
+	grcan_sanitize_selection(ofdev);
+	grcan_sanitize_txsize(ofdev);
+	grcan_sanitize_rxsize(ofdev);
+}
+
+static const struct attribute *const sysfs_grcan_attrs[] = {
+	/* Config attrs */
+	&dev_attr_enable0.attr,
+	&dev_attr_enable1.attr,
+	&dev_attr_selection.attr,
+	NULL,
+};
+
+static const struct attribute_group sysfs_grcan_group = {
+	.name	= "grcan",
+	.attrs	= (struct attribute **)sysfs_grcan_attrs,
+};
+
+
+/* ========== Setting up the driver ========== */
+
+static const struct net_device_ops grcan_netdev_ops = {
+	.ndo_open	= grcan_open,
+	.ndo_stop	= grcan_close,
+	.ndo_start_xmit	= grcan_start_xmit,
+};
+
+static int grcan_setup_netdev(struct platform_device *ofdev,
+			      void __iomem *base,
+			      int irq, u32 ambafreq, bool txbug)
+{
+	struct net_device *dev;
+	struct grcan_priv *priv;
+	struct grcan_registers __iomem *regs;
+	int err;
+
+	dev = alloc_candev(sizeof(struct grcan_priv), 0);
+	if (!dev)
+		return -ENOMEM;
+
+	dev->irq = irq;
+	dev->flags |= IFF_ECHO;
+	dev->netdev_ops = &grcan_netdev_ops;
+	dev->sysfs_groups[0] = &sysfs_grcan_group;
+
+	priv = netdev_priv(dev);
+	memcpy(&priv->config, &grcan_module_config,
+	       sizeof(struct grcan_device_config));
+	priv->dev = dev;
+	priv->regs = (struct grcan_registers *) base;
+	priv->can.bittiming_const = &grcan_bittiming_const;
+	priv->can.do_set_bittiming = grcan_set_bittiming;
+	priv->can.do_set_mode = grcan_set_mode;
+	priv->can.do_get_berr_counter = grcan_get_berr_counter;
+	priv->can.clock.freq = ambafreq;
+	priv->can.ctrlmode_supported =
+		CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_ONE_SHOT;
+	priv->need_txbug_workaround = txbug;
+
+	/* Discover if triple sampling is supported by hardware */
+	regs = priv->regs;
+	grcan_set_bits(&regs->ctrl, GRCAN_CTRL_RESET);
+	grcan_set_bits(&regs->conf, GRCAN_CONF_TRIPLESAMP);
+	if (grcan_read_bits(&regs->conf, GRCAN_CONF_TRIPLESAMP)) {
+		priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES;
+		dev_info(&ofdev->dev, "Hardware supports triple-sampling\n");
+	}
+
+	spin_lock_init(&priv->lock);
+
+	if (priv->need_txbug_workaround) {
+		init_timer(&priv->rr_timer);
+		priv->rr_timer.function = grcan_running_reset;
+		priv->rr_timer.data = (unsigned long)dev;
+
+		init_timer(&priv->hang_timer);
+		priv->hang_timer.function = grcan_initiate_running_reset;
+		priv->hang_timer.data = (unsigned long)dev;
+	}
+
+	netif_napi_add(dev, &priv->napi, grcan_poll, GRCAN_NAPI_WEIGHT);
+
+	SET_NETDEV_DEV(dev, &ofdev->dev);
+	dev_info(&ofdev->dev, "regs=0x%p, irq=%d, clock=%d\n",
+		 priv->regs, dev->irq, priv->can.clock.freq);
+
+	err = register_candev(dev);
+	if (err) {
+		dev_err(&ofdev->dev, "registering %s failed (err=%d)\n",
+			DRV_NAME, err);
+		goto exit_free_candev;
+	}
+	dev_set_drvdata(&ofdev->dev, dev);
+
+	/* Reset device to allow bit-timing to be set. No need to call
+	 * grcan_reset at this stage. That is done in grcan_open.
+	 */
+	grcan_write_reg(&regs->ctrl, GRCAN_CTRL_RESET);
+
+	return 0;
+exit_free_candev:
+	free_candev(dev);
+	return err;
+}
+
+static int __devinit grcan_probe(struct platform_device *ofdev)
+{
+	struct device_node *np = ofdev->dev.of_node;
+	struct resource *res;
+	u32 sysid, ambafreq;
+	int irq, err;
+	void __iomem *base;
+	bool txbug = true;
+
+	/* Compare GRLIB version number with the first that does not
+	 * have the tx bug (see start_xmit)
+	 */
+	err = of_property_read_u32(np, "systemid", &sysid);
+	if (!err && ((sysid & GRLIB_VERSION_MASK)
+		     >= GRCAN_TXBUG_SAFE_GRLIB_VERSION))
+		txbug = false;
+
+	err = of_property_read_u32(np, "freq", &ambafreq);
+	if (err) {
+		dev_err(&ofdev->dev, "unable to fetch \"freq\" property\n");
+		goto exit_error;
+	}
+
+	res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
+	base = devm_request_and_ioremap(&ofdev->dev, res);
+	if (!base) {
+		dev_err(&ofdev->dev, "couldn't map IO resource\n");
+		err = -EADDRNOTAVAIL;
+		goto exit_error;
+	}
+
+	irq = irq_of_parse_and_map(np, GRCAN_IRQIX_IRQ);
+	if (irq == NO_IRQ) {
+		dev_err(&ofdev->dev, "no irq found\n");
+		err = -ENODEV;
+		goto exit_error;
+	}
+
+	grcan_sanitize_module_config(ofdev);
+
+	err = grcan_setup_netdev(ofdev, base, irq, ambafreq, txbug);
+	if (err)
+		goto exit_dispose_irq;
+
+	return 0;
+
+exit_dispose_irq:
+	irq_dispose_mapping(irq);
+exit_error:
+	dev_err(&ofdev->dev,
+		"%s socket CAN driver initialization failed with error %d\n",
+		DRV_NAME, err);
+	return err;
+}
+
+static int __devexit grcan_remove(struct platform_device *ofdev)
+{
+	struct net_device *dev = dev_get_drvdata(&ofdev->dev);
+	struct grcan_priv *priv = netdev_priv(dev);
+
+	unregister_candev(dev); /* Will in turn call grcan_close */
+
+	irq_dispose_mapping(dev->irq);
+	dev_set_drvdata(&ofdev->dev, NULL);
+	netif_napi_del(&priv->napi);
+	free_candev(dev);
+
+	dev_info(&ofdev->dev, "%s socket CAN driver removed\n", DRV_NAME);
+	return 0;
+}
+
+static struct of_device_id grcan_match[] = {
+	{.name = "GAISLER_GRCAN"},
+	{.name = "01_03d"},
+	{.name = "GAISLER_GRHCAN"},
+	{.name = "01_034"},
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, grcan_match);
+
+static struct platform_driver grcan_driver = {
+	.driver = {
+		.name = DRV_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = grcan_match,
+	},
+	.probe = grcan_probe,
+	.remove = __devexit_p(grcan_remove),
+};
+
+module_platform_driver(grcan_driver);
+
+MODULE_AUTHOR("Aeroflex Gaisler AB.");
+MODULE_DESCRIPTION("Socket CAN driver for Aeroflex Gaisler GRCAN");
+MODULE_LICENSE("GPL");
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* Re: [PATCH v3] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-11-01 16:08                       ` Andreas Larsson
  2012-11-02 14:23                         ` [PATCH v5] " Andreas Larsson
@ 2012-11-05  9:28                         ` Wolfgang Grandegger
  2012-11-07  7:32                           ` Andreas Larsson
  1 sibling, 1 reply; 41+ messages in thread
From: Wolfgang Grandegger @ 2012-11-05  9:28 UTC (permalink / raw)
  To: Andreas Larsson
  Cc: linux-can, Marc Kleine-Budde, devicetree-discuss, software

On 11/01/2012 05:08 PM, Andreas Larsson wrote:
> On 2012-10-31 21:21, Wolfgang Grandegger wrote:
...
>>>> This is most probably an ack slot bus error similar to. You seem not to
>>>> handle bus errors and it's not a controller problem as the state did
>>>> not
>>>> change.
>>>
>>> No, the hardware has no support for can-bus error reporting.
>>
>> OK, but why is CAN_ERR_CRTL set?
> 
> Maybe I am just confused with the terminology. What I mean is that the
> only error reporting that is supported by the hardware (apart from AMBA
> bus errors, but that is unrelated to the discussion) is the error
> counter related errors.

We have to distinguish between state changes, bus error and other
errors. To make that clear, I have added an (old) annotated output from
the SJA1000, which is the defacto reference. Bus error reporting is
enabled and no cable is connected. Watch the TX error count increasing
and how the state changes:

  $ ./candump -e 0xffff any
  can0  20000088  [8] 00 00 80 19 00 08 00 00   ERRORFRAME
               \             \  \-- ACK slot.
                \             \-- error occured on transmission
                 \-- Bus-error | Protocol violations (data[2], data[3]).

  can0  20000088  [8] 00 00 80 19 00 10 00 00   ERRORFRAME
  can0  20000088  [8] 00 00 80 19 00 18 00 00   ERRORFRAME
  can0  20000088  [8] 00 00 80 19 00 20 00 00   ERRORFRAME
  can0  20000088  [8] 00 00 80 19 00 28 00 00   ERRORFRAME
  can0  20000088  [8] 00 00 80 19 00 30 00 00   ERRORFRAME
  can0  20000088  [8] 00 00 80 19 00 38 00 00   ERRORFRAME
  can0  20000088  [8] 00 00 80 19 00 40 00 00   ERRORFRAME
  can0  20000088  [8] 00 00 80 19 00 48 00 00   ERRORFRAME
  can0  20000088  [8] 00 00 80 19 00 50 00 00   ERRORFRAME
  can0  20000088  [8] 00 00 80 19 00 58 00 00   ERRORFRAME
  can0  2000008C  [8] 00 08 80 19 00 60 00 00   ERRORFRAME
               \          \--  reached warning level for TX errors
                \-- | Controller problems (see data[1]).

  can0  20000088  [8] 00 00 80 19 00 68 00 00   ERRORFRAME
  can0  20000088  [8] 00 00 80 19 00 70 00 00   ERRORFRAME
  can0  20000088  [8] 00 00 80 19 00 78 00 00   ERRORFRAME
  can0  2000008C  [8] 00 20 80 19 00 80 00 00   ERRORFRAME
               \          \--   reached passive level for TX errors
                \-- | Controller problems (see data[1]).

  can0  20000088  [8] 00 00 80 19 00 80 00 00   ERRORFRAME
                                      \  \-- RXerror count
                                       \-- TXerror count

  can0  20000088  [8] 00 00 80 19 00 80 00 00   ERRORFRAME
  ...
  can0  20000088  [8] 00 00 80 19 00 80 00 00   ERRORFRAME


> From what I can see CAN_ERR_BUSERROR is not reported in the error
> counter related cases by the other drivers I looked in. The grcan
> hardware does not support reporting errors like form and stuff errors
> and which bits the errors occured in and the like.

CAN controller normally report state changes and some, like the SJA1000,
also individual bus errors including more information about the cause of
the problem. That information is not available for your controller and
therefore it does not make sense to report empty bus errors to the app.

> Have I understood it correctly that reporting about protocol errors like
> that is what it is to support CAN_CTRLMODE_BERR_REPORTING? This seems to
> be the case but the janz-ican3 driver connects
> CAN_CTRLMODE_BERR_REPORTING to all error frame reporting, so I am not
> entirely sure.

The "berr-reporting" has been introduced some time ago, because the
bus-error rate can be quite high and may hang the system, especially
low-end systems. On the SJA1000 or Flexcan this can be simply achieved
by enabling bus-error interrupts. Signaling of state changes should
always work, though.

>>>> http://lxr.linux.no/#linux+v3.6.4/drivers/net/can/flexcan.c#L353
>>>>
>>>>>     can0  20000004  [8] 00 20 00 00 00 00 88 00   ERRORFRAME
>>>>>           controller-problem{tx-error-passive}
>>>>>           error-counter-tx-rx{{136}{0}}
>>>>
>>>> OK, a state change to error passive. The device seems not to report
>>>> changes to error warning.
>>>
>>> No, there is no interrupts or anything that alert about the error
>>> states. That is why I set the sate based on the error counters in the
>>> error handler.
>>
>> Who does trigger the message above?
> 
> Sorry for confusing the matter. There is no interrupt for error warning,
> but there are interrupts for increases of the error counters and the
> other state changes. So to be able to report on error warning I check
> the error counters and do it manually.

OK.

>> Obviously the device restarts automatically after bus-off. Can this be
>> switched off. The normal procedure is to call "ip ... type can restart"
>> or to set "restart-ms" for automatic restart after the specified delay.
> 
> Yes, the hardware becomes error active after having monitored 11
> consecutive recessive bits on the bus 128 times (as allowed by the 2.0
> CAN spec). There is no way of turning this off, so to conform to the
> normal linux procedure of not doing this, I shut down the device on bus
> off interrupt.

This should be handled in the following way:

1. If priv->can.restart_ms == 0: do *not* allow automatic restart
   That's what you alredy have implemented.

2. If priv->can.restart_ms  > 0 : do allow automatic restart.
   This requires to send CAN_ERR_RESTARTED when the system goes
   bus-on. See at91_can and mcp251x as example.

> In addition I have thrown out the arbitration lost error frame
> generation as arbitration errors can not be singled out. The TXLOSS
> interrupt might be due to arbitration error, but is also triggered in
> great numbers when there is no one else on the can bus or when there is
> a problem with the hardware interface or the bus itself.
> 
> This is how things look currently with no one else on the bus:
> ~ # cansend can0 123#45
>   can0  20000004  [8] 00 08 00 00 00 00 60 00   ERRORFRAME
>         controller-problem{tx-error-warning}
>         error-counter-tx-rx{{96}{0}}
>   can0  20000004  [8] 00 20 00 00 00 00 80 00   ERRORFRAME
>         controller-problem{tx-error-passive}
>         error-counter-tx-rx{{128}{0}}
> ~ #
> 
> And this is how it looks with a short-circuited bus:
> ~ # cansend can0 123#45
>   can0  20000004  [8] 00 08 00 00 00 00 90 00   ERRORFRAME
>         controller-problem{tx-error-warning}
>         error-counter-tx-rx{{144}{0}}
>   can0  20000004  [8] 00 20 00 00 00 00 98 00   ERRORFRAME
>         controller-problem{tx-error-passive}
>         error-counter-tx-rx{{152}{0}}
>   can0  20000040  [8] 00 00 00 00 00 00 00 00   ERRORFRAME
>         bus-off
> ~ #

This looks good now. Just the automatic restart is missing as described
above.

Wolfgang.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v3] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-11-05  9:28                         ` [PATCH v3] " Wolfgang Grandegger
@ 2012-11-07  7:32                           ` Andreas Larsson
  2012-11-07 11:15                             ` Wolfgang Grandegger
  0 siblings, 1 reply; 41+ messages in thread
From: Andreas Larsson @ 2012-11-07  7:32 UTC (permalink / raw)
  To: Wolfgang Grandegger
  Cc: linux-can, Marc Kleine-Budde, devicetree-discuss, software

On 11/05/2012 10:28 AM, Wolfgang Grandegger wrote:
> On 11/01/2012 05:08 PM, Andreas Larsson wrote:
>> On 2012-10-31 21:21, Wolfgang Grandegger wrote:
...
>> Yes, the hardware becomes error active after having monitored 11
>> consecutive recessive bits on the bus 128 times (as allowed by the 2.0
>> CAN spec). There is no way of turning this off, so to conform to the
>> normal linux procedure of not doing this, I shut down the device on bus
>> off interrupt.
>
> This should be handled in the following way:
>
> 1. If priv->can.restart_ms == 0: do *not* allow automatic restart
>     That's what you alredy have implemented.
>
> 2. If priv->can.restart_ms  > 0 : do allow automatic restart.
>     This requires to send CAN_ERR_RESTARTED when the system goes
>     bus-on. See at91_can and mcp251x as example.
>
>> In addition I have thrown out the arbitration lost error frame
>> generation as arbitration errors can not be singled out. The TXLOSS
>> interrupt might be due to arbitration error, but is also triggered in
>> great numbers when there is no one else on the can bus or when there is
>> a problem with the hardware interface or the bus itself.
>>
>> This is how things look currently with no one else on the bus:
>> ~ # cansend can0 123#45
>>    can0  20000004  [8] 00 08 00 00 00 00 60 00   ERRORFRAME
>>          controller-problem{tx-error-warning}
>>          error-counter-tx-rx{{96}{0}}
>>    can0  20000004  [8] 00 20 00 00 00 00 80 00   ERRORFRAME
>>          controller-problem{tx-error-passive}
>>          error-counter-tx-rx{{128}{0}}
>> ~ #
>>
>> And this is how it looks with a short-circuited bus:
>> ~ # cansend can0 123#45
>>    can0  20000004  [8] 00 08 00 00 00 00 90 00   ERRORFRAME
>>          controller-problem{tx-error-warning}
>>          error-counter-tx-rx{{144}{0}}
>>    can0  20000004  [8] 00 20 00 00 00 00 98 00   ERRORFRAME
>>          controller-problem{tx-error-passive}
>>          error-counter-tx-rx{{152}{0}}
>>    can0  20000040  [8] 00 00 00 00 00 00 00 00   ERRORFRAME
>>          bus-off
>> ~ #
>
> This looks good now. Just the automatic restart is missing as described
> above.

When doing the bus_off handling as in at91_can, on a short-circuited bus with 
restart-ms != 0, the result of a cansend is an endless and frequent stream of

   can0  20000004  [8] 00 20 00 00 00 00 88 00   ERRORFRAME
         controller-problem{tx-error-passive}
         error-counter-tx-rx{{136}{0}}
   can0  20000040  [8] 00 00 00 00 00 00 80 00   ERRORFRAME
         bus-off
         error-counter-tx-rx{{128}{0}}
   can0  20000104  [8] 00 00 00 00 00 00 10 00   ERRORFRAME
         controller-problem{}
         restarted-after-bus-off
         error-counter-tx-rx{{16}{0}}
   can0  20000004  [8] 00 10 00 00 00 00 57 80   ERRORFRAME
         controller-problem{rx-error-passive}
         error-counter-tx-rx{{87}{128}}
   can0  20000040  [8] 00 00 00 00 00 00 80 00   ERRORFRAME
         bus-off
         error-counter-tx-rx{{128}{0}}
   can0  20000104  [8] 00 00 00 00 00 00 08 00   ERRORFRAME
         controller-problem{}
         restarted-after-bus-off
         error-counter-tx-rx{{8}{0}}
   can0  20000004  [8] 00 10 00 00 00 00 57 80   ERRORFRAME
         controller-problem{rx-error-passive}
         error-counter-tx-rx{{87}{128}}
   can0  20000040  [8] 00 00 00 00 00 00 80 00   ERRORFRAME
         bus-off
         error-counter-tx-rx{{128}{0}}
   can0  20000104  [8] 00 00 00 00 00 00 08 00   ERRORFRAME
         controller-problem{}
         restarted-after-bus-off
         error-counter-tx-rx{{8}{0}}
   [...]

as the grcan core continues to try to resend the frame when it comes back again. 
To mimic the sja1000 behavior as closely as possible, I guess that the driver 
also would need to make sure that the tx and rx buffers are cleaned out so that 
this resending does not happen, right?

To do this, the hardware needs to be stopped anyway. Therefore, in my opinion it 
is much simpler to handle it as it is in v5: always shut down the hardware on 
bus off and, in the case of a non-zero restart_ms, let restart timer trigger 
can_restart that will call grcan_set_mode which will restart the hardware with 
empty buffers. Do you see any problems with this approach?

The added benefit of this approach is that then the actual millisecond value of 
the non-zero restart_ms is used instead of having the hardware quickly restart 
regardless of the value.

In any case I have some other fixes for v6.

Cheers,
Andreas

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v3] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-11-07  7:32                           ` Andreas Larsson
@ 2012-11-07 11:15                             ` Wolfgang Grandegger
  2012-11-07 12:55                               ` Andreas Larsson
  0 siblings, 1 reply; 41+ messages in thread
From: Wolfgang Grandegger @ 2012-11-07 11:15 UTC (permalink / raw)
  To: Andreas Larsson
  Cc: linux-can, Marc Kleine-Budde, devicetree-discuss, software

On 11/07/2012 08:32 AM, Andreas Larsson wrote:
> On 11/05/2012 10:28 AM, Wolfgang Grandegger wrote:
>> On 11/01/2012 05:08 PM, Andreas Larsson wrote:
>>> On 2012-10-31 21:21, Wolfgang Grandegger wrote:
> ...
>>> Yes, the hardware becomes error active after having monitored 11
>>> consecutive recessive bits on the bus 128 times (as allowed by the 2.0
>>> CAN spec). There is no way of turning this off, so to conform to the
>>> normal linux procedure of not doing this, I shut down the device on bus
>>> off interrupt.
>>
>> This should be handled in the following way:
>>
>> 1. If priv->can.restart_ms == 0: do *not* allow automatic restart
>>     That's what you alredy have implemented.
>>
>> 2. If priv->can.restart_ms  > 0 : do allow automatic restart.
>>     This requires to send CAN_ERR_RESTARTED when the system goes
>>     bus-on. See at91_can and mcp251x as example.
>>
>>> In addition I have thrown out the arbitration lost error frame
>>> generation as arbitration errors can not be singled out. The TXLOSS
>>> interrupt might be due to arbitration error, but is also triggered in
>>> great numbers when there is no one else on the can bus or when there is
>>> a problem with the hardware interface or the bus itself.
>>>
>>> This is how things look currently with no one else on the bus:
>>> ~ # cansend can0 123#45
>>>    can0  20000004  [8] 00 08 00 00 00 00 60 00   ERRORFRAME
>>>          controller-problem{tx-error-warning}
>>>          error-counter-tx-rx{{96}{0}}
>>>    can0  20000004  [8] 00 20 00 00 00 00 80 00   ERRORFRAME
>>>          controller-problem{tx-error-passive}
>>>          error-counter-tx-rx{{128}{0}}
>>> ~ #
>>>
>>> And this is how it looks with a short-circuited bus:
>>> ~ # cansend can0 123#45
>>>    can0  20000004  [8] 00 08 00 00 00 00 90 00   ERRORFRAME
>>>          controller-problem{tx-error-warning}
>>>          error-counter-tx-rx{{144}{0}}
>>>    can0  20000004  [8] 00 20 00 00 00 00 98 00   ERRORFRAME
>>>          controller-problem{tx-error-passive}
>>>          error-counter-tx-rx{{152}{0}}
>>>    can0  20000040  [8] 00 00 00 00 00 00 00 00   ERRORFRAME
>>>          bus-off
>>> ~ #
>>
>> This looks good now. Just the automatic restart is missing as described
>> above.
> 
> When doing the bus_off handling as in at91_can, on a short-circuited bus
> with restart-ms != 0, the result of a cansend is an endless and frequent
> stream of
> 
>   can0  20000004  [8] 00 20 00 00 00 00 88 00   ERRORFRAME
>         controller-problem{tx-error-passive}
>         error-counter-tx-rx{{136}{0}}
>   can0  20000040  [8] 00 00 00 00 00 00 80 00   ERRORFRAME
>         bus-off
>         error-counter-tx-rx{{128}{0}}
>   can0  20000104  [8] 00 00 00 00 00 00 10 00   ERRORFRAME
>         controller-problem{}
>         restarted-after-bus-off
>         error-counter-tx-rx{{16}{0}}
>   can0  20000004  [8] 00 10 00 00 00 00 57 80   ERRORFRAME
>         controller-problem{rx-error-passive}
>         error-counter-tx-rx{{87}{128}}
>   can0  20000040  [8] 00 00 00 00 00 00 80 00   ERRORFRAME
>         bus-off
>         error-counter-tx-rx{{128}{0}}
>   can0  20000104  [8] 00 00 00 00 00 00 08 00   ERRORFRAME
>         controller-problem{}
>         restarted-after-bus-off
>         error-counter-tx-rx{{8}{0}}
>   can0  20000004  [8] 00 10 00 00 00 00 57 80   ERRORFRAME
>         controller-problem{rx-error-passive}
>         error-counter-tx-rx{{87}{128}}
>   can0  20000040  [8] 00 00 00 00 00 00 80 00   ERRORFRAME
>         bus-off
>         error-counter-tx-rx{{128}{0}}
>   can0  20000104  [8] 00 00 00 00 00 00 08 00   ERRORFRAME
>         controller-problem{}
>         restarted-after-bus-off
>         error-counter-tx-rx{{8}{0}}
>   [...]
> 
> as the grcan core continues to try to resend the frame when it comes
> back again. To mimic the sja1000 behavior as closely as possible, I
> guess that the driver also would need to make sure that the tx and rx
> buffers are cleaned out so that this resending does not happen, right?

No, what you see is the normal behavior for automatic restart by the
hardware. A bus-off recovery is *not* the same than a controller restart.

> To do this, the hardware needs to be stopped anyway. Therefore, in my
> opinion it is much simpler to handle it as it is in v5: always shut down
> the hardware on bus off and, in the case of a non-zero restart_ms, let
> restart timer trigger can_restart that will call grcan_set_mode which
> will restart the hardware with empty buffers. Do you see any problems
> with this approach?

The application will start to send frames anyway and will again trigger
a bus-off as long as the electronic problem persists. Flushing the
buffers will not cure the problem.

> The added benefit of this approach is that then the actual millisecond
> value of the non-zero restart_ms is used instead of having the hardware
> quickly restart regardless of the value.

See above.

> In any case I have some other fixes for v6.

OK.

Wolfgang.


^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v3] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-11-07 11:15                             ` Wolfgang Grandegger
@ 2012-11-07 12:55                               ` Andreas Larsson
  2012-11-07 15:20                                 ` [PATCH v6] " Andreas Larsson
  0 siblings, 1 reply; 41+ messages in thread
From: Andreas Larsson @ 2012-11-07 12:55 UTC (permalink / raw)
  To: Wolfgang Grandegger
  Cc: linux-can, Marc Kleine-Budde, devicetree-discuss, software

On 11/07/2012 12:15 PM, Wolfgang Grandegger wrote:
> On 11/07/2012 08:32 AM, Andreas Larsson wrote:
>> On 11/05/2012 10:28 AM, Wolfgang Grandegger wrote:
> ...
>>> This looks good now. Just the automatic restart is missing as described
>>> above.
>>
>> When doing the bus_off handling as in at91_can, on a short-circuited bus
>> with restart-ms != 0, the result of a cansend is an endless and frequent
>> stream of
>>
>>    can0  20000004  [8] 00 20 00 00 00 00 88 00   ERRORFRAME
>>          controller-problem{tx-error-passive}
>>          error-counter-tx-rx{{136}{0}}
>>    can0  20000040  [8] 00 00 00 00 00 00 80 00   ERRORFRAME
>>          bus-off
>>          error-counter-tx-rx{{128}{0}}
>>    can0  20000104  [8] 00 00 00 00 00 00 10 00   ERRORFRAME
>>          controller-problem{}
>>          restarted-after-bus-off
>>          error-counter-tx-rx{{16}{0}}
>>    can0  20000004  [8] 00 10 00 00 00 00 57 80   ERRORFRAME
>>          controller-problem{rx-error-passive}
>>          error-counter-tx-rx{{87}{128}}
>>    can0  20000040  [8] 00 00 00 00 00 00 80 00   ERRORFRAME
>>          bus-off
>>          error-counter-tx-rx{{128}{0}}
>>    can0  20000104  [8] 00 00 00 00 00 00 08 00   ERRORFRAME
>>          controller-problem{}
>>          restarted-after-bus-off
>>          error-counter-tx-rx{{8}{0}}
>>    can0  20000004  [8] 00 10 00 00 00 00 57 80   ERRORFRAME
>>          controller-problem{rx-error-passive}
>>          error-counter-tx-rx{{87}{128}}
>>    can0  20000040  [8] 00 00 00 00 00 00 80 00   ERRORFRAME
>>          bus-off
>>          error-counter-tx-rx{{128}{0}}
>>    can0  20000104  [8] 00 00 00 00 00 00 08 00   ERRORFRAME
>>          controller-problem{}
>>          restarted-after-bus-off
>>          error-counter-tx-rx{{8}{0}}
>>    [...]
>>
>> as the grcan core continues to try to resend the frame when it comes
>> back again. To mimic the sja1000 behavior as closely as possible, I
>> guess that the driver also would need to make sure that the tx and rx
>> buffers are cleaned out so that this resending does not happen, right?
>
> No, what you see is the normal behavior for automatic restart by the
> hardware. A bus-off recovery is *not* the same than a controller restart.

OK, if these automatic restarts are an OK behavior when restart_ms is non-zero I 
am happy with taking the at91_can approach to things.

Cheers,
Andreas


^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH v6] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-11-07 12:55                               ` Andreas Larsson
@ 2012-11-07 15:20                                 ` Andreas Larsson
  2012-11-08  8:29                                   ` Wolfgang Grandegger
  0 siblings, 1 reply; 41+ messages in thread
From: Andreas Larsson @ 2012-11-07 15:20 UTC (permalink / raw)
  To: Wolfgang Grandegger
  Cc: linux-can, software, Marc Kleine-Budde, devicetree-discuss

This driver supports GRCAN and CRHCAN CAN controllers available in the GRLIB
VHDL IP core library.

Signed-off-by: Andreas Larsson <andreas@gaisler.com>
---
 Documentation/ABI/testing/sysfs-class-net-grcan    |   35 +
 .../devicetree/bindings/net/can/grcan.txt          |   28 +
 Documentation/kernel-parameters.txt                |   19 +
 drivers/net/can/Kconfig                            |    9 +
 drivers/net/can/Makefile                           |    1 +
 drivers/net/can/grcan.c                            | 1739 ++++++++++++++++++++
 6 files changed, 1831 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-class-net-grcan
 create mode 100644 Documentation/devicetree/bindings/net/can/grcan.txt
 create mode 100644 drivers/net/can/grcan.c

diff --git a/Documentation/ABI/testing/sysfs-class-net-grcan b/Documentation/ABI/testing/sysfs-class-net-grcan
new file mode 100644
index 0000000..2c4acfb
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-net-grcan
@@ -0,0 +1,35 @@
+
+What:		/sys/class/net/<iface>/grcan/enable0
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas@gaisler.com>
+Description:
+		Hardware configuration of physical interface 0. This file reads
+		and writes the "Enable 0" bit of the configuration register.
+		Possible values: 0 or 1. See the GRCAN chapter of the GRLIB IP
+		core library documentation for details. The default value is 0
+		or set by the module parameter grcan.enable0 and can be read at
+		/sys/module/grcan/parameters/enable0.
+
+What:		/sys/class/net/<iface>/grcan/enable1
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas@gaisler.com>
+Description:
+		Hardware configuration of physical interface 1. This file reads
+		and writes the "Enable 1" bit of the configuration register.
+		Possible values: 0 or 1. See the GRCAN chapter of the GRLIB IP
+		core library documentation for details. The default value is 0
+		or set by the module parameter grcan.enable1 and can be read at
+		/sys/module/grcan/parameters/enable1.
+
+What:		/sys/class/net/<iface>/grcan/selection
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas@gaisler.com>
+Description:
+		Configuration of which physical interface to be used. Possible
+		values: 0 or 1. See the GRCAN chapter of the GRLIB IP core
+		library documentation for details. The default value is 0 or is
+		set by the module parameter grcan.selection and can be read at
+		/sys/module/grcan/parameters/selection.
diff --git a/Documentation/devicetree/bindings/net/can/grcan.txt b/Documentation/devicetree/bindings/net/can/grcan.txt
new file mode 100644
index 0000000..34ef349
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/can/grcan.txt
@@ -0,0 +1,28 @@
+Aeroflex Gaisler GRCAN and GRHCAN CAN controllers.
+
+The GRCAN and CRHCAN CAN controllers are available in the GRLIB VHDL IP core
+library.
+
+Note: These properties are built from the AMBA plug&play in a Leon SPARC system
+(the ordinary environment for GRCAN and GRHCAN). There are no dts files for
+sparc.
+
+Required properties:
+
+- name : Should be "GAISLER_GRCAN", "01_03d", "GAISLER_GRHCAN" or "01_034"
+
+- reg : Address and length of the register set for the device
+
+- freq : Frequency of the external oscillator clock in Hz (the frequency of
+	the amba bus in the ordinary case)
+
+- interrupts : Interrupt number for this device
+
+Optional properties:
+
+- systemid : If not present or if the value of the least significant 16 bits
+	of this 32-bit property is smaller than GRCAN_TXBUG_SAFE_GRLIB_VERSION
+	a bug workaround is activated.
+
+For further information look in the documentation for the GLIB IP core library:
+http://www.gaisler.com/products/grlib/grip.pdf
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 9776f06..006fa75 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -905,6 +905,25 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 	gpt		[EFI] Forces disk with valid GPT signature but
 			invalid Protective MBR to be treated as GPT.
 
+	grcan.enable0=	[HW] Configuration of physical interface 0. Determines
+			the "Enable 0" bit of the configuration register.
+			Format: 0 | 1
+			Default: 0
+	grcan.enable1=	[HW] Configuration of physical interface 1. Determines
+			the "Enable 0" bit of the configuration register.
+			Format: 0 | 1
+			Default: 0
+	grcan.selection=
+			[HW] Selection of which physical interface to use.
+			Format: 0 | 1
+			Default: 0
+	grcan.txsize=	[HW] Sets the size of the tx buffer.
+			Format: <unsigned int> such that (txsize & ~0x1fffc0) == 0.
+			Default: 1024
+	grcan.rxsize=	[HW] Sets the size of the rx buffer.
+			Format: <unsigned int> such that (rxsize & ~0x1fffc0) == 0.
+			Default: 1024
+
 	hashdist=	[KNL,NUMA] Large hashes allocated during boot
 			are distributed across NUMA nodes.  Defaults on
 			for 64-bit NUMA, off otherwise.
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
index bb709fd..b56bd9e 100644
--- a/drivers/net/can/Kconfig
+++ b/drivers/net/can/Kconfig
@@ -110,6 +110,15 @@ config PCH_CAN
 	  is an IOH for x86 embedded processor (Intel Atom E6xx series).
 	  This driver can access CAN bus.
 
+config CAN_GRCAN
+	tristate "Aeroflex Gaisler GRCAN and GRHCAN CAN devices"
+	depends on CAN_DEV && OF
+	---help---
+	  Say Y here if you want to use Aeroflex Gaisler GRCAN or GRHCAN.
+	  Note that the driver supports little endian, even though little
+	  endian syntheses of the cores would need some modifications on
+	  the hardware level to work.
+
 source "drivers/net/can/mscan/Kconfig"
 
 source "drivers/net/can/sja1000/Kconfig"
diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
index 938be37..7de5986 100644
--- a/drivers/net/can/Makefile
+++ b/drivers/net/can/Makefile
@@ -22,5 +22,6 @@ obj-$(CONFIG_CAN_BFIN)		+= bfin_can.o
 obj-$(CONFIG_CAN_JANZ_ICAN3)	+= janz-ican3.o
 obj-$(CONFIG_CAN_FLEXCAN)	+= flexcan.o
 obj-$(CONFIG_PCH_CAN)		+= pch_can.o
+obj-$(CONFIG_CAN_GRCAN)		+= grcan.o
 
 ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/grcan.c b/drivers/net/can/grcan.c
new file mode 100644
index 0000000..a8c6da5
--- /dev/null
+++ b/drivers/net/can/grcan.c
@@ -0,0 +1,1739 @@
+/*
+ * Socket CAN driver for Aeroflex Gaisler GRCAN and GRHCAN.
+ *
+ * 2012 (c) Aeroflex Gaisler AB
+ *
+ * This driver supports GRCAN and GRHCAN CAN controllers available in the GRLIB
+ * VHDL IP core library.
+ *
+ * Full documentation of the GRCAN core can be found here:
+ * http://www.gaisler.com/products/grlib/grip.pdf
+ *
+ * See "Documentation/devicetree/bindings/net/can/grcan.txt" for information on
+ * open firmware properties.
+ *
+ * See "Documentation/ABI/testing/sysfs-class-net-grcan" for information on the
+ * sysfs interface.
+ *
+ * See "Documentation/kernel-parameters.txt" for information on the module
+ * parameters.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Contributors: Andreas Larsson <andreas@gaisler.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/can/dev.h>
+#include <linux/spinlock.h>
+
+#include <linux/of_platform.h>
+#include <asm/prom.h>
+
+#include <linux/of_irq.h>
+
+#include <linux/dma-mapping.h>
+
+#define DRV_NAME	"grcan"
+
+#define GRCAN_NAPI_WEIGHT	16
+
+#define GRCAN_RESERVE_SIZE(slot1, slot2) (((slot2) - (slot1)) / 4 - 1)
+
+struct grcan_registers {
+	u32 conf;	/* 0x00 */
+	u32 stat;	/* 0x04 */
+	u32 ctrl;	/* 0x08 */
+	u32 __reserved1[GRCAN_RESERVE_SIZE(0x08, 0x18)];
+	u32 smask;	/* 0x18 - CanMASK */
+	u32 scode;	/* 0x1c - CanCODE */
+	u32 __reserved2[GRCAN_RESERVE_SIZE(0x1c, 0x100)];
+	u32 pimsr;	/* 0x100 */
+	u32 pimr;	/* 0x104 */
+	u32 pisr;	/* 0x108 */
+	u32 pir;	/* 0x10C */
+	u32 imr;	/* 0x110 */
+	u32 picr;	/* 0x114 */
+	u32 __reserved3[GRCAN_RESERVE_SIZE(0x114, 0x200)];
+	u32 txctrl;	/* 0x200 */
+	u32 txaddr;	/* 0x204 */
+	u32 txsize;	/* 0x208 */
+	u32 txwr;	/* 0x20C */
+	u32 txrd;	/* 0x210 */
+	u32 txirq;	/* 0x214 */
+	u32 __reserved4[GRCAN_RESERVE_SIZE(0x214, 0x300)];
+	u32 rxctrl;	/* 0x300 */
+	u32 rxaddr;	/* 0x304 */
+	u32 rxsize;	/* 0x308 */
+	u32 rxwr;	/* 0x30C */
+	u32 rxrd;	/* 0x310 */
+	u32 rxirq;	/* 0x314 */
+	u32 rxmask;	/* 0x318 */
+	u32 rxcode;	/* 0x31C */
+};
+
+#define GRCAN_CONF_ABORT	0x00000001
+#define GRCAN_CONF_ENABLE0	0x00000002
+#define GRCAN_CONF_ENABLE1	0x00000004
+#define GRCAN_CONF_SELECTION	0x00000008
+#define GRCAN_CONF_SILENT	0x00000010
+#define GRCAN_CONF_TRIPLESAMP	0x00000020 /* Available in some hardware */
+#define GRCAN_CONF_BPR		0x00000300 /* Note: not BRP */
+#define GRCAN_CONF_RSJ		0x00007000
+#define GRCAN_CONF_PS1		0x00f00000
+#define GRCAN_CONF_PS2		0x000f0000
+#define GRCAN_CONF_SCALER	0xff000000
+#define GRCAN_CONF_OPERATION						\
+	(GRCAN_CONF_ABORT | GRCAN_CONF_ENABLE0 | GRCAN_CONF_ENABLE1	\
+	 | GRCAN_CONF_SELECTION | GRCAN_CONF_SILENT			\
+	 | GRCAN_CONF_TRIPLESAMP)
+#define GRCAN_CONF_TIMING						\
+	(GRCAN_CONF_BPR | GRCAN_CONF_RSJ | GRCAN_CONF_PS1		\
+	 | GRCAN_CONF_PS2 | GRCAN_CONF_SCALER)
+
+#define GRCAN_CONF_RSJ_MIN	1
+#define GRCAN_CONF_RSJ_MAX	4
+#define GRCAN_CONF_PS1_MIN	1
+#define GRCAN_CONF_PS1_MAX	15
+#define GRCAN_CONF_PS2_MIN	2
+#define GRCAN_CONF_PS2_MAX	8
+#define GRCAN_CONF_SCALER_MIN	0
+#define GRCAN_CONF_SCALER_MAX	255
+#define GRCAN_CONF_SCALER_INC	1
+
+#define GRCAN_CONF_BPR_BIT	8
+#define GRCAN_CONF_RSJ_BIT	12
+#define GRCAN_CONF_PS1_BIT	20
+#define GRCAN_CONF_PS2_BIT	16
+#define GRCAN_CONF_SCALER_BIT	24
+
+#define GRCAN_STAT_PASS		0x000001
+#define GRCAN_STAT_OFF		0x000002
+#define GRCAN_STAT_OR		0x000004
+#define GRCAN_STAT_AHBERR	0x000008
+#define GRCAN_STAT_ACTIVE	0x000010
+#define GRCAN_STAT_RXERRCNT	0x00ff00
+#define GRCAN_STAT_TXERRCNT	0xff0000
+
+#define GRCAN_STAT_ERRCTR_RELATED	(GRCAN_STAT_PASS | GRCAN_STAT_OFF)
+
+#define GRCAN_STAT_RXERRCNT_BIT	8
+#define GRCAN_STAT_TXERRCNT_BIT	16
+
+#define GRCAN_STAT_ERRCNT_WARNING_LIMIT	96
+#define GRCAN_STAT_ERRCNT_PASSIVE_LIMIT	127
+
+
+#define GRCAN_CTRL_RESET	0x2
+#define GRCAN_CTRL_ENABLE	0x1
+
+#define GRCAN_TXCTRL_ENABLE	0x1
+#define GRCAN_TXCTRL_ONGOING	0x2
+#define GRCAN_TXCTRL_SINGLE	0x4
+
+#define GRCAN_RXCTRL_ENABLE	0x1
+#define GRCAN_RXCTRL_ONGOING	0x2
+
+/* Relative offset of IRQ sources to AMBA Plug&Play */
+#define GRCAN_IRQIX_IRQ		0
+#define GRCAN_IRQIX_TXSYNC	1
+#define GRCAN_IRQIX_RXSYNC	2
+
+#define GRCAN_IRQ_PASS		0x00001
+#define GRCAN_IRQ_OFF		0x00002
+#define GRCAN_IRQ_OR		0x00004
+#define GRCAN_IRQ_RXAHBERR	0x00008
+#define GRCAN_IRQ_TXAHBERR	0x00010
+#define GRCAN_IRQ_RXIRQ		0x00020
+#define GRCAN_IRQ_TXIRQ		0x00040
+#define GRCAN_IRQ_RXFULL	0x00080
+#define GRCAN_IRQ_TXEMPTY	0x00100
+#define GRCAN_IRQ_RX		0x00200
+#define GRCAN_IRQ_TX		0x00400
+#define GRCAN_IRQ_RXSYNC	0x00800
+#define GRCAN_IRQ_TXSYNC	0x01000
+#define GRCAN_IRQ_RXERRCTR	0x02000
+#define GRCAN_IRQ_TXERRCTR	0x04000
+#define GRCAN_IRQ_RXMISS	0x08000
+#define GRCAN_IRQ_TXLOSS	0x10000
+
+#define GRCAN_IRQ_NONE	0
+#define GRCAN_IRQ_ALL							\
+	(GRCAN_IRQ_PASS | GRCAN_IRQ_OFF | GRCAN_IRQ_OR			\
+	 | GRCAN_IRQ_RXAHBERR | GRCAN_IRQ_TXAHBERR			\
+	 | GRCAN_IRQ_RXIRQ | GRCAN_IRQ_TXIRQ				\
+	 | GRCAN_IRQ_RXFULL | GRCAN_IRQ_TXEMPTY				\
+	 | GRCAN_IRQ_RX | GRCAN_IRQ_TX | GRCAN_IRQ_RXSYNC		\
+	 | GRCAN_IRQ_TXSYNC | GRCAN_IRQ_RXERRCTR			\
+	 | GRCAN_IRQ_TXERRCTR | GRCAN_IRQ_RXMISS			\
+	 | GRCAN_IRQ_TXLOSS)
+
+#define GRCAN_IRQ_ERRCTR_RELATED (GRCAN_IRQ_RXERRCTR | GRCAN_IRQ_TXERRCTR \
+				  | GRCAN_IRQ_PASS | GRCAN_IRQ_OFF)
+#define GRCAN_IRQ_ERRORS (GRCAN_IRQ_ERRCTR_RELATED | GRCAN_IRQ_OR	\
+			  | GRCAN_IRQ_TXAHBERR | GRCAN_IRQ_RXAHBERR	\
+			  | GRCAN_IRQ_TXLOSS)
+#define GRCAN_IRQ_DEFAULT (GRCAN_IRQ_RX | GRCAN_IRQ_TX | GRCAN_IRQ_ERRORS)
+
+#define GRCAN_MSG_SIZE		16
+
+#define GRCAN_MSG_IDE		0x80000000
+#define GRCAN_MSG_RTR		0x40000000
+#define GRCAN_MSG_BID		0x1ffc0000
+#define GRCAN_MSG_EID		0x1fffffff
+#define GRCAN_MSG_IDE_BIT	31
+#define GRCAN_MSG_RTR_BIT	30
+#define GRCAN_MSG_BID_BIT	18
+#define GRCAN_MSG_EID_BIT	0
+
+#define GRCAN_MSG_DLC		0xf0000000
+#define GRCAN_MSG_TXERRC	0x00ff0000
+#define GRCAN_MSG_RXERRC	0x0000ff00
+#define GRCAN_MSG_DLC_BIT	28
+#define GRCAN_MSG_TXERRC_BIT	16
+#define GRCAN_MSG_RXERRC_BIT	8
+#define GRCAN_MSG_AHBERR	0x00000008
+#define GRCAN_MSG_OR		0x00000004
+#define GRCAN_MSG_OFF		0x00000002
+#define GRCAN_MSG_PASS		0x00000001
+
+#define GRCAN_MSG_DATA_SLOT_INDEX(i) (2 + (i) / 4)
+#define GRCAN_MSG_DATA_SHIFT(i) ((3 - (i) % 4) * 8)
+
+#define GRCAN_BUFFER_ALIGNMENT		1024
+#define GRCAN_DEFAULT_BUFFER_SIZE	1024
+#define GRCAN_VALID_TR_SIZE_MASK	0x001fffc0
+
+#define GRCAN_INVALID_BUFFER_SIZE(s)			\
+	((s) == 0 || ((s) & ~GRCAN_VALID_TR_SIZE_MASK))
+
+#if GRCAN_INVALID_BUFFER_SIZE(GRCAN_DEFAULT_BUFFER_SIZE)
+#error "Invalid default buffer size"
+#endif
+
+struct grcan_dma_buffer {
+	size_t size;
+	void *buf;
+	dma_addr_t handle;
+};
+
+struct grcan_dma {
+	size_t base_size;
+	void *base_buf;
+	dma_addr_t base_handle;
+	struct grcan_dma_buffer tx;
+	struct grcan_dma_buffer rx;
+};
+
+/* GRCAN configuration parameters */
+struct grcan_device_config {
+	unsigned short enable0;
+	unsigned short enable1;
+	unsigned short selection;
+	unsigned int txsize;
+	unsigned int rxsize;
+};
+
+#define GRCAN_DEFAULT_DEVICE_CONFIG {				\
+		.enable0	= 0,				\
+		.enable1	= 0,				\
+		.selection	= 0,				\
+		.txsize		= GRCAN_DEFAULT_BUFFER_SIZE,	\
+		.rxsize		= GRCAN_DEFAULT_BUFFER_SIZE,	\
+		}
+
+#define GRCAN_TXBUG_SAFE_GRLIB_VERSION	0x4100
+#define GRLIB_VERSION_MASK		0xffff
+
+
+/* GRCAN private data structure */
+struct grcan_priv {
+	struct can_priv can;	/* must be the first member */
+	struct net_device *dev;
+	struct napi_struct napi;
+
+	struct grcan_registers __iomem *regs;	/* ioremap'ed registers */
+	struct grcan_device_config config;
+	struct grcan_dma dma;
+
+	struct sk_buff **echo_skb;	/* We allocate this on our own */
+	u8 *txdlc;			/* Length of queued frames */
+
+	/* The echo skb pointer, pointing into echo_skb and indicating which
+	 * frames can be echoed back. See the "Notes on the tx cyclic buffer
+	 * handling"-comment for grcan_start_xmit for more details.
+	 */
+	u32 eskbp;
+
+	/* Lock for controlling changes to the netif tx queue state, accesses to
+	 * the echo_skb pointer eskbp and for making sure that a running reset
+	 * and/or a close of the interface is done without interference from
+	 * other parts of the code.
+	 *
+	 * The echo_skb pointer, eskbp, should only be accessed under this lock
+	 * as it can be changed in several places and together with decisions on
+	 * whether to wake up the tx queue.
+	 *
+	 * The tx queue must never be woken up if there is a running reset or
+	 * close in progress.
+	 *
+	 * A running reset (see below on need_txbug_workaround) should never be
+	 * done if the interface is closing down and several running resets
+	 * should never be scheduled simultaneously.
+	 */
+	spinlock_t lock;
+
+	/* Whether a workaround is needed due to a bug in older hardware. In
+	 * this case, the driver both tries to prevent the bug from being
+	 * triggered and recovers, if the bug nevertheless happens, by doing a
+	 * running reset. A running reset, resets the device and continues from
+	 * where it were without being noticeable from outside the driver (apart
+	 * from slight delays).
+	 */
+	bool need_txbug_workaround;
+
+	/* To trigger initization of running reset and to trigger running reset
+	 * respectively in the case of a hanged device due to a txbug.
+	 */
+	struct timer_list hang_timer;
+	struct timer_list rr_timer;
+
+	/* To avoid waking up the netif queue and restarting timers
+	 * when a reset is scheduled or when closing of the device is
+	 * undergoing
+	 */
+	bool resetting;
+	bool closing;
+};
+
+/* Wait time for a short wait for ongoing to clear */
+#define GRCAN_SHORTWAIT_USECS	10
+
+/* Limit on the number of transmitted bits of an eff frame according to the CAN
+ * specification: 1 bit start of frame, 32 bits arbitration field, 6 bits
+ * control field, 8 bytes data field, 16 bits crc field, 2 bits ACK field and 7
+ * bits end of frame
+ */
+#define GRCAN_EFF_FRAME_MAX_BITS	(1+32+6+8*8+16+2+7)
+
+#if defined(__BIG_ENDIAN)
+static inline u32 grcan_read_reg(u32 __iomem *reg)
+{
+	return ioread32be(reg);
+}
+
+static inline void grcan_write_reg(u32 __iomem *reg, u32 val)
+{
+	iowrite32be(val, reg);
+}
+#else
+static inline u32 grcan_read_reg(u32 __iomem *reg)
+{
+	return ioread32(reg);
+}
+
+static inline void grcan_write_reg(u32 __iomem *reg, u32 val)
+{
+	iowrite32(val, reg);
+}
+#endif
+
+static inline void grcan_clear_bits(u32 __iomem *reg, u32 mask)
+{
+	grcan_write_reg(reg, grcan_read_reg(reg) & ~mask);
+}
+
+static inline void grcan_set_bits(u32 __iomem *reg, u32 mask)
+{
+	grcan_write_reg(reg, grcan_read_reg(reg) | mask);
+}
+
+static inline u32 grcan_read_bits(u32 __iomem *reg, u32 mask)
+{
+	return grcan_read_reg(reg) & mask;
+}
+
+static inline void grcan_write_bits(u32 __iomem *reg, u32 value, u32 mask)
+{
+	u32 old = grcan_read_reg(reg);
+
+	grcan_write_reg(reg, (old & ~mask) | (value & mask));
+}
+
+/* a and b should both be in [0,size] and a == b == size should not hold */
+static inline u32 grcan_ring_add(u32 a, u32 b, u32 size)
+{
+	u32 sum = a + b;
+
+	if (sum < size)
+		return sum;
+	else
+		return sum - size;
+}
+
+/* a and b should both be in [0,size) */
+static inline u32 grcan_ring_sub(u32 a, u32 b, u32 size)
+{
+	return grcan_ring_add(a, size - b, size);
+}
+
+/* Available slots for new transmissions */
+static inline u32 grcan_txspace(size_t txsize, u32 txwr, u32 eskbp)
+{
+	u32 slots = txsize / GRCAN_MSG_SIZE - 1;
+	u32 used = grcan_ring_sub(txwr, eskbp, txsize) / GRCAN_MSG_SIZE;
+
+	return slots - used;
+}
+
+/* Configuration parameters that can be set via module parameters */
+static struct grcan_device_config grcan_module_config =
+	GRCAN_DEFAULT_DEVICE_CONFIG;
+
+static struct can_bittiming_const grcan_bittiming_const = {
+	.name		= DRV_NAME,
+	.tseg1_min	= GRCAN_CONF_PS1_MIN + 1,
+	.tseg1_max	= GRCAN_CONF_PS1_MAX + 1,
+	.tseg2_min	= GRCAN_CONF_PS2_MIN,
+	.tseg2_max	= GRCAN_CONF_PS2_MAX,
+	.sjw_max	= GRCAN_CONF_RSJ_MAX,
+	.brp_min	= GRCAN_CONF_SCALER_MIN + 1,
+	.brp_max	= GRCAN_CONF_SCALER_MAX + 1,
+	.brp_inc	= GRCAN_CONF_SCALER_INC,
+};
+
+static int grcan_set_bittiming(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct can_bittiming *bt = &priv->can.bittiming;
+	u32 timing = 0;
+	int bpr, rsj, ps1, ps2, scaler;
+
+	/* Should never happen - function will not be called when
+	 * device is up
+	 */
+	if (grcan_read_bits(&regs->ctrl, GRCAN_CTRL_ENABLE))
+		return -EBUSY;
+
+	bpr = 0; /* Note bpr and brp are different concepts */
+	rsj = bt->sjw;
+	ps1 = (bt->prop_seg + bt->phase_seg1) - 1; /* tseg1 - 1 */
+	ps2 = bt->phase_seg2;
+	scaler = (bt->brp - 1);
+	timing |= (bpr << GRCAN_CONF_BPR_BIT) & GRCAN_CONF_BPR;
+	timing |= (rsj << GRCAN_CONF_RSJ_BIT) & GRCAN_CONF_RSJ;
+	timing |= (ps1 << GRCAN_CONF_PS1_BIT) & GRCAN_CONF_PS1;
+	timing |= (ps2 << GRCAN_CONF_PS2_BIT) & GRCAN_CONF_PS2;
+	timing |= (scaler << GRCAN_CONF_SCALER_BIT) & GRCAN_CONF_SCALER;
+
+	dev_info(dev->dev.parent,
+		 "setting timing=0x%x\n", timing);
+	grcan_write_bits(&regs->conf, timing, GRCAN_CONF_TIMING);
+	return 0;
+}
+
+static int grcan_get_berr_counter(const struct net_device *dev,
+				  struct can_berr_counter *bec)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	u32 status = grcan_read_reg(&regs->stat);
+
+	bec->txerr = (status & GRCAN_STAT_TXERRCNT) >> GRCAN_STAT_TXERRCNT_BIT;
+	bec->rxerr = (status & GRCAN_STAT_RXERRCNT) >> GRCAN_STAT_RXERRCNT_BIT;
+	return 0;
+}
+
+static int grcan_poll(struct napi_struct *napi, int budget);
+
+/* Reset device, but keep configuration information */
+static void grcan_reset(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	u32 config = grcan_read_reg(&regs->conf);
+
+	grcan_set_bits(&regs->ctrl, GRCAN_CTRL_RESET);
+	grcan_write_reg(&regs->conf, config);
+
+	priv->eskbp = grcan_read_reg(&regs->txrd);
+	priv->can.state = CAN_STATE_STOPPED;
+
+	/* Turn off hardware filtering - regs->rxcode set to 0 by reset */
+	grcan_write_reg(&regs->rxmask, 0);
+}
+
+/* stop device without changing any configurations */
+static void grcan_stop_hardware(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+
+	grcan_write_reg(&regs->imr, GRCAN_IRQ_NONE);
+	grcan_clear_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
+	grcan_clear_bits(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+	grcan_clear_bits(&regs->ctrl, GRCAN_CTRL_ENABLE);
+}
+
+/* Let priv->eskbp catch up to regs->txrd and echo back the skbs if echo
+ * is true and free them otherwise.
+ *
+ * If budget is >= 0, stop after handling at most budget skbs. Otherwise,
+ * continue until priv->eskbp catches up to regs->txrd.
+ *
+ * priv->lock *must* be held when calling this function
+ */
+static int catch_up_echo_skb(struct net_device *dev, int budget, bool echo)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	struct net_device_stats *stats = &dev->stats;
+	int i, work_done;
+
+	/* Updates to priv->eskbp and wake-ups of the queue needs to
+	 * be atomic towards the reads of priv->eskbp and shut-downs
+	 * of the queue in grcan_start_xmit.
+	 */
+	u32 txrd = grcan_read_reg(&regs->txrd);
+
+	for (work_done = 0; work_done < budget || budget < 0; work_done++) {
+		if (priv->eskbp == txrd)
+			break;
+		i = priv->eskbp / GRCAN_MSG_SIZE;
+		if (echo) {
+			/* Normal echo of messages */
+			stats->tx_packets++;
+			stats->tx_bytes += priv->txdlc[i];
+			priv->txdlc[i] = 0;
+			can_get_echo_skb(dev, i);
+		} else {
+			/* For cleanup of untransmitted messages */
+			can_free_echo_skb(dev, i);
+		}
+
+		priv->eskbp = grcan_ring_add(priv->eskbp, GRCAN_MSG_SIZE,
+					     dma->tx.size);
+		txrd = grcan_read_reg(&regs->txrd);
+	}
+	return work_done;
+}
+
+static void grcan_lost_one_shot_frame(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	u32 txrd;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	catch_up_echo_skb(dev, -1, true);
+
+	if (unlikely(grcan_read_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE))) {
+		/* Should never happen */
+		netdev_err(dev, "TXCTRL enabled at TXLOSS in one shot mode\n");
+	} else {
+		/* By the time an GRCAN_IRQ_TXLOSS is generated in
+		 * one-shot mode there is no problem in writing
+		 * to TXRD even in versions of the hardware in
+		 * which GRCAN_TXCTRL_ONGOING is not cleared properly
+		 * in one-shot mode.
+		 */
+
+		/* Skip message and discard echo-skb */
+		txrd = grcan_read_reg(&regs->txrd);
+		txrd = grcan_ring_add(txrd, GRCAN_MSG_SIZE, dma->tx.size);
+		grcan_write_reg(&regs->txrd, txrd);
+		catch_up_echo_skb(dev, -1, false);
+
+		if (!priv->resetting && !priv->closing &&
+		    !(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)) {
+			netif_wake_queue(dev);
+			grcan_set_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
+		}
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static void grcan_err(struct net_device *dev, u32 sources, u32 status)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	struct net_device_stats *stats = &dev->stats;
+	struct can_frame cf;
+
+	/* Zero potential error_frame */
+	memset(&cf, 0, sizeof(cf));
+
+	/* Message lost interrupt. This might be due to arbitration error, but
+	 * is also triggered when there is no one else on the can bus or when
+	 * there is a problem with the hardware interface or the bus itself. As
+	 * arbitration errors can not be singled out, no error frames are
+	 * generated reporting this event as an arbitration error.
+	 */
+	if (sources & GRCAN_IRQ_TXLOSS) {
+		/* Take care of failed one-shot transmit */
+		if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT)
+			grcan_lost_one_shot_frame(dev);
+
+		/* Stop printing as soon as error passive or bus off is in
+		 * effect. When not in one-shot mode, GRCAN_IRQ_TXLOSS can be
+		 * triggered over and over again for one message again even if
+		 * the controller is error passive.
+		 */
+		if (!(status & GRCAN_STAT_ERRCTR_RELATED)) {
+			netdev_dbg(dev, "tx message lost\n");
+			stats->tx_errors++;
+		}
+	}
+
+	/* Conditions dealing with the error counters. There is no interrupt for
+	 * error warning, but there are interrupts for increases of the error
+	 * counters.
+	 */
+	if ((sources & GRCAN_IRQ_ERRCTR_RELATED) ||
+	    (status & GRCAN_STAT_ERRCTR_RELATED)) {
+		enum can_state state = priv->can.state;
+		enum can_state oldstate = state;
+		u32 txerr = (status & GRCAN_STAT_TXERRCNT)
+			>> GRCAN_STAT_TXERRCNT_BIT;
+		u32 rxerr = (status & GRCAN_STAT_RXERRCNT)
+			>> GRCAN_STAT_RXERRCNT_BIT;
+
+		/* Figure out current state */
+		if (status & GRCAN_STAT_OFF) {
+			state = CAN_STATE_BUS_OFF;
+		} else if (status & GRCAN_STAT_PASS) {
+			state = CAN_STATE_ERROR_PASSIVE;
+		} else if (txerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT ||
+			   rxerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT) {
+			state = CAN_STATE_ERROR_WARNING;
+		} else {
+			state = CAN_STATE_ERROR_ACTIVE;
+		}
+
+		/* Handle and report state changes */
+		if (state != oldstate) {
+			switch (state) {
+			case CAN_STATE_BUS_OFF:
+				netdev_dbg(dev, "bus-off\n");
+				netif_carrier_off(dev);
+				priv->can.can_stats.bus_off++;
+
+				/* Prevent the hardware from recovering from bus
+				 * off on its own if restart is disabled.
+				 */
+				if (!priv->can.restart_ms)
+					grcan_stop_hardware(dev);
+
+				cf.can_id |= CAN_ERR_BUSOFF;
+				break;
+
+			case CAN_STATE_ERROR_PASSIVE:
+				netdev_dbg(dev, "Error passive condition\n");
+				priv->can.can_stats.error_passive++;
+
+				cf.can_id |= CAN_ERR_CRTL;
+				if (txerr >= GRCAN_STAT_ERRCNT_PASSIVE_LIMIT)
+					cf.data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
+				if (rxerr >= GRCAN_STAT_ERRCNT_PASSIVE_LIMIT)
+					cf.data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
+				break;
+
+			case CAN_STATE_ERROR_WARNING:
+				netdev_dbg(dev, "Error warning condition\n");
+				priv->can.can_stats.error_warning++;
+
+				cf.can_id |= CAN_ERR_CRTL;
+				if (txerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT)
+					cf.data[1] |= CAN_ERR_CRTL_TX_WARNING;
+				if (rxerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT)
+					cf.data[1] |= CAN_ERR_CRTL_RX_WARNING;
+				break;
+
+			case CAN_STATE_ERROR_ACTIVE:
+				netdev_dbg(dev, "Error active condition\n");
+				cf.can_id |= CAN_ERR_CRTL;
+				break;
+
+			default:
+				/* There are no others at this point */
+				break;
+			}
+			cf.data[6] = txerr;
+			cf.data[7] = rxerr;
+			priv->can.state = state;
+		}
+
+		/* Report automatic restarts */
+		if (priv->can.restart_ms && oldstate == CAN_STATE_BUS_OFF) {
+			unsigned long flags;
+
+			cf.can_id |= CAN_ERR_RESTARTED;
+			netdev_dbg(dev, "restarted\n");
+			priv->can.can_stats.restarts++;
+			netif_carrier_on(dev);
+
+			spin_lock_irqsave(&priv->lock, flags);
+
+			if (!priv->resetting && !priv->closing) {
+				u32 txwr = grcan_read_reg(&regs->txwr);
+
+				if (grcan_txspace(dma->tx.size, txwr,
+						  priv->eskbp))
+					netif_wake_queue(dev);
+			}
+
+			spin_unlock_irqrestore(&priv->lock, flags);
+		}
+	}
+
+	/* Data overrun interrupt */
+	if ((sources & GRCAN_IRQ_OR) || (status & GRCAN_STAT_OR)) {
+		netdev_dbg(dev, "got data overrun interrupt\n");
+		stats->rx_over_errors++;
+		stats->rx_errors++;
+
+		cf.can_id |= CAN_ERR_CRTL;
+		cf.data[1] |= CAN_ERR_CRTL_RX_OVERFLOW;
+	}
+
+	/* AHB bus error interrupts (not CAN bus errors) - shut down the
+	 * device.
+	 */
+	if (sources & (GRCAN_IRQ_TXAHBERR | GRCAN_IRQ_RXAHBERR) ||
+	    (status & GRCAN_STAT_AHBERR)) {
+		char *txrx = "";
+		unsigned long flags;
+
+		if (sources & GRCAN_IRQ_TXAHBERR) {
+			txrx = "on tx ";
+			stats->tx_errors++;
+		} else if (sources & GRCAN_IRQ_RXAHBERR) {
+			txrx = "on rx ";
+			stats->rx_errors++;
+		}
+		netdev_err(dev, "Fatal AHB buss error %s- halting device\n",
+			   txrx);
+
+		spin_lock_irqsave(&priv->lock, flags);
+
+		/* Prevent anything to be enabled again and halt device */
+		priv->closing = true;
+		netif_stop_queue(dev);
+		grcan_stop_hardware(dev);
+		priv->can.state = CAN_STATE_STOPPED;
+
+		spin_unlock_irqrestore(&priv->lock, flags);
+	}
+
+	/* Pass on error frame if something to report,
+	 * i.e. id contains some information
+	 */
+	if (cf.can_id) {
+		struct can_frame *skb_cf;
+		struct sk_buff *skb = alloc_can_err_skb(dev, &skb_cf);
+
+		if (skb == NULL) {
+			netdev_dbg(dev, "could not allocate error frame\n");
+			return;
+		}
+		skb_cf->can_id |= cf.can_id;
+		memcpy(skb_cf->data, cf.data, sizeof(cf.data));
+
+		netif_rx(skb);
+	}
+}
+
+static irqreturn_t grcan_interrupt(int irq, void *dev_id)
+{
+	struct net_device *dev = (struct net_device *)dev_id;
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	u32 sources, status;
+
+	/* Find out the source */
+	sources = grcan_read_reg(&regs->pimsr);
+	if (!sources)
+		return IRQ_NONE;
+	grcan_write_reg(&regs->picr, sources);
+	status = grcan_read_reg(&regs->stat);
+
+	/* If we got TX progress, the device has not hanged,
+	 * so disable the hang timer
+	 */
+	if (priv->need_txbug_workaround &&
+	    (sources & (GRCAN_IRQ_TX | GRCAN_IRQ_TXLOSS))) {
+		del_timer(&priv->hang_timer);
+	}
+
+	/* Frame(s) received or transmitted */
+	if (sources & (GRCAN_IRQ_TX | GRCAN_IRQ_RX)) {
+		/* Disable tx/rx interrupts and schedule poll() */
+		grcan_clear_bits(&regs->imr, GRCAN_IRQ_TX | GRCAN_IRQ_RX);
+		napi_schedule(&priv->napi);
+	}
+
+	/* (Potential) error conditions to take care of */
+	if (sources & GRCAN_IRQ_ERRORS)
+		grcan_err(dev, sources, status);
+
+	return IRQ_HANDLED;
+}
+
+/* Reset device and restart operations from where they were.
+ *
+ * This assumes that RXCTRL & RXCTRL is properly disabled and that RX
+ * is not ONGOING (TX might be stuck in ONGOING due to a harwrware bug
+ * for single shot)
+ */
+static void grcan_running_reset(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *)data;
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	unsigned long flags;
+
+	/* This temporarily messes with eskbp, so we need to lock
+	 * priv->lock
+	 */
+	spin_lock_irqsave(&priv->lock, flags);
+
+	priv->resetting = false;
+	del_timer(&priv->hang_timer);
+	del_timer(&priv->rr_timer);
+
+	if (!priv->closing) {
+		/* Save and reset - config register preserved by grcan_reset */
+		u32 imr = grcan_read_reg(&regs->imr);
+
+		u32 txaddr = grcan_read_reg(&regs->txaddr);
+		u32 txsize = grcan_read_reg(&regs->txsize);
+		u32 txwr = grcan_read_reg(&regs->txwr);
+		u32 txrd = grcan_read_reg(&regs->txrd);
+		u32 eskbp = priv->eskbp;
+
+		u32 rxaddr = grcan_read_reg(&regs->rxaddr);
+		u32 rxsize = grcan_read_reg(&regs->rxsize);
+		u32 rxwr = grcan_read_reg(&regs->rxwr);
+		u32 rxrd = grcan_read_reg(&regs->rxrd);
+
+		grcan_reset(dev);
+
+		/* Restore */
+		grcan_write_reg(&regs->txaddr, txaddr);
+		grcan_write_reg(&regs->txsize, txsize);
+		grcan_write_reg(&regs->txwr, txwr);
+		grcan_write_reg(&regs->txrd, txrd);
+		priv->eskbp = eskbp;
+
+		grcan_write_reg(&regs->rxaddr, rxaddr);
+		grcan_write_reg(&regs->rxsize, rxsize);
+		grcan_write_reg(&regs->rxwr, rxwr);
+		grcan_write_reg(&regs->rxrd, rxrd);
+
+		/* Turn on device again */
+		grcan_write_reg(&regs->imr, imr);
+		priv->can.state = CAN_STATE_ERROR_ACTIVE;
+		grcan_write_reg(&regs->txctrl, GRCAN_TXCTRL_ENABLE
+				| (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT
+				   ? GRCAN_TXCTRL_SINGLE : 0));
+		grcan_write_reg(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+		grcan_write_reg(&regs->ctrl, GRCAN_CTRL_ENABLE);
+
+		/* Start queue if there is size and listen-onle mode is not
+		 * enabled
+		 */
+		if (grcan_txspace(priv->dma.tx.size, txwr, priv->eskbp) &&
+		    !(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
+			netif_wake_queue(dev);
+
+
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	netdev_err(dev, "Device reset and restored\n");
+}
+
+/* Waiting time in usecs corresponding to the transmission of three maximum
+ * sized can frames in the given bitrate (in bits/sec). Waiting for this amount
+ * of time makes sure that the can controller have time to finish sending or
+ * receiving a frame with a good margin.
+ *
+ * usecs/sec * number of frames * bits/frame / bits/sec
+ */
+static inline u32 grcan_ongoing_wait_usecs(__u32 bitrate)
+{
+	return 1000000 * 3 * GRCAN_EFF_FRAME_MAX_BITS / bitrate;
+}
+
+/* Set timer so that it will not fire until after a period in which the can
+ * controller have a good margin to finish transmitting a frame unless it has
+ * hanged
+ */
+static inline void grcan_reset_timer(struct timer_list *timer, __u32 bitrate)
+{
+	u32 wait_jiffies = usecs_to_jiffies(grcan_ongoing_wait_usecs(bitrate));
+
+	mod_timer(timer, jiffies + wait_jiffies);
+}
+
+/* Disable channels and schedule a running reset */
+static void grcan_initiate_running_reset(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *)data;
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	unsigned long flags;
+
+	netdev_err(dev, "Device seems hanged - reset scheduled\n");
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	/* The main body of this function must never be executed again
+	 * until after an execution of grcan_running_reset
+	 */
+	if (!priv->resetting && !priv->closing) {
+		priv->resetting = true;
+		netif_stop_queue(dev);
+		grcan_clear_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
+		grcan_clear_bits(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+		grcan_reset_timer(&priv->rr_timer, priv->can.bittiming.bitrate);
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static void grcan_free_dma_buffers(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_dma *dma = &priv->dma;
+
+	dma_free_coherent(&dev->dev, dma->base_size, dma->base_buf,
+			  dma->base_handle);
+	memset(dma, 0, sizeof(*dma));
+}
+
+static int grcan_allocate_dma_buffers(struct net_device *dev,
+				      size_t tsize, size_t rsize)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_dma *dma = &priv->dma;
+	struct grcan_dma_buffer *large = rsize > tsize ? &dma->rx : &dma->tx;
+	struct grcan_dma_buffer *small = rsize > tsize ? &dma->tx : &dma->rx;
+	size_t shift;
+
+	/* Need a whole number of GRCAN_BUFFER_ALIGNMENT for the large,
+	 * i.e. first buffer
+	 */
+	size_t maxs = max(tsize, rsize);
+	size_t lsize = ALIGN(maxs, GRCAN_BUFFER_ALIGNMENT);
+
+	/* Put the small buffer after that */
+	size_t ssize = min(tsize, rsize);
+
+	/* Extra GRCAN_BUFFER_ALIGNMENT to allow for alignment */
+	dma->base_size = lsize + ssize + GRCAN_BUFFER_ALIGNMENT;
+	dma->base_buf = dma_alloc_coherent(&dev->dev,
+					   dma->base_size,
+					   &dma->base_handle,
+					   GFP_KERNEL);
+
+	if (!dma->base_buf)
+		return -ENOMEM;
+
+	dma->tx.size = tsize;
+	dma->rx.size = rsize;
+
+	large->handle = ALIGN(dma->base_handle, GRCAN_BUFFER_ALIGNMENT);
+	small->handle = large->handle + lsize;
+	shift = large->handle - dma->base_handle;
+
+	large->buf = dma->base_buf + shift;
+	small->buf = large->buf + lsize;
+
+	return 0;
+}
+
+
+/* priv->lock *must* be held when calling this function */
+static int grcan_start(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	u32 confop, txctrl;
+
+	grcan_reset(dev);
+
+	grcan_write_reg(&regs->txaddr, priv->dma.tx.handle);
+	grcan_write_reg(&regs->txsize, priv->dma.tx.size);
+	/* regs->txwr, regs->txrd and priv->eskbp already set to 0 by reset */
+
+	grcan_write_reg(&regs->rxaddr, priv->dma.rx.handle);
+	grcan_write_reg(&regs->rxsize, priv->dma.rx.size);
+	/* regs->rxwr and regs->rxrd already set to 0 by reset */
+
+	/* Enable interrupts */
+	grcan_read_reg(&regs->pir);
+	grcan_write_reg(&regs->imr, GRCAN_IRQ_DEFAULT);
+
+	/* Enable interfaces, channels and device */
+	confop = GRCAN_CONF_ABORT
+		| (priv->config.enable0 ? GRCAN_CONF_ENABLE0 : 0)
+		| (priv->config.enable1 ? GRCAN_CONF_ENABLE1 : 0)
+		| (priv->config.selection ? GRCAN_CONF_SELECTION : 0)
+		| (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY ?
+		   GRCAN_CONF_SILENT : 0)
+		| (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES ?
+		   GRCAN_CONF_TRIPLESAMP : 0);
+	grcan_write_bits(&regs->conf, confop, GRCAN_CONF_OPERATION);
+	txctrl = GRCAN_TXCTRL_ENABLE
+		| (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT
+		   ? GRCAN_TXCTRL_SINGLE : 0);
+	grcan_write_reg(&regs->txctrl, txctrl);
+	grcan_write_reg(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+	grcan_write_reg(&regs->ctrl, GRCAN_CTRL_ENABLE);
+
+	priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+	return 0;
+}
+
+static int grcan_set_mode(struct net_device *dev, enum can_mode mode)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+	int err = 0;
+
+	if (mode == CAN_MODE_START) {
+		/* This might be called to restart the device to recover from
+		 * bus off errors
+		 */
+		spin_lock_irqsave(&priv->lock, flags);
+		if (priv->closing || priv->resetting) {
+			err = -EBUSY;
+		} else {
+			netdev_info(dev, "Restarting device\n");
+			grcan_start(dev);
+			if (!(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
+				netif_wake_queue(dev);
+		}
+		spin_unlock_irqrestore(&priv->lock, flags);
+		return err;
+	}
+	return -EOPNOTSUPP;
+}
+
+static int grcan_open(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_dma *dma = &priv->dma;
+	unsigned long flags;
+	int err;
+
+	/* Allocate memory */
+	if (GRCAN_INVALID_BUFFER_SIZE(priv->config.txsize) ||
+	    GRCAN_INVALID_BUFFER_SIZE(priv->config.rxsize)) {
+		/* Should never be able go this far with invalid sizes */
+		netdev_err(dev, "Invalid buffer size pair 0x%x 0x%x\n",
+			   priv->config.txsize, priv->config.rxsize);
+		return -EINVAL;
+	}
+	err = grcan_allocate_dma_buffers(dev, priv->config.txsize,
+					 priv->config.rxsize);
+	if (err) {
+		netdev_err(dev, "could not allocate DMA buffers\n");
+		return err;
+	}
+
+	priv->echo_skb = devm_kzalloc(&dev->dev,
+				      dma->tx.size * sizeof(*priv->echo_skb),
+				      GFP_KERNEL);
+	if (!priv->echo_skb) {
+		err = -ENOMEM;
+		goto exit_free_dma_buffers;
+	}
+	priv->can.echo_skb_max = dma->tx.size;
+	priv->can.echo_skb = priv->echo_skb;
+
+	priv->txdlc = devm_kzalloc(&dev->dev,
+				   dma->tx.size * sizeof(*priv->txdlc),
+				   GFP_KERNEL);
+	if (!priv->txdlc) {
+		err = -ENOMEM;
+		goto exit_free_echo_skb;
+	}
+
+	/* Get can device up */
+	err = open_candev(dev);
+	if (err)
+		goto exit_free_txdlc;
+
+	err = devm_request_irq(&dev->dev, dev->irq, grcan_interrupt,
+			       IRQF_SHARED, dev->name, (void *)dev);
+	if (err)
+		goto exit_close_candev;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	grcan_start(dev);
+	napi_enable(&priv->napi);
+	if (!(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
+		netif_start_queue(dev);
+	priv->resetting = false;
+	priv->closing = false;
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return 0;
+
+exit_close_candev:
+	close_candev(dev);
+exit_free_txdlc:
+	devm_kfree(&dev->dev, priv->txdlc);
+exit_free_echo_skb:
+	devm_kfree(&dev->dev, priv->echo_skb);
+exit_free_dma_buffers:
+	grcan_free_dma_buffers(dev);
+	return err;
+}
+
+static int grcan_close(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+
+	napi_disable(&priv->napi);
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	priv->closing = true;
+	if (priv->need_txbug_workaround) {
+		del_timer_sync(&priv->hang_timer);
+		del_timer_sync(&priv->rr_timer);
+	}
+	netif_stop_queue(dev);
+	grcan_stop_hardware(dev);
+	priv->can.state = CAN_STATE_STOPPED;
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	devm_free_irq(&dev->dev, dev->irq, (void *)dev);
+	close_candev(dev);
+
+	grcan_free_dma_buffers(dev);
+	priv->can.echo_skb_max = 0;
+	priv->can.echo_skb = NULL;
+	devm_kfree(&dev->dev, priv->echo_skb);
+	devm_kfree(&dev->dev, priv->txdlc);
+
+	return 0;
+}
+
+static int grcan_transmit_catch_up(struct net_device *dev, int budget)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+	int work_done;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	work_done = catch_up_echo_skb(dev, budget, true);
+	if (work_done) {
+		if (!priv->resetting && !priv->closing &&
+		    !(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
+			netif_wake_queue(dev);
+
+		/* With napi we don't get TX interrupts for a while,
+		 * so prevent a running reset while catching up
+		 */
+		if (priv->need_txbug_workaround)
+			del_timer(&priv->hang_timer);
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return work_done;
+}
+
+static int grcan_receive(struct net_device *dev, int budget)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	struct net_device_stats *stats = &dev->stats;
+	struct can_frame *cf;
+	struct sk_buff *skb;
+	u32 wr, rd, startrd;
+	u32 *slot;
+	u32 i, rtr, eff, j, shift;
+	int work_done = 0;
+
+	rd = grcan_read_reg(&regs->rxrd);
+	startrd = rd;
+	for (work_done = 0; work_done < budget; work_done++) {
+		/* Check for packet to receive */
+		wr = grcan_read_reg(&regs->rxwr);
+		if (rd == wr)
+			break;
+
+		/* Take care of packet */
+		skb = alloc_can_skb(dev, &cf);
+		if (skb == NULL) {
+			netdev_err(dev,
+				   "dropping frame: skb allocation failed\n");
+			stats->rx_dropped++;
+			continue;
+		}
+
+		slot = dma->rx.buf + rd;
+		eff = slot[0] & GRCAN_MSG_IDE;
+		rtr = slot[0] & GRCAN_MSG_RTR;
+		if (eff) {
+			cf->can_id = ((slot[0] & GRCAN_MSG_EID)
+				      >> GRCAN_MSG_EID_BIT);
+			cf->can_id |= CAN_EFF_FLAG;
+		} else {
+			cf->can_id = ((slot[0] & GRCAN_MSG_BID)
+				      >> GRCAN_MSG_BID_BIT);
+		}
+		cf->can_dlc = get_can_dlc((slot[1] & GRCAN_MSG_DLC)
+					  >> GRCAN_MSG_DLC_BIT);
+		if (rtr) {
+			cf->can_id |= CAN_RTR_FLAG;
+		} else {
+			for (i = 0; i < cf->can_dlc; i++) {
+				j = GRCAN_MSG_DATA_SLOT_INDEX(i);
+				shift = GRCAN_MSG_DATA_SHIFT(i);
+				cf->data[i] = (u8)((slot[j] >> shift) & 0xff);
+			}
+		}
+		netif_receive_skb(skb);
+
+		/* Update statistics and read pointer */
+		stats->rx_packets++;
+		stats->rx_bytes += cf->can_dlc;
+		rd = grcan_ring_add(rd, GRCAN_MSG_SIZE, dma->rx.size);
+	}
+
+	/* Make sure everything is read before allowing hardware to
+	 * use the memory
+	 */
+	mb();
+
+	/* Update read pointer - no need to check for ongoing */
+	if (likely(rd != startrd))
+		grcan_write_reg(&regs->rxrd, rd);
+
+	return work_done;
+}
+
+static int grcan_poll(struct napi_struct *napi, int budget)
+{
+	struct grcan_priv *priv = container_of(napi, struct grcan_priv, napi);
+	struct net_device *dev = priv->dev;
+	struct grcan_registers __iomem *regs = priv->regs;
+	int rx_work_done = grcan_receive(dev, budget);
+	int tx_work_done = grcan_transmit_catch_up(dev, budget);
+
+	if (rx_work_done < budget && tx_work_done < budget) {
+		napi_complete(napi);
+		/* Enable tx and rx interrupts again */
+		if (!priv->closing)
+			grcan_set_bits(&regs->imr, GRCAN_IRQ_TX | GRCAN_IRQ_RX);
+	}
+	return rx_work_done;
+}
+
+/* Work tx bug by waiting while for the risky situation to clear. If that fails,
+ * drop a frame in one-shot mode or indicate a busy device otherwise.
+ *
+ * Returns 0 on successful wait. Otherwise it sets *netdev_tx_status to the
+ * value that should be returned by grcan_start_xmit when aborting the xmit.
+ */
+static int grcan_txbug_workaround(struct net_device *dev, struct sk_buff *skb,
+				  u32 txwr, u32 oneshotmode,
+				  netdev_tx_t *netdev_tx_status)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	int i;
+	unsigned long flags;
+
+	/* Wait a while for ongoing to be cleared or read pointer to catch up to
+	 * write pointer. The latter is needed due to a bug in older versions of
+	 * GRCAN in which ONGOING is not cleared properly one-shot mode when a
+	 * transmission fails.
+	 */
+	for (i = 0; i < GRCAN_SHORTWAIT_USECS; i++) {
+		udelay(1);
+		if (!grcan_read_bits(&regs->txctrl, GRCAN_TXCTRL_ONGOING) ||
+		    grcan_read_reg(&regs->txrd) == txwr) {
+			return 0;
+		}
+	}
+
+	/* Clean up, in case the situation was not resolved */
+	spin_lock_irqsave(&priv->lock, flags);
+	if (!priv->resetting && !priv->closing) {
+		/* Queue might have been stopped earlier in grcan_start_xmit */
+		if (grcan_txspace(dma->tx.size, txwr, priv->eskbp))
+			netif_wake_queue(dev);
+		/* Set a timer to resolve a hanged tx controller */
+		if (!timer_pending(&priv->hang_timer))
+			grcan_reset_timer(&priv->hang_timer,
+					  priv->can.bittiming.bitrate);
+	}
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	if (oneshotmode) {
+		/* In one-shot mode we should never end up here because
+		 * then the interrupt handler increases txrd on TXLOSS,
+		 * but it is consistent with one-shot mode to drop the
+		 * frame in this case.
+		 */
+		kfree_skb(skb);
+		*netdev_tx_status = NETDEV_TX_OK;
+	} else {
+		/* In normal mode the socket-can transmission queue get
+		 * to keep the frame so that it can be retransmitted
+		 * later
+		 */
+		*netdev_tx_status = NETDEV_TX_BUSY;
+	}
+	return -EBUSY;
+}
+
+/* Notes on the tx cyclic buffer handling:
+ *
+ * regs->txwr	- the next slot for the driver to put data to be sent
+ * regs->txrd	- the next slot for the device to read data
+ * priv->eskbp	- the next slot for the driver to call can_put_echo_skb for
+ *
+ * grcan_start_xmit can enter more messages as long as regs->txwr does
+ * not reach priv->eskbp (within 1 message gap)
+ *
+ * The device sends messages until regs->txrd reaches regs->txwr
+ *
+ * The interrupt calls handler calls can_put_echo_skb until
+ * priv->eskbp reaches regs->txrd
+ */
+static netdev_tx_t grcan_start_xmit(struct sk_buff *skb,
+				    struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	struct can_frame *cf = (struct can_frame *)skb->data;
+	u32 id, txwr, txrd, space, txctrl;
+	int slotindex;
+	u32 *slot;
+	u32 i, rtr, eff, dlc, tmp, err;
+	int j, shift;
+	unsigned long flags;
+	u32 oneshotmode = priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT;
+
+	if (can_dropped_invalid_skb(dev, skb))
+		return NETDEV_TX_OK;
+
+	/* Trying to transmit in silent mode will generate error interrupts, but
+	 * this should never happen - the queue should not have been started.
+	 */
+	if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
+		return NETDEV_TX_BUSY;
+
+	/* Reads of priv->eskbp and shut-downs of the queue needs to
+	 * be atomic towards the updates to priv->eskbp and wake-ups
+	 * of the queue in the interrupt handler.
+	 */
+	spin_lock_irqsave(&priv->lock, flags);
+
+	txwr = grcan_read_reg(&regs->txwr);
+	space = grcan_txspace(dma->tx.size, txwr, priv->eskbp);
+
+	slotindex = txwr / GRCAN_MSG_SIZE;
+	slot = dma->tx.buf + txwr;
+
+	if (unlikely(space == 1))
+		netif_stop_queue(dev);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+	/* End of critical section*/
+
+	/* This should never happen. If circular buffer is full, the
+	 * netif_stop_queue should have been stopped already.
+	 */
+	if (unlikely(!space)) {
+		netdev_err(dev, "No buffer space, but queue is non-stopped.\n");
+		return NETDEV_TX_BUSY;
+	}
+
+	/* Convert and write CAN message to DMA buffer */
+	eff = cf->can_id & CAN_EFF_FLAG;
+	rtr = cf->can_id & CAN_RTR_FLAG;
+	id = cf->can_id & (eff ? CAN_EFF_MASK : CAN_SFF_MASK);
+	dlc = cf->can_dlc;
+	if (eff)
+		tmp = (id << GRCAN_MSG_EID_BIT) & GRCAN_MSG_EID;
+	else
+		tmp = (id << GRCAN_MSG_BID_BIT) & GRCAN_MSG_BID;
+	slot[0] = (eff ? GRCAN_MSG_IDE : 0) | (rtr ? GRCAN_MSG_RTR : 0) | tmp;
+
+	slot[1] = ((dlc << GRCAN_MSG_DLC_BIT) & GRCAN_MSG_DLC);
+	slot[2] = 0;
+	slot[3] = 0;
+	for (i = 0; i < dlc; i++) {
+		j = GRCAN_MSG_DATA_SLOT_INDEX(i);
+		shift = GRCAN_MSG_DATA_SHIFT(i);
+		slot[j] |= cf->data[i] << shift;
+	}
+
+	/* Checking that channel has not been disabled. These cases
+	 * should never happen
+	 */
+	txctrl = grcan_read_reg(&regs->txctrl);
+	if (!(txctrl & GRCAN_TXCTRL_ENABLE))
+		netdev_err(dev, "tx channel spuriously disabled\n");
+
+	if (oneshotmode && !(txctrl & GRCAN_TXCTRL_SINGLE))
+		netdev_err(dev, "one-shot mode spuriously disabled\n");
+
+	/* Bug workaround for old version of grcan where updating txwr
+	 * in the same clock cycle as the controller updates txrd to
+	 * the current txwr could hang the can controller
+	 */
+	if (priv->need_txbug_workaround) {
+		txrd = grcan_read_reg(&regs->txrd);
+		if (unlikely(grcan_ring_sub(txwr, txrd, dma->tx.size) == 1)) {
+			netdev_tx_t txstatus;
+
+			err = grcan_txbug_workaround(dev, skb, txwr,
+						     oneshotmode, &txstatus);
+			if (err)
+				return txstatus;
+		}
+	}
+
+	/* Prepare skb for echoing. This must be after the bug workaround above
+	 * as ownership of the skb is passed on by calling can_put_echo_skb.
+	 * Returning NETDEV_TX_BUSY or accessing skb or cf after a call to
+	 * can_put_echo_skb would be an error unless other measures are
+	 * taken.
+	 */
+	priv->txdlc[slotindex] = cf->can_dlc; /* Store dlc for statistics */
+	can_put_echo_skb(skb, dev, slotindex);
+
+	/* Make sure everything is written before allowing hardware to
+	 * read from the memory
+	 */
+	wmb();
+
+	/* Update write pointer to start transmission */
+	grcan_write_reg(&regs->txwr,
+			grcan_ring_add(txwr, GRCAN_MSG_SIZE, dma->tx.size));
+
+	return NETDEV_TX_OK;
+}
+
+
+/* ========== Setting up sysfs interface and module parameters ========== */
+
+
+#define GRCAN_NOT_BOOL(val) ((val) < 0 || (val) > 1)
+
+#define GRCAN_MODULE_PARAM(name, mtype, valcheckf)			\
+	static void grcan_sanitize_##name(struct platform_device *pd)	\
+	{								\
+		struct grcan_device_config grcan_default_config		\
+			= GRCAN_DEFAULT_DEVICE_CONFIG;			\
+		if (valcheckf(grcan_module_config.name)) {		\
+			dev_err(&pd->dev,				\
+				"Invalid module parameter value for "	\
+				#name " - setting default\n");		\
+			grcan_module_config.name =			\
+				grcan_default_config.name;		\
+		}							\
+	}								\
+	module_param_named(name, grcan_module_config.name,		\
+			   mtype, S_IRUGO)
+
+#define GRCAN_CONFIG_ATTR(name)						\
+	static ssize_t grcan_store_##name(struct device *sdev,		\
+					  struct device_attribute *att,	\
+					  const char *buf,		\
+					  size_t count)			\
+	{								\
+		struct net_device *dev = to_net_dev(sdev);		\
+		struct grcan_priv *priv = netdev_priv(dev);		\
+		u8 val;							\
+		int ret;						\
+		if (dev->flags & IFF_UP)				\
+			return -EBUSY;					\
+		ret = kstrtou8(buf, 0, &val);				\
+		if (ret < 0 || val < 0 || val > 1)			\
+			return -EINVAL;					\
+		priv->config.name = val;				\
+		return count;						\
+	}								\
+	static ssize_t grcan_show_##name(struct device *sdev,		\
+					 struct device_attribute *att,	\
+					 char *buf)			\
+	{								\
+		struct net_device *dev = to_net_dev(sdev);		\
+		struct grcan_priv *priv = netdev_priv(dev);		\
+		return sprintf(buf, "%d\n", priv->config.name);		\
+	}								\
+	static DEVICE_ATTR(name, S_IRUGO | S_IWUSR,			\
+			   grcan_show_##name,				\
+			   grcan_store_##name);				\
+	GRCAN_MODULE_PARAM(name, ushort, GRCAN_NOT_BOOL)
+
+/* The following configuration options are made available both via module
+ * parameters and writable sysfs files. See the chapter about GRCAN in the
+ * documentation for the GRLIB VHDL library for further details.
+ */
+
+/* Configure enable0 - Hardware configuration for interface 0 */
+GRCAN_CONFIG_ATTR(enable0);
+
+/* Configure enable1 - Hardware configuration for interface 1 */
+GRCAN_CONFIG_ATTR(enable1);
+
+/* Configure selection - Selection on which interface to use */
+GRCAN_CONFIG_ATTR(selection);
+
+
+/* The following configuration options are only available via module
+ * parameters.
+ */
+
+/* Configure size of tx buffer */
+GRCAN_MODULE_PARAM(txsize, uint, GRCAN_INVALID_BUFFER_SIZE);
+
+/* Configure size of rx buffer */
+GRCAN_MODULE_PARAM(rxsize, uint, GRCAN_INVALID_BUFFER_SIZE);
+
+
+/* Function that makes sure that configuration done using
+ * module parameters are set to valid values
+ */
+static void grcan_sanitize_module_config(struct platform_device *ofdev)
+{
+	grcan_sanitize_enable0(ofdev);
+	grcan_sanitize_enable1(ofdev);
+	grcan_sanitize_selection(ofdev);
+	grcan_sanitize_txsize(ofdev);
+	grcan_sanitize_rxsize(ofdev);
+}
+
+static const struct attribute *const sysfs_grcan_attrs[] = {
+	/* Config attrs */
+	&dev_attr_enable0.attr,
+	&dev_attr_enable1.attr,
+	&dev_attr_selection.attr,
+	NULL,
+};
+
+static const struct attribute_group sysfs_grcan_group = {
+	.name	= "grcan",
+	.attrs	= (struct attribute **)sysfs_grcan_attrs,
+};
+
+
+/* ========== Setting up the driver ========== */
+
+static const struct net_device_ops grcan_netdev_ops = {
+	.ndo_open	= grcan_open,
+	.ndo_stop	= grcan_close,
+	.ndo_start_xmit	= grcan_start_xmit,
+};
+
+static int grcan_setup_netdev(struct platform_device *ofdev,
+			      void __iomem *base,
+			      int irq, u32 ambafreq, bool txbug)
+{
+	struct net_device *dev;
+	struct grcan_priv *priv;
+	struct grcan_registers __iomem *regs;
+	int err;
+
+	dev = alloc_candev(sizeof(struct grcan_priv), 0);
+	if (!dev)
+		return -ENOMEM;
+
+	dev->irq = irq;
+	dev->flags |= IFF_ECHO;
+	dev->netdev_ops = &grcan_netdev_ops;
+	dev->sysfs_groups[0] = &sysfs_grcan_group;
+
+	priv = netdev_priv(dev);
+	memcpy(&priv->config, &grcan_module_config,
+	       sizeof(struct grcan_device_config));
+	priv->dev = dev;
+	priv->regs = (struct grcan_registers *)base;
+	priv->can.bittiming_const = &grcan_bittiming_const;
+	priv->can.do_set_bittiming = grcan_set_bittiming;
+	priv->can.do_set_mode = grcan_set_mode;
+	priv->can.do_get_berr_counter = grcan_get_berr_counter;
+	priv->can.clock.freq = ambafreq;
+	priv->can.ctrlmode_supported =
+		CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_ONE_SHOT;
+	priv->need_txbug_workaround = txbug;
+
+	/* Discover if triple sampling is supported by hardware */
+	regs = priv->regs;
+	grcan_set_bits(&regs->ctrl, GRCAN_CTRL_RESET);
+	grcan_set_bits(&regs->conf, GRCAN_CONF_TRIPLESAMP);
+	if (grcan_read_bits(&regs->conf, GRCAN_CONF_TRIPLESAMP)) {
+		priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES;
+		dev_info(&ofdev->dev, "Hardware supports triple-sampling\n");
+	}
+
+	spin_lock_init(&priv->lock);
+
+	if (priv->need_txbug_workaround) {
+		init_timer(&priv->rr_timer);
+		priv->rr_timer.function = grcan_running_reset;
+		priv->rr_timer.data = (unsigned long)dev;
+
+		init_timer(&priv->hang_timer);
+		priv->hang_timer.function = grcan_initiate_running_reset;
+		priv->hang_timer.data = (unsigned long)dev;
+	}
+
+	netif_napi_add(dev, &priv->napi, grcan_poll, GRCAN_NAPI_WEIGHT);
+
+	SET_NETDEV_DEV(dev, &ofdev->dev);
+	dev_info(&ofdev->dev, "regs=0x%p, irq=%d, clock=%d\n",
+		 priv->regs, dev->irq, priv->can.clock.freq);
+
+	err = register_candev(dev);
+	if (err) {
+		dev_err(&ofdev->dev, "registering %s failed (err=%d)\n",
+			DRV_NAME, err);
+		goto exit_free_candev;
+	}
+	dev_set_drvdata(&ofdev->dev, dev);
+
+	/* Reset device to allow bit-timing to be set. No need to call
+	 * grcan_reset at this stage. That is done in grcan_open.
+	 */
+	grcan_write_reg(&regs->ctrl, GRCAN_CTRL_RESET);
+
+	return 0;
+exit_free_candev:
+	free_candev(dev);
+	return err;
+}
+
+static int __devinit grcan_probe(struct platform_device *ofdev)
+{
+	struct device_node *np = ofdev->dev.of_node;
+	struct resource *res;
+	u32 sysid, ambafreq;
+	int irq, err;
+	void __iomem *base;
+	bool txbug = true;
+
+	/* Compare GRLIB version number with the first that does not
+	 * have the tx bug (see start_xmit)
+	 */
+	err = of_property_read_u32(np, "systemid", &sysid);
+	if (!err && ((sysid & GRLIB_VERSION_MASK)
+		     >= GRCAN_TXBUG_SAFE_GRLIB_VERSION))
+		txbug = false;
+
+	err = of_property_read_u32(np, "freq", &ambafreq);
+	if (err) {
+		dev_err(&ofdev->dev, "unable to fetch \"freq\" property\n");
+		goto exit_error;
+	}
+
+	res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
+	base = devm_request_and_ioremap(&ofdev->dev, res);
+	if (!base) {
+		dev_err(&ofdev->dev, "couldn't map IO resource\n");
+		err = -EADDRNOTAVAIL;
+		goto exit_error;
+	}
+
+	irq = irq_of_parse_and_map(np, GRCAN_IRQIX_IRQ);
+	if (irq == NO_IRQ) {
+		dev_err(&ofdev->dev, "no irq found\n");
+		err = -ENODEV;
+		goto exit_error;
+	}
+
+	grcan_sanitize_module_config(ofdev);
+
+	err = grcan_setup_netdev(ofdev, base, irq, ambafreq, txbug);
+	if (err)
+		goto exit_dispose_irq;
+
+	return 0;
+
+exit_dispose_irq:
+	irq_dispose_mapping(irq);
+exit_error:
+	dev_err(&ofdev->dev,
+		"%s socket CAN driver initialization failed with error %d\n",
+		DRV_NAME, err);
+	return err;
+}
+
+static int __devexit grcan_remove(struct platform_device *ofdev)
+{
+	struct net_device *dev = dev_get_drvdata(&ofdev->dev);
+	struct grcan_priv *priv = netdev_priv(dev);
+
+	unregister_candev(dev); /* Will in turn call grcan_close */
+
+	irq_dispose_mapping(dev->irq);
+	dev_set_drvdata(&ofdev->dev, NULL);
+	netif_napi_del(&priv->napi);
+	free_candev(dev);
+
+	dev_info(&ofdev->dev, "%s socket CAN driver removed\n", DRV_NAME);
+	return 0;
+}
+
+static struct of_device_id grcan_match[] = {
+	{.name = "GAISLER_GRCAN"},
+	{.name = "01_03d"},
+	{.name = "GAISLER_GRHCAN"},
+	{.name = "01_034"},
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, grcan_match);
+
+static struct platform_driver grcan_driver = {
+	.driver = {
+		.name = DRV_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = grcan_match,
+	},
+	.probe = grcan_probe,
+	.remove = __devexit_p(grcan_remove),
+};
+
+module_platform_driver(grcan_driver);
+
+MODULE_AUTHOR("Aeroflex Gaisler AB.");
+MODULE_DESCRIPTION("Socket CAN driver for Aeroflex Gaisler GRCAN");
+MODULE_LICENSE("GPL");
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* Re: [PATCH v6] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-11-07 15:20                                 ` [PATCH v6] " Andreas Larsson
@ 2012-11-08  8:29                                   ` Wolfgang Grandegger
  2012-11-08  9:27                                     ` Marc Kleine-Budde
  2012-11-08 10:33                                     ` [PATCH v6] " Andreas Larsson
  0 siblings, 2 replies; 41+ messages in thread
From: Wolfgang Grandegger @ 2012-11-08  8:29 UTC (permalink / raw)
  To: Andreas Larsson
  Cc: linux-can, software, Marc Kleine-Budde, devicetree-discuss

On 11/07/2012 04:20 PM, Andreas Larsson wrote:
> This driver supports GRCAN and CRHCAN CAN controllers available in the GRLIB
> VHDL IP core library.
> 
> Signed-off-by: Andreas Larsson <andreas@gaisler.com>

Acked-by: Wolfgang Grandegger <wg@grandegger.com>

Looks good now. Thanks for your patience.

Wolfgang.


^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v6] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-11-08  8:29                                   ` Wolfgang Grandegger
@ 2012-11-08  9:27                                     ` Marc Kleine-Budde
  2012-11-08 10:37                                       ` Andreas Larsson
       [not found]                                       ` <509B7B1E.5040509-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
  2012-11-08 10:33                                     ` [PATCH v6] " Andreas Larsson
  1 sibling, 2 replies; 41+ messages in thread
From: Marc Kleine-Budde @ 2012-11-08  9:27 UTC (permalink / raw)
  To: Wolfgang Grandegger
  Cc: Andreas Larsson, linux-can, software, devicetree-discuss

[-- Attachment #1: Type: text/plain, Size: 759 bytes --]

On 11/08/2012 09:29 AM, Wolfgang Grandegger wrote:
> On 11/07/2012 04:20 PM, Andreas Larsson wrote:
>> This driver supports GRCAN and CRHCAN CAN controllers available in the GRLIB
>> VHDL IP core library.
>>
>> Signed-off-by: Andreas Larsson <andreas@gaisler.com>
> 
> Acked-by: Wolfgang Grandegger <wg@grandegger.com>
> 
> Looks good now. Thanks for your patience.

I'm still fighting against the flexcan, I'll have a look at the driver
this afternoon.

regards, Marc
-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v6] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-11-08  8:29                                   ` Wolfgang Grandegger
  2012-11-08  9:27                                     ` Marc Kleine-Budde
@ 2012-11-08 10:33                                     ` Andreas Larsson
  1 sibling, 0 replies; 41+ messages in thread
From: Andreas Larsson @ 2012-11-08 10:33 UTC (permalink / raw)
  To: Wolfgang Grandegger
  Cc: linux-can, software, Marc Kleine-Budde, devicetree-discuss

On 11/08/2012 09:29 AM, Wolfgang Grandegger wrote:
> On 11/07/2012 04:20 PM, Andreas Larsson wrote:
>> This driver supports GRCAN and CRHCAN CAN controllers available in the GRLIB
>> VHDL IP core library.
>>
>> Signed-off-by: Andreas Larsson <andreas@gaisler.com>
>
> Acked-by: Wolfgang Grandegger <wg@grandegger.com>
>
> Looks good now. Thanks for your patience.

Thanks a lot for all the feedback!

Cheers,
Andreas


^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v6] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-11-08  9:27                                     ` Marc Kleine-Budde
@ 2012-11-08 10:37                                       ` Andreas Larsson
       [not found]                                       ` <509B7B1E.5040509-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
  1 sibling, 0 replies; 41+ messages in thread
From: Andreas Larsson @ 2012-11-08 10:37 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: Wolfgang Grandegger, linux-can, software, devicetree-discuss

On 11/08/2012 10:27 AM, Marc Kleine-Budde wrote:
> On 11/08/2012 09:29 AM, Wolfgang Grandegger wrote:
>> On 11/07/2012 04:20 PM, Andreas Larsson wrote:
>>> This driver supports GRCAN and CRHCAN CAN controllers available in the GRLIB
>>> VHDL IP core library.
>>>
>>> Signed-off-by: Andreas Larsson <andreas@gaisler.com>
>>
>> Acked-by: Wolfgang Grandegger <wg@grandegger.com>
>>
>> Looks good now. Thanks for your patience.
>
> I'm still fighting against the flexcan, I'll have a look at the driver
> this afternoon.

Excellent! I have since v6 added a new bit-timing parameter restriction needed 
for the newly added triple sampling mode, so I'll send in a v7.

Cheers,
Andreas


^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH v7] can: grcan: Add device driver for GRCAN and GRHCAN cores
       [not found]                                       ` <509B7B1E.5040509-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
@ 2012-11-08 13:10                                         ` Andreas Larsson
  2012-11-09  0:01                                           ` Marc Kleine-Budde
  0 siblings, 1 reply; 41+ messages in thread
From: Andreas Larsson @ 2012-11-08 13:10 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	software-FkzTOoA/JUlBDgjK7y7TUQ,
	linux-can-u79uwXL29TY76Z2rM5mHXA

This driver supports GRCAN and CRHCAN CAN controllers available in the GRLIB
VHDL IP core library.

Signed-off-by: Andreas Larsson <andreas-FkzTOoA/JUlBDgjK7y7TUQ@public.gmane.org>
Acked-by: Wolfgang Grandegger <wg-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
---
Changes since v6: bittiming parameter checks, variable/constant renames, comment edits

 Documentation/ABI/testing/sysfs-class-net-grcan    |   35 +
 .../devicetree/bindings/net/can/grcan.txt          |   28 +
 Documentation/kernel-parameters.txt                |   18 +
 drivers/net/can/Kconfig                            |    9 +
 drivers/net/can/Makefile                           |    1 +
 drivers/net/can/grcan.c                            | 1732 ++++++++++++++++++++
 6 files changed, 1823 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-class-net-grcan
 create mode 100644 Documentation/devicetree/bindings/net/can/grcan.txt
 create mode 100644 drivers/net/can/grcan.c

diff --git a/Documentation/ABI/testing/sysfs-class-net-grcan b/Documentation/ABI/testing/sysfs-class-net-grcan
new file mode 100644
index 0000000..f418c92
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-net-grcan
@@ -0,0 +1,35 @@
+
+What:		/sys/class/net/<iface>/grcan/enable0
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas-FkzTOoA/JUlBDgjK7y7TUQ@public.gmane.org>
+Description:
+		Hardware configuration of physical interface 0. This file reads
+		and writes the "Enable 0" bit of the configuration register.
+		Possible values: 0 or 1. See the GRCAN chapter of the GRLIB IP
+		core library documentation for details. The default value is 0
+		or set by the module parameter grcan.enable0 and can be read at
+		/sys/module/grcan/parameters/enable0.
+
+What:		/sys/class/net/<iface>/grcan/enable1
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas-FkzTOoA/JUlBDgjK7y7TUQ@public.gmane.org>
+Description:
+		Hardware configuration of physical interface 1. This file reads
+		and writes the "Enable 1" bit of the configuration register.
+		Possible values: 0 or 1. See the GRCAN chapter of the GRLIB IP
+		core library documentation for details. The default value is 0
+		or set by the module parameter grcan.enable1 and can be read at
+		/sys/module/grcan/parameters/enable1.
+
+What:		/sys/class/net/<iface>/grcan/select
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas-FkzTOoA/JUlBDgjK7y7TUQ@public.gmane.org>
+Description:
+		Configuration of which physical interface to be used. Possible
+		values: 0 or 1. See the GRCAN chapter of the GRLIB IP core
+		library documentation for details. The default value is 0 or is
+		set by the module parameter grcan.select and can be read at
+		/sys/module/grcan/parameters/select.
diff --git a/Documentation/devicetree/bindings/net/can/grcan.txt b/Documentation/devicetree/bindings/net/can/grcan.txt
new file mode 100644
index 0000000..34ef349
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/can/grcan.txt
@@ -0,0 +1,28 @@
+Aeroflex Gaisler GRCAN and GRHCAN CAN controllers.
+
+The GRCAN and CRHCAN CAN controllers are available in the GRLIB VHDL IP core
+library.
+
+Note: These properties are built from the AMBA plug&play in a Leon SPARC system
+(the ordinary environment for GRCAN and GRHCAN). There are no dts files for
+sparc.
+
+Required properties:
+
+- name : Should be "GAISLER_GRCAN", "01_03d", "GAISLER_GRHCAN" or "01_034"
+
+- reg : Address and length of the register set for the device
+
+- freq : Frequency of the external oscillator clock in Hz (the frequency of
+	the amba bus in the ordinary case)
+
+- interrupts : Interrupt number for this device
+
+Optional properties:
+
+- systemid : If not present or if the value of the least significant 16 bits
+	of this 32-bit property is smaller than GRCAN_TXBUG_SAFE_GRLIB_VERSION
+	a bug workaround is activated.
+
+For further information look in the documentation for the GLIB IP core library:
+http://www.gaisler.com/products/grlib/grip.pdf
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 9776f06..3da4f96 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -905,6 +905,24 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 	gpt		[EFI] Forces disk with valid GPT signature but
 			invalid Protective MBR to be treated as GPT.
 
+	grcan.enable0=	[HW] Configuration of physical interface 0. Determines
+			the "Enable 0" bit of the configuration register.
+			Format: 0 | 1
+			Default: 0
+	grcan.enable1=	[HW] Configuration of physical interface 1. Determines
+			the "Enable 0" bit of the configuration register.
+			Format: 0 | 1
+			Default: 0
+	grcan.select=	[HW] Select which physical interface to use.
+			Format: 0 | 1
+			Default: 0
+	grcan.txsize=	[HW] Sets the size of the tx buffer.
+			Format: <unsigned int> such that (txsize & ~0x1fffc0) == 0.
+			Default: 1024
+	grcan.rxsize=	[HW] Sets the size of the rx buffer.
+			Format: <unsigned int> such that (rxsize & ~0x1fffc0) == 0.
+			Default: 1024
+
 	hashdist=	[KNL,NUMA] Large hashes allocated during boot
 			are distributed across NUMA nodes.  Defaults on
 			for 64-bit NUMA, off otherwise.
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
index bb709fd..b56bd9e 100644
--- a/drivers/net/can/Kconfig
+++ b/drivers/net/can/Kconfig
@@ -110,6 +110,15 @@ config PCH_CAN
 	  is an IOH for x86 embedded processor (Intel Atom E6xx series).
 	  This driver can access CAN bus.
 
+config CAN_GRCAN
+	tristate "Aeroflex Gaisler GRCAN and GRHCAN CAN devices"
+	depends on CAN_DEV && OF
+	---help---
+	  Say Y here if you want to use Aeroflex Gaisler GRCAN or GRHCAN.
+	  Note that the driver supports little endian, even though little
+	  endian syntheses of the cores would need some modifications on
+	  the hardware level to work.
+
 source "drivers/net/can/mscan/Kconfig"
 
 source "drivers/net/can/sja1000/Kconfig"
diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
index 938be37..7de5986 100644
--- a/drivers/net/can/Makefile
+++ b/drivers/net/can/Makefile
@@ -22,5 +22,6 @@ obj-$(CONFIG_CAN_BFIN)		+= bfin_can.o
 obj-$(CONFIG_CAN_JANZ_ICAN3)	+= janz-ican3.o
 obj-$(CONFIG_CAN_FLEXCAN)	+= flexcan.o
 obj-$(CONFIG_PCH_CAN)		+= pch_can.o
+obj-$(CONFIG_CAN_GRCAN)		+= grcan.o
 
 ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/grcan.c b/drivers/net/can/grcan.c
new file mode 100644
index 0000000..2cabf78
--- /dev/null
+++ b/drivers/net/can/grcan.c
@@ -0,0 +1,1732 @@
+/*
+ * Socket CAN driver for Aeroflex Gaisler GRCAN and GRHCAN.
+ *
+ * 2012 (c) Aeroflex Gaisler AB
+ *
+ * This driver supports GRCAN and GRHCAN CAN controllers available in the GRLIB
+ * VHDL IP core library.
+ *
+ * Full documentation of the GRCAN core can be found here:
+ * http://www.gaisler.com/products/grlib/grip.pdf
+ *
+ * See "Documentation/devicetree/bindings/net/can/grcan.txt" for information on
+ * open firmware properties.
+ *
+ * See "Documentation/ABI/testing/sysfs-class-net-grcan" for information on the
+ * sysfs interface.
+ *
+ * See "Documentation/kernel-parameters.txt" for information on the module
+ * parameters.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Contributors: Andreas Larsson <andreas-FkzTOoA/JUlBDgjK7y7TUQ@public.gmane.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/can/dev.h>
+#include <linux/spinlock.h>
+
+#include <linux/of_platform.h>
+#include <asm/prom.h>
+
+#include <linux/of_irq.h>
+
+#include <linux/dma-mapping.h>
+
+#define DRV_NAME	"grcan"
+
+#define GRCAN_NAPI_WEIGHT	16
+
+#define GRCAN_RESERVE_SIZE(slot1, slot2) (((slot2) - (slot1)) / 4 - 1)
+
+struct grcan_registers {
+	u32 conf;	/* 0x00 */
+	u32 stat;	/* 0x04 */
+	u32 ctrl;	/* 0x08 */
+	u32 __reserved1[GRCAN_RESERVE_SIZE(0x08, 0x18)];
+	u32 smask;	/* 0x18 - CanMASK */
+	u32 scode;	/* 0x1c - CanCODE */
+	u32 __reserved2[GRCAN_RESERVE_SIZE(0x1c, 0x100)];
+	u32 pimsr;	/* 0x100 */
+	u32 pimr;	/* 0x104 */
+	u32 pisr;	/* 0x108 */
+	u32 pir;	/* 0x10C */
+	u32 imr;	/* 0x110 */
+	u32 picr;	/* 0x114 */
+	u32 __reserved3[GRCAN_RESERVE_SIZE(0x114, 0x200)];
+	u32 txctrl;	/* 0x200 */
+	u32 txaddr;	/* 0x204 */
+	u32 txsize;	/* 0x208 */
+	u32 txwr;	/* 0x20C */
+	u32 txrd;	/* 0x210 */
+	u32 txirq;	/* 0x214 */
+	u32 __reserved4[GRCAN_RESERVE_SIZE(0x214, 0x300)];
+	u32 rxctrl;	/* 0x300 */
+	u32 rxaddr;	/* 0x304 */
+	u32 rxsize;	/* 0x308 */
+	u32 rxwr;	/* 0x30C */
+	u32 rxrd;	/* 0x310 */
+	u32 rxirq;	/* 0x314 */
+	u32 rxmask;	/* 0x318 */
+	u32 rxcode;	/* 0x31C */
+};
+
+#define GRCAN_CONF_ABORT	0x00000001
+#define GRCAN_CONF_ENABLE0	0x00000002
+#define GRCAN_CONF_ENABLE1	0x00000004
+#define GRCAN_CONF_SELECT	0x00000008
+#define GRCAN_CONF_SILENT	0x00000010
+#define GRCAN_CONF_SAM		0x00000020 /* Available in some hardware */
+#define GRCAN_CONF_BPR		0x00000300 /* Note: not BRP */
+#define GRCAN_CONF_RSJ		0x00007000
+#define GRCAN_CONF_PS1		0x00f00000
+#define GRCAN_CONF_PS2		0x000f0000
+#define GRCAN_CONF_SCALER	0xff000000
+#define GRCAN_CONF_OPERATION						\
+	(GRCAN_CONF_ABORT | GRCAN_CONF_ENABLE0 | GRCAN_CONF_ENABLE1	\
+	 | GRCAN_CONF_SELECT | GRCAN_CONF_SILENT | GRCAN_CONF_SAM)
+#define GRCAN_CONF_TIMING						\
+	(GRCAN_CONF_BPR | GRCAN_CONF_RSJ | GRCAN_CONF_PS1		\
+	 | GRCAN_CONF_PS2 | GRCAN_CONF_SCALER)
+
+#define GRCAN_CONF_RSJ_MIN	1
+#define GRCAN_CONF_RSJ_MAX	4
+#define GRCAN_CONF_PS1_MIN	1
+#define GRCAN_CONF_PS1_MAX	15
+#define GRCAN_CONF_PS2_MIN	2
+#define GRCAN_CONF_PS2_MAX	8
+#define GRCAN_CONF_SCALER_MIN	0
+#define GRCAN_CONF_SCALER_MAX	255
+#define GRCAN_CONF_SCALER_INC	1
+
+#define GRCAN_CONF_BPR_BIT	8
+#define GRCAN_CONF_RSJ_BIT	12
+#define GRCAN_CONF_PS1_BIT	20
+#define GRCAN_CONF_PS2_BIT	16
+#define GRCAN_CONF_SCALER_BIT	24
+
+#define GRCAN_STAT_PASS		0x000001
+#define GRCAN_STAT_OFF		0x000002
+#define GRCAN_STAT_OR		0x000004
+#define GRCAN_STAT_AHBERR	0x000008
+#define GRCAN_STAT_ACTIVE	0x000010
+#define GRCAN_STAT_RXERRCNT	0x00ff00
+#define GRCAN_STAT_TXERRCNT	0xff0000
+
+#define GRCAN_STAT_ERRCTR_RELATED	(GRCAN_STAT_PASS | GRCAN_STAT_OFF)
+
+#define GRCAN_STAT_RXERRCNT_BIT	8
+#define GRCAN_STAT_TXERRCNT_BIT	16
+
+#define GRCAN_STAT_ERRCNT_WARNING_LIMIT	96
+#define GRCAN_STAT_ERRCNT_PASSIVE_LIMIT	127
+
+#define GRCAN_CTRL_RESET	0x2
+#define GRCAN_CTRL_ENABLE	0x1
+
+#define GRCAN_TXCTRL_ENABLE	0x1
+#define GRCAN_TXCTRL_ONGOING	0x2
+#define GRCAN_TXCTRL_SINGLE	0x4
+
+#define GRCAN_RXCTRL_ENABLE	0x1
+#define GRCAN_RXCTRL_ONGOING	0x2
+
+/* Relative offset of IRQ sources to AMBA Plug&Play */
+#define GRCAN_IRQIX_IRQ		0
+#define GRCAN_IRQIX_TXSYNC	1
+#define GRCAN_IRQIX_RXSYNC	2
+
+#define GRCAN_IRQ_PASS		0x00001
+#define GRCAN_IRQ_OFF		0x00002
+#define GRCAN_IRQ_OR		0x00004
+#define GRCAN_IRQ_RXAHBERR	0x00008
+#define GRCAN_IRQ_TXAHBERR	0x00010
+#define GRCAN_IRQ_RXIRQ		0x00020
+#define GRCAN_IRQ_TXIRQ		0x00040
+#define GRCAN_IRQ_RXFULL	0x00080
+#define GRCAN_IRQ_TXEMPTY	0x00100
+#define GRCAN_IRQ_RX		0x00200
+#define GRCAN_IRQ_TX		0x00400
+#define GRCAN_IRQ_RXSYNC	0x00800
+#define GRCAN_IRQ_TXSYNC	0x01000
+#define GRCAN_IRQ_RXERRCTR	0x02000
+#define GRCAN_IRQ_TXERRCTR	0x04000
+#define GRCAN_IRQ_RXMISS	0x08000
+#define GRCAN_IRQ_TXLOSS	0x10000
+
+#define GRCAN_IRQ_NONE	0
+#define GRCAN_IRQ_ALL							\
+	(GRCAN_IRQ_PASS | GRCAN_IRQ_OFF | GRCAN_IRQ_OR			\
+	 | GRCAN_IRQ_RXAHBERR | GRCAN_IRQ_TXAHBERR			\
+	 | GRCAN_IRQ_RXIRQ | GRCAN_IRQ_TXIRQ				\
+	 | GRCAN_IRQ_RXFULL | GRCAN_IRQ_TXEMPTY				\
+	 | GRCAN_IRQ_RX | GRCAN_IRQ_TX | GRCAN_IRQ_RXSYNC		\
+	 | GRCAN_IRQ_TXSYNC | GRCAN_IRQ_RXERRCTR			\
+	 | GRCAN_IRQ_TXERRCTR | GRCAN_IRQ_RXMISS			\
+	 | GRCAN_IRQ_TXLOSS)
+
+#define GRCAN_IRQ_ERRCTR_RELATED (GRCAN_IRQ_RXERRCTR | GRCAN_IRQ_TXERRCTR \
+				  | GRCAN_IRQ_PASS | GRCAN_IRQ_OFF)
+#define GRCAN_IRQ_ERRORS (GRCAN_IRQ_ERRCTR_RELATED | GRCAN_IRQ_OR	\
+			  | GRCAN_IRQ_TXAHBERR | GRCAN_IRQ_RXAHBERR	\
+			  | GRCAN_IRQ_TXLOSS)
+#define GRCAN_IRQ_DEFAULT (GRCAN_IRQ_RX | GRCAN_IRQ_TX | GRCAN_IRQ_ERRORS)
+
+#define GRCAN_MSG_SIZE		16
+
+#define GRCAN_MSG_IDE		0x80000000
+#define GRCAN_MSG_RTR		0x40000000
+#define GRCAN_MSG_BID		0x1ffc0000
+#define GRCAN_MSG_EID		0x1fffffff
+#define GRCAN_MSG_IDE_BIT	31
+#define GRCAN_MSG_RTR_BIT	30
+#define GRCAN_MSG_BID_BIT	18
+#define GRCAN_MSG_EID_BIT	0
+
+#define GRCAN_MSG_DLC		0xf0000000
+#define GRCAN_MSG_TXERRC	0x00ff0000
+#define GRCAN_MSG_RXERRC	0x0000ff00
+#define GRCAN_MSG_DLC_BIT	28
+#define GRCAN_MSG_TXERRC_BIT	16
+#define GRCAN_MSG_RXERRC_BIT	8
+#define GRCAN_MSG_AHBERR	0x00000008
+#define GRCAN_MSG_OR		0x00000004
+#define GRCAN_MSG_OFF		0x00000002
+#define GRCAN_MSG_PASS		0x00000001
+
+#define GRCAN_MSG_DATA_SLOT_INDEX(i) (2 + (i) / 4)
+#define GRCAN_MSG_DATA_SHIFT(i) ((3 - (i) % 4) * 8)
+
+#define GRCAN_BUFFER_ALIGNMENT		1024
+#define GRCAN_DEFAULT_BUFFER_SIZE	1024
+#define GRCAN_VALID_TR_SIZE_MASK	0x001fffc0
+
+#define GRCAN_INVALID_BUFFER_SIZE(s)			\
+	((s) == 0 || ((s) & ~GRCAN_VALID_TR_SIZE_MASK))
+
+#if GRCAN_INVALID_BUFFER_SIZE(GRCAN_DEFAULT_BUFFER_SIZE)
+#error "Invalid default buffer size"
+#endif
+
+struct grcan_dma_buffer {
+	size_t size;
+	void *buf;
+	dma_addr_t handle;
+};
+
+struct grcan_dma {
+	size_t base_size;
+	void *base_buf;
+	dma_addr_t base_handle;
+	struct grcan_dma_buffer tx;
+	struct grcan_dma_buffer rx;
+};
+
+/* GRCAN configuration parameters */
+struct grcan_device_config {
+	unsigned short enable0;
+	unsigned short enable1;
+	unsigned short select;
+	unsigned int txsize;
+	unsigned int rxsize;
+};
+
+#define GRCAN_DEFAULT_DEVICE_CONFIG {				\
+		.enable0	= 0,				\
+		.enable1	= 0,				\
+		.select		= 0,				\
+		.txsize		= GRCAN_DEFAULT_BUFFER_SIZE,	\
+		.rxsize		= GRCAN_DEFAULT_BUFFER_SIZE,	\
+		}
+
+#define GRCAN_TXBUG_SAFE_GRLIB_VERSION	0x4100
+#define GRLIB_VERSION_MASK		0xffff
+
+/* GRCAN private data structure */
+struct grcan_priv {
+	struct can_priv can;	/* must be the first member */
+	struct net_device *dev;
+	struct napi_struct napi;
+
+	struct grcan_registers __iomem *regs;	/* ioremap'ed registers */
+	struct grcan_device_config config;
+	struct grcan_dma dma;
+
+	struct sk_buff **echo_skb;	/* We allocate this on our own */
+	u8 *txdlc;			/* Length of queued frames */
+
+	/* The echo skb pointer, pointing into echo_skb and indicating which
+	 * frames can be echoed back. See the "Notes on the tx cyclic buffer
+	 * handling"-comment for grcan_start_xmit for more details.
+	 */
+	u32 eskbp;
+
+	/* Lock for controlling changes to the netif tx queue state, accesses to
+	 * the echo_skb pointer eskbp and for making sure that a running reset
+	 * and/or a close of the interface is done without interference from
+	 * other parts of the code.
+	 *
+	 * The echo_skb pointer, eskbp, should only be accessed under this lock
+	 * as it can be changed in several places and together with decisions on
+	 * whether to wake up the tx queue.
+	 *
+	 * The tx queue must never be woken up if there is a running reset or
+	 * close in progress.
+	 *
+	 * A running reset (see below on need_txbug_workaround) should never be
+	 * done if the interface is closing down and several running resets
+	 * should never be scheduled simultaneously.
+	 */
+	spinlock_t lock;
+
+	/* Whether a workaround is needed due to a bug in older hardware. In
+	 * this case, the driver both tries to prevent the bug from being
+	 * triggered and recovers, if the bug nevertheless happens, by doing a
+	 * running reset. A running reset, resets the device and continues from
+	 * where it were without being noticeable from outside the driver (apart
+	 * from slight delays).
+	 */
+	bool need_txbug_workaround;
+
+	/* To trigger initization of running reset and to trigger running reset
+	 * respectively in the case of a hanged device due to a txbug.
+	 */
+	struct timer_list hang_timer;
+	struct timer_list rr_timer;
+
+	/* To avoid waking up the netif queue and restarting timers
+	 * when a reset is scheduled or when closing of the device is
+	 * undergoing
+	 */
+	bool resetting;
+	bool closing;
+};
+
+/* Wait time for a short wait for ongoing to clear */
+#define GRCAN_SHORTWAIT_USECS	10
+
+/* Limit on the number of transmitted bits of an eff frame according to the CAN
+ * specification: 1 bit start of frame, 32 bits arbitration field, 6 bits
+ * control field, 8 bytes data field, 16 bits crc field, 2 bits ACK field and 7
+ * bits end of frame
+ */
+#define GRCAN_EFF_FRAME_MAX_BITS	(1+32+6+8*8+16+2+7)
+
+#if defined(__BIG_ENDIAN)
+static inline u32 grcan_read_reg(u32 __iomem *reg)
+{
+	return ioread32be(reg);
+}
+
+static inline void grcan_write_reg(u32 __iomem *reg, u32 val)
+{
+	iowrite32be(val, reg);
+}
+#else
+static inline u32 grcan_read_reg(u32 __iomem *reg)
+{
+	return ioread32(reg);
+}
+
+static inline void grcan_write_reg(u32 __iomem *reg, u32 val)
+{
+	iowrite32(val, reg);
+}
+#endif
+
+static inline void grcan_clear_bits(u32 __iomem *reg, u32 mask)
+{
+	grcan_write_reg(reg, grcan_read_reg(reg) & ~mask);
+}
+
+static inline void grcan_set_bits(u32 __iomem *reg, u32 mask)
+{
+	grcan_write_reg(reg, grcan_read_reg(reg) | mask);
+}
+
+static inline u32 grcan_read_bits(u32 __iomem *reg, u32 mask)
+{
+	return grcan_read_reg(reg) & mask;
+}
+
+static inline void grcan_write_bits(u32 __iomem *reg, u32 value, u32 mask)
+{
+	u32 old = grcan_read_reg(reg);
+
+	grcan_write_reg(reg, (old & ~mask) | (value & mask));
+}
+
+/* a and b should both be in [0,size] and a == b == size should not hold */
+static inline u32 grcan_ring_add(u32 a, u32 b, u32 size)
+{
+	u32 sum = a + b;
+
+	if (sum < size)
+		return sum;
+	else
+		return sum - size;
+}
+
+/* a and b should both be in [0,size) */
+static inline u32 grcan_ring_sub(u32 a, u32 b, u32 size)
+{
+	return grcan_ring_add(a, size - b, size);
+}
+
+/* Available slots for new transmissions */
+static inline u32 grcan_txspace(size_t txsize, u32 txwr, u32 eskbp)
+{
+	u32 slots = txsize / GRCAN_MSG_SIZE - 1;
+	u32 used = grcan_ring_sub(txwr, eskbp, txsize) / GRCAN_MSG_SIZE;
+
+	return slots - used;
+}
+
+/* Configuration parameters that can be set via module parameters */
+static struct grcan_device_config grcan_module_config =
+	GRCAN_DEFAULT_DEVICE_CONFIG;
+
+static struct can_bittiming_const grcan_bittiming_const = {
+	.name		= DRV_NAME,
+	.tseg1_min	= GRCAN_CONF_PS1_MIN + 1,
+	.tseg1_max	= GRCAN_CONF_PS1_MAX + 1,
+	.tseg2_min	= GRCAN_CONF_PS2_MIN,
+	.tseg2_max	= GRCAN_CONF_PS2_MAX,
+	.sjw_max	= GRCAN_CONF_RSJ_MAX,
+	.brp_min	= GRCAN_CONF_SCALER_MIN + 1,
+	.brp_max	= GRCAN_CONF_SCALER_MAX + 1,
+	.brp_inc	= GRCAN_CONF_SCALER_INC,
+};
+
+static int grcan_set_bittiming(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct can_bittiming *bt = &priv->can.bittiming;
+	u32 timing = 0;
+	int bpr, rsj, ps1, ps2, scaler;
+
+	/* Should never happen - function will not be called when
+	 * device is up
+	 */
+	if (grcan_read_bits(&regs->ctrl, GRCAN_CTRL_ENABLE))
+		return -EBUSY;
+
+	bpr = 0; /* Note bpr and brp are different concepts */
+	rsj = bt->sjw;
+	ps1 = (bt->prop_seg + bt->phase_seg1) - 1; /* tseg1 - 1 */
+	ps2 = bt->phase_seg2;
+	scaler = (bt->brp - 1);
+	timing |= (bpr << GRCAN_CONF_BPR_BIT) & GRCAN_CONF_BPR;
+	timing |= (rsj << GRCAN_CONF_RSJ_BIT) & GRCAN_CONF_RSJ;
+	timing |= (ps1 << GRCAN_CONF_PS1_BIT) & GRCAN_CONF_PS1;
+	timing |= (ps2 << GRCAN_CONF_PS2_BIT) & GRCAN_CONF_PS2;
+	timing |= (scaler << GRCAN_CONF_SCALER_BIT) & GRCAN_CONF_SCALER;
+
+	netdev_info(dev, "setting timing=0x%x\n", timing);
+	if (!(ps1 > ps2)) {
+		netdev_err(dev, "PS1 > PS2 must hold: PS1=%d, PS2=%d\n",
+			   ps1, ps2);
+		return -EINVAL;
+	}
+	if (!(ps2 >= rsj)) {
+		netdev_err(dev, "PS2 >= RSJ must hold: PS2=%d, RSJ=%d\n",
+			   ps2, rsj);
+		return -EINVAL;
+	}
+
+	grcan_write_bits(&regs->conf, timing, GRCAN_CONF_TIMING);
+	return 0;
+}
+
+static int grcan_get_berr_counter(const struct net_device *dev,
+				  struct can_berr_counter *bec)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	u32 status = grcan_read_reg(&regs->stat);
+
+	bec->txerr = (status & GRCAN_STAT_TXERRCNT) >> GRCAN_STAT_TXERRCNT_BIT;
+	bec->rxerr = (status & GRCAN_STAT_RXERRCNT) >> GRCAN_STAT_RXERRCNT_BIT;
+	return 0;
+}
+
+static int grcan_poll(struct napi_struct *napi, int budget);
+
+/* Reset device, but keep configuration information */
+static void grcan_reset(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	u32 config = grcan_read_reg(&regs->conf);
+
+	grcan_set_bits(&regs->ctrl, GRCAN_CTRL_RESET);
+	grcan_write_reg(&regs->conf, config);
+
+	priv->eskbp = grcan_read_reg(&regs->txrd);
+	priv->can.state = CAN_STATE_STOPPED;
+
+	/* Turn off hardware filtering - regs->rxcode set to 0 by reset */
+	grcan_write_reg(&regs->rxmask, 0);
+}
+
+/* stop device without changing any configurations */
+static void grcan_stop_hardware(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+
+	grcan_write_reg(&regs->imr, GRCAN_IRQ_NONE);
+	grcan_clear_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
+	grcan_clear_bits(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+	grcan_clear_bits(&regs->ctrl, GRCAN_CTRL_ENABLE);
+}
+
+/* Let priv->eskbp catch up to regs->txrd and echo back the skbs if echo
+ * is true and free them otherwise.
+ *
+ * If budget is >= 0, stop after handling at most budget skbs. Otherwise,
+ * continue until priv->eskbp catches up to regs->txrd.
+ *
+ * priv->lock *must* be held when calling this function
+ */
+static int catch_up_echo_skb(struct net_device *dev, int budget, bool echo)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	struct net_device_stats *stats = &dev->stats;
+	int i, work_done;
+
+	/* Updates to priv->eskbp and wake-ups of the queue needs to
+	 * be atomic towards the reads of priv->eskbp and shut-downs
+	 * of the queue in grcan_start_xmit.
+	 */
+	u32 txrd = grcan_read_reg(&regs->txrd);
+
+	for (work_done = 0; work_done < budget || budget < 0; work_done++) {
+		if (priv->eskbp == txrd)
+			break;
+		i = priv->eskbp / GRCAN_MSG_SIZE;
+		if (echo) {
+			/* Normal echo of messages */
+			stats->tx_packets++;
+			stats->tx_bytes += priv->txdlc[i];
+			priv->txdlc[i] = 0;
+			can_get_echo_skb(dev, i);
+		} else {
+			/* For cleanup of untransmitted messages */
+			can_free_echo_skb(dev, i);
+		}
+
+		priv->eskbp = grcan_ring_add(priv->eskbp, GRCAN_MSG_SIZE,
+					     dma->tx.size);
+		txrd = grcan_read_reg(&regs->txrd);
+	}
+	return work_done;
+}
+
+static void grcan_lost_one_shot_frame(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	u32 txrd;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	catch_up_echo_skb(dev, -1, true);
+
+	if (unlikely(grcan_read_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE))) {
+		/* Should never happen */
+		netdev_err(dev, "TXCTRL enabled at TXLOSS in one shot mode\n");
+	} else {
+		/* By the time an GRCAN_IRQ_TXLOSS is generated in
+		 * one-shot mode there is no problem in writing
+		 * to TXRD even in versions of the hardware in
+		 * which GRCAN_TXCTRL_ONGOING is not cleared properly
+		 * in one-shot mode.
+		 */
+
+		/* Skip message and discard echo-skb */
+		txrd = grcan_read_reg(&regs->txrd);
+		txrd = grcan_ring_add(txrd, GRCAN_MSG_SIZE, dma->tx.size);
+		grcan_write_reg(&regs->txrd, txrd);
+		catch_up_echo_skb(dev, -1, false);
+
+		if (!priv->resetting && !priv->closing &&
+		    !(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)) {
+			netif_wake_queue(dev);
+			grcan_set_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
+		}
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static void grcan_err(struct net_device *dev, u32 sources, u32 status)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	struct net_device_stats *stats = &dev->stats;
+	struct can_frame cf;
+
+	/* Zero potential error_frame */
+	memset(&cf, 0, sizeof(cf));
+
+	/* Message lost interrupt. This might be due to arbitration error, but
+	 * is also triggered when there is no one else on the can bus or when
+	 * there is a problem with the hardware interface or the bus itself. As
+	 * arbitration errors can not be singled out, no error frames are
+	 * generated reporting this event as an arbitration error.
+	 */
+	if (sources & GRCAN_IRQ_TXLOSS) {
+		/* Take care of failed one-shot transmit */
+		if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT)
+			grcan_lost_one_shot_frame(dev);
+
+		/* Stop printing as soon as error passive or bus off is in
+		 * effect to limit the amount of txloss debug printouts.
+		 */
+		if (!(status & GRCAN_STAT_ERRCTR_RELATED)) {
+			netdev_dbg(dev, "tx message lost\n");
+			stats->tx_errors++;
+		}
+	}
+
+	/* Conditions dealing with the error counters. There is no interrupt for
+	 * error warning, but there are interrupts for increases of the error
+	 * counters.
+	 */
+	if ((sources & GRCAN_IRQ_ERRCTR_RELATED) ||
+	    (status & GRCAN_STAT_ERRCTR_RELATED)) {
+		enum can_state state = priv->can.state;
+		enum can_state oldstate = state;
+		u32 txerr = (status & GRCAN_STAT_TXERRCNT)
+			>> GRCAN_STAT_TXERRCNT_BIT;
+		u32 rxerr = (status & GRCAN_STAT_RXERRCNT)
+			>> GRCAN_STAT_RXERRCNT_BIT;
+
+		/* Figure out current state */
+		if (status & GRCAN_STAT_OFF) {
+			state = CAN_STATE_BUS_OFF;
+		} else if (status & GRCAN_STAT_PASS) {
+			state = CAN_STATE_ERROR_PASSIVE;
+		} else if (txerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT ||
+			   rxerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT) {
+			state = CAN_STATE_ERROR_WARNING;
+		} else {
+			state = CAN_STATE_ERROR_ACTIVE;
+		}
+
+		/* Handle and report state changes */
+		if (state != oldstate) {
+			switch (state) {
+			case CAN_STATE_BUS_OFF:
+				netdev_dbg(dev, "bus-off\n");
+				netif_carrier_off(dev);
+				priv->can.can_stats.bus_off++;
+
+				/* Prevent the hardware from recovering from bus
+				 * off on its own if restart is disabled.
+				 */
+				if (!priv->can.restart_ms)
+					grcan_stop_hardware(dev);
+
+				cf.can_id |= CAN_ERR_BUSOFF;
+				break;
+
+			case CAN_STATE_ERROR_PASSIVE:
+				netdev_dbg(dev, "Error passive condition\n");
+				priv->can.can_stats.error_passive++;
+
+				cf.can_id |= CAN_ERR_CRTL;
+				if (txerr >= GRCAN_STAT_ERRCNT_PASSIVE_LIMIT)
+					cf.data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
+				if (rxerr >= GRCAN_STAT_ERRCNT_PASSIVE_LIMIT)
+					cf.data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
+				break;
+
+			case CAN_STATE_ERROR_WARNING:
+				netdev_dbg(dev, "Error warning condition\n");
+				priv->can.can_stats.error_warning++;
+
+				cf.can_id |= CAN_ERR_CRTL;
+				if (txerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT)
+					cf.data[1] |= CAN_ERR_CRTL_TX_WARNING;
+				if (rxerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT)
+					cf.data[1] |= CAN_ERR_CRTL_RX_WARNING;
+				break;
+
+			case CAN_STATE_ERROR_ACTIVE:
+				netdev_dbg(dev, "Error active condition\n");
+				cf.can_id |= CAN_ERR_CRTL;
+				break;
+
+			default:
+				/* There are no others at this point */
+				break;
+			}
+			cf.data[6] = txerr;
+			cf.data[7] = rxerr;
+			priv->can.state = state;
+		}
+
+		/* Report automatic restarts */
+		if (priv->can.restart_ms && oldstate == CAN_STATE_BUS_OFF) {
+			unsigned long flags;
+
+			cf.can_id |= CAN_ERR_RESTARTED;
+			netdev_dbg(dev, "restarted\n");
+			priv->can.can_stats.restarts++;
+			netif_carrier_on(dev);
+
+			spin_lock_irqsave(&priv->lock, flags);
+
+			if (!priv->resetting && !priv->closing) {
+				u32 txwr = grcan_read_reg(&regs->txwr);
+
+				if (grcan_txspace(dma->tx.size, txwr,
+						  priv->eskbp))
+					netif_wake_queue(dev);
+			}
+
+			spin_unlock_irqrestore(&priv->lock, flags);
+		}
+	}
+
+	/* Data overrun interrupt */
+	if ((sources & GRCAN_IRQ_OR) || (status & GRCAN_STAT_OR)) {
+		netdev_dbg(dev, "got data overrun interrupt\n");
+		stats->rx_over_errors++;
+		stats->rx_errors++;
+
+		cf.can_id |= CAN_ERR_CRTL;
+		cf.data[1] |= CAN_ERR_CRTL_RX_OVERFLOW;
+	}
+
+	/* AHB bus error interrupts (not CAN bus errors) - shut down the
+	 * device.
+	 */
+	if (sources & (GRCAN_IRQ_TXAHBERR | GRCAN_IRQ_RXAHBERR) ||
+	    (status & GRCAN_STAT_AHBERR)) {
+		char *txrx = "";
+		unsigned long flags;
+
+		if (sources & GRCAN_IRQ_TXAHBERR) {
+			txrx = "on tx ";
+			stats->tx_errors++;
+		} else if (sources & GRCAN_IRQ_RXAHBERR) {
+			txrx = "on rx ";
+			stats->rx_errors++;
+		}
+		netdev_err(dev, "Fatal AHB buss error %s- halting device\n",
+			   txrx);
+
+		spin_lock_irqsave(&priv->lock, flags);
+
+		/* Prevent anything to be enabled again and halt device */
+		priv->closing = true;
+		netif_stop_queue(dev);
+		grcan_stop_hardware(dev);
+		priv->can.state = CAN_STATE_STOPPED;
+
+		spin_unlock_irqrestore(&priv->lock, flags);
+	}
+
+	/* Pass on error frame if something to report,
+	 * i.e. id contains some information
+	 */
+	if (cf.can_id) {
+		struct can_frame *skb_cf;
+		struct sk_buff *skb = alloc_can_err_skb(dev, &skb_cf);
+
+		if (skb == NULL) {
+			netdev_dbg(dev, "could not allocate error frame\n");
+			return;
+		}
+		skb_cf->can_id |= cf.can_id;
+		memcpy(skb_cf->data, cf.data, sizeof(cf.data));
+
+		netif_rx(skb);
+	}
+}
+
+static irqreturn_t grcan_interrupt(int irq, void *dev_id)
+{
+	struct net_device *dev = (struct net_device *)dev_id;
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	u32 sources, status;
+
+	/* Find out the source */
+	sources = grcan_read_reg(&regs->pimsr);
+	if (!sources)
+		return IRQ_NONE;
+	grcan_write_reg(&regs->picr, sources);
+	status = grcan_read_reg(&regs->stat);
+
+	/* If we got TX progress, the device has not hanged,
+	 * so disable the hang timer
+	 */
+	if (priv->need_txbug_workaround &&
+	    (sources & (GRCAN_IRQ_TX | GRCAN_IRQ_TXLOSS))) {
+		del_timer(&priv->hang_timer);
+	}
+
+	/* Frame(s) received or transmitted */
+	if (sources & (GRCAN_IRQ_TX | GRCAN_IRQ_RX)) {
+		/* Disable tx/rx interrupts and schedule poll() */
+		grcan_clear_bits(&regs->imr, GRCAN_IRQ_TX | GRCAN_IRQ_RX);
+		napi_schedule(&priv->napi);
+	}
+
+	/* (Potential) error conditions to take care of */
+	if (sources & GRCAN_IRQ_ERRORS)
+		grcan_err(dev, sources, status);
+
+	return IRQ_HANDLED;
+}
+
+/* Reset device and restart operations from where they were.
+ *
+ * This assumes that RXCTRL & RXCTRL is properly disabled and that RX
+ * is not ONGOING (TX might be stuck in ONGOING due to a harwrware bug
+ * for single shot)
+ */
+static void grcan_running_reset(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *)data;
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	unsigned long flags;
+
+	/* This temporarily messes with eskbp, so we need to lock
+	 * priv->lock
+	 */
+	spin_lock_irqsave(&priv->lock, flags);
+
+	priv->resetting = false;
+	del_timer(&priv->hang_timer);
+	del_timer(&priv->rr_timer);
+
+	if (!priv->closing) {
+		/* Save and reset - config register preserved by grcan_reset */
+		u32 imr = grcan_read_reg(&regs->imr);
+
+		u32 txaddr = grcan_read_reg(&regs->txaddr);
+		u32 txsize = grcan_read_reg(&regs->txsize);
+		u32 txwr = grcan_read_reg(&regs->txwr);
+		u32 txrd = grcan_read_reg(&regs->txrd);
+		u32 eskbp = priv->eskbp;
+
+		u32 rxaddr = grcan_read_reg(&regs->rxaddr);
+		u32 rxsize = grcan_read_reg(&regs->rxsize);
+		u32 rxwr = grcan_read_reg(&regs->rxwr);
+		u32 rxrd = grcan_read_reg(&regs->rxrd);
+
+		grcan_reset(dev);
+
+		/* Restore */
+		grcan_write_reg(&regs->txaddr, txaddr);
+		grcan_write_reg(&regs->txsize, txsize);
+		grcan_write_reg(&regs->txwr, txwr);
+		grcan_write_reg(&regs->txrd, txrd);
+		priv->eskbp = eskbp;
+
+		grcan_write_reg(&regs->rxaddr, rxaddr);
+		grcan_write_reg(&regs->rxsize, rxsize);
+		grcan_write_reg(&regs->rxwr, rxwr);
+		grcan_write_reg(&regs->rxrd, rxrd);
+
+		/* Turn on device again */
+		grcan_write_reg(&regs->imr, imr);
+		priv->can.state = CAN_STATE_ERROR_ACTIVE;
+		grcan_write_reg(&regs->txctrl, GRCAN_TXCTRL_ENABLE
+				| (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT
+				   ? GRCAN_TXCTRL_SINGLE : 0));
+		grcan_write_reg(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+		grcan_write_reg(&regs->ctrl, GRCAN_CTRL_ENABLE);
+
+		/* Start queue if there is size and listen-onle mode is not
+		 * enabled
+		 */
+		if (grcan_txspace(priv->dma.tx.size, txwr, priv->eskbp) &&
+		    !(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
+			netif_wake_queue(dev);
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	netdev_err(dev, "Device reset and restored\n");
+}
+
+/* Waiting time in usecs corresponding to the transmission of three maximum
+ * sized can frames in the given bitrate (in bits/sec). Waiting for this amount
+ * of time makes sure that the can controller have time to finish sending or
+ * receiving a frame with a good margin.
+ *
+ * usecs/sec * number of frames * bits/frame / bits/sec
+ */
+static inline u32 grcan_ongoing_wait_usecs(__u32 bitrate)
+{
+	return 1000000 * 3 * GRCAN_EFF_FRAME_MAX_BITS / bitrate;
+}
+
+/* Set timer so that it will not fire until after a period in which the can
+ * controller have a good margin to finish transmitting a frame unless it has
+ * hanged
+ */
+static inline void grcan_reset_timer(struct timer_list *timer, __u32 bitrate)
+{
+	u32 wait_jiffies = usecs_to_jiffies(grcan_ongoing_wait_usecs(bitrate));
+
+	mod_timer(timer, jiffies + wait_jiffies);
+}
+
+/* Disable channels and schedule a running reset */
+static void grcan_initiate_running_reset(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *)data;
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	unsigned long flags;
+
+	netdev_err(dev, "Device seems hanged - reset scheduled\n");
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	/* The main body of this function must never be executed again
+	 * until after an execution of grcan_running_reset
+	 */
+	if (!priv->resetting && !priv->closing) {
+		priv->resetting = true;
+		netif_stop_queue(dev);
+		grcan_clear_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
+		grcan_clear_bits(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+		grcan_reset_timer(&priv->rr_timer, priv->can.bittiming.bitrate);
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static void grcan_free_dma_buffers(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_dma *dma = &priv->dma;
+
+	dma_free_coherent(&dev->dev, dma->base_size, dma->base_buf,
+			  dma->base_handle);
+	memset(dma, 0, sizeof(*dma));
+}
+
+static int grcan_allocate_dma_buffers(struct net_device *dev,
+				      size_t tsize, size_t rsize)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_dma *dma = &priv->dma;
+	struct grcan_dma_buffer *large = rsize > tsize ? &dma->rx : &dma->tx;
+	struct grcan_dma_buffer *small = rsize > tsize ? &dma->tx : &dma->rx;
+	size_t shift;
+
+	/* Need a whole number of GRCAN_BUFFER_ALIGNMENT for the large,
+	 * i.e. first buffer
+	 */
+	size_t maxs = max(tsize, rsize);
+	size_t lsize = ALIGN(maxs, GRCAN_BUFFER_ALIGNMENT);
+
+	/* Put the small buffer after that */
+	size_t ssize = min(tsize, rsize);
+
+	/* Extra GRCAN_BUFFER_ALIGNMENT to allow for alignment */
+	dma->base_size = lsize + ssize + GRCAN_BUFFER_ALIGNMENT;
+	dma->base_buf = dma_alloc_coherent(&dev->dev,
+					   dma->base_size,
+					   &dma->base_handle,
+					   GFP_KERNEL);
+
+	if (!dma->base_buf)
+		return -ENOMEM;
+
+	dma->tx.size = tsize;
+	dma->rx.size = rsize;
+
+	large->handle = ALIGN(dma->base_handle, GRCAN_BUFFER_ALIGNMENT);
+	small->handle = large->handle + lsize;
+	shift = large->handle - dma->base_handle;
+
+	large->buf = dma->base_buf + shift;
+	small->buf = large->buf + lsize;
+
+	return 0;
+}
+
+/* priv->lock *must* be held when calling this function */
+static int grcan_start(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	u32 confop, txctrl;
+
+	grcan_reset(dev);
+
+	grcan_write_reg(&regs->txaddr, priv->dma.tx.handle);
+	grcan_write_reg(&regs->txsize, priv->dma.tx.size);
+	/* regs->txwr, regs->txrd and priv->eskbp already set to 0 by reset */
+
+	grcan_write_reg(&regs->rxaddr, priv->dma.rx.handle);
+	grcan_write_reg(&regs->rxsize, priv->dma.rx.size);
+	/* regs->rxwr and regs->rxrd already set to 0 by reset */
+
+	/* Enable interrupts */
+	grcan_read_reg(&regs->pir);
+	grcan_write_reg(&regs->imr, GRCAN_IRQ_DEFAULT);
+
+	/* Enable interfaces, channels and device */
+	confop = GRCAN_CONF_ABORT
+		| (priv->config.enable0 ? GRCAN_CONF_ENABLE0 : 0)
+		| (priv->config.enable1 ? GRCAN_CONF_ENABLE1 : 0)
+		| (priv->config.select ? GRCAN_CONF_SELECT : 0)
+		| (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY ?
+		   GRCAN_CONF_SILENT : 0)
+		| (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES ?
+		   GRCAN_CONF_SAM : 0);
+	grcan_write_bits(&regs->conf, confop, GRCAN_CONF_OPERATION);
+	txctrl = GRCAN_TXCTRL_ENABLE
+		| (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT
+		   ? GRCAN_TXCTRL_SINGLE : 0);
+	grcan_write_reg(&regs->txctrl, txctrl);
+	grcan_write_reg(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+	grcan_write_reg(&regs->ctrl, GRCAN_CTRL_ENABLE);
+
+	priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+	return 0;
+}
+
+static int grcan_set_mode(struct net_device *dev, enum can_mode mode)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+	int err = 0;
+
+	if (mode == CAN_MODE_START) {
+		/* This might be called to restart the device to recover from
+		 * bus off errors
+		 */
+		spin_lock_irqsave(&priv->lock, flags);
+		if (priv->closing || priv->resetting) {
+			err = -EBUSY;
+		} else {
+			netdev_info(dev, "Restarting device\n");
+			grcan_start(dev);
+			if (!(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
+				netif_wake_queue(dev);
+		}
+		spin_unlock_irqrestore(&priv->lock, flags);
+		return err;
+	}
+	return -EOPNOTSUPP;
+}
+
+static int grcan_open(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_dma *dma = &priv->dma;
+	unsigned long flags;
+	int err;
+
+	/* Allocate memory */
+	if (GRCAN_INVALID_BUFFER_SIZE(priv->config.txsize) ||
+	    GRCAN_INVALID_BUFFER_SIZE(priv->config.rxsize)) {
+		/* Should never be able go this far with invalid sizes */
+		netdev_err(dev, "Invalid buffer size pair 0x%x 0x%x\n",
+			   priv->config.txsize, priv->config.rxsize);
+		return -EINVAL;
+	}
+	err = grcan_allocate_dma_buffers(dev, priv->config.txsize,
+					 priv->config.rxsize);
+	if (err) {
+		netdev_err(dev, "could not allocate DMA buffers\n");
+		return err;
+	}
+
+	priv->echo_skb = devm_kzalloc(&dev->dev,
+				      dma->tx.size * sizeof(*priv->echo_skb),
+				      GFP_KERNEL);
+	if (!priv->echo_skb) {
+		err = -ENOMEM;
+		goto exit_free_dma_buffers;
+	}
+	priv->can.echo_skb_max = dma->tx.size;
+	priv->can.echo_skb = priv->echo_skb;
+
+	priv->txdlc = devm_kzalloc(&dev->dev,
+				   dma->tx.size * sizeof(*priv->txdlc),
+				   GFP_KERNEL);
+	if (!priv->txdlc) {
+		err = -ENOMEM;
+		goto exit_free_echo_skb;
+	}
+
+	/* Get can device up */
+	err = open_candev(dev);
+	if (err)
+		goto exit_free_txdlc;
+
+	err = devm_request_irq(&dev->dev, dev->irq, grcan_interrupt,
+			       IRQF_SHARED, dev->name, (void *)dev);
+	if (err)
+		goto exit_close_candev;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	grcan_start(dev);
+	napi_enable(&priv->napi);
+	if (!(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
+		netif_start_queue(dev);
+	priv->resetting = false;
+	priv->closing = false;
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return 0;
+
+exit_close_candev:
+	close_candev(dev);
+exit_free_txdlc:
+	devm_kfree(&dev->dev, priv->txdlc);
+exit_free_echo_skb:
+	devm_kfree(&dev->dev, priv->echo_skb);
+exit_free_dma_buffers:
+	grcan_free_dma_buffers(dev);
+	return err;
+}
+
+static int grcan_close(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+
+	napi_disable(&priv->napi);
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	priv->closing = true;
+	if (priv->need_txbug_workaround) {
+		del_timer_sync(&priv->hang_timer);
+		del_timer_sync(&priv->rr_timer);
+	}
+	netif_stop_queue(dev);
+	grcan_stop_hardware(dev);
+	priv->can.state = CAN_STATE_STOPPED;
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	devm_free_irq(&dev->dev, dev->irq, (void *)dev);
+	close_candev(dev);
+
+	grcan_free_dma_buffers(dev);
+	priv->can.echo_skb_max = 0;
+	priv->can.echo_skb = NULL;
+	devm_kfree(&dev->dev, priv->echo_skb);
+	devm_kfree(&dev->dev, priv->txdlc);
+
+	return 0;
+}
+
+static int grcan_transmit_catch_up(struct net_device *dev, int budget)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+	int work_done;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	work_done = catch_up_echo_skb(dev, budget, true);
+	if (work_done) {
+		if (!priv->resetting && !priv->closing &&
+		    !(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
+			netif_wake_queue(dev);
+
+		/* With napi we don't get TX interrupts for a while,
+		 * so prevent a running reset while catching up
+		 */
+		if (priv->need_txbug_workaround)
+			del_timer(&priv->hang_timer);
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return work_done;
+}
+
+static int grcan_receive(struct net_device *dev, int budget)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	struct net_device_stats *stats = &dev->stats;
+	struct can_frame *cf;
+	struct sk_buff *skb;
+	u32 wr, rd, startrd;
+	u32 *slot;
+	u32 i, rtr, eff, j, shift;
+	int work_done = 0;
+
+	rd = grcan_read_reg(&regs->rxrd);
+	startrd = rd;
+	for (work_done = 0; work_done < budget; work_done++) {
+		/* Check for packet to receive */
+		wr = grcan_read_reg(&regs->rxwr);
+		if (rd == wr)
+			break;
+
+		/* Take care of packet */
+		skb = alloc_can_skb(dev, &cf);
+		if (skb == NULL) {
+			netdev_err(dev,
+				   "dropping frame: skb allocation failed\n");
+			stats->rx_dropped++;
+			continue;
+		}
+
+		slot = dma->rx.buf + rd;
+		eff = slot[0] & GRCAN_MSG_IDE;
+		rtr = slot[0] & GRCAN_MSG_RTR;
+		if (eff) {
+			cf->can_id = ((slot[0] & GRCAN_MSG_EID)
+				      >> GRCAN_MSG_EID_BIT);
+			cf->can_id |= CAN_EFF_FLAG;
+		} else {
+			cf->can_id = ((slot[0] & GRCAN_MSG_BID)
+				      >> GRCAN_MSG_BID_BIT);
+		}
+		cf->can_dlc = get_can_dlc((slot[1] & GRCAN_MSG_DLC)
+					  >> GRCAN_MSG_DLC_BIT);
+		if (rtr) {
+			cf->can_id |= CAN_RTR_FLAG;
+		} else {
+			for (i = 0; i < cf->can_dlc; i++) {
+				j = GRCAN_MSG_DATA_SLOT_INDEX(i);
+				shift = GRCAN_MSG_DATA_SHIFT(i);
+				cf->data[i] = (u8)((slot[j] >> shift) & 0xff);
+			}
+		}
+		netif_receive_skb(skb);
+
+		/* Update statistics and read pointer */
+		stats->rx_packets++;
+		stats->rx_bytes += cf->can_dlc;
+		rd = grcan_ring_add(rd, GRCAN_MSG_SIZE, dma->rx.size);
+	}
+
+	/* Make sure everything is read before allowing hardware to
+	 * use the memory
+	 */
+	mb();
+
+	/* Update read pointer - no need to check for ongoing */
+	if (likely(rd != startrd))
+		grcan_write_reg(&regs->rxrd, rd);
+
+	return work_done;
+}
+
+static int grcan_poll(struct napi_struct *napi, int budget)
+{
+	struct grcan_priv *priv = container_of(napi, struct grcan_priv, napi);
+	struct net_device *dev = priv->dev;
+	struct grcan_registers __iomem *regs = priv->regs;
+	int rx_work_done = grcan_receive(dev, budget);
+	int tx_work_done = grcan_transmit_catch_up(dev, budget);
+
+	if (rx_work_done < budget && tx_work_done < budget) {
+		napi_complete(napi);
+		/* Enable tx and rx interrupts again */
+		if (!priv->closing)
+			grcan_set_bits(&regs->imr, GRCAN_IRQ_TX | GRCAN_IRQ_RX);
+	}
+	return rx_work_done;
+}
+
+/* Work tx bug by waiting while for the risky situation to clear. If that fails,
+ * drop a frame in one-shot mode or indicate a busy device otherwise.
+ *
+ * Returns 0 on successful wait. Otherwise it sets *netdev_tx_status to the
+ * value that should be returned by grcan_start_xmit when aborting the xmit.
+ */
+static int grcan_txbug_workaround(struct net_device *dev, struct sk_buff *skb,
+				  u32 txwr, u32 oneshotmode,
+				  netdev_tx_t *netdev_tx_status)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	int i;
+	unsigned long flags;
+
+	/* Wait a while for ongoing to be cleared or read pointer to catch up to
+	 * write pointer. The latter is needed due to a bug in older versions of
+	 * GRCAN in which ONGOING is not cleared properly one-shot mode when a
+	 * transmission fails.
+	 */
+	for (i = 0; i < GRCAN_SHORTWAIT_USECS; i++) {
+		udelay(1);
+		if (!grcan_read_bits(&regs->txctrl, GRCAN_TXCTRL_ONGOING) ||
+		    grcan_read_reg(&regs->txrd) == txwr) {
+			return 0;
+		}
+	}
+
+	/* Clean up, in case the situation was not resolved */
+	spin_lock_irqsave(&priv->lock, flags);
+	if (!priv->resetting && !priv->closing) {
+		/* Queue might have been stopped earlier in grcan_start_xmit */
+		if (grcan_txspace(dma->tx.size, txwr, priv->eskbp))
+			netif_wake_queue(dev);
+		/* Set a timer to resolve a hanged tx controller */
+		if (!timer_pending(&priv->hang_timer))
+			grcan_reset_timer(&priv->hang_timer,
+					  priv->can.bittiming.bitrate);
+	}
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	if (oneshotmode) {
+		/* In one-shot mode we should never end up here because
+		 * then the interrupt handler increases txrd on TXLOSS,
+		 * but it is consistent with one-shot mode to drop the
+		 * frame in this case.
+		 */
+		kfree_skb(skb);
+		*netdev_tx_status = NETDEV_TX_OK;
+	} else {
+		/* In normal mode the socket-can transmission queue get
+		 * to keep the frame so that it can be retransmitted
+		 * later
+		 */
+		*netdev_tx_status = NETDEV_TX_BUSY;
+	}
+	return -EBUSY;
+}
+
+/* Notes on the tx cyclic buffer handling:
+ *
+ * regs->txwr	- the next slot for the driver to put data to be sent
+ * regs->txrd	- the next slot for the device to read data
+ * priv->eskbp	- the next slot for the driver to call can_put_echo_skb for
+ *
+ * grcan_start_xmit can enter more messages as long as regs->txwr does
+ * not reach priv->eskbp (within 1 message gap)
+ *
+ * The device sends messages until regs->txrd reaches regs->txwr
+ *
+ * The interrupt calls handler calls can_put_echo_skb until
+ * priv->eskbp reaches regs->txrd
+ */
+static netdev_tx_t grcan_start_xmit(struct sk_buff *skb,
+				    struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	struct can_frame *cf = (struct can_frame *)skb->data;
+	u32 id, txwr, txrd, space, txctrl;
+	int slotindex;
+	u32 *slot;
+	u32 i, rtr, eff, dlc, tmp, err;
+	int j, shift;
+	unsigned long flags;
+	u32 oneshotmode = priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT;
+
+	if (can_dropped_invalid_skb(dev, skb))
+		return NETDEV_TX_OK;
+
+	/* Trying to transmit in silent mode will generate error interrupts, but
+	 * this should never happen - the queue should not have been started.
+	 */
+	if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
+		return NETDEV_TX_BUSY;
+
+	/* Reads of priv->eskbp and shut-downs of the queue needs to
+	 * be atomic towards the updates to priv->eskbp and wake-ups
+	 * of the queue in the interrupt handler.
+	 */
+	spin_lock_irqsave(&priv->lock, flags);
+
+	txwr = grcan_read_reg(&regs->txwr);
+	space = grcan_txspace(dma->tx.size, txwr, priv->eskbp);
+
+	slotindex = txwr / GRCAN_MSG_SIZE;
+	slot = dma->tx.buf + txwr;
+
+	if (unlikely(space == 1))
+		netif_stop_queue(dev);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+	/* End of critical section*/
+
+	/* This should never happen. If circular buffer is full, the
+	 * netif_stop_queue should have been stopped already.
+	 */
+	if (unlikely(!space)) {
+		netdev_err(dev, "No buffer space, but queue is non-stopped.\n");
+		return NETDEV_TX_BUSY;
+	}
+
+	/* Convert and write CAN message to DMA buffer */
+	eff = cf->can_id & CAN_EFF_FLAG;
+	rtr = cf->can_id & CAN_RTR_FLAG;
+	id = cf->can_id & (eff ? CAN_EFF_MASK : CAN_SFF_MASK);
+	dlc = cf->can_dlc;
+	if (eff)
+		tmp = (id << GRCAN_MSG_EID_BIT) & GRCAN_MSG_EID;
+	else
+		tmp = (id << GRCAN_MSG_BID_BIT) & GRCAN_MSG_BID;
+	slot[0] = (eff ? GRCAN_MSG_IDE : 0) | (rtr ? GRCAN_MSG_RTR : 0) | tmp;
+
+	slot[1] = ((dlc << GRCAN_MSG_DLC_BIT) & GRCAN_MSG_DLC);
+	slot[2] = 0;
+	slot[3] = 0;
+	for (i = 0; i < dlc; i++) {
+		j = GRCAN_MSG_DATA_SLOT_INDEX(i);
+		shift = GRCAN_MSG_DATA_SHIFT(i);
+		slot[j] |= cf->data[i] << shift;
+	}
+
+	/* Checking that channel has not been disabled. These cases
+	 * should never happen
+	 */
+	txctrl = grcan_read_reg(&regs->txctrl);
+	if (!(txctrl & GRCAN_TXCTRL_ENABLE))
+		netdev_err(dev, "tx channel spuriously disabled\n");
+
+	if (oneshotmode && !(txctrl & GRCAN_TXCTRL_SINGLE))
+		netdev_err(dev, "one-shot mode spuriously disabled\n");
+
+	/* Bug workaround for old version of grcan where updating txwr
+	 * in the same clock cycle as the controller updates txrd to
+	 * the current txwr could hang the can controller
+	 */
+	if (priv->need_txbug_workaround) {
+		txrd = grcan_read_reg(&regs->txrd);
+		if (unlikely(grcan_ring_sub(txwr, txrd, dma->tx.size) == 1)) {
+			netdev_tx_t txstatus;
+
+			err = grcan_txbug_workaround(dev, skb, txwr,
+						     oneshotmode, &txstatus);
+			if (err)
+				return txstatus;
+		}
+	}
+
+	/* Prepare skb for echoing. This must be after the bug workaround above
+	 * as ownership of the skb is passed on by calling can_put_echo_skb.
+	 * Returning NETDEV_TX_BUSY or accessing skb or cf after a call to
+	 * can_put_echo_skb would be an error unless other measures are
+	 * taken.
+	 */
+	priv->txdlc[slotindex] = cf->can_dlc; /* Store dlc for statistics */
+	can_put_echo_skb(skb, dev, slotindex);
+
+	/* Make sure everything is written before allowing hardware to
+	 * read from the memory
+	 */
+	wmb();
+
+	/* Update write pointer to start transmission */
+	grcan_write_reg(&regs->txwr,
+			grcan_ring_add(txwr, GRCAN_MSG_SIZE, dma->tx.size));
+
+	return NETDEV_TX_OK;
+}
+
+/* ========== Setting up sysfs interface and module parameters ========== */
+
+#define GRCAN_NOT_BOOL(val) ((val) < 0 || (val) > 1)
+
+#define GRCAN_MODULE_PARAM(name, mtype, valcheckf)			\
+	static void grcan_sanitize_##name(struct platform_device *pd)	\
+	{								\
+		struct grcan_device_config grcan_default_config		\
+			= GRCAN_DEFAULT_DEVICE_CONFIG;			\
+		if (valcheckf(grcan_module_config.name)) {		\
+			dev_err(&pd->dev,				\
+				"Invalid module parameter value for "	\
+				#name " - setting default\n");		\
+			grcan_module_config.name =			\
+				grcan_default_config.name;		\
+		}							\
+	}								\
+	module_param_named(name, grcan_module_config.name,		\
+			   mtype, S_IRUGO)
+
+#define GRCAN_CONFIG_ATTR(name)						\
+	static ssize_t grcan_store_##name(struct device *sdev,		\
+					  struct device_attribute *att,	\
+					  const char *buf,		\
+					  size_t count)			\
+	{								\
+		struct net_device *dev = to_net_dev(sdev);		\
+		struct grcan_priv *priv = netdev_priv(dev);		\
+		u8 val;							\
+		int ret;						\
+		if (dev->flags & IFF_UP)				\
+			return -EBUSY;					\
+		ret = kstrtou8(buf, 0, &val);				\
+		if (ret < 0 || val < 0 || val > 1)			\
+			return -EINVAL;					\
+		priv->config.name = val;				\
+		return count;						\
+	}								\
+	static ssize_t grcan_show_##name(struct device *sdev,		\
+					 struct device_attribute *att,	\
+					 char *buf)			\
+	{								\
+		struct net_device *dev = to_net_dev(sdev);		\
+		struct grcan_priv *priv = netdev_priv(dev);		\
+		return sprintf(buf, "%d\n", priv->config.name);		\
+	}								\
+	static DEVICE_ATTR(name, S_IRUGO | S_IWUSR,			\
+			   grcan_show_##name,				\
+			   grcan_store_##name);				\
+	GRCAN_MODULE_PARAM(name, ushort, GRCAN_NOT_BOOL)
+
+/* The following configuration options are made available both via module
+ * parameters and writable sysfs files. See the chapter about GRCAN in the
+ * documentation for the GRLIB VHDL library for further details.
+ */
+
+/* Configure enable0 - Hardware configuration for interface 0 */
+GRCAN_CONFIG_ATTR(enable0);
+
+/* Configure enable1 - Hardware configuration for interface 1 */
+GRCAN_CONFIG_ATTR(enable1);
+
+/* Configure select - Select which interface to use */
+GRCAN_CONFIG_ATTR(select);
+
+/* The tx and rx buffer size configuration options are only available via module
+ * parameters.
+ */
+GRCAN_MODULE_PARAM(txsize, uint, GRCAN_INVALID_BUFFER_SIZE);
+GRCAN_MODULE_PARAM(rxsize, uint, GRCAN_INVALID_BUFFER_SIZE);
+
+/* Function that makes sure that configuration done using
+ * module parameters are set to valid values
+ */
+static void grcan_sanitize_module_config(struct platform_device *ofdev)
+{
+	grcan_sanitize_enable0(ofdev);
+	grcan_sanitize_enable1(ofdev);
+	grcan_sanitize_select(ofdev);
+	grcan_sanitize_txsize(ofdev);
+	grcan_sanitize_rxsize(ofdev);
+}
+
+static const struct attribute *const sysfs_grcan_attrs[] = {
+	/* Config attrs */
+	&dev_attr_enable0.attr,
+	&dev_attr_enable1.attr,
+	&dev_attr_select.attr,
+	NULL,
+};
+
+static const struct attribute_group sysfs_grcan_group = {
+	.name	= "grcan",
+	.attrs	= (struct attribute **)sysfs_grcan_attrs,
+};
+
+/* ========== Setting up the driver ========== */
+
+static const struct net_device_ops grcan_netdev_ops = {
+	.ndo_open	= grcan_open,
+	.ndo_stop	= grcan_close,
+	.ndo_start_xmit	= grcan_start_xmit,
+};
+
+static int grcan_setup_netdev(struct platform_device *ofdev,
+			      void __iomem *base,
+			      int irq, u32 ambafreq, bool txbug)
+{
+	struct net_device *dev;
+	struct grcan_priv *priv;
+	struct grcan_registers __iomem *regs;
+	int err;
+
+	dev = alloc_candev(sizeof(struct grcan_priv), 0);
+	if (!dev)
+		return -ENOMEM;
+
+	dev->irq = irq;
+	dev->flags |= IFF_ECHO;
+	dev->netdev_ops = &grcan_netdev_ops;
+	dev->sysfs_groups[0] = &sysfs_grcan_group;
+
+	priv = netdev_priv(dev);
+	memcpy(&priv->config, &grcan_module_config,
+	       sizeof(struct grcan_device_config));
+	priv->dev = dev;
+	priv->regs = (struct grcan_registers *)base;
+	priv->can.bittiming_const = &grcan_bittiming_const;
+	priv->can.do_set_bittiming = grcan_set_bittiming;
+	priv->can.do_set_mode = grcan_set_mode;
+	priv->can.do_get_berr_counter = grcan_get_berr_counter;
+	priv->can.clock.freq = ambafreq;
+	priv->can.ctrlmode_supported =
+		CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_ONE_SHOT;
+	priv->need_txbug_workaround = txbug;
+
+	/* Discover if triple sampling is supported by hardware */
+	regs = priv->regs;
+	grcan_set_bits(&regs->ctrl, GRCAN_CTRL_RESET);
+	grcan_set_bits(&regs->conf, GRCAN_CONF_SAM);
+	if (grcan_read_bits(&regs->conf, GRCAN_CONF_SAM)) {
+		priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES;
+		dev_info(&ofdev->dev, "Hardware supports triple-sampling\n");
+	}
+
+	spin_lock_init(&priv->lock);
+
+	if (priv->need_txbug_workaround) {
+		init_timer(&priv->rr_timer);
+		priv->rr_timer.function = grcan_running_reset;
+		priv->rr_timer.data = (unsigned long)dev;
+
+		init_timer(&priv->hang_timer);
+		priv->hang_timer.function = grcan_initiate_running_reset;
+		priv->hang_timer.data = (unsigned long)dev;
+	}
+
+	netif_napi_add(dev, &priv->napi, grcan_poll, GRCAN_NAPI_WEIGHT);
+
+	SET_NETDEV_DEV(dev, &ofdev->dev);
+	dev_info(&ofdev->dev, "regs=0x%p, irq=%d, clock=%d\n",
+		 priv->regs, dev->irq, priv->can.clock.freq);
+
+	err = register_candev(dev);
+	if (err) {
+		dev_err(&ofdev->dev, "registering %s failed (err=%d)\n",
+			DRV_NAME, err);
+		goto exit_free_candev;
+	}
+	dev_set_drvdata(&ofdev->dev, dev);
+
+	/* Reset device to allow bit-timing to be set. No need to call
+	 * grcan_reset at this stage. That is done in grcan_open.
+	 */
+	grcan_write_reg(&regs->ctrl, GRCAN_CTRL_RESET);
+
+	return 0;
+exit_free_candev:
+	free_candev(dev);
+	return err;
+}
+
+static int __devinit grcan_probe(struct platform_device *ofdev)
+{
+	struct device_node *np = ofdev->dev.of_node;
+	struct resource *res;
+	u32 sysid, ambafreq;
+	int irq, err;
+	void __iomem *base;
+	bool txbug = true;
+
+	/* Compare GRLIB version number with the first that does not
+	 * have the tx bug (see start_xmit)
+	 */
+	err = of_property_read_u32(np, "systemid", &sysid);
+	if (!err && ((sysid & GRLIB_VERSION_MASK)
+		     >= GRCAN_TXBUG_SAFE_GRLIB_VERSION))
+		txbug = false;
+
+	err = of_property_read_u32(np, "freq", &ambafreq);
+	if (err) {
+		dev_err(&ofdev->dev, "unable to fetch \"freq\" property\n");
+		goto exit_error;
+	}
+
+	res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
+	base = devm_request_and_ioremap(&ofdev->dev, res);
+	if (!base) {
+		dev_err(&ofdev->dev, "couldn't map IO resource\n");
+		err = -EADDRNOTAVAIL;
+		goto exit_error;
+	}
+
+	irq = irq_of_parse_and_map(np, GRCAN_IRQIX_IRQ);
+	if (irq == NO_IRQ) {
+		dev_err(&ofdev->dev, "no irq found\n");
+		err = -ENODEV;
+		goto exit_error;
+	}
+
+	grcan_sanitize_module_config(ofdev);
+
+	err = grcan_setup_netdev(ofdev, base, irq, ambafreq, txbug);
+	if (err)
+		goto exit_dispose_irq;
+
+	return 0;
+
+exit_dispose_irq:
+	irq_dispose_mapping(irq);
+exit_error:
+	dev_err(&ofdev->dev,
+		"%s socket CAN driver initialization failed with error %d\n",
+		DRV_NAME, err);
+	return err;
+}
+
+static int __devexit grcan_remove(struct platform_device *ofdev)
+{
+	struct net_device *dev = dev_get_drvdata(&ofdev->dev);
+	struct grcan_priv *priv = netdev_priv(dev);
+
+	unregister_candev(dev); /* Will in turn call grcan_close */
+
+	irq_dispose_mapping(dev->irq);
+	dev_set_drvdata(&ofdev->dev, NULL);
+	netif_napi_del(&priv->napi);
+	free_candev(dev);
+
+	dev_info(&ofdev->dev, "%s socket CAN driver removed\n", DRV_NAME);
+	return 0;
+}
+
+static struct of_device_id grcan_match[] = {
+	{.name = "GAISLER_GRCAN"},
+	{.name = "01_03d"},
+	{.name = "GAISLER_GRHCAN"},
+	{.name = "01_034"},
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, grcan_match);
+
+static struct platform_driver grcan_driver = {
+	.driver = {
+		.name = DRV_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = grcan_match,
+	},
+	.probe = grcan_probe,
+	.remove = __devexit_p(grcan_remove),
+};
+
+module_platform_driver(grcan_driver);
+
+MODULE_AUTHOR("Aeroflex Gaisler AB.");
+MODULE_DESCRIPTION("Socket CAN driver for Aeroflex Gaisler GRCAN");
+MODULE_LICENSE("GPL");
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* Re: [PATCH v7] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-11-08 13:10                                         ` [PATCH v7] " Andreas Larsson
@ 2012-11-09  0:01                                           ` Marc Kleine-Budde
  2012-11-12 14:57                                             ` [PATCH v8] " Andreas Larsson
  0 siblings, 1 reply; 41+ messages in thread
From: Marc Kleine-Budde @ 2012-11-09  0:01 UTC (permalink / raw)
  To: Andreas Larsson
  Cc: linux-can, software, Wolfgang Grandegger, devicetree-discuss

[-- Attachment #1: Type: text/plain, Size: 65687 bytes --]

On 11/08/2012 02:10 PM, Andreas Larsson wrote:
> This driver supports GRCAN and CRHCAN CAN controllers available in the GRLIB
> VHDL IP core library.
> 
> Signed-off-by: Andreas Larsson <andreas@gaisler.com>
> Acked-by: Wolfgang Grandegger <wg@grandegger.com>

sparse finds these errors:

drivers/net/can/grcan.c:1581:23:
	warning: cast removes address space of expression
drivers/net/can/grcan.c:1581:20:
	warning: incorrect type in assignment (different address spaces)
drivers/net/can/grcan.c:1581:20:
	expected struct grcan_registers [noderef] <asn:2>*regs
drivers/net/can/grcan.c:1581:20:
	got struct grcan_registers *<noident>

More comments inline.

Marc

> ---
> Changes since v6: bittiming parameter checks, variable/constant renames, comment edits
> 
>  Documentation/ABI/testing/sysfs-class-net-grcan    |   35 +
>  .../devicetree/bindings/net/can/grcan.txt          |   28 +
>  Documentation/kernel-parameters.txt                |   18 +
>  drivers/net/can/Kconfig                            |    9 +
>  drivers/net/can/Makefile                           |    1 +
>  drivers/net/can/grcan.c                            | 1732 ++++++++++++++++++++
>  6 files changed, 1823 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/ABI/testing/sysfs-class-net-grcan
>  create mode 100644 Documentation/devicetree/bindings/net/can/grcan.txt
>  create mode 100644 drivers/net/can/grcan.c
> 
> diff --git a/Documentation/ABI/testing/sysfs-class-net-grcan b/Documentation/ABI/testing/sysfs-class-net-grcan
> new file mode 100644
> index 0000000..f418c92
> --- /dev/null
> +++ b/Documentation/ABI/testing/sysfs-class-net-grcan
> @@ -0,0 +1,35 @@
> +
> +What:		/sys/class/net/<iface>/grcan/enable0
> +Date:		October 2012
> +KernelVersion:	3.8
> +Contact:	Andreas Larsson <andreas@gaisler.com>
> +Description:
> +		Hardware configuration of physical interface 0. This file reads
> +		and writes the "Enable 0" bit of the configuration register.
> +		Possible values: 0 or 1. See the GRCAN chapter of the GRLIB IP
> +		core library documentation for details. The default value is 0
> +		or set by the module parameter grcan.enable0 and can be read at
> +		/sys/module/grcan/parameters/enable0.
> +
> +What:		/sys/class/net/<iface>/grcan/enable1
> +Date:		October 2012
> +KernelVersion:	3.8
> +Contact:	Andreas Larsson <andreas@gaisler.com>
> +Description:
> +		Hardware configuration of physical interface 1. This file reads
> +		and writes the "Enable 1" bit of the configuration register.
> +		Possible values: 0 or 1. See the GRCAN chapter of the GRLIB IP
> +		core library documentation for details. The default value is 0
> +		or set by the module parameter grcan.enable1 and can be read at
> +		/sys/module/grcan/parameters/enable1.
> +
> +What:		/sys/class/net/<iface>/grcan/select
> +Date:		October 2012
> +KernelVersion:	3.8
> +Contact:	Andreas Larsson <andreas@gaisler.com>
> +Description:
> +		Configuration of which physical interface to be used. Possible
> +		values: 0 or 1. See the GRCAN chapter of the GRLIB IP core
> +		library documentation for details. The default value is 0 or is
> +		set by the module parameter grcan.select and can be read at
> +		/sys/module/grcan/parameters/select.
> diff --git a/Documentation/devicetree/bindings/net/can/grcan.txt b/Documentation/devicetree/bindings/net/can/grcan.txt
> new file mode 100644
> index 0000000..34ef349
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/can/grcan.txt
> @@ -0,0 +1,28 @@
> +Aeroflex Gaisler GRCAN and GRHCAN CAN controllers.
> +
> +The GRCAN and CRHCAN CAN controllers are available in the GRLIB VHDL IP core
> +library.
> +
> +Note: These properties are built from the AMBA plug&play in a Leon SPARC system
> +(the ordinary environment for GRCAN and GRHCAN). There are no dts files for
> +sparc.
> +
> +Required properties:
> +
> +- name : Should be "GAISLER_GRCAN", "01_03d", "GAISLER_GRHCAN" or "01_034"
> +
> +- reg : Address and length of the register set for the device
> +
> +- freq : Frequency of the external oscillator clock in Hz (the frequency of
> +	the amba bus in the ordinary case)
> +
> +- interrupts : Interrupt number for this device
> +
> +Optional properties:
> +
> +- systemid : If not present or if the value of the least significant 16 bits
> +	of this 32-bit property is smaller than GRCAN_TXBUG_SAFE_GRLIB_VERSION
> +	a bug workaround is activated.
> +
> +For further information look in the documentation for the GLIB IP core library:
> +http://www.gaisler.com/products/grlib/grip.pdf
> diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
> index 9776f06..3da4f96 100644
> --- a/Documentation/kernel-parameters.txt
> +++ b/Documentation/kernel-parameters.txt
> @@ -905,6 +905,24 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
>  	gpt		[EFI] Forces disk with valid GPT signature but
>  			invalid Protective MBR to be treated as GPT.
>  
> +	grcan.enable0=	[HW] Configuration of physical interface 0. Determines
> +			the "Enable 0" bit of the configuration register.
> +			Format: 0 | 1
> +			Default: 0
> +	grcan.enable1=	[HW] Configuration of physical interface 1. Determines
> +			the "Enable 0" bit of the configuration register.
> +			Format: 0 | 1
> +			Default: 0
> +	grcan.select=	[HW] Select which physical interface to use.
> +			Format: 0 | 1
> +			Default: 0
> +	grcan.txsize=	[HW] Sets the size of the tx buffer.
> +			Format: <unsigned int> such that (txsize & ~0x1fffc0) == 0.
> +			Default: 1024
> +	grcan.rxsize=	[HW] Sets the size of the rx buffer.
> +			Format: <unsigned int> such that (rxsize & ~0x1fffc0) == 0.
> +			Default: 1024
> +
>  	hashdist=	[KNL,NUMA] Large hashes allocated during boot
>  			are distributed across NUMA nodes.  Defaults on
>  			for 64-bit NUMA, off otherwise.
> diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
> index bb709fd..b56bd9e 100644
> --- a/drivers/net/can/Kconfig
> +++ b/drivers/net/can/Kconfig
> @@ -110,6 +110,15 @@ config PCH_CAN
>  	  is an IOH for x86 embedded processor (Intel Atom E6xx series).
>  	  This driver can access CAN bus.
>  
> +config CAN_GRCAN
> +	tristate "Aeroflex Gaisler GRCAN and GRHCAN CAN devices"
> +	depends on CAN_DEV && OF
> +	---help---
> +	  Say Y here if you want to use Aeroflex Gaisler GRCAN or GRHCAN.
> +	  Note that the driver supports little endian, even though little
> +	  endian syntheses of the cores would need some modifications on
> +	  the hardware level to work.
> +
>  source "drivers/net/can/mscan/Kconfig"
>  
>  source "drivers/net/can/sja1000/Kconfig"
> diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
> index 938be37..7de5986 100644
> --- a/drivers/net/can/Makefile
> +++ b/drivers/net/can/Makefile
> @@ -22,5 +22,6 @@ obj-$(CONFIG_CAN_BFIN)		+= bfin_can.o
>  obj-$(CONFIG_CAN_JANZ_ICAN3)	+= janz-ican3.o
>  obj-$(CONFIG_CAN_FLEXCAN)	+= flexcan.o
>  obj-$(CONFIG_PCH_CAN)		+= pch_can.o
> +obj-$(CONFIG_CAN_GRCAN)		+= grcan.o
>  
>  ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
> diff --git a/drivers/net/can/grcan.c b/drivers/net/can/grcan.c
> new file mode 100644
> index 0000000..2cabf78
> --- /dev/null
> +++ b/drivers/net/can/grcan.c
> @@ -0,0 +1,1732 @@
> +/*
> + * Socket CAN driver for Aeroflex Gaisler GRCAN and GRHCAN.
> + *
> + * 2012 (c) Aeroflex Gaisler AB
> + *
> + * This driver supports GRCAN and GRHCAN CAN controllers available in the GRLIB
> + * VHDL IP core library.
> + *
> + * Full documentation of the GRCAN core can be found here:
> + * http://www.gaisler.com/products/grlib/grip.pdf
> + *
> + * See "Documentation/devicetree/bindings/net/can/grcan.txt" for information on
> + * open firmware properties.
> + *
> + * See "Documentation/ABI/testing/sysfs-class-net-grcan" for information on the
> + * sysfs interface.
> + *
> + * See "Documentation/kernel-parameters.txt" for information on the module
> + * parameters.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as published by the
> + * Free Software Foundation; either version 2 of the License, or (at your
> + * option) any later version.
> + *
> + * Contributors: Andreas Larsson <andreas@gaisler.com>
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/interrupt.h>
> +#include <linux/netdevice.h>
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/can/dev.h>
> +#include <linux/spinlock.h>
> +
> +#include <linux/of_platform.h>
> +#include <asm/prom.h>
> +
> +#include <linux/of_irq.h>
> +
> +#include <linux/dma-mapping.h>
> +
> +#define DRV_NAME	"grcan"
> +
> +#define GRCAN_NAPI_WEIGHT	16
> +
> +#define GRCAN_RESERVE_SIZE(slot1, slot2) (((slot2) - (slot1)) / 4 - 1)
> +
> +struct grcan_registers {
> +	u32 conf;	/* 0x00 */
> +	u32 stat;	/* 0x04 */
> +	u32 ctrl;	/* 0x08 */
> +	u32 __reserved1[GRCAN_RESERVE_SIZE(0x08, 0x18)];
> +	u32 smask;	/* 0x18 - CanMASK */
> +	u32 scode;	/* 0x1c - CanCODE */
> +	u32 __reserved2[GRCAN_RESERVE_SIZE(0x1c, 0x100)];
> +	u32 pimsr;	/* 0x100 */
> +	u32 pimr;	/* 0x104 */
> +	u32 pisr;	/* 0x108 */
> +	u32 pir;	/* 0x10C */
> +	u32 imr;	/* 0x110 */
> +	u32 picr;	/* 0x114 */
> +	u32 __reserved3[GRCAN_RESERVE_SIZE(0x114, 0x200)];
> +	u32 txctrl;	/* 0x200 */
> +	u32 txaddr;	/* 0x204 */
> +	u32 txsize;	/* 0x208 */
> +	u32 txwr;	/* 0x20C */
> +	u32 txrd;	/* 0x210 */
> +	u32 txirq;	/* 0x214 */
> +	u32 __reserved4[GRCAN_RESERVE_SIZE(0x214, 0x300)];
> +	u32 rxctrl;	/* 0x300 */
> +	u32 rxaddr;	/* 0x304 */
> +	u32 rxsize;	/* 0x308 */
> +	u32 rxwr;	/* 0x30C */
> +	u32 rxrd;	/* 0x310 */
> +	u32 rxirq;	/* 0x314 */
> +	u32 rxmask;	/* 0x318 */
> +	u32 rxcode;	/* 0x31C */
> +};
> +
> +#define GRCAN_CONF_ABORT	0x00000001
> +#define GRCAN_CONF_ENABLE0	0x00000002
> +#define GRCAN_CONF_ENABLE1	0x00000004
> +#define GRCAN_CONF_SELECT	0x00000008
> +#define GRCAN_CONF_SILENT	0x00000010
> +#define GRCAN_CONF_SAM		0x00000020 /* Available in some hardware */
> +#define GRCAN_CONF_BPR		0x00000300 /* Note: not BRP */
> +#define GRCAN_CONF_RSJ		0x00007000
> +#define GRCAN_CONF_PS1		0x00f00000
> +#define GRCAN_CONF_PS2		0x000f0000
> +#define GRCAN_CONF_SCALER	0xff000000
> +#define GRCAN_CONF_OPERATION						\
> +	(GRCAN_CONF_ABORT | GRCAN_CONF_ENABLE0 | GRCAN_CONF_ENABLE1	\
> +	 | GRCAN_CONF_SELECT | GRCAN_CONF_SILENT | GRCAN_CONF_SAM)
> +#define GRCAN_CONF_TIMING						\
> +	(GRCAN_CONF_BPR | GRCAN_CONF_RSJ | GRCAN_CONF_PS1		\
> +	 | GRCAN_CONF_PS2 | GRCAN_CONF_SCALER)
> +
> +#define GRCAN_CONF_RSJ_MIN	1
> +#define GRCAN_CONF_RSJ_MAX	4
> +#define GRCAN_CONF_PS1_MIN	1
> +#define GRCAN_CONF_PS1_MAX	15
> +#define GRCAN_CONF_PS2_MIN	2
> +#define GRCAN_CONF_PS2_MAX	8
> +#define GRCAN_CONF_SCALER_MIN	0
> +#define GRCAN_CONF_SCALER_MAX	255
> +#define GRCAN_CONF_SCALER_INC	1
> +
> +#define GRCAN_CONF_BPR_BIT	8
> +#define GRCAN_CONF_RSJ_BIT	12
> +#define GRCAN_CONF_PS1_BIT	20
> +#define GRCAN_CONF_PS2_BIT	16
> +#define GRCAN_CONF_SCALER_BIT	24
> +
> +#define GRCAN_STAT_PASS		0x000001
> +#define GRCAN_STAT_OFF		0x000002
> +#define GRCAN_STAT_OR		0x000004
> +#define GRCAN_STAT_AHBERR	0x000008
> +#define GRCAN_STAT_ACTIVE	0x000010
> +#define GRCAN_STAT_RXERRCNT	0x00ff00
> +#define GRCAN_STAT_TXERRCNT	0xff0000
> +
> +#define GRCAN_STAT_ERRCTR_RELATED	(GRCAN_STAT_PASS | GRCAN_STAT_OFF)
> +
> +#define GRCAN_STAT_RXERRCNT_BIT	8
> +#define GRCAN_STAT_TXERRCNT_BIT	16
> +
> +#define GRCAN_STAT_ERRCNT_WARNING_LIMIT	96
> +#define GRCAN_STAT_ERRCNT_PASSIVE_LIMIT	127
> +
> +#define GRCAN_CTRL_RESET	0x2
> +#define GRCAN_CTRL_ENABLE	0x1
> +
> +#define GRCAN_TXCTRL_ENABLE	0x1
> +#define GRCAN_TXCTRL_ONGOING	0x2
> +#define GRCAN_TXCTRL_SINGLE	0x4
> +
> +#define GRCAN_RXCTRL_ENABLE	0x1
> +#define GRCAN_RXCTRL_ONGOING	0x2
> +
> +/* Relative offset of IRQ sources to AMBA Plug&Play */
> +#define GRCAN_IRQIX_IRQ		0
> +#define GRCAN_IRQIX_TXSYNC	1
> +#define GRCAN_IRQIX_RXSYNC	2
> +
> +#define GRCAN_IRQ_PASS		0x00001
> +#define GRCAN_IRQ_OFF		0x00002
> +#define GRCAN_IRQ_OR		0x00004
> +#define GRCAN_IRQ_RXAHBERR	0x00008
> +#define GRCAN_IRQ_TXAHBERR	0x00010
> +#define GRCAN_IRQ_RXIRQ		0x00020
> +#define GRCAN_IRQ_TXIRQ		0x00040
> +#define GRCAN_IRQ_RXFULL	0x00080
> +#define GRCAN_IRQ_TXEMPTY	0x00100
> +#define GRCAN_IRQ_RX		0x00200
> +#define GRCAN_IRQ_TX		0x00400
> +#define GRCAN_IRQ_RXSYNC	0x00800
> +#define GRCAN_IRQ_TXSYNC	0x01000
> +#define GRCAN_IRQ_RXERRCTR	0x02000
> +#define GRCAN_IRQ_TXERRCTR	0x04000
> +#define GRCAN_IRQ_RXMISS	0x08000
> +#define GRCAN_IRQ_TXLOSS	0x10000
> +
> +#define GRCAN_IRQ_NONE	0
> +#define GRCAN_IRQ_ALL							\
> +	(GRCAN_IRQ_PASS | GRCAN_IRQ_OFF | GRCAN_IRQ_OR			\
> +	 | GRCAN_IRQ_RXAHBERR | GRCAN_IRQ_TXAHBERR			\
> +	 | GRCAN_IRQ_RXIRQ | GRCAN_IRQ_TXIRQ				\
> +	 | GRCAN_IRQ_RXFULL | GRCAN_IRQ_TXEMPTY				\
> +	 | GRCAN_IRQ_RX | GRCAN_IRQ_TX | GRCAN_IRQ_RXSYNC		\
> +	 | GRCAN_IRQ_TXSYNC | GRCAN_IRQ_RXERRCTR			\
> +	 | GRCAN_IRQ_TXERRCTR | GRCAN_IRQ_RXMISS			\
> +	 | GRCAN_IRQ_TXLOSS)
> +
> +#define GRCAN_IRQ_ERRCTR_RELATED (GRCAN_IRQ_RXERRCTR | GRCAN_IRQ_TXERRCTR \
> +				  | GRCAN_IRQ_PASS | GRCAN_IRQ_OFF)
> +#define GRCAN_IRQ_ERRORS (GRCAN_IRQ_ERRCTR_RELATED | GRCAN_IRQ_OR	\
> +			  | GRCAN_IRQ_TXAHBERR | GRCAN_IRQ_RXAHBERR	\
> +			  | GRCAN_IRQ_TXLOSS)
> +#define GRCAN_IRQ_DEFAULT (GRCAN_IRQ_RX | GRCAN_IRQ_TX | GRCAN_IRQ_ERRORS)
> +
> +#define GRCAN_MSG_SIZE		16
> +
> +#define GRCAN_MSG_IDE		0x80000000
> +#define GRCAN_MSG_RTR		0x40000000
> +#define GRCAN_MSG_BID		0x1ffc0000
> +#define GRCAN_MSG_EID		0x1fffffff
> +#define GRCAN_MSG_IDE_BIT	31
> +#define GRCAN_MSG_RTR_BIT	30
> +#define GRCAN_MSG_BID_BIT	18
> +#define GRCAN_MSG_EID_BIT	0
> +
> +#define GRCAN_MSG_DLC		0xf0000000
> +#define GRCAN_MSG_TXERRC	0x00ff0000
> +#define GRCAN_MSG_RXERRC	0x0000ff00
> +#define GRCAN_MSG_DLC_BIT	28
> +#define GRCAN_MSG_TXERRC_BIT	16
> +#define GRCAN_MSG_RXERRC_BIT	8
> +#define GRCAN_MSG_AHBERR	0x00000008
> +#define GRCAN_MSG_OR		0x00000004
> +#define GRCAN_MSG_OFF		0x00000002
> +#define GRCAN_MSG_PASS		0x00000001
> +
> +#define GRCAN_MSG_DATA_SLOT_INDEX(i) (2 + (i) / 4)
> +#define GRCAN_MSG_DATA_SHIFT(i) ((3 - (i) % 4) * 8)
> +
> +#define GRCAN_BUFFER_ALIGNMENT		1024
> +#define GRCAN_DEFAULT_BUFFER_SIZE	1024
> +#define GRCAN_VALID_TR_SIZE_MASK	0x001fffc0
> +
> +#define GRCAN_INVALID_BUFFER_SIZE(s)			\
> +	((s) == 0 || ((s) & ~GRCAN_VALID_TR_SIZE_MASK))
> +
> +#if GRCAN_INVALID_BUFFER_SIZE(GRCAN_DEFAULT_BUFFER_SIZE)
> +#error "Invalid default buffer size"
> +#endif
> +
> +struct grcan_dma_buffer {
> +	size_t size;
> +	void *buf;
> +	dma_addr_t handle;
> +};
> +
> +struct grcan_dma {
> +	size_t base_size;
> +	void *base_buf;
> +	dma_addr_t base_handle;
> +	struct grcan_dma_buffer tx;
> +	struct grcan_dma_buffer rx;
> +};
> +
> +/* GRCAN configuration parameters */
> +struct grcan_device_config {
> +	unsigned short enable0;
> +	unsigned short enable1;
> +	unsigned short select;
> +	unsigned int txsize;
> +	unsigned int rxsize;
> +};
> +
> +#define GRCAN_DEFAULT_DEVICE_CONFIG {				\
> +		.enable0	= 0,				\
> +		.enable1	= 0,				\
> +		.select		= 0,				\
> +		.txsize		= GRCAN_DEFAULT_BUFFER_SIZE,	\
> +		.rxsize		= GRCAN_DEFAULT_BUFFER_SIZE,	\
> +		}
> +
> +#define GRCAN_TXBUG_SAFE_GRLIB_VERSION	0x4100
> +#define GRLIB_VERSION_MASK		0xffff
> +
> +/* GRCAN private data structure */
> +struct grcan_priv {
> +	struct can_priv can;	/* must be the first member */
> +	struct net_device *dev;
> +	struct napi_struct napi;
> +
> +	struct grcan_registers __iomem *regs;	/* ioremap'ed registers */
> +	struct grcan_device_config config;
> +	struct grcan_dma dma;
> +
> +	struct sk_buff **echo_skb;	/* We allocate this on our own */
> +	u8 *txdlc;			/* Length of queued frames */
> +
> +	/* The echo skb pointer, pointing into echo_skb and indicating which
> +	 * frames can be echoed back. See the "Notes on the tx cyclic buffer
> +	 * handling"-comment for grcan_start_xmit for more details.
> +	 */
> +	u32 eskbp;
> +
> +	/* Lock for controlling changes to the netif tx queue state, accesses to
> +	 * the echo_skb pointer eskbp and for making sure that a running reset
> +	 * and/or a close of the interface is done without interference from
> +	 * other parts of the code.
> +	 *
> +	 * The echo_skb pointer, eskbp, should only be accessed under this lock
> +	 * as it can be changed in several places and together with decisions on
> +	 * whether to wake up the tx queue.
> +	 *
> +	 * The tx queue must never be woken up if there is a running reset or
> +	 * close in progress.
> +	 *
> +	 * A running reset (see below on need_txbug_workaround) should never be
> +	 * done if the interface is closing down and several running resets
> +	 * should never be scheduled simultaneously.
> +	 */
> +	spinlock_t lock;
> +
> +	/* Whether a workaround is needed due to a bug in older hardware. In
> +	 * this case, the driver both tries to prevent the bug from being
> +	 * triggered and recovers, if the bug nevertheless happens, by doing a
> +	 * running reset. A running reset, resets the device and continues from
> +	 * where it were without being noticeable from outside the driver (apart
> +	 * from slight delays).
> +	 */
> +	bool need_txbug_workaround;
> +
> +	/* To trigger initization of running reset and to trigger running reset
> +	 * respectively in the case of a hanged device due to a txbug.
> +	 */
> +	struct timer_list hang_timer;
> +	struct timer_list rr_timer;
> +
> +	/* To avoid waking up the netif queue and restarting timers
> +	 * when a reset is scheduled or when closing of the device is
> +	 * undergoing
> +	 */
> +	bool resetting;
> +	bool closing;
> +};
> +
> +/* Wait time for a short wait for ongoing to clear */
> +#define GRCAN_SHORTWAIT_USECS	10
> +
> +/* Limit on the number of transmitted bits of an eff frame according to the CAN
> + * specification: 1 bit start of frame, 32 bits arbitration field, 6 bits
> + * control field, 8 bytes data field, 16 bits crc field, 2 bits ACK field and 7
> + * bits end of frame
> + */
> +#define GRCAN_EFF_FRAME_MAX_BITS	(1+32+6+8*8+16+2+7)
> +
> +#if defined(__BIG_ENDIAN)
> +static inline u32 grcan_read_reg(u32 __iomem *reg)
> +{
> +	return ioread32be(reg);
> +}
> +
> +static inline void grcan_write_reg(u32 __iomem *reg, u32 val)
> +{
> +	iowrite32be(val, reg);
> +}
> +#else
> +static inline u32 grcan_read_reg(u32 __iomem *reg)
> +{
> +	return ioread32(reg);
> +}
> +
> +static inline void grcan_write_reg(u32 __iomem *reg, u32 val)
> +{
> +	iowrite32(val, reg);
> +}
> +#endif
> +
> +static inline void grcan_clear_bits(u32 __iomem *reg, u32 mask)
> +{
> +	grcan_write_reg(reg, grcan_read_reg(reg) & ~mask);
> +}
> +
> +static inline void grcan_set_bits(u32 __iomem *reg, u32 mask)
> +{
> +	grcan_write_reg(reg, grcan_read_reg(reg) | mask);
> +}
> +
> +static inline u32 grcan_read_bits(u32 __iomem *reg, u32 mask)
> +{
> +	return grcan_read_reg(reg) & mask;
> +}
> +
> +static inline void grcan_write_bits(u32 __iomem *reg, u32 value, u32 mask)
> +{
> +	u32 old = grcan_read_reg(reg);
> +
> +	grcan_write_reg(reg, (old & ~mask) | (value & mask));
> +}
> +
> +/* a and b should both be in [0,size] and a == b == size should not hold */
> +static inline u32 grcan_ring_add(u32 a, u32 b, u32 size)
> +{
> +	u32 sum = a + b;
> +
> +	if (sum < size)
> +		return sum;
> +	else
> +		return sum - size;
> +}
> +
> +/* a and b should both be in [0,size) */
> +static inline u32 grcan_ring_sub(u32 a, u32 b, u32 size)
> +{
> +	return grcan_ring_add(a, size - b, size);
> +}
> +
> +/* Available slots for new transmissions */
> +static inline u32 grcan_txspace(size_t txsize, u32 txwr, u32 eskbp)
> +{
> +	u32 slots = txsize / GRCAN_MSG_SIZE - 1;
> +	u32 used = grcan_ring_sub(txwr, eskbp, txsize) / GRCAN_MSG_SIZE;
> +
> +	return slots - used;
> +}
> +
> +/* Configuration parameters that can be set via module parameters */
> +static struct grcan_device_config grcan_module_config =
> +	GRCAN_DEFAULT_DEVICE_CONFIG;
> +
> +static struct can_bittiming_const grcan_bittiming_const = {
> +	.name		= DRV_NAME,
> +	.tseg1_min	= GRCAN_CONF_PS1_MIN + 1,
> +	.tseg1_max	= GRCAN_CONF_PS1_MAX + 1,
> +	.tseg2_min	= GRCAN_CONF_PS2_MIN,
> +	.tseg2_max	= GRCAN_CONF_PS2_MAX,
> +	.sjw_max	= GRCAN_CONF_RSJ_MAX,
> +	.brp_min	= GRCAN_CONF_SCALER_MIN + 1,
> +	.brp_max	= GRCAN_CONF_SCALER_MAX + 1,
> +	.brp_inc	= GRCAN_CONF_SCALER_INC,
> +};
> +
> +static int grcan_set_bittiming(struct net_device *dev)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	struct can_bittiming *bt = &priv->can.bittiming;
> +	u32 timing = 0;
> +	int bpr, rsj, ps1, ps2, scaler;
> +
> +	/* Should never happen - function will not be called when
> +	 * device is up
> +	 */
> +	if (grcan_read_bits(&regs->ctrl, GRCAN_CTRL_ENABLE))
> +		return -EBUSY;
> +
> +	bpr = 0; /* Note bpr and brp are different concepts */
> +	rsj = bt->sjw;
> +	ps1 = (bt->prop_seg + bt->phase_seg1) - 1; /* tseg1 - 1 */
> +	ps2 = bt->phase_seg2;
> +	scaler = (bt->brp - 1);
> +	timing |= (bpr << GRCAN_CONF_BPR_BIT) & GRCAN_CONF_BPR;
> +	timing |= (rsj << GRCAN_CONF_RSJ_BIT) & GRCAN_CONF_RSJ;
> +	timing |= (ps1 << GRCAN_CONF_PS1_BIT) & GRCAN_CONF_PS1;
> +	timing |= (ps2 << GRCAN_CONF_PS2_BIT) & GRCAN_CONF_PS2;
> +	timing |= (scaler << GRCAN_CONF_SCALER_BIT) & GRCAN_CONF_SCALER;
> +
> +	netdev_info(dev, "setting timing=0x%x\n", timing);
> +	if (!(ps1 > ps2)) {
> +		netdev_err(dev, "PS1 > PS2 must hold: PS1=%d, PS2=%d\n",
> +			   ps1, ps2);
> +		return -EINVAL;
> +	}
> +	if (!(ps2 >= rsj)) {
> +		netdev_err(dev, "PS2 >= RSJ must hold: PS2=%d, RSJ=%d\n",
> +			   ps2, rsj);
> +		return -EINVAL;
> +	}
> +
> +	grcan_write_bits(&regs->conf, timing, GRCAN_CONF_TIMING);
> +	return 0;
> +}
> +
> +static int grcan_get_berr_counter(const struct net_device *dev,
> +				  struct can_berr_counter *bec)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	u32 status = grcan_read_reg(&regs->stat);
> +
> +	bec->txerr = (status & GRCAN_STAT_TXERRCNT) >> GRCAN_STAT_TXERRCNT_BIT;
> +	bec->rxerr = (status & GRCAN_STAT_RXERRCNT) >> GRCAN_STAT_RXERRCNT_BIT;
> +	return 0;
> +}
> +
> +static int grcan_poll(struct napi_struct *napi, int budget);
> +
> +/* Reset device, but keep configuration information */
> +static void grcan_reset(struct net_device *dev)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	u32 config = grcan_read_reg(&regs->conf);
> +
> +	grcan_set_bits(&regs->ctrl, GRCAN_CTRL_RESET);
> +	grcan_write_reg(&regs->conf, config);
> +
> +	priv->eskbp = grcan_read_reg(&regs->txrd);
> +	priv->can.state = CAN_STATE_STOPPED;
> +
> +	/* Turn off hardware filtering - regs->rxcode set to 0 by reset */
> +	grcan_write_reg(&regs->rxmask, 0);
> +}
> +
> +/* stop device without changing any configurations */
> +static void grcan_stop_hardware(struct net_device *dev)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +
> +	grcan_write_reg(&regs->imr, GRCAN_IRQ_NONE);
> +	grcan_clear_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
> +	grcan_clear_bits(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
> +	grcan_clear_bits(&regs->ctrl, GRCAN_CTRL_ENABLE);
> +}
> +
> +/* Let priv->eskbp catch up to regs->txrd and echo back the skbs if echo
> + * is true and free them otherwise.
> + *
> + * If budget is >= 0, stop after handling at most budget skbs. Otherwise,
> + * continue until priv->eskbp catches up to regs->txrd.
> + *
> + * priv->lock *must* be held when calling this function
> + */
> +static int catch_up_echo_skb(struct net_device *dev, int budget, bool echo)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	struct grcan_dma *dma = &priv->dma;
> +	struct net_device_stats *stats = &dev->stats;
> +	int i, work_done;
> +
> +	/* Updates to priv->eskbp and wake-ups of the queue needs to
> +	 * be atomic towards the reads of priv->eskbp and shut-downs
> +	 * of the queue in grcan_start_xmit.
> +	 */
> +	u32 txrd = grcan_read_reg(&regs->txrd);
> +
> +	for (work_done = 0; work_done < budget || budget < 0; work_done++) {
> +		if (priv->eskbp == txrd)
> +			break;
> +		i = priv->eskbp / GRCAN_MSG_SIZE;
> +		if (echo) {
> +			/* Normal echo of messages */
> +			stats->tx_packets++;
> +			stats->tx_bytes += priv->txdlc[i];
> +			priv->txdlc[i] = 0;
> +			can_get_echo_skb(dev, i);
> +		} else {
> +			/* For cleanup of untransmitted messages */
> +			can_free_echo_skb(dev, i);
> +		}
> +
> +		priv->eskbp = grcan_ring_add(priv->eskbp, GRCAN_MSG_SIZE,
> +					     dma->tx.size);
> +		txrd = grcan_read_reg(&regs->txrd);
> +	}
> +	return work_done;
> +}
> +
> +static void grcan_lost_one_shot_frame(struct net_device *dev)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	struct grcan_dma *dma = &priv->dma;
> +	u32 txrd;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&priv->lock, flags);
> +
> +	catch_up_echo_skb(dev, -1, true);
> +
> +	if (unlikely(grcan_read_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE))) {
> +		/* Should never happen */
> +		netdev_err(dev, "TXCTRL enabled at TXLOSS in one shot mode\n");
> +	} else {
> +		/* By the time an GRCAN_IRQ_TXLOSS is generated in
> +		 * one-shot mode there is no problem in writing
> +		 * to TXRD even in versions of the hardware in
> +		 * which GRCAN_TXCTRL_ONGOING is not cleared properly
> +		 * in one-shot mode.
> +		 */
> +
> +		/* Skip message and discard echo-skb */
> +		txrd = grcan_read_reg(&regs->txrd);
> +		txrd = grcan_ring_add(txrd, GRCAN_MSG_SIZE, dma->tx.size);
> +		grcan_write_reg(&regs->txrd, txrd);
> +		catch_up_echo_skb(dev, -1, false);
> +
> +		if (!priv->resetting && !priv->closing &&
> +		    !(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)) {
> +			netif_wake_queue(dev);
> +			grcan_set_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
> +		}
> +	}
> +
> +	spin_unlock_irqrestore(&priv->lock, flags);
> +}
> +
> +static void grcan_err(struct net_device *dev, u32 sources, u32 status)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	struct grcan_dma *dma = &priv->dma;
> +	struct net_device_stats *stats = &dev->stats;
> +	struct can_frame cf;
> +
> +	/* Zero potential error_frame */
> +	memset(&cf, 0, sizeof(cf));
> +
> +	/* Message lost interrupt. This might be due to arbitration error, but
> +	 * is also triggered when there is no one else on the can bus or when
> +	 * there is a problem with the hardware interface or the bus itself. As
> +	 * arbitration errors can not be singled out, no error frames are
> +	 * generated reporting this event as an arbitration error.
> +	 */
> +	if (sources & GRCAN_IRQ_TXLOSS) {
> +		/* Take care of failed one-shot transmit */
> +		if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT)
> +			grcan_lost_one_shot_frame(dev);
> +
> +		/* Stop printing as soon as error passive or bus off is in
> +		 * effect to limit the amount of txloss debug printouts.
> +		 */
> +		if (!(status & GRCAN_STAT_ERRCTR_RELATED)) {
> +			netdev_dbg(dev, "tx message lost\n");
> +			stats->tx_errors++;
> +		}
> +	}
> +
> +	/* Conditions dealing with the error counters. There is no interrupt for
> +	 * error warning, but there are interrupts for increases of the error
> +	 * counters.
> +	 */
> +	if ((sources & GRCAN_IRQ_ERRCTR_RELATED) ||
> +	    (status & GRCAN_STAT_ERRCTR_RELATED)) {
> +		enum can_state state = priv->can.state;
> +		enum can_state oldstate = state;
> +		u32 txerr = (status & GRCAN_STAT_TXERRCNT)
> +			>> GRCAN_STAT_TXERRCNT_BIT;
> +		u32 rxerr = (status & GRCAN_STAT_RXERRCNT)
> +			>> GRCAN_STAT_RXERRCNT_BIT;
> +
> +		/* Figure out current state */
> +		if (status & GRCAN_STAT_OFF) {
> +			state = CAN_STATE_BUS_OFF;
> +		} else if (status & GRCAN_STAT_PASS) {
> +			state = CAN_STATE_ERROR_PASSIVE;
> +		} else if (txerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT ||
> +			   rxerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT) {
> +			state = CAN_STATE_ERROR_WARNING;
> +		} else {
> +			state = CAN_STATE_ERROR_ACTIVE;
> +		}
> +
> +		/* Handle and report state changes */
> +		if (state != oldstate) {
> +			switch (state) {
> +			case CAN_STATE_BUS_OFF:
> +				netdev_dbg(dev, "bus-off\n");
> +				netif_carrier_off(dev);
> +				priv->can.can_stats.bus_off++;
> +
> +				/* Prevent the hardware from recovering from bus
> +				 * off on its own if restart is disabled.
> +				 */
> +				if (!priv->can.restart_ms)
> +					grcan_stop_hardware(dev);
> +
> +				cf.can_id |= CAN_ERR_BUSOFF;
> +				break;
> +
> +			case CAN_STATE_ERROR_PASSIVE:
> +				netdev_dbg(dev, "Error passive condition\n");
> +				priv->can.can_stats.error_passive++;
> +
> +				cf.can_id |= CAN_ERR_CRTL;
> +				if (txerr >= GRCAN_STAT_ERRCNT_PASSIVE_LIMIT)
> +					cf.data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
> +				if (rxerr >= GRCAN_STAT_ERRCNT_PASSIVE_LIMIT)
> +					cf.data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
> +				break;
> +
> +			case CAN_STATE_ERROR_WARNING:
> +				netdev_dbg(dev, "Error warning condition\n");
> +				priv->can.can_stats.error_warning++;
> +
> +				cf.can_id |= CAN_ERR_CRTL;
> +				if (txerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT)
> +					cf.data[1] |= CAN_ERR_CRTL_TX_WARNING;
> +				if (rxerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT)
> +					cf.data[1] |= CAN_ERR_CRTL_RX_WARNING;
> +				break;
> +
> +			case CAN_STATE_ERROR_ACTIVE:
> +				netdev_dbg(dev, "Error active condition\n");
> +				cf.can_id |= CAN_ERR_CRTL;
> +				break;
> +
> +			default:
> +				/* There are no others at this point */
> +				break;
> +			}
> +			cf.data[6] = txerr;
> +			cf.data[7] = rxerr;
> +			priv->can.state = state;
> +		}
> +
> +		/* Report automatic restarts */
> +		if (priv->can.restart_ms && oldstate == CAN_STATE_BUS_OFF) {
> +			unsigned long flags;
> +
> +			cf.can_id |= CAN_ERR_RESTARTED;
> +			netdev_dbg(dev, "restarted\n");
> +			priv->can.can_stats.restarts++;
> +			netif_carrier_on(dev);
> +
> +			spin_lock_irqsave(&priv->lock, flags);
> +
> +			if (!priv->resetting && !priv->closing) {
> +				u32 txwr = grcan_read_reg(&regs->txwr);
> +
> +				if (grcan_txspace(dma->tx.size, txwr,
> +						  priv->eskbp))
> +					netif_wake_queue(dev);
> +			}
> +
> +			spin_unlock_irqrestore(&priv->lock, flags);
> +		}
> +	}
> +
> +	/* Data overrun interrupt */
> +	if ((sources & GRCAN_IRQ_OR) || (status & GRCAN_STAT_OR)) {
> +		netdev_dbg(dev, "got data overrun interrupt\n");
> +		stats->rx_over_errors++;
> +		stats->rx_errors++;
> +
> +		cf.can_id |= CAN_ERR_CRTL;
> +		cf.data[1] |= CAN_ERR_CRTL_RX_OVERFLOW;
> +	}
> +
> +	/* AHB bus error interrupts (not CAN bus errors) - shut down the
> +	 * device.
> +	 */
> +	if (sources & (GRCAN_IRQ_TXAHBERR | GRCAN_IRQ_RXAHBERR) ||
> +	    (status & GRCAN_STAT_AHBERR)) {
> +		char *txrx = "";
> +		unsigned long flags;
> +
> +		if (sources & GRCAN_IRQ_TXAHBERR) {
> +			txrx = "on tx ";
> +			stats->tx_errors++;
> +		} else if (sources & GRCAN_IRQ_RXAHBERR) {
> +			txrx = "on rx ";
> +			stats->rx_errors++;
> +		}
> +		netdev_err(dev, "Fatal AHB buss error %s- halting device\n",
> +			   txrx);
> +
> +		spin_lock_irqsave(&priv->lock, flags);
> +
> +		/* Prevent anything to be enabled again and halt device */
> +		priv->closing = true;
> +		netif_stop_queue(dev);
> +		grcan_stop_hardware(dev);
> +		priv->can.state = CAN_STATE_STOPPED;
> +
> +		spin_unlock_irqrestore(&priv->lock, flags);
> +	}
> +
> +	/* Pass on error frame if something to report,
> +	 * i.e. id contains some information
> +	 */
> +	if (cf.can_id) {
> +		struct can_frame *skb_cf;
> +		struct sk_buff *skb = alloc_can_err_skb(dev, &skb_cf);
> +
> +		if (skb == NULL) {
> +			netdev_dbg(dev, "could not allocate error frame\n");
> +			return;
> +		}
> +		skb_cf->can_id |= cf.can_id;
> +		memcpy(skb_cf->data, cf.data, sizeof(cf.data));
> +
> +		netif_rx(skb);
> +	}
> +}
> +
> +static irqreturn_t grcan_interrupt(int irq, void *dev_id)
> +{
> +	struct net_device *dev = (struct net_device *)dev_id;
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	u32 sources, status;
> +
> +	/* Find out the source */
> +	sources = grcan_read_reg(&regs->pimsr);
> +	if (!sources)
> +		return IRQ_NONE;
> +	grcan_write_reg(&regs->picr, sources);
> +	status = grcan_read_reg(&regs->stat);
> +
> +	/* If we got TX progress, the device has not hanged,
> +	 * so disable the hang timer
> +	 */
> +	if (priv->need_txbug_workaround &&
> +	    (sources & (GRCAN_IRQ_TX | GRCAN_IRQ_TXLOSS))) {
> +		del_timer(&priv->hang_timer);
> +	}
> +
> +	/* Frame(s) received or transmitted */
> +	if (sources & (GRCAN_IRQ_TX | GRCAN_IRQ_RX)) {
> +		/* Disable tx/rx interrupts and schedule poll() */
> +		grcan_clear_bits(&regs->imr, GRCAN_IRQ_TX | GRCAN_IRQ_RX);
> +		napi_schedule(&priv->napi);
> +	}
> +
> +	/* (Potential) error conditions to take care of */
> +	if (sources & GRCAN_IRQ_ERRORS)
> +		grcan_err(dev, sources, status);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +/* Reset device and restart operations from where they were.
> + *
> + * This assumes that RXCTRL & RXCTRL is properly disabled and that RX
> + * is not ONGOING (TX might be stuck in ONGOING due to a harwrware bug
> + * for single shot)
> + */
> +static void grcan_running_reset(unsigned long data)
> +{
> +	struct net_device *dev = (struct net_device *)data;
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	unsigned long flags;
> +
> +	/* This temporarily messes with eskbp, so we need to lock
> +	 * priv->lock
> +	 */
> +	spin_lock_irqsave(&priv->lock, flags);
> +
> +	priv->resetting = false;
> +	del_timer(&priv->hang_timer);
> +	del_timer(&priv->rr_timer);
> +
> +	if (!priv->closing) {
> +		/* Save and reset - config register preserved by grcan_reset */
> +		u32 imr = grcan_read_reg(&regs->imr);
> +
> +		u32 txaddr = grcan_read_reg(&regs->txaddr);
> +		u32 txsize = grcan_read_reg(&regs->txsize);
> +		u32 txwr = grcan_read_reg(&regs->txwr);
> +		u32 txrd = grcan_read_reg(&regs->txrd);
> +		u32 eskbp = priv->eskbp;
> +
> +		u32 rxaddr = grcan_read_reg(&regs->rxaddr);
> +		u32 rxsize = grcan_read_reg(&regs->rxsize);
> +		u32 rxwr = grcan_read_reg(&regs->rxwr);
> +		u32 rxrd = grcan_read_reg(&regs->rxrd);
> +
> +		grcan_reset(dev);
> +
> +		/* Restore */
> +		grcan_write_reg(&regs->txaddr, txaddr);
> +		grcan_write_reg(&regs->txsize, txsize);
> +		grcan_write_reg(&regs->txwr, txwr);
> +		grcan_write_reg(&regs->txrd, txrd);
> +		priv->eskbp = eskbp;
> +
> +		grcan_write_reg(&regs->rxaddr, rxaddr);
> +		grcan_write_reg(&regs->rxsize, rxsize);
> +		grcan_write_reg(&regs->rxwr, rxwr);
> +		grcan_write_reg(&regs->rxrd, rxrd);
> +
> +		/* Turn on device again */
> +		grcan_write_reg(&regs->imr, imr);
> +		priv->can.state = CAN_STATE_ERROR_ACTIVE;
> +		grcan_write_reg(&regs->txctrl, GRCAN_TXCTRL_ENABLE
> +				| (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT
> +				   ? GRCAN_TXCTRL_SINGLE : 0));
> +		grcan_write_reg(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
> +		grcan_write_reg(&regs->ctrl, GRCAN_CTRL_ENABLE);
> +
> +		/* Start queue if there is size and listen-onle mode is not
> +		 * enabled
> +		 */
> +		if (grcan_txspace(priv->dma.tx.size, txwr, priv->eskbp) &&
> +		    !(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
> +			netif_wake_queue(dev);
> +	}
> +
> +	spin_unlock_irqrestore(&priv->lock, flags);
> +
> +	netdev_err(dev, "Device reset and restored\n");
> +}
> +
> +/* Waiting time in usecs corresponding to the transmission of three maximum
> + * sized can frames in the given bitrate (in bits/sec). Waiting for this amount
> + * of time makes sure that the can controller have time to finish sending or
> + * receiving a frame with a good margin.
> + *
> + * usecs/sec * number of frames * bits/frame / bits/sec
> + */
> +static inline u32 grcan_ongoing_wait_usecs(__u32 bitrate)
> +{
> +	return 1000000 * 3 * GRCAN_EFF_FRAME_MAX_BITS / bitrate;
> +}
> +
> +/* Set timer so that it will not fire until after a period in which the can
> + * controller have a good margin to finish transmitting a frame unless it has
> + * hanged
> + */
> +static inline void grcan_reset_timer(struct timer_list *timer, __u32 bitrate)
> +{
> +	u32 wait_jiffies = usecs_to_jiffies(grcan_ongoing_wait_usecs(bitrate));
> +
> +	mod_timer(timer, jiffies + wait_jiffies);
> +}
> +
> +/* Disable channels and schedule a running reset */
> +static void grcan_initiate_running_reset(unsigned long data)
> +{
> +	struct net_device *dev = (struct net_device *)data;
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	unsigned long flags;
> +
> +	netdev_err(dev, "Device seems hanged - reset scheduled\n");
> +
> +	spin_lock_irqsave(&priv->lock, flags);
> +
> +	/* The main body of this function must never be executed again
> +	 * until after an execution of grcan_running_reset
> +	 */
> +	if (!priv->resetting && !priv->closing) {
> +		priv->resetting = true;
> +		netif_stop_queue(dev);
> +		grcan_clear_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
> +		grcan_clear_bits(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
> +		grcan_reset_timer(&priv->rr_timer, priv->can.bittiming.bitrate);
> +	}
> +
> +	spin_unlock_irqrestore(&priv->lock, flags);
> +}
> +
> +static void grcan_free_dma_buffers(struct net_device *dev)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_dma *dma = &priv->dma;
> +
> +	dma_free_coherent(&dev->dev, dma->base_size, dma->base_buf,
> +			  dma->base_handle);
> +	memset(dma, 0, sizeof(*dma));
> +}
> +
> +static int grcan_allocate_dma_buffers(struct net_device *dev,
> +				      size_t tsize, size_t rsize)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_dma *dma = &priv->dma;
> +	struct grcan_dma_buffer *large = rsize > tsize ? &dma->rx : &dma->tx;
> +	struct grcan_dma_buffer *small = rsize > tsize ? &dma->tx : &dma->rx;
> +	size_t shift;
> +
> +	/* Need a whole number of GRCAN_BUFFER_ALIGNMENT for the large,
> +	 * i.e. first buffer
> +	 */
> +	size_t maxs = max(tsize, rsize);
> +	size_t lsize = ALIGN(maxs, GRCAN_BUFFER_ALIGNMENT);
> +
> +	/* Put the small buffer after that */
> +	size_t ssize = min(tsize, rsize);
> +
> +	/* Extra GRCAN_BUFFER_ALIGNMENT to allow for alignment */
> +	dma->base_size = lsize + ssize + GRCAN_BUFFER_ALIGNMENT;
> +	dma->base_buf = dma_alloc_coherent(&dev->dev,
> +					   dma->base_size,
> +					   &dma->base_handle,
> +					   GFP_KERNEL);
> +
> +	if (!dma->base_buf)
> +		return -ENOMEM;
> +
> +	dma->tx.size = tsize;
> +	dma->rx.size = rsize;
> +
> +	large->handle = ALIGN(dma->base_handle, GRCAN_BUFFER_ALIGNMENT);
> +	small->handle = large->handle + lsize;
> +	shift = large->handle - dma->base_handle;
> +
> +	large->buf = dma->base_buf + shift;
> +	small->buf = large->buf + lsize;
> +
> +	return 0;
> +}
> +
> +/* priv->lock *must* be held when calling this function */
> +static int grcan_start(struct net_device *dev)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	u32 confop, txctrl;
> +
> +	grcan_reset(dev);
> +
> +	grcan_write_reg(&regs->txaddr, priv->dma.tx.handle);
> +	grcan_write_reg(&regs->txsize, priv->dma.tx.size);
> +	/* regs->txwr, regs->txrd and priv->eskbp already set to 0 by reset */
> +
> +	grcan_write_reg(&regs->rxaddr, priv->dma.rx.handle);
> +	grcan_write_reg(&regs->rxsize, priv->dma.rx.size);
> +	/* regs->rxwr and regs->rxrd already set to 0 by reset */
> +
> +	/* Enable interrupts */
> +	grcan_read_reg(&regs->pir);
> +	grcan_write_reg(&regs->imr, GRCAN_IRQ_DEFAULT);
> +
> +	/* Enable interfaces, channels and device */
> +	confop = GRCAN_CONF_ABORT
> +		| (priv->config.enable0 ? GRCAN_CONF_ENABLE0 : 0)
> +		| (priv->config.enable1 ? GRCAN_CONF_ENABLE1 : 0)
> +		| (priv->config.select ? GRCAN_CONF_SELECT : 0)
> +		| (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY ?
> +		   GRCAN_CONF_SILENT : 0)
> +		| (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES ?
> +		   GRCAN_CONF_SAM : 0);
> +	grcan_write_bits(&regs->conf, confop, GRCAN_CONF_OPERATION);
> +	txctrl = GRCAN_TXCTRL_ENABLE
> +		| (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT
> +		   ? GRCAN_TXCTRL_SINGLE : 0);
> +	grcan_write_reg(&regs->txctrl, txctrl);
> +	grcan_write_reg(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
> +	grcan_write_reg(&regs->ctrl, GRCAN_CTRL_ENABLE);
> +
> +	priv->can.state = CAN_STATE_ERROR_ACTIVE;
> +
> +	return 0;
> +}
> +
> +static int grcan_set_mode(struct net_device *dev, enum can_mode mode)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	unsigned long flags;
> +	int err = 0;
> +
> +	if (mode == CAN_MODE_START) {
> +		/* This might be called to restart the device to recover from
> +		 * bus off errors
> +		 */
> +		spin_lock_irqsave(&priv->lock, flags);
> +		if (priv->closing || priv->resetting) {
> +			err = -EBUSY;
> +		} else {
> +			netdev_info(dev, "Restarting device\n");
> +			grcan_start(dev);
> +			if (!(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
> +				netif_wake_queue(dev);
> +		}
> +		spin_unlock_irqrestore(&priv->lock, flags);
> +		return err;
> +	}
> +	return -EOPNOTSUPP;
> +}
> +
> +static int grcan_open(struct net_device *dev)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_dma *dma = &priv->dma;
> +	unsigned long flags;
> +	int err;
> +
> +	/* Allocate memory */
> +	if (GRCAN_INVALID_BUFFER_SIZE(priv->config.txsize) ||
> +	    GRCAN_INVALID_BUFFER_SIZE(priv->config.rxsize)) {
> +		/* Should never be able go this far with invalid sizes */
> +		netdev_err(dev, "Invalid buffer size pair 0x%x 0x%x\n",
> +			   priv->config.txsize, priv->config.rxsize);
> +		return -EINVAL;
> +	}

Are these values checked when entering the kernel? If it's not needed
here, please remove.

> +	err = grcan_allocate_dma_buffers(dev, priv->config.txsize,
> +					 priv->config.rxsize);
> +	if (err) {
> +		netdev_err(dev, "could not allocate DMA buffers\n");
> +		return err;
> +	}

> +	priv->echo_skb = devm_kzalloc(&dev->dev,
> +				      dma->tx.size * sizeof(*priv->echo_skb),
> +				      GFP_KERNEL);

It makes no sense to use devm_ function the _open function.

> +	if (!priv->echo_skb) {
> +		err = -ENOMEM;
> +		goto exit_free_dma_buffers;
> +	}
> +	priv->can.echo_skb_max = dma->tx.size;
> +	priv->can.echo_skb = priv->echo_skb;
> +
> +	priv->txdlc = devm_kzalloc(&dev->dev,
> +				   dma->tx.size * sizeof(*priv->txdlc),
> +				   GFP_KERNEL);
> +	if (!priv->txdlc) {
> +		err = -ENOMEM;
> +		goto exit_free_echo_skb;
> +	}
> +
> +	/* Get can device up */
> +	err = open_candev(dev);
> +	if (err)
> +		goto exit_free_txdlc;
> +
> +	err = devm_request_irq(&dev->dev, dev->irq, grcan_interrupt,
> +			       IRQF_SHARED, dev->name, (void *)dev);

the cast is not needed

> +	if (err)
> +		goto exit_close_candev;
> +
> +	spin_lock_irqsave(&priv->lock, flags);
> +
> +	grcan_start(dev);
> +	napi_enable(&priv->napi);

Enable napi before starting interrupts.

> +	if (!(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
> +		netif_start_queue(dev);
> +	priv->resetting = false;
> +	priv->closing = false;
> +
> +	spin_unlock_irqrestore(&priv->lock, flags);
> +
> +	return 0;
> +
> +exit_close_candev:
> +	close_candev(dev);
> +exit_free_txdlc:
> +	devm_kfree(&dev->dev, priv->txdlc);
> +exit_free_echo_skb:
> +	devm_kfree(&dev->dev, priv->echo_skb);
> +exit_free_dma_buffers:
> +	grcan_free_dma_buffers(dev);
> +	return err;
> +}
> +
> +static int grcan_close(struct net_device *dev)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	unsigned long flags;
> +
> +	napi_disable(&priv->napi);
> +
> +	spin_lock_irqsave(&priv->lock, flags);
> +
> +	priv->closing = true;
> +	if (priv->need_txbug_workaround) {
> +		del_timer_sync(&priv->hang_timer);
> +		del_timer_sync(&priv->rr_timer);
> +	}
> +	netif_stop_queue(dev);
> +	grcan_stop_hardware(dev);
> +	priv->can.state = CAN_STATE_STOPPED;
> +
> +	spin_unlock_irqrestore(&priv->lock, flags);
> +
> +	devm_free_irq(&dev->dev, dev->irq, (void *)dev);
> +	close_candev(dev);
> +
> +	grcan_free_dma_buffers(dev);
> +	priv->can.echo_skb_max = 0;
> +	priv->can.echo_skb = NULL;
> +	devm_kfree(&dev->dev, priv->echo_skb);
> +	devm_kfree(&dev->dev, priv->txdlc);
> +
> +	return 0;
> +}
> +
> +static int grcan_transmit_catch_up(struct net_device *dev, int budget)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	unsigned long flags;
> +	int work_done;
> +
> +	spin_lock_irqsave(&priv->lock, flags);
> +
> +	work_done = catch_up_echo_skb(dev, budget, true);
> +	if (work_done) {
> +		if (!priv->resetting && !priv->closing &&
> +		    !(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
> +			netif_wake_queue(dev);
> +
> +		/* With napi we don't get TX interrupts for a while,
> +		 * so prevent a running reset while catching up
> +		 */
> +		if (priv->need_txbug_workaround)
> +			del_timer(&priv->hang_timer);
> +	}
> +
> +	spin_unlock_irqrestore(&priv->lock, flags);
> +
> +	return work_done;
> +}
> +
> +static int grcan_receive(struct net_device *dev, int budget)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	struct grcan_dma *dma = &priv->dma;
> +	struct net_device_stats *stats = &dev->stats;
> +	struct can_frame *cf;
> +	struct sk_buff *skb;
> +	u32 wr, rd, startrd;
> +	u32 *slot;
> +	u32 i, rtr, eff, j, shift;
> +	int work_done = 0;
> +
> +	rd = grcan_read_reg(&regs->rxrd);
> +	startrd = rd;
> +	for (work_done = 0; work_done < budget; work_done++) {
> +		/* Check for packet to receive */
> +		wr = grcan_read_reg(&regs->rxwr);
> +		if (rd == wr)
> +			break;
> +
> +		/* Take care of packet */
> +		skb = alloc_can_skb(dev, &cf);
> +		if (skb == NULL) {
> +			netdev_err(dev,
> +				   "dropping frame: skb allocation failed\n");
> +			stats->rx_dropped++;
> +			continue;
> +		}
> +
> +		slot = dma->rx.buf + rd;
> +		eff = slot[0] & GRCAN_MSG_IDE;
> +		rtr = slot[0] & GRCAN_MSG_RTR;
> +		if (eff) {
> +			cf->can_id = ((slot[0] & GRCAN_MSG_EID)
> +				      >> GRCAN_MSG_EID_BIT);
> +			cf->can_id |= CAN_EFF_FLAG;
> +		} else {
> +			cf->can_id = ((slot[0] & GRCAN_MSG_BID)
> +				      >> GRCAN_MSG_BID_BIT);
> +		}
> +		cf->can_dlc = get_can_dlc((slot[1] & GRCAN_MSG_DLC)
> +					  >> GRCAN_MSG_DLC_BIT);
> +		if (rtr) {
> +			cf->can_id |= CAN_RTR_FLAG;
> +		} else {
> +			for (i = 0; i < cf->can_dlc; i++) {
> +				j = GRCAN_MSG_DATA_SLOT_INDEX(i);
> +				shift = GRCAN_MSG_DATA_SHIFT(i);
> +				cf->data[i] = (u8)((slot[j] >> shift) & 0xff);
& 0xff is not needed, as ->data[] is only 8 bit wide
> +			}
> +		}
> +		netif_receive_skb(skb);
> +
> +		/* Update statistics and read pointer */
> +		stats->rx_packets++;
> +		stats->rx_bytes += cf->can_dlc;
> +		rd = grcan_ring_add(rd, GRCAN_MSG_SIZE, dma->rx.size);
> +	}
> +
> +	/* Make sure everything is read before allowing hardware to
> +	 * use the memory
> +	 */
> +	mb();
> +
> +	/* Update read pointer - no need to check for ongoing */
> +	if (likely(rd != startrd))
> +		grcan_write_reg(&regs->rxrd, rd);
> +
> +	return work_done;
> +}
> +
> +static int grcan_poll(struct napi_struct *napi, int budget)
> +{
> +	struct grcan_priv *priv = container_of(napi, struct grcan_priv, napi);
> +	struct net_device *dev = priv->dev;
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	int rx_work_done = grcan_receive(dev, budget);
> +	int tx_work_done = grcan_transmit_catch_up(dev, budget);

This is correct C-code but please put the functions call into seperate
lines.....is the budget ment for both rx and tx or for rx+tx?

> +
> +	if (rx_work_done < budget && tx_work_done < budget) {
> +		napi_complete(napi);
> +		/* Enable tx and rx interrupts again */
> +		if (!priv->closing)
> +			grcan_set_bits(&regs->imr, GRCAN_IRQ_TX | GRCAN_IRQ_RX);
> +	}
> +	return rx_work_done;
> +}
> +
> +/* Work tx bug by waiting while for the risky situation to clear. If that fails,
> + * drop a frame in one-shot mode or indicate a busy device otherwise.
> + *
> + * Returns 0 on successful wait. Otherwise it sets *netdev_tx_status to the
> + * value that should be returned by grcan_start_xmit when aborting the xmit.
> + */
> +static int grcan_txbug_workaround(struct net_device *dev, struct sk_buff *skb,
> +				  u32 txwr, u32 oneshotmode,
> +				  netdev_tx_t *netdev_tx_status)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	struct grcan_dma *dma = &priv->dma;
> +	int i;
> +	unsigned long flags;
> +
> +	/* Wait a while for ongoing to be cleared or read pointer to catch up to
> +	 * write pointer. The latter is needed due to a bug in older versions of
> +	 * GRCAN in which ONGOING is not cleared properly one-shot mode when a
> +	 * transmission fails.
> +	 */
> +	for (i = 0; i < GRCAN_SHORTWAIT_USECS; i++) {
> +		udelay(1);
> +		if (!grcan_read_bits(&regs->txctrl, GRCAN_TXCTRL_ONGOING) ||
> +		    grcan_read_reg(&regs->txrd) == txwr) {
> +			return 0;
> +		}
> +	}
> +
> +	/* Clean up, in case the situation was not resolved */
> +	spin_lock_irqsave(&priv->lock, flags);
> +	if (!priv->resetting && !priv->closing) {
> +		/* Queue might have been stopped earlier in grcan_start_xmit */
> +		if (grcan_txspace(dma->tx.size, txwr, priv->eskbp))
> +			netif_wake_queue(dev);
> +		/* Set a timer to resolve a hanged tx controller */
> +		if (!timer_pending(&priv->hang_timer))
> +			grcan_reset_timer(&priv->hang_timer,
> +					  priv->can.bittiming.bitrate);
> +	}
> +	spin_unlock_irqrestore(&priv->lock, flags);
> +
> +	if (oneshotmode) {
> +		/* In one-shot mode we should never end up here because
> +		 * then the interrupt handler increases txrd on TXLOSS,
> +		 * but it is consistent with one-shot mode to drop the
> +		 * frame in this case.
> +		 */
> +		kfree_skb(skb);
> +		*netdev_tx_status = NETDEV_TX_OK;
> +	} else {
> +		/* In normal mode the socket-can transmission queue get
> +		 * to keep the frame so that it can be retransmitted
> +		 * later
> +		 */
> +		*netdev_tx_status = NETDEV_TX_BUSY;
> +	}
> +	return -EBUSY;
> +}
> +
> +/* Notes on the tx cyclic buffer handling:
> + *
> + * regs->txwr	- the next slot for the driver to put data to be sent
> + * regs->txrd	- the next slot for the device to read data
> + * priv->eskbp	- the next slot for the driver to call can_put_echo_skb for
> + *
> + * grcan_start_xmit can enter more messages as long as regs->txwr does
> + * not reach priv->eskbp (within 1 message gap)
> + *
> + * The device sends messages until regs->txrd reaches regs->txwr
> + *
> + * The interrupt calls handler calls can_put_echo_skb until
> + * priv->eskbp reaches regs->txrd
> + */
> +static netdev_tx_t grcan_start_xmit(struct sk_buff *skb,
> +				    struct net_device *dev)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	struct grcan_dma *dma = &priv->dma;
> +	struct can_frame *cf = (struct can_frame *)skb->data;
> +	u32 id, txwr, txrd, space, txctrl;
> +	int slotindex;
> +	u32 *slot;
> +	u32 i, rtr, eff, dlc, tmp, err;
> +	int j, shift;
> +	unsigned long flags;
> +	u32 oneshotmode = priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT;
> +
> +	if (can_dropped_invalid_skb(dev, skb))
> +		return NETDEV_TX_OK;
> +
> +	/* Trying to transmit in silent mode will generate error interrupts, but
> +	 * this should never happen - the queue should not have been started.
> +	 */
> +	if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
> +		return NETDEV_TX_BUSY;
> +
> +	/* Reads of priv->eskbp and shut-downs of the queue needs to
> +	 * be atomic towards the updates to priv->eskbp and wake-ups
> +	 * of the queue in the interrupt handler.
> +	 */
> +	spin_lock_irqsave(&priv->lock, flags);
> +
> +	txwr = grcan_read_reg(&regs->txwr);
> +	space = grcan_txspace(dma->tx.size, txwr, priv->eskbp);
> +
> +	slotindex = txwr / GRCAN_MSG_SIZE;
> +	slot = dma->tx.buf + txwr;
> +
> +	if (unlikely(space == 1))
> +		netif_stop_queue(dev);
> +
> +	spin_unlock_irqrestore(&priv->lock, flags);
> +	/* End of critical section*/
> +
> +	/* This should never happen. If circular buffer is full, the
> +	 * netif_stop_queue should have been stopped already.
> +	 */
> +	if (unlikely(!space)) {
> +		netdev_err(dev, "No buffer space, but queue is non-stopped.\n");
> +		return NETDEV_TX_BUSY;
> +	}
> +
> +	/* Convert and write CAN message to DMA buffer */
> +	eff = cf->can_id & CAN_EFF_FLAG;
> +	rtr = cf->can_id & CAN_RTR_FLAG;
> +	id = cf->can_id & (eff ? CAN_EFF_MASK : CAN_SFF_MASK);
> +	dlc = cf->can_dlc;
> +	if (eff)
> +		tmp = (id << GRCAN_MSG_EID_BIT) & GRCAN_MSG_EID;
> +	else
> +		tmp = (id << GRCAN_MSG_BID_BIT) & GRCAN_MSG_BID;
> +	slot[0] = (eff ? GRCAN_MSG_IDE : 0) | (rtr ? GRCAN_MSG_RTR : 0) | tmp;
> +
> +	slot[1] = ((dlc << GRCAN_MSG_DLC_BIT) & GRCAN_MSG_DLC);
> +	slot[2] = 0;
> +	slot[3] = 0;
> +	for (i = 0; i < dlc; i++) {
> +		j = GRCAN_MSG_DATA_SLOT_INDEX(i);
> +		shift = GRCAN_MSG_DATA_SHIFT(i);
> +		slot[j] |= cf->data[i] << shift;
> +	}
> +
> +	/* Checking that channel has not been disabled. These cases
> +	 * should never happen
> +	 */
> +	txctrl = grcan_read_reg(&regs->txctrl);
> +	if (!(txctrl & GRCAN_TXCTRL_ENABLE))
> +		netdev_err(dev, "tx channel spuriously disabled\n");
> +
> +	if (oneshotmode && !(txctrl & GRCAN_TXCTRL_SINGLE))
> +		netdev_err(dev, "one-shot mode spuriously disabled\n");
> +
> +	/* Bug workaround for old version of grcan where updating txwr
> +	 * in the same clock cycle as the controller updates txrd to
> +	 * the current txwr could hang the can controller
> +	 */
> +	if (priv->need_txbug_workaround) {
> +		txrd = grcan_read_reg(&regs->txrd);
> +		if (unlikely(grcan_ring_sub(txwr, txrd, dma->tx.size) == 1)) {
> +			netdev_tx_t txstatus;
> +
> +			err = grcan_txbug_workaround(dev, skb, txwr,
> +						     oneshotmode, &txstatus);
> +			if (err)
> +				return txstatus;
> +		}
> +	}
> +
> +	/* Prepare skb for echoing. This must be after the bug workaround above
> +	 * as ownership of the skb is passed on by calling can_put_echo_skb.
> +	 * Returning NETDEV_TX_BUSY or accessing skb or cf after a call to
> +	 * can_put_echo_skb would be an error unless other measures are
> +	 * taken.
> +	 */
> +	priv->txdlc[slotindex] = cf->can_dlc; /* Store dlc for statistics */
> +	can_put_echo_skb(skb, dev, slotindex);
> +
> +	/* Make sure everything is written before allowing hardware to
> +	 * read from the memory
> +	 */
> +	wmb();
> +
> +	/* Update write pointer to start transmission */
> +	grcan_write_reg(&regs->txwr,
> +			grcan_ring_add(txwr, GRCAN_MSG_SIZE, dma->tx.size));
> +
> +	return NETDEV_TX_OK;
> +}
> +
> +/* ========== Setting up sysfs interface and module parameters ========== */
> +
> +#define GRCAN_NOT_BOOL(val) ((val) < 0 || (val) > 1)
> +
> +#define GRCAN_MODULE_PARAM(name, mtype, valcheckf)			\
> +	static void grcan_sanitize_##name(struct platform_device *pd)	\
> +	{								\
> +		struct grcan_device_config grcan_default_config		\
> +			= GRCAN_DEFAULT_DEVICE_CONFIG;			\
> +		if (valcheckf(grcan_module_config.name)) {		\
> +			dev_err(&pd->dev,				\
> +				"Invalid module parameter value for "	\
> +				#name " - setting default\n");		\
> +			grcan_module_config.name =			\
> +				grcan_default_config.name;		\
> +		}							\
> +	}								\
> +	module_param_named(name, grcan_module_config.name,		\
> +			   mtype, S_IRUGO)
> +
> +#define GRCAN_CONFIG_ATTR(name)						\
> +	static ssize_t grcan_store_##name(struct device *sdev,		\
> +					  struct device_attribute *att,	\
> +					  const char *buf,		\
> +					  size_t count)			\
> +	{								\
> +		struct net_device *dev = to_net_dev(sdev);		\
> +		struct grcan_priv *priv = netdev_priv(dev);		\
> +		u8 val;							\
> +		int ret;						\
> +		if (dev->flags & IFF_UP)				\
> +			return -EBUSY;					\
> +		ret = kstrtou8(buf, 0, &val);				\
> +		if (ret < 0 || val < 0 || val > 1)			\
> +			return -EINVAL;					\
> +		priv->config.name = val;				\
> +		return count;						\
> +	}								\
> +	static ssize_t grcan_show_##name(struct device *sdev,		\
> +					 struct device_attribute *att,	\
> +					 char *buf)			\
> +	{								\
> +		struct net_device *dev = to_net_dev(sdev);		\
> +		struct grcan_priv *priv = netdev_priv(dev);		\
> +		return sprintf(buf, "%d\n", priv->config.name);		\
> +	}								\
> +	static DEVICE_ATTR(name, S_IRUGO | S_IWUSR,			\
> +			   grcan_show_##name,				\
> +			   grcan_store_##name);				\
> +	GRCAN_MODULE_PARAM(name, ushort, GRCAN_NOT_BOOL)
> +
> +/* The following configuration options are made available both via module
> + * parameters and writable sysfs files. See the chapter about GRCAN in the
> + * documentation for the GRLIB VHDL library for further details.
> + */
> +
> +/* Configure enable0 - Hardware configuration for interface 0 */
> +GRCAN_CONFIG_ATTR(enable0);
> +
> +/* Configure enable1 - Hardware configuration for interface 1 */
> +GRCAN_CONFIG_ATTR(enable1);
> +
> +/* Configure select - Select which interface to use */
> +GRCAN_CONFIG_ATTR(select);
> +
> +/* The tx and rx buffer size configuration options are only available via module
> + * parameters.
> + */
> +GRCAN_MODULE_PARAM(txsize, uint, GRCAN_INVALID_BUFFER_SIZE);
> +GRCAN_MODULE_PARAM(rxsize, uint, GRCAN_INVALID_BUFFER_SIZE);
> +
> +/* Function that makes sure that configuration done using
> + * module parameters are set to valid values
> + */
> +static void grcan_sanitize_module_config(struct platform_device *ofdev)
> +{
> +	grcan_sanitize_enable0(ofdev);
> +	grcan_sanitize_enable1(ofdev);
> +	grcan_sanitize_select(ofdev);
> +	grcan_sanitize_txsize(ofdev);
> +	grcan_sanitize_rxsize(ofdev);
> +}
> +
> +static const struct attribute *const sysfs_grcan_attrs[] = {
> +	/* Config attrs */
> +	&dev_attr_enable0.attr,
> +	&dev_attr_enable1.attr,
> +	&dev_attr_select.attr,
> +	NULL,
> +};
> +
> +static const struct attribute_group sysfs_grcan_group = {
> +	.name	= "grcan",
> +	.attrs	= (struct attribute **)sysfs_grcan_attrs,
> +};
> +
> +/* ========== Setting up the driver ========== */
> +
> +static const struct net_device_ops grcan_netdev_ops = {
> +	.ndo_open	= grcan_open,
> +	.ndo_stop	= grcan_close,
> +	.ndo_start_xmit	= grcan_start_xmit,
> +};
> +
> +static int grcan_setup_netdev(struct platform_device *ofdev,
> +			      void __iomem *base,
> +			      int irq, u32 ambafreq, bool txbug)
> +{
> +	struct net_device *dev;
> +	struct grcan_priv *priv;
> +	struct grcan_registers __iomem *regs;
> +	int err;
> +
> +	dev = alloc_candev(sizeof(struct grcan_priv), 0);
> +	if (!dev)
> +		return -ENOMEM;
> +
> +	dev->irq = irq;
> +	dev->flags |= IFF_ECHO;
> +	dev->netdev_ops = &grcan_netdev_ops;
> +	dev->sysfs_groups[0] = &sysfs_grcan_group;
> +
> +	priv = netdev_priv(dev);
> +	memcpy(&priv->config, &grcan_module_config,
> +	       sizeof(struct grcan_device_config));
> +	priv->dev = dev;
> +	priv->regs = (struct grcan_registers *)base;

no cast please, it should not be needed.

> +	priv->can.bittiming_const = &grcan_bittiming_const;
> +	priv->can.do_set_bittiming = grcan_set_bittiming;
> +	priv->can.do_set_mode = grcan_set_mode;
> +	priv->can.do_get_berr_counter = grcan_get_berr_counter;
> +	priv->can.clock.freq = ambafreq;
> +	priv->can.ctrlmode_supported =
> +		CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_ONE_SHOT;
> +	priv->need_txbug_workaround = txbug;
> +
> +	/* Discover if triple sampling is supported by hardware */
> +	regs = priv->regs;
> +	grcan_set_bits(&regs->ctrl, GRCAN_CTRL_RESET);
> +	grcan_set_bits(&regs->conf, GRCAN_CONF_SAM);
> +	if (grcan_read_bits(&regs->conf, GRCAN_CONF_SAM)) {
> +		priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES;
> +		dev_info(&ofdev->dev, "Hardware supports triple-sampling\n");

For a more quiet startup, please remove.

> +	}
> +
> +	spin_lock_init(&priv->lock);
> +
> +	if (priv->need_txbug_workaround) {
> +		init_timer(&priv->rr_timer);
> +		priv->rr_timer.function = grcan_running_reset;
> +		priv->rr_timer.data = (unsigned long)dev;
> +
> +		init_timer(&priv->hang_timer);
> +		priv->hang_timer.function = grcan_initiate_running_reset;
> +		priv->hang_timer.data = (unsigned long)dev;
> +	}
> +
> +	netif_napi_add(dev, &priv->napi, grcan_poll, GRCAN_NAPI_WEIGHT);
> +
> +	SET_NETDEV_DEV(dev, &ofdev->dev);
> +	dev_info(&ofdev->dev, "regs=0x%p, irq=%d, clock=%d\n",
> +		 priv->regs, dev->irq, priv->can.clock.freq);
> +
> +	err = register_candev(dev);
> +	if (err) {
> +		dev_err(&ofdev->dev, "registering %s failed (err=%d)\n",
> +			DRV_NAME, err);
> +		goto exit_free_candev;
> +	}
> +	dev_set_drvdata(&ofdev->dev, dev);
> +
> +	/* Reset device to allow bit-timing to be set. No need to call
> +	 * grcan_reset at this stage. That is done in grcan_open.
> +	 */
> +	grcan_write_reg(&regs->ctrl, GRCAN_CTRL_RESET);
> +
> +	return 0;
> +exit_free_candev:
> +	free_candev(dev);
> +	return err;
> +}
> +
> +static int __devinit grcan_probe(struct platform_device *ofdev)
> +{
> +	struct device_node *np = ofdev->dev.of_node;
> +	struct resource *res;
> +	u32 sysid, ambafreq;
> +	int irq, err;
> +	void __iomem *base;
> +	bool txbug = true;
> +
> +	/* Compare GRLIB version number with the first that does not
> +	 * have the tx bug (see start_xmit)
> +	 */
> +	err = of_property_read_u32(np, "systemid", &sysid);
> +	if (!err && ((sysid & GRLIB_VERSION_MASK)
> +		     >= GRCAN_TXBUG_SAFE_GRLIB_VERSION))
> +		txbug = false;
> +
> +	err = of_property_read_u32(np, "freq", &ambafreq);
> +	if (err) {
> +		dev_err(&ofdev->dev, "unable to fetch \"freq\" property\n");
> +		goto exit_error;
> +	}
> +
> +	res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
> +	base = devm_request_and_ioremap(&ofdev->dev, res);
> +	if (!base) {
> +		dev_err(&ofdev->dev, "couldn't map IO resource\n");
> +		err = -EADDRNOTAVAIL;
> +		goto exit_error;
> +	}
> +
> +	irq = irq_of_parse_and_map(np, GRCAN_IRQIX_IRQ);
> +	if (irq == NO_IRQ) {
> +		dev_err(&ofdev->dev, "no irq found\n");
> +		err = -ENODEV;
> +		goto exit_error;
> +	}
> +
> +	grcan_sanitize_module_config(ofdev);
> +
> +	err = grcan_setup_netdev(ofdev, base, irq, ambafreq, txbug);
> +	if (err)
> +		goto exit_dispose_irq;
> +
> +	return 0;
> +
> +exit_dispose_irq:
> +	irq_dispose_mapping(irq);
> +exit_error:
> +	dev_err(&ofdev->dev,
> +		"%s socket CAN driver initialization failed with error %d\n",
> +		DRV_NAME, err);
                ^^^^^^^^^

not needed, you're using dev_err(), which has all relevant information.
Or better remove completly as the framework will print this information too.

> +	return err;
> +}
> +
> +static int __devexit grcan_remove(struct platform_device *ofdev)
> +{
> +	struct net_device *dev = dev_get_drvdata(&ofdev->dev);
> +	struct grcan_priv *priv = netdev_priv(dev);
> +
> +	unregister_candev(dev); /* Will in turn call grcan_close */
> +
> +	irq_dispose_mapping(dev->irq);
> +	dev_set_drvdata(&ofdev->dev, NULL);
> +	netif_napi_del(&priv->napi);
> +	free_candev(dev);
> +
> +	dev_info(&ofdev->dev, "%s socket CAN driver removed\n", DRV_NAME);

You can remove that completely.

> +	return 0;
> +}
> +
> +static struct of_device_id grcan_match[] = {
> +	{.name = "GAISLER_GRCAN"},
> +	{.name = "01_03d"},
> +	{.name = "GAISLER_GRHCAN"},
> +	{.name = "01_034"},
> +	{},
> +};
> +
> +MODULE_DEVICE_TABLE(of, grcan_match);
> +
> +static struct platform_driver grcan_driver = {
> +	.driver = {
> +		.name = DRV_NAME,
> +		.owner = THIS_MODULE,
> +		.of_match_table = grcan_match,
> +	},
> +	.probe = grcan_probe,
> +	.remove = __devexit_p(grcan_remove),
> +};
> +
> +module_platform_driver(grcan_driver);
> +
> +MODULE_AUTHOR("Aeroflex Gaisler AB.");
> +MODULE_DESCRIPTION("Socket CAN driver for Aeroflex Gaisler GRCAN");
> +MODULE_LICENSE("GPL");
> 


-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH v8] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-11-09  0:01                                           ` Marc Kleine-Budde
@ 2012-11-12 14:57                                             ` Andreas Larsson
  2012-11-13 21:15                                               ` Marc Kleine-Budde
  0 siblings, 1 reply; 41+ messages in thread
From: Andreas Larsson @ 2012-11-12 14:57 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: linux-can, software, Wolfgang Grandegger, devicetree-discuss

This driver supports GRCAN and CRHCAN CAN controllers available in the GRLIB
VHDL IP core library.

Signed-off-by: Andreas Larsson <andreas@gaisler.com>
Acked-by: Wolfgang Grandegger <wg@grandegger.com>
---
Changes since v7:
- Enable napi before turning on interrupts
- Remove unneeded casts, unneded checks and improper devm_ usages
- Fix, downgrade or remove some printouts
- Rewrite poll function so that tx gets its own budget and so that undone work
  does not fall between the cracks when enabling interrupts
- Don't check irq number against NO_IRQ that does not exist on all OF enabled
  platforms
- Document kernel parameters with MODULE_PARM_DESC

 Documentation/ABI/testing/sysfs-class-net-grcan    |   35 +
 .../devicetree/bindings/net/can/grcan.txt          |   28 +
 Documentation/kernel-parameters.txt                |   18 +
 drivers/net/can/Kconfig                            |    9 +
 drivers/net/can/Makefile                           |    1 +
 drivers/net/can/grcan.c                            | 1768 ++++++++++++++++++++
 6 files changed, 1859 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-class-net-grcan
 create mode 100644 Documentation/devicetree/bindings/net/can/grcan.txt
 create mode 100644 drivers/net/can/grcan.c

diff --git a/Documentation/ABI/testing/sysfs-class-net-grcan b/Documentation/ABI/testing/sysfs-class-net-grcan
new file mode 100644
index 0000000..f418c92
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-net-grcan
@@ -0,0 +1,35 @@
+
+What:		/sys/class/net/<iface>/grcan/enable0
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas@gaisler.com>
+Description:
+		Hardware configuration of physical interface 0. This file reads
+		and writes the "Enable 0" bit of the configuration register.
+		Possible values: 0 or 1. See the GRCAN chapter of the GRLIB IP
+		core library documentation for details. The default value is 0
+		or set by the module parameter grcan.enable0 and can be read at
+		/sys/module/grcan/parameters/enable0.
+
+What:		/sys/class/net/<iface>/grcan/enable1
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas@gaisler.com>
+Description:
+		Hardware configuration of physical interface 1. This file reads
+		and writes the "Enable 1" bit of the configuration register.
+		Possible values: 0 or 1. See the GRCAN chapter of the GRLIB IP
+		core library documentation for details. The default value is 0
+		or set by the module parameter grcan.enable1 and can be read at
+		/sys/module/grcan/parameters/enable1.
+
+What:		/sys/class/net/<iface>/grcan/select
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas@gaisler.com>
+Description:
+		Configuration of which physical interface to be used. Possible
+		values: 0 or 1. See the GRCAN chapter of the GRLIB IP core
+		library documentation for details. The default value is 0 or is
+		set by the module parameter grcan.select and can be read at
+		/sys/module/grcan/parameters/select.
diff --git a/Documentation/devicetree/bindings/net/can/grcan.txt b/Documentation/devicetree/bindings/net/can/grcan.txt
new file mode 100644
index 0000000..34ef349
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/can/grcan.txt
@@ -0,0 +1,28 @@
+Aeroflex Gaisler GRCAN and GRHCAN CAN controllers.
+
+The GRCAN and CRHCAN CAN controllers are available in the GRLIB VHDL IP core
+library.
+
+Note: These properties are built from the AMBA plug&play in a Leon SPARC system
+(the ordinary environment for GRCAN and GRHCAN). There are no dts files for
+sparc.
+
+Required properties:
+
+- name : Should be "GAISLER_GRCAN", "01_03d", "GAISLER_GRHCAN" or "01_034"
+
+- reg : Address and length of the register set for the device
+
+- freq : Frequency of the external oscillator clock in Hz (the frequency of
+	the amba bus in the ordinary case)
+
+- interrupts : Interrupt number for this device
+
+Optional properties:
+
+- systemid : If not present or if the value of the least significant 16 bits
+	of this 32-bit property is smaller than GRCAN_TXBUG_SAFE_GRLIB_VERSION
+	a bug workaround is activated.
+
+For further information look in the documentation for the GLIB IP core library:
+http://www.gaisler.com/products/grlib/grip.pdf
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 9776f06..3da4f96 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -905,6 +905,24 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 	gpt		[EFI] Forces disk with valid GPT signature but
 			invalid Protective MBR to be treated as GPT.
 
+	grcan.enable0=	[HW] Configuration of physical interface 0. Determines
+			the "Enable 0" bit of the configuration register.
+			Format: 0 | 1
+			Default: 0
+	grcan.enable1=	[HW] Configuration of physical interface 1. Determines
+			the "Enable 0" bit of the configuration register.
+			Format: 0 | 1
+			Default: 0
+	grcan.select=	[HW] Select which physical interface to use.
+			Format: 0 | 1
+			Default: 0
+	grcan.txsize=	[HW] Sets the size of the tx buffer.
+			Format: <unsigned int> such that (txsize & ~0x1fffc0) == 0.
+			Default: 1024
+	grcan.rxsize=	[HW] Sets the size of the rx buffer.
+			Format: <unsigned int> such that (rxsize & ~0x1fffc0) == 0.
+			Default: 1024
+
 	hashdist=	[KNL,NUMA] Large hashes allocated during boot
 			are distributed across NUMA nodes.  Defaults on
 			for 64-bit NUMA, off otherwise.
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
index bb709fd..b56bd9e 100644
--- a/drivers/net/can/Kconfig
+++ b/drivers/net/can/Kconfig
@@ -110,6 +110,15 @@ config PCH_CAN
 	  is an IOH for x86 embedded processor (Intel Atom E6xx series).
 	  This driver can access CAN bus.
 
+config CAN_GRCAN
+	tristate "Aeroflex Gaisler GRCAN and GRHCAN CAN devices"
+	depends on CAN_DEV && OF
+	---help---
+	  Say Y here if you want to use Aeroflex Gaisler GRCAN or GRHCAN.
+	  Note that the driver supports little endian, even though little
+	  endian syntheses of the cores would need some modifications on
+	  the hardware level to work.
+
 source "drivers/net/can/mscan/Kconfig"
 
 source "drivers/net/can/sja1000/Kconfig"
diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
index 938be37..7de5986 100644
--- a/drivers/net/can/Makefile
+++ b/drivers/net/can/Makefile
@@ -22,5 +22,6 @@ obj-$(CONFIG_CAN_BFIN)		+= bfin_can.o
 obj-$(CONFIG_CAN_JANZ_ICAN3)	+= janz-ican3.o
 obj-$(CONFIG_CAN_FLEXCAN)	+= flexcan.o
 obj-$(CONFIG_PCH_CAN)		+= pch_can.o
+obj-$(CONFIG_CAN_GRCAN)		+= grcan.o
 
 ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/grcan.c b/drivers/net/can/grcan.c
new file mode 100644
index 0000000..2eafe74
--- /dev/null
+++ b/drivers/net/can/grcan.c
@@ -0,0 +1,1768 @@
+/*
+ * Socket CAN driver for Aeroflex Gaisler GRCAN and GRHCAN.
+ *
+ * 2012 (c) Aeroflex Gaisler AB
+ *
+ * This driver supports GRCAN and GRHCAN CAN controllers available in the GRLIB
+ * VHDL IP core library.
+ *
+ * Full documentation of the GRCAN core can be found here:
+ * http://www.gaisler.com/products/grlib/grip.pdf
+ *
+ * See "Documentation/devicetree/bindings/net/can/grcan.txt" for information on
+ * open firmware properties.
+ *
+ * See "Documentation/ABI/testing/sysfs-class-net-grcan" for information on the
+ * sysfs interface.
+ *
+ * See "Documentation/kernel-parameters.txt" for information on the module
+ * parameters.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Contributors: Andreas Larsson <andreas@gaisler.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/can/dev.h>
+#include <linux/spinlock.h>
+
+#include <linux/of_platform.h>
+#include <asm/prom.h>
+
+#include <linux/of_irq.h>
+
+#include <linux/dma-mapping.h>
+
+#define DRV_NAME	"grcan"
+
+#define GRCAN_TX_BUDGET		16
+#define GRCAN_NAPI_WEIGHT	16
+
+#define GRCAN_RESERVE_SIZE(slot1, slot2) (((slot2) - (slot1)) / 4 - 1)
+
+struct grcan_registers {
+	u32 conf;	/* 0x00 */
+	u32 stat;	/* 0x04 */
+	u32 ctrl;	/* 0x08 */
+	u32 __reserved1[GRCAN_RESERVE_SIZE(0x08, 0x18)];
+	u32 smask;	/* 0x18 - CanMASK */
+	u32 scode;	/* 0x1c - CanCODE */
+	u32 __reserved2[GRCAN_RESERVE_SIZE(0x1c, 0x100)];
+	u32 pimsr;	/* 0x100 */
+	u32 pimr;	/* 0x104 */
+	u32 pisr;	/* 0x108 */
+	u32 pir;	/* 0x10C */
+	u32 imr;	/* 0x110 */
+	u32 picr;	/* 0x114 */
+	u32 __reserved3[GRCAN_RESERVE_SIZE(0x114, 0x200)];
+	u32 txctrl;	/* 0x200 */
+	u32 txaddr;	/* 0x204 */
+	u32 txsize;	/* 0x208 */
+	u32 txwr;	/* 0x20C */
+	u32 txrd;	/* 0x210 */
+	u32 txirq;	/* 0x214 */
+	u32 __reserved4[GRCAN_RESERVE_SIZE(0x214, 0x300)];
+	u32 rxctrl;	/* 0x300 */
+	u32 rxaddr;	/* 0x304 */
+	u32 rxsize;	/* 0x308 */
+	u32 rxwr;	/* 0x30C */
+	u32 rxrd;	/* 0x310 */
+	u32 rxirq;	/* 0x314 */
+	u32 rxmask;	/* 0x318 */
+	u32 rxcode;	/* 0x31C */
+};
+
+#define GRCAN_CONF_ABORT	0x00000001
+#define GRCAN_CONF_ENABLE0	0x00000002
+#define GRCAN_CONF_ENABLE1	0x00000004
+#define GRCAN_CONF_SELECT	0x00000008
+#define GRCAN_CONF_SILENT	0x00000010
+#define GRCAN_CONF_SAM		0x00000020 /* Available in some hardware */
+#define GRCAN_CONF_BPR		0x00000300 /* Note: not BRP */
+#define GRCAN_CONF_RSJ		0x00007000
+#define GRCAN_CONF_PS1		0x00f00000
+#define GRCAN_CONF_PS2		0x000f0000
+#define GRCAN_CONF_SCALER	0xff000000
+#define GRCAN_CONF_OPERATION						\
+	(GRCAN_CONF_ABORT | GRCAN_CONF_ENABLE0 | GRCAN_CONF_ENABLE1	\
+	 | GRCAN_CONF_SELECT | GRCAN_CONF_SILENT | GRCAN_CONF_SAM)
+#define GRCAN_CONF_TIMING						\
+	(GRCAN_CONF_BPR | GRCAN_CONF_RSJ | GRCAN_CONF_PS1		\
+	 | GRCAN_CONF_PS2 | GRCAN_CONF_SCALER)
+
+#define GRCAN_CONF_RSJ_MIN	1
+#define GRCAN_CONF_RSJ_MAX	4
+#define GRCAN_CONF_PS1_MIN	1
+#define GRCAN_CONF_PS1_MAX	15
+#define GRCAN_CONF_PS2_MIN	2
+#define GRCAN_CONF_PS2_MAX	8
+#define GRCAN_CONF_SCALER_MIN	0
+#define GRCAN_CONF_SCALER_MAX	255
+#define GRCAN_CONF_SCALER_INC	1
+
+#define GRCAN_CONF_BPR_BIT	8
+#define GRCAN_CONF_RSJ_BIT	12
+#define GRCAN_CONF_PS1_BIT	20
+#define GRCAN_CONF_PS2_BIT	16
+#define GRCAN_CONF_SCALER_BIT	24
+
+#define GRCAN_STAT_PASS		0x000001
+#define GRCAN_STAT_OFF		0x000002
+#define GRCAN_STAT_OR		0x000004
+#define GRCAN_STAT_AHBERR	0x000008
+#define GRCAN_STAT_ACTIVE	0x000010
+#define GRCAN_STAT_RXERRCNT	0x00ff00
+#define GRCAN_STAT_TXERRCNT	0xff0000
+
+#define GRCAN_STAT_ERRCTR_RELATED	(GRCAN_STAT_PASS | GRCAN_STAT_OFF)
+
+#define GRCAN_STAT_RXERRCNT_BIT	8
+#define GRCAN_STAT_TXERRCNT_BIT	16
+
+#define GRCAN_STAT_ERRCNT_WARNING_LIMIT	96
+#define GRCAN_STAT_ERRCNT_PASSIVE_LIMIT	127
+
+#define GRCAN_CTRL_RESET	0x2
+#define GRCAN_CTRL_ENABLE	0x1
+
+#define GRCAN_TXCTRL_ENABLE	0x1
+#define GRCAN_TXCTRL_ONGOING	0x2
+#define GRCAN_TXCTRL_SINGLE	0x4
+
+#define GRCAN_RXCTRL_ENABLE	0x1
+#define GRCAN_RXCTRL_ONGOING	0x2
+
+/* Relative offset of IRQ sources to AMBA Plug&Play */
+#define GRCAN_IRQIX_IRQ		0
+#define GRCAN_IRQIX_TXSYNC	1
+#define GRCAN_IRQIX_RXSYNC	2
+
+#define GRCAN_IRQ_PASS		0x00001
+#define GRCAN_IRQ_OFF		0x00002
+#define GRCAN_IRQ_OR		0x00004
+#define GRCAN_IRQ_RXAHBERR	0x00008
+#define GRCAN_IRQ_TXAHBERR	0x00010
+#define GRCAN_IRQ_RXIRQ		0x00020
+#define GRCAN_IRQ_TXIRQ		0x00040
+#define GRCAN_IRQ_RXFULL	0x00080
+#define GRCAN_IRQ_TXEMPTY	0x00100
+#define GRCAN_IRQ_RX		0x00200
+#define GRCAN_IRQ_TX		0x00400
+#define GRCAN_IRQ_RXSYNC	0x00800
+#define GRCAN_IRQ_TXSYNC	0x01000
+#define GRCAN_IRQ_RXERRCTR	0x02000
+#define GRCAN_IRQ_TXERRCTR	0x04000
+#define GRCAN_IRQ_RXMISS	0x08000
+#define GRCAN_IRQ_TXLOSS	0x10000
+
+#define GRCAN_IRQ_NONE	0
+#define GRCAN_IRQ_ALL							\
+	(GRCAN_IRQ_PASS | GRCAN_IRQ_OFF | GRCAN_IRQ_OR			\
+	 | GRCAN_IRQ_RXAHBERR | GRCAN_IRQ_TXAHBERR			\
+	 | GRCAN_IRQ_RXIRQ | GRCAN_IRQ_TXIRQ				\
+	 | GRCAN_IRQ_RXFULL | GRCAN_IRQ_TXEMPTY				\
+	 | GRCAN_IRQ_RX | GRCAN_IRQ_TX | GRCAN_IRQ_RXSYNC		\
+	 | GRCAN_IRQ_TXSYNC | GRCAN_IRQ_RXERRCTR			\
+	 | GRCAN_IRQ_TXERRCTR | GRCAN_IRQ_RXMISS			\
+	 | GRCAN_IRQ_TXLOSS)
+
+#define GRCAN_IRQ_ERRCTR_RELATED (GRCAN_IRQ_RXERRCTR | GRCAN_IRQ_TXERRCTR \
+				  | GRCAN_IRQ_PASS | GRCAN_IRQ_OFF)
+#define GRCAN_IRQ_ERRORS (GRCAN_IRQ_ERRCTR_RELATED | GRCAN_IRQ_OR	\
+			  | GRCAN_IRQ_TXAHBERR | GRCAN_IRQ_RXAHBERR	\
+			  | GRCAN_IRQ_TXLOSS)
+#define GRCAN_IRQ_DEFAULT (GRCAN_IRQ_RX | GRCAN_IRQ_TX | GRCAN_IRQ_ERRORS)
+
+#define GRCAN_MSG_SIZE		16
+
+#define GRCAN_MSG_IDE		0x80000000
+#define GRCAN_MSG_RTR		0x40000000
+#define GRCAN_MSG_BID		0x1ffc0000
+#define GRCAN_MSG_EID		0x1fffffff
+#define GRCAN_MSG_IDE_BIT	31
+#define GRCAN_MSG_RTR_BIT	30
+#define GRCAN_MSG_BID_BIT	18
+#define GRCAN_MSG_EID_BIT	0
+
+#define GRCAN_MSG_DLC		0xf0000000
+#define GRCAN_MSG_TXERRC	0x00ff0000
+#define GRCAN_MSG_RXERRC	0x0000ff00
+#define GRCAN_MSG_DLC_BIT	28
+#define GRCAN_MSG_TXERRC_BIT	16
+#define GRCAN_MSG_RXERRC_BIT	8
+#define GRCAN_MSG_AHBERR	0x00000008
+#define GRCAN_MSG_OR		0x00000004
+#define GRCAN_MSG_OFF		0x00000002
+#define GRCAN_MSG_PASS		0x00000001
+
+#define GRCAN_MSG_DATA_SLOT_INDEX(i) (2 + (i) / 4)
+#define GRCAN_MSG_DATA_SHIFT(i) ((3 - (i) % 4) * 8)
+
+#define GRCAN_BUFFER_ALIGNMENT		1024
+#define GRCAN_DEFAULT_BUFFER_SIZE	1024
+#define GRCAN_VALID_TR_SIZE_MASK	0x001fffc0
+
+#define GRCAN_INVALID_BUFFER_SIZE(s)			\
+	((s) == 0 || ((s) & ~GRCAN_VALID_TR_SIZE_MASK))
+
+#if GRCAN_INVALID_BUFFER_SIZE(GRCAN_DEFAULT_BUFFER_SIZE)
+#error "Invalid default buffer size"
+#endif
+
+struct grcan_dma_buffer {
+	size_t size;
+	void *buf;
+	dma_addr_t handle;
+};
+
+struct grcan_dma {
+	size_t base_size;
+	void *base_buf;
+	dma_addr_t base_handle;
+	struct grcan_dma_buffer tx;
+	struct grcan_dma_buffer rx;
+};
+
+/* GRCAN configuration parameters */
+struct grcan_device_config {
+	unsigned short enable0;
+	unsigned short enable1;
+	unsigned short select;
+	unsigned int txsize;
+	unsigned int rxsize;
+};
+
+#define GRCAN_DEFAULT_DEVICE_CONFIG {				\
+		.enable0	= 0,				\
+		.enable1	= 0,				\
+		.select		= 0,				\
+		.txsize		= GRCAN_DEFAULT_BUFFER_SIZE,	\
+		.rxsize		= GRCAN_DEFAULT_BUFFER_SIZE,	\
+		}
+
+#define GRCAN_TXBUG_SAFE_GRLIB_VERSION	0x4100
+#define GRLIB_VERSION_MASK		0xffff
+
+/* GRCAN private data structure */
+struct grcan_priv {
+	struct can_priv can;	/* must be the first member */
+	struct net_device *dev;
+	struct napi_struct napi;
+
+	struct grcan_registers __iomem *regs;	/* ioremap'ed registers */
+	struct grcan_device_config config;
+	struct grcan_dma dma;
+
+	struct sk_buff **echo_skb;	/* We allocate this on our own */
+	u8 *txdlc;			/* Length of queued frames */
+
+	/* The echo skb pointer, pointing into echo_skb and indicating which
+	 * frames can be echoed back. See the "Notes on the tx cyclic buffer
+	 * handling"-comment for grcan_start_xmit for more details.
+	 */
+	u32 eskbp;
+
+	/* Lock for controlling changes to the netif tx queue state, accesses to
+	 * the echo_skb pointer eskbp and for making sure that a running reset
+	 * and/or a close of the interface is done without interference from
+	 * other parts of the code.
+	 *
+	 * The echo_skb pointer, eskbp, should only be accessed under this lock
+	 * as it can be changed in several places and together with decisions on
+	 * whether to wake up the tx queue.
+	 *
+	 * The tx queue must never be woken up if there is a running reset or
+	 * close in progress.
+	 *
+	 * A running reset (see below on need_txbug_workaround) should never be
+	 * done if the interface is closing down and several running resets
+	 * should never be scheduled simultaneously.
+	 */
+	spinlock_t lock;
+
+	/* Whether a workaround is needed due to a bug in older hardware. In
+	 * this case, the driver both tries to prevent the bug from being
+	 * triggered and recovers, if the bug nevertheless happens, by doing a
+	 * running reset. A running reset, resets the device and continues from
+	 * where it were without being noticeable from outside the driver (apart
+	 * from slight delays).
+	 */
+	bool need_txbug_workaround;
+
+	/* To trigger initization of running reset and to trigger running reset
+	 * respectively in the case of a hanged device due to a txbug.
+	 */
+	struct timer_list hang_timer;
+	struct timer_list rr_timer;
+
+	/* To avoid waking up the netif queue and restarting timers
+	 * when a reset is scheduled or when closing of the device is
+	 * undergoing
+	 */
+	bool resetting;
+	bool closing;
+};
+
+/* Wait time for a short wait for ongoing to clear */
+#define GRCAN_SHORTWAIT_USECS	10
+
+/* Limit on the number of transmitted bits of an eff frame according to the CAN
+ * specification: 1 bit start of frame, 32 bits arbitration field, 6 bits
+ * control field, 8 bytes data field, 16 bits crc field, 2 bits ACK field and 7
+ * bits end of frame
+ */
+#define GRCAN_EFF_FRAME_MAX_BITS	(1+32+6+8*8+16+2+7)
+
+#if defined(__BIG_ENDIAN)
+static inline u32 grcan_read_reg(u32 __iomem *reg)
+{
+	return ioread32be(reg);
+}
+
+static inline void grcan_write_reg(u32 __iomem *reg, u32 val)
+{
+	iowrite32be(val, reg);
+}
+#else
+static inline u32 grcan_read_reg(u32 __iomem *reg)
+{
+	return ioread32(reg);
+}
+
+static inline void grcan_write_reg(u32 __iomem *reg, u32 val)
+{
+	iowrite32(val, reg);
+}
+#endif
+
+static inline void grcan_clear_bits(u32 __iomem *reg, u32 mask)
+{
+	grcan_write_reg(reg, grcan_read_reg(reg) & ~mask);
+}
+
+static inline void grcan_set_bits(u32 __iomem *reg, u32 mask)
+{
+	grcan_write_reg(reg, grcan_read_reg(reg) | mask);
+}
+
+static inline u32 grcan_read_bits(u32 __iomem *reg, u32 mask)
+{
+	return grcan_read_reg(reg) & mask;
+}
+
+static inline void grcan_write_bits(u32 __iomem *reg, u32 value, u32 mask)
+{
+	u32 old = grcan_read_reg(reg);
+
+	grcan_write_reg(reg, (old & ~mask) | (value & mask));
+}
+
+/* a and b should both be in [0,size] and a == b == size should not hold */
+static inline u32 grcan_ring_add(u32 a, u32 b, u32 size)
+{
+	u32 sum = a + b;
+
+	if (sum < size)
+		return sum;
+	else
+		return sum - size;
+}
+
+/* a and b should both be in [0,size) */
+static inline u32 grcan_ring_sub(u32 a, u32 b, u32 size)
+{
+	return grcan_ring_add(a, size - b, size);
+}
+
+/* Available slots for new transmissions */
+static inline u32 grcan_txspace(size_t txsize, u32 txwr, u32 eskbp)
+{
+	u32 slots = txsize / GRCAN_MSG_SIZE - 1;
+	u32 used = grcan_ring_sub(txwr, eskbp, txsize) / GRCAN_MSG_SIZE;
+
+	return slots - used;
+}
+
+/* Configuration parameters that can be set via module parameters */
+static struct grcan_device_config grcan_module_config =
+	GRCAN_DEFAULT_DEVICE_CONFIG;
+
+static struct can_bittiming_const grcan_bittiming_const = {
+	.name		= DRV_NAME,
+	.tseg1_min	= GRCAN_CONF_PS1_MIN + 1,
+	.tseg1_max	= GRCAN_CONF_PS1_MAX + 1,
+	.tseg2_min	= GRCAN_CONF_PS2_MIN,
+	.tseg2_max	= GRCAN_CONF_PS2_MAX,
+	.sjw_max	= GRCAN_CONF_RSJ_MAX,
+	.brp_min	= GRCAN_CONF_SCALER_MIN + 1,
+	.brp_max	= GRCAN_CONF_SCALER_MAX + 1,
+	.brp_inc	= GRCAN_CONF_SCALER_INC,
+};
+
+static int grcan_set_bittiming(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct can_bittiming *bt = &priv->can.bittiming;
+	u32 timing = 0;
+	int bpr, rsj, ps1, ps2, scaler;
+
+	/* Should never happen - function will not be called when
+	 * device is up
+	 */
+	if (grcan_read_bits(&regs->ctrl, GRCAN_CTRL_ENABLE))
+		return -EBUSY;
+
+	bpr = 0; /* Note bpr and brp are different concepts */
+	rsj = bt->sjw;
+	ps1 = (bt->prop_seg + bt->phase_seg1) - 1; /* tseg1 - 1 */
+	ps2 = bt->phase_seg2;
+	scaler = (bt->brp - 1);
+	timing |= (bpr << GRCAN_CONF_BPR_BIT) & GRCAN_CONF_BPR;
+	timing |= (rsj << GRCAN_CONF_RSJ_BIT) & GRCAN_CONF_RSJ;
+	timing |= (ps1 << GRCAN_CONF_PS1_BIT) & GRCAN_CONF_PS1;
+	timing |= (ps2 << GRCAN_CONF_PS2_BIT) & GRCAN_CONF_PS2;
+	timing |= (scaler << GRCAN_CONF_SCALER_BIT) & GRCAN_CONF_SCALER;
+
+	netdev_info(dev, "setting timing=0x%x\n", timing);
+	if (!(ps1 > ps2)) {
+		netdev_err(dev, "PS1 > PS2 must hold: PS1=%d, PS2=%d\n",
+			   ps1, ps2);
+		return -EINVAL;
+	}
+	if (!(ps2 >= rsj)) {
+		netdev_err(dev, "PS2 >= RSJ must hold: PS2=%d, RSJ=%d\n",
+			   ps2, rsj);
+		return -EINVAL;
+	}
+
+	grcan_write_bits(&regs->conf, timing, GRCAN_CONF_TIMING);
+	return 0;
+}
+
+static int grcan_get_berr_counter(const struct net_device *dev,
+				  struct can_berr_counter *bec)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	u32 status = grcan_read_reg(&regs->stat);
+
+	bec->txerr = (status & GRCAN_STAT_TXERRCNT) >> GRCAN_STAT_TXERRCNT_BIT;
+	bec->rxerr = (status & GRCAN_STAT_RXERRCNT) >> GRCAN_STAT_RXERRCNT_BIT;
+	return 0;
+}
+
+static int grcan_poll(struct napi_struct *napi, int budget);
+
+/* Reset device, but keep configuration information */
+static void grcan_reset(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	u32 config = grcan_read_reg(&regs->conf);
+
+	grcan_set_bits(&regs->ctrl, GRCAN_CTRL_RESET);
+	grcan_write_reg(&regs->conf, config);
+
+	priv->eskbp = grcan_read_reg(&regs->txrd);
+	priv->can.state = CAN_STATE_STOPPED;
+
+	/* Turn off hardware filtering - regs->rxcode set to 0 by reset */
+	grcan_write_reg(&regs->rxmask, 0);
+}
+
+/* stop device without changing any configurations */
+static void grcan_stop_hardware(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+
+	grcan_write_reg(&regs->imr, GRCAN_IRQ_NONE);
+	grcan_clear_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
+	grcan_clear_bits(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+	grcan_clear_bits(&regs->ctrl, GRCAN_CTRL_ENABLE);
+}
+
+/* Let priv->eskbp catch up to regs->txrd and echo back the skbs if echo
+ * is true and free them otherwise.
+ *
+ * If budget is >= 0, stop after handling at most budget skbs. Otherwise,
+ * continue until priv->eskbp catches up to regs->txrd.
+ *
+ * priv->lock *must* be held when calling this function
+ */
+static int catch_up_echo_skb(struct net_device *dev, int budget, bool echo)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	struct net_device_stats *stats = &dev->stats;
+	int i, work_done;
+
+	/* Updates to priv->eskbp and wake-ups of the queue needs to
+	 * be atomic towards the reads of priv->eskbp and shut-downs
+	 * of the queue in grcan_start_xmit.
+	 */
+	u32 txrd = grcan_read_reg(&regs->txrd);
+
+	for (work_done = 0; work_done < budget || budget < 0; work_done++) {
+		if (priv->eskbp == txrd)
+			break;
+		i = priv->eskbp / GRCAN_MSG_SIZE;
+		if (echo) {
+			/* Normal echo of messages */
+			stats->tx_packets++;
+			stats->tx_bytes += priv->txdlc[i];
+			priv->txdlc[i] = 0;
+			can_get_echo_skb(dev, i);
+		} else {
+			/* For cleanup of untransmitted messages */
+			can_free_echo_skb(dev, i);
+		}
+
+		priv->eskbp = grcan_ring_add(priv->eskbp, GRCAN_MSG_SIZE,
+					     dma->tx.size);
+		txrd = grcan_read_reg(&regs->txrd);
+	}
+	return work_done;
+}
+
+static void grcan_lost_one_shot_frame(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	u32 txrd;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	catch_up_echo_skb(dev, -1, true);
+
+	if (unlikely(grcan_read_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE))) {
+		/* Should never happen */
+		netdev_err(dev, "TXCTRL enabled at TXLOSS in one shot mode\n");
+	} else {
+		/* By the time an GRCAN_IRQ_TXLOSS is generated in
+		 * one-shot mode there is no problem in writing
+		 * to TXRD even in versions of the hardware in
+		 * which GRCAN_TXCTRL_ONGOING is not cleared properly
+		 * in one-shot mode.
+		 */
+
+		/* Skip message and discard echo-skb */
+		txrd = grcan_read_reg(&regs->txrd);
+		txrd = grcan_ring_add(txrd, GRCAN_MSG_SIZE, dma->tx.size);
+		grcan_write_reg(&regs->txrd, txrd);
+		catch_up_echo_skb(dev, -1, false);
+
+		if (!priv->resetting && !priv->closing &&
+		    !(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)) {
+			netif_wake_queue(dev);
+			grcan_set_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
+		}
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static void grcan_err(struct net_device *dev, u32 sources, u32 status)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	struct net_device_stats *stats = &dev->stats;
+	struct can_frame cf;
+
+	/* Zero potential error_frame */
+	memset(&cf, 0, sizeof(cf));
+
+	/* Message lost interrupt. This might be due to arbitration error, but
+	 * is also triggered when there is no one else on the can bus or when
+	 * there is a problem with the hardware interface or the bus itself. As
+	 * arbitration errors can not be singled out, no error frames are
+	 * generated reporting this event as an arbitration error.
+	 */
+	if (sources & GRCAN_IRQ_TXLOSS) {
+		/* Take care of failed one-shot transmit */
+		if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT)
+			grcan_lost_one_shot_frame(dev);
+
+		/* Stop printing as soon as error passive or bus off is in
+		 * effect to limit the amount of txloss debug printouts.
+		 */
+		if (!(status & GRCAN_STAT_ERRCTR_RELATED)) {
+			netdev_dbg(dev, "tx message lost\n");
+			stats->tx_errors++;
+		}
+	}
+
+	/* Conditions dealing with the error counters. There is no interrupt for
+	 * error warning, but there are interrupts for increases of the error
+	 * counters.
+	 */
+	if ((sources & GRCAN_IRQ_ERRCTR_RELATED) ||
+	    (status & GRCAN_STAT_ERRCTR_RELATED)) {
+		enum can_state state = priv->can.state;
+		enum can_state oldstate = state;
+		u32 txerr = (status & GRCAN_STAT_TXERRCNT)
+			>> GRCAN_STAT_TXERRCNT_BIT;
+		u32 rxerr = (status & GRCAN_STAT_RXERRCNT)
+			>> GRCAN_STAT_RXERRCNT_BIT;
+
+		/* Figure out current state */
+		if (status & GRCAN_STAT_OFF) {
+			state = CAN_STATE_BUS_OFF;
+		} else if (status & GRCAN_STAT_PASS) {
+			state = CAN_STATE_ERROR_PASSIVE;
+		} else if (txerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT ||
+			   rxerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT) {
+			state = CAN_STATE_ERROR_WARNING;
+		} else {
+			state = CAN_STATE_ERROR_ACTIVE;
+		}
+
+		/* Handle and report state changes */
+		if (state != oldstate) {
+			switch (state) {
+			case CAN_STATE_BUS_OFF:
+				netdev_dbg(dev, "bus-off\n");
+				netif_carrier_off(dev);
+				priv->can.can_stats.bus_off++;
+
+				/* Prevent the hardware from recovering from bus
+				 * off on its own if restart is disabled.
+				 */
+				if (!priv->can.restart_ms)
+					grcan_stop_hardware(dev);
+
+				cf.can_id |= CAN_ERR_BUSOFF;
+				break;
+
+			case CAN_STATE_ERROR_PASSIVE:
+				netdev_dbg(dev, "Error passive condition\n");
+				priv->can.can_stats.error_passive++;
+
+				cf.can_id |= CAN_ERR_CRTL;
+				if (txerr >= GRCAN_STAT_ERRCNT_PASSIVE_LIMIT)
+					cf.data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
+				if (rxerr >= GRCAN_STAT_ERRCNT_PASSIVE_LIMIT)
+					cf.data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
+				break;
+
+			case CAN_STATE_ERROR_WARNING:
+				netdev_dbg(dev, "Error warning condition\n");
+				priv->can.can_stats.error_warning++;
+
+				cf.can_id |= CAN_ERR_CRTL;
+				if (txerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT)
+					cf.data[1] |= CAN_ERR_CRTL_TX_WARNING;
+				if (rxerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT)
+					cf.data[1] |= CAN_ERR_CRTL_RX_WARNING;
+				break;
+
+			case CAN_STATE_ERROR_ACTIVE:
+				netdev_dbg(dev, "Error active condition\n");
+				cf.can_id |= CAN_ERR_CRTL;
+				break;
+
+			default:
+				/* There are no others at this point */
+				break;
+			}
+			cf.data[6] = txerr;
+			cf.data[7] = rxerr;
+			priv->can.state = state;
+		}
+
+		/* Report automatic restarts */
+		if (priv->can.restart_ms && oldstate == CAN_STATE_BUS_OFF) {
+			unsigned long flags;
+
+			cf.can_id |= CAN_ERR_RESTARTED;
+			netdev_dbg(dev, "restarted\n");
+			priv->can.can_stats.restarts++;
+			netif_carrier_on(dev);
+
+			spin_lock_irqsave(&priv->lock, flags);
+
+			if (!priv->resetting && !priv->closing) {
+				u32 txwr = grcan_read_reg(&regs->txwr);
+
+				if (grcan_txspace(dma->tx.size, txwr,
+						  priv->eskbp))
+					netif_wake_queue(dev);
+			}
+
+			spin_unlock_irqrestore(&priv->lock, flags);
+		}
+	}
+
+	/* Data overrun interrupt */
+	if ((sources & GRCAN_IRQ_OR) || (status & GRCAN_STAT_OR)) {
+		netdev_dbg(dev, "got data overrun interrupt\n");
+		stats->rx_over_errors++;
+		stats->rx_errors++;
+
+		cf.can_id |= CAN_ERR_CRTL;
+		cf.data[1] |= CAN_ERR_CRTL_RX_OVERFLOW;
+	}
+
+	/* AHB bus error interrupts (not CAN bus errors) - shut down the
+	 * device.
+	 */
+	if (sources & (GRCAN_IRQ_TXAHBERR | GRCAN_IRQ_RXAHBERR) ||
+	    (status & GRCAN_STAT_AHBERR)) {
+		char *txrx = "";
+		unsigned long flags;
+
+		if (sources & GRCAN_IRQ_TXAHBERR) {
+			txrx = "on tx ";
+			stats->tx_errors++;
+		} else if (sources & GRCAN_IRQ_RXAHBERR) {
+			txrx = "on rx ";
+			stats->rx_errors++;
+		}
+		netdev_err(dev, "Fatal AHB buss error %s- halting device\n",
+			   txrx);
+
+		spin_lock_irqsave(&priv->lock, flags);
+
+		/* Prevent anything to be enabled again and halt device */
+		priv->closing = true;
+		netif_stop_queue(dev);
+		grcan_stop_hardware(dev);
+		priv->can.state = CAN_STATE_STOPPED;
+
+		spin_unlock_irqrestore(&priv->lock, flags);
+	}
+
+	/* Pass on error frame if something to report,
+	 * i.e. id contains some information
+	 */
+	if (cf.can_id) {
+		struct can_frame *skb_cf;
+		struct sk_buff *skb = alloc_can_err_skb(dev, &skb_cf);
+
+		if (skb == NULL) {
+			netdev_dbg(dev, "could not allocate error frame\n");
+			return;
+		}
+		skb_cf->can_id |= cf.can_id;
+		memcpy(skb_cf->data, cf.data, sizeof(cf.data));
+
+		netif_rx(skb);
+	}
+}
+
+static irqreturn_t grcan_interrupt(int irq, void *dev_id)
+{
+	struct net_device *dev = dev_id;
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	u32 sources, status;
+
+	/* Find out the source */
+	sources = grcan_read_reg(&regs->pimsr);
+	if (!sources)
+		return IRQ_NONE;
+	grcan_write_reg(&regs->picr, sources);
+	status = grcan_read_reg(&regs->stat);
+
+	/* If we got TX progress, the device has not hanged,
+	 * so disable the hang timer
+	 */
+	if (priv->need_txbug_workaround &&
+	    (sources & (GRCAN_IRQ_TX | GRCAN_IRQ_TXLOSS))) {
+		del_timer(&priv->hang_timer);
+	}
+
+	/* Frame(s) received or transmitted */
+	if (sources & (GRCAN_IRQ_TX | GRCAN_IRQ_RX)) {
+		/* Disable tx/rx interrupts and schedule poll() */
+		grcan_clear_bits(&regs->imr, GRCAN_IRQ_TX | GRCAN_IRQ_RX);
+		napi_schedule(&priv->napi);
+	}
+
+	/* (Potential) error conditions to take care of */
+	if (sources & GRCAN_IRQ_ERRORS)
+		grcan_err(dev, sources, status);
+
+	return IRQ_HANDLED;
+}
+
+/* Reset device and restart operations from where they were.
+ *
+ * This assumes that RXCTRL & RXCTRL is properly disabled and that RX
+ * is not ONGOING (TX might be stuck in ONGOING due to a harwrware bug
+ * for single shot)
+ */
+static void grcan_running_reset(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *)data;
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	unsigned long flags;
+
+	/* This temporarily messes with eskbp, so we need to lock
+	 * priv->lock
+	 */
+	spin_lock_irqsave(&priv->lock, flags);
+
+	priv->resetting = false;
+	del_timer(&priv->hang_timer);
+	del_timer(&priv->rr_timer);
+
+	if (!priv->closing) {
+		/* Save and reset - config register preserved by grcan_reset */
+		u32 imr = grcan_read_reg(&regs->imr);
+
+		u32 txaddr = grcan_read_reg(&regs->txaddr);
+		u32 txsize = grcan_read_reg(&regs->txsize);
+		u32 txwr = grcan_read_reg(&regs->txwr);
+		u32 txrd = grcan_read_reg(&regs->txrd);
+		u32 eskbp = priv->eskbp;
+
+		u32 rxaddr = grcan_read_reg(&regs->rxaddr);
+		u32 rxsize = grcan_read_reg(&regs->rxsize);
+		u32 rxwr = grcan_read_reg(&regs->rxwr);
+		u32 rxrd = grcan_read_reg(&regs->rxrd);
+
+		grcan_reset(dev);
+
+		/* Restore */
+		grcan_write_reg(&regs->txaddr, txaddr);
+		grcan_write_reg(&regs->txsize, txsize);
+		grcan_write_reg(&regs->txwr, txwr);
+		grcan_write_reg(&regs->txrd, txrd);
+		priv->eskbp = eskbp;
+
+		grcan_write_reg(&regs->rxaddr, rxaddr);
+		grcan_write_reg(&regs->rxsize, rxsize);
+		grcan_write_reg(&regs->rxwr, rxwr);
+		grcan_write_reg(&regs->rxrd, rxrd);
+
+		/* Turn on device again */
+		grcan_write_reg(&regs->imr, imr);
+		priv->can.state = CAN_STATE_ERROR_ACTIVE;
+		grcan_write_reg(&regs->txctrl, GRCAN_TXCTRL_ENABLE
+				| (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT
+				   ? GRCAN_TXCTRL_SINGLE : 0));
+		grcan_write_reg(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+		grcan_write_reg(&regs->ctrl, GRCAN_CTRL_ENABLE);
+
+		/* Start queue if there is size and listen-onle mode is not
+		 * enabled
+		 */
+		if (grcan_txspace(priv->dma.tx.size, txwr, priv->eskbp) &&
+		    !(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
+			netif_wake_queue(dev);
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	netdev_err(dev, "Device reset and restored\n");
+}
+
+/* Waiting time in usecs corresponding to the transmission of three maximum
+ * sized can frames in the given bitrate (in bits/sec). Waiting for this amount
+ * of time makes sure that the can controller have time to finish sending or
+ * receiving a frame with a good margin.
+ *
+ * usecs/sec * number of frames * bits/frame / bits/sec
+ */
+static inline u32 grcan_ongoing_wait_usecs(__u32 bitrate)
+{
+	return 1000000 * 3 * GRCAN_EFF_FRAME_MAX_BITS / bitrate;
+}
+
+/* Set timer so that it will not fire until after a period in which the can
+ * controller have a good margin to finish transmitting a frame unless it has
+ * hanged
+ */
+static inline void grcan_reset_timer(struct timer_list *timer, __u32 bitrate)
+{
+	u32 wait_jiffies = usecs_to_jiffies(grcan_ongoing_wait_usecs(bitrate));
+
+	mod_timer(timer, jiffies + wait_jiffies);
+}
+
+/* Disable channels and schedule a running reset */
+static void grcan_initiate_running_reset(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *)data;
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	unsigned long flags;
+
+	netdev_err(dev, "Device seems hanged - reset scheduled\n");
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	/* The main body of this function must never be executed again
+	 * until after an execution of grcan_running_reset
+	 */
+	if (!priv->resetting && !priv->closing) {
+		priv->resetting = true;
+		netif_stop_queue(dev);
+		grcan_clear_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
+		grcan_clear_bits(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+		grcan_reset_timer(&priv->rr_timer, priv->can.bittiming.bitrate);
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static void grcan_free_dma_buffers(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_dma *dma = &priv->dma;
+
+	dma_free_coherent(&dev->dev, dma->base_size, dma->base_buf,
+			  dma->base_handle);
+	memset(dma, 0, sizeof(*dma));
+}
+
+static int grcan_allocate_dma_buffers(struct net_device *dev,
+				      size_t tsize, size_t rsize)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_dma *dma = &priv->dma;
+	struct grcan_dma_buffer *large = rsize > tsize ? &dma->rx : &dma->tx;
+	struct grcan_dma_buffer *small = rsize > tsize ? &dma->tx : &dma->rx;
+	size_t shift;
+
+	/* Need a whole number of GRCAN_BUFFER_ALIGNMENT for the large,
+	 * i.e. first buffer
+	 */
+	size_t maxs = max(tsize, rsize);
+	size_t lsize = ALIGN(maxs, GRCAN_BUFFER_ALIGNMENT);
+
+	/* Put the small buffer after that */
+	size_t ssize = min(tsize, rsize);
+
+	/* Extra GRCAN_BUFFER_ALIGNMENT to allow for alignment */
+	dma->base_size = lsize + ssize + GRCAN_BUFFER_ALIGNMENT;
+	dma->base_buf = dma_alloc_coherent(&dev->dev,
+					   dma->base_size,
+					   &dma->base_handle,
+					   GFP_KERNEL);
+
+	if (!dma->base_buf)
+		return -ENOMEM;
+
+	dma->tx.size = tsize;
+	dma->rx.size = rsize;
+
+	large->handle = ALIGN(dma->base_handle, GRCAN_BUFFER_ALIGNMENT);
+	small->handle = large->handle + lsize;
+	shift = large->handle - dma->base_handle;
+
+	large->buf = dma->base_buf + shift;
+	small->buf = large->buf + lsize;
+
+	return 0;
+}
+
+/* priv->lock *must* be held when calling this function */
+static int grcan_start(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	u32 confop, txctrl;
+
+	grcan_reset(dev);
+
+	grcan_write_reg(&regs->txaddr, priv->dma.tx.handle);
+	grcan_write_reg(&regs->txsize, priv->dma.tx.size);
+	/* regs->txwr, regs->txrd and priv->eskbp already set to 0 by reset */
+
+	grcan_write_reg(&regs->rxaddr, priv->dma.rx.handle);
+	grcan_write_reg(&regs->rxsize, priv->dma.rx.size);
+	/* regs->rxwr and regs->rxrd already set to 0 by reset */
+
+	/* Enable interrupts */
+	grcan_read_reg(&regs->pir);
+	grcan_write_reg(&regs->imr, GRCAN_IRQ_DEFAULT);
+
+	/* Enable interfaces, channels and device */
+	confop = GRCAN_CONF_ABORT
+		| (priv->config.enable0 ? GRCAN_CONF_ENABLE0 : 0)
+		| (priv->config.enable1 ? GRCAN_CONF_ENABLE1 : 0)
+		| (priv->config.select ? GRCAN_CONF_SELECT : 0)
+		| (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY ?
+		   GRCAN_CONF_SILENT : 0)
+		| (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES ?
+		   GRCAN_CONF_SAM : 0);
+	grcan_write_bits(&regs->conf, confop, GRCAN_CONF_OPERATION);
+	txctrl = GRCAN_TXCTRL_ENABLE
+		| (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT
+		   ? GRCAN_TXCTRL_SINGLE : 0);
+	grcan_write_reg(&regs->txctrl, txctrl);
+	grcan_write_reg(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+	grcan_write_reg(&regs->ctrl, GRCAN_CTRL_ENABLE);
+
+	priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+	return 0;
+}
+
+static int grcan_set_mode(struct net_device *dev, enum can_mode mode)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+	int err = 0;
+
+	if (mode == CAN_MODE_START) {
+		/* This might be called to restart the device to recover from
+		 * bus off errors
+		 */
+		spin_lock_irqsave(&priv->lock, flags);
+		if (priv->closing || priv->resetting) {
+			err = -EBUSY;
+		} else {
+			netdev_info(dev, "Restarting device\n");
+			grcan_start(dev);
+			if (!(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
+				netif_wake_queue(dev);
+		}
+		spin_unlock_irqrestore(&priv->lock, flags);
+		return err;
+	}
+	return -EOPNOTSUPP;
+}
+
+static int grcan_open(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_dma *dma = &priv->dma;
+	unsigned long flags;
+	int err;
+
+	/* Allocate memory */
+	err = grcan_allocate_dma_buffers(dev, priv->config.txsize,
+					 priv->config.rxsize);
+	if (err) {
+		netdev_err(dev, "could not allocate DMA buffers\n");
+		return err;
+	}
+
+	priv->echo_skb = kzalloc(dma->tx.size * sizeof(*priv->echo_skb),
+				 GFP_KERNEL);
+	if (!priv->echo_skb) {
+		err = -ENOMEM;
+		goto exit_free_dma_buffers;
+	}
+	priv->can.echo_skb_max = dma->tx.size;
+	priv->can.echo_skb = priv->echo_skb;
+
+	priv->txdlc = kzalloc(dma->tx.size * sizeof(*priv->txdlc), GFP_KERNEL);
+	if (!priv->txdlc) {
+		err = -ENOMEM;
+		goto exit_free_echo_skb;
+	}
+
+	/* Get can device up */
+	err = open_candev(dev);
+	if (err)
+		goto exit_free_txdlc;
+
+	err = request_irq(dev->irq, grcan_interrupt, IRQF_SHARED,
+			  dev->name, dev);
+	if (err)
+		goto exit_close_candev;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	napi_enable(&priv->napi);
+	grcan_start(dev);
+	if (!(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
+		netif_start_queue(dev);
+	priv->resetting = false;
+	priv->closing = false;
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return 0;
+
+exit_close_candev:
+	close_candev(dev);
+exit_free_txdlc:
+	kfree(priv->txdlc);
+exit_free_echo_skb:
+	kfree(priv->echo_skb);
+exit_free_dma_buffers:
+	grcan_free_dma_buffers(dev);
+	return err;
+}
+
+static int grcan_close(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+
+	napi_disable(&priv->napi);
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	priv->closing = true;
+	if (priv->need_txbug_workaround) {
+		del_timer_sync(&priv->hang_timer);
+		del_timer_sync(&priv->rr_timer);
+	}
+	netif_stop_queue(dev);
+	grcan_stop_hardware(dev);
+	priv->can.state = CAN_STATE_STOPPED;
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	free_irq(dev->irq, dev);
+	close_candev(dev);
+
+	grcan_free_dma_buffers(dev);
+	priv->can.echo_skb_max = 0;
+	priv->can.echo_skb = NULL;
+	kfree(priv->echo_skb);
+	kfree(priv->txdlc);
+
+	return 0;
+}
+
+static void grcan_transmit_catch_up(struct net_device *dev, int budget)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+	int work_done;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	work_done = catch_up_echo_skb(dev, budget, true);
+	if (work_done) {
+		if (!priv->resetting && !priv->closing &&
+		    !(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
+			netif_wake_queue(dev);
+
+		/* With napi we don't get TX interrupts for a while,
+		 * so prevent a running reset while catching up
+		 */
+		if (priv->need_txbug_workaround)
+			del_timer(&priv->hang_timer);
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static int grcan_receive(struct net_device *dev, int budget)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	struct net_device_stats *stats = &dev->stats;
+	struct can_frame *cf;
+	struct sk_buff *skb;
+	u32 wr, rd, startrd;
+	u32 *slot;
+	u32 i, rtr, eff, j, shift;
+	int work_done = 0;
+
+	rd = grcan_read_reg(&regs->rxrd);
+	startrd = rd;
+	for (work_done = 0; work_done < budget; work_done++) {
+		/* Check for packet to receive */
+		wr = grcan_read_reg(&regs->rxwr);
+		if (rd == wr)
+			break;
+
+		/* Take care of packet */
+		skb = alloc_can_skb(dev, &cf);
+		if (skb == NULL) {
+			netdev_err(dev,
+				   "dropping frame: skb allocation failed\n");
+			stats->rx_dropped++;
+			continue;
+		}
+
+		slot = dma->rx.buf + rd;
+		eff = slot[0] & GRCAN_MSG_IDE;
+		rtr = slot[0] & GRCAN_MSG_RTR;
+		if (eff) {
+			cf->can_id = ((slot[0] & GRCAN_MSG_EID)
+				      >> GRCAN_MSG_EID_BIT);
+			cf->can_id |= CAN_EFF_FLAG;
+		} else {
+			cf->can_id = ((slot[0] & GRCAN_MSG_BID)
+				      >> GRCAN_MSG_BID_BIT);
+		}
+		cf->can_dlc = get_can_dlc((slot[1] & GRCAN_MSG_DLC)
+					  >> GRCAN_MSG_DLC_BIT);
+		if (rtr) {
+			cf->can_id |= CAN_RTR_FLAG;
+		} else {
+			for (i = 0; i < cf->can_dlc; i++) {
+				j = GRCAN_MSG_DATA_SLOT_INDEX(i);
+				shift = GRCAN_MSG_DATA_SHIFT(i);
+				cf->data[i] = (u8)(slot[j] >> shift);
+			}
+		}
+		netif_receive_skb(skb);
+
+		/* Update statistics and read pointer */
+		stats->rx_packets++;
+		stats->rx_bytes += cf->can_dlc;
+		rd = grcan_ring_add(rd, GRCAN_MSG_SIZE, dma->rx.size);
+	}
+
+	/* Make sure everything is read before allowing hardware to
+	 * use the memory
+	 */
+	mb();
+
+	/* Update read pointer - no need to check for ongoing */
+	if (likely(rd != startrd))
+		grcan_write_reg(&regs->rxrd, rd);
+
+	return work_done;
+}
+
+/* priv->lock *must* be held when calling this function */
+static inline int grcan_poll_all_done(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	u32 txrd = grcan_read_reg(&regs->txrd);
+	u32 rxwr = grcan_read_reg(&regs->rxwr);
+	u32 rxrd = grcan_read_reg(&regs->rxrd);
+
+	return priv->eskbp == txrd && rxwr == rxrd;
+}
+
+static int grcan_poll(struct napi_struct *napi, int rx_budget)
+{
+	struct grcan_priv *priv = container_of(napi, struct grcan_priv, napi);
+	struct net_device *dev = priv->dev;
+	struct grcan_registers __iomem *regs = priv->regs;
+	int rx_work_done;
+	unsigned long flags;
+
+	/* Receive according to given budget */
+	rx_work_done = grcan_receive(dev, rx_budget);
+
+	/* Catch up echo skb according to separate budget to get the benefits of
+	 * napi for tx as well. The given rx_budget might not be appropriate for
+	 * the tx side.
+	 */
+	grcan_transmit_catch_up(dev, GRCAN_TX_BUDGET);
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	if (grcan_poll_all_done(dev)) {
+		bool complete = true;
+
+		if (!priv->closing) {
+			/* Enable tx and rx interrupts again */
+			grcan_set_bits(&regs->imr, GRCAN_IRQ_TX | GRCAN_IRQ_RX);
+
+			/* If more work arrived between detecting completion and
+			 * turning on interrupts, we need to keep napi running
+			 */
+			if (!grcan_poll_all_done(dev)) {
+				complete = false;
+				grcan_clear_bits(&regs->imr,
+						 GRCAN_IRQ_TX | GRCAN_IRQ_RX);
+			}
+		}
+		if (complete)
+			napi_complete(napi);
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return rx_work_done;
+}
+
+/* Work tx bug by waiting while for the risky situation to clear. If that fails,
+ * drop a frame in one-shot mode or indicate a busy device otherwise.
+ *
+ * Returns 0 on successful wait. Otherwise it sets *netdev_tx_status to the
+ * value that should be returned by grcan_start_xmit when aborting the xmit.
+ */
+static int grcan_txbug_workaround(struct net_device *dev, struct sk_buff *skb,
+				  u32 txwr, u32 oneshotmode,
+				  netdev_tx_t *netdev_tx_status)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	int i;
+	unsigned long flags;
+
+	/* Wait a while for ongoing to be cleared or read pointer to catch up to
+	 * write pointer. The latter is needed due to a bug in older versions of
+	 * GRCAN in which ONGOING is not cleared properly one-shot mode when a
+	 * transmission fails.
+	 */
+	for (i = 0; i < GRCAN_SHORTWAIT_USECS; i++) {
+		udelay(1);
+		if (!grcan_read_bits(&regs->txctrl, GRCAN_TXCTRL_ONGOING) ||
+		    grcan_read_reg(&regs->txrd) == txwr) {
+			return 0;
+		}
+	}
+
+	/* Clean up, in case the situation was not resolved */
+	spin_lock_irqsave(&priv->lock, flags);
+	if (!priv->resetting && !priv->closing) {
+		/* Queue might have been stopped earlier in grcan_start_xmit */
+		if (grcan_txspace(dma->tx.size, txwr, priv->eskbp))
+			netif_wake_queue(dev);
+		/* Set a timer to resolve a hanged tx controller */
+		if (!timer_pending(&priv->hang_timer))
+			grcan_reset_timer(&priv->hang_timer,
+					  priv->can.bittiming.bitrate);
+	}
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	if (oneshotmode) {
+		/* In one-shot mode we should never end up here because
+		 * then the interrupt handler increases txrd on TXLOSS,
+		 * but it is consistent with one-shot mode to drop the
+		 * frame in this case.
+		 */
+		kfree_skb(skb);
+		*netdev_tx_status = NETDEV_TX_OK;
+	} else {
+		/* In normal mode the socket-can transmission queue get
+		 * to keep the frame so that it can be retransmitted
+		 * later
+		 */
+		*netdev_tx_status = NETDEV_TX_BUSY;
+	}
+	return -EBUSY;
+}
+
+/* Notes on the tx cyclic buffer handling:
+ *
+ * regs->txwr	- the next slot for the driver to put data to be sent
+ * regs->txrd	- the next slot for the device to read data
+ * priv->eskbp	- the next slot for the driver to call can_put_echo_skb for
+ *
+ * grcan_start_xmit can enter more messages as long as regs->txwr does
+ * not reach priv->eskbp (within 1 message gap)
+ *
+ * The device sends messages until regs->txrd reaches regs->txwr
+ *
+ * The interrupt calls handler calls can_put_echo_skb until
+ * priv->eskbp reaches regs->txrd
+ */
+static netdev_tx_t grcan_start_xmit(struct sk_buff *skb,
+				    struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	struct can_frame *cf = (struct can_frame *)skb->data;
+	u32 id, txwr, txrd, space, txctrl;
+	int slotindex;
+	u32 *slot;
+	u32 i, rtr, eff, dlc, tmp, err;
+	int j, shift;
+	unsigned long flags;
+	u32 oneshotmode = priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT;
+
+	if (can_dropped_invalid_skb(dev, skb))
+		return NETDEV_TX_OK;
+
+	/* Trying to transmit in silent mode will generate error interrupts, but
+	 * this should never happen - the queue should not have been started.
+	 */
+	if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
+		return NETDEV_TX_BUSY;
+
+	/* Reads of priv->eskbp and shut-downs of the queue needs to
+	 * be atomic towards the updates to priv->eskbp and wake-ups
+	 * of the queue in the interrupt handler.
+	 */
+	spin_lock_irqsave(&priv->lock, flags);
+
+	txwr = grcan_read_reg(&regs->txwr);
+	space = grcan_txspace(dma->tx.size, txwr, priv->eskbp);
+
+	slotindex = txwr / GRCAN_MSG_SIZE;
+	slot = dma->tx.buf + txwr;
+
+	if (unlikely(space == 1))
+		netif_stop_queue(dev);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+	/* End of critical section*/
+
+	/* This should never happen. If circular buffer is full, the
+	 * netif_stop_queue should have been stopped already.
+	 */
+	if (unlikely(!space)) {
+		netdev_err(dev, "No buffer space, but queue is non-stopped.\n");
+		return NETDEV_TX_BUSY;
+	}
+
+	/* Convert and write CAN message to DMA buffer */
+	eff = cf->can_id & CAN_EFF_FLAG;
+	rtr = cf->can_id & CAN_RTR_FLAG;
+	id = cf->can_id & (eff ? CAN_EFF_MASK : CAN_SFF_MASK);
+	dlc = cf->can_dlc;
+	if (eff)
+		tmp = (id << GRCAN_MSG_EID_BIT) & GRCAN_MSG_EID;
+	else
+		tmp = (id << GRCAN_MSG_BID_BIT) & GRCAN_MSG_BID;
+	slot[0] = (eff ? GRCAN_MSG_IDE : 0) | (rtr ? GRCAN_MSG_RTR : 0) | tmp;
+
+	slot[1] = ((dlc << GRCAN_MSG_DLC_BIT) & GRCAN_MSG_DLC);
+	slot[2] = 0;
+	slot[3] = 0;
+	for (i = 0; i < dlc; i++) {
+		j = GRCAN_MSG_DATA_SLOT_INDEX(i);
+		shift = GRCAN_MSG_DATA_SHIFT(i);
+		slot[j] |= cf->data[i] << shift;
+	}
+
+	/* Checking that channel has not been disabled. These cases
+	 * should never happen
+	 */
+	txctrl = grcan_read_reg(&regs->txctrl);
+	if (!(txctrl & GRCAN_TXCTRL_ENABLE))
+		netdev_err(dev, "tx channel spuriously disabled\n");
+
+	if (oneshotmode && !(txctrl & GRCAN_TXCTRL_SINGLE))
+		netdev_err(dev, "one-shot mode spuriously disabled\n");
+
+	/* Bug workaround for old version of grcan where updating txwr
+	 * in the same clock cycle as the controller updates txrd to
+	 * the current txwr could hang the can controller
+	 */
+	if (priv->need_txbug_workaround) {
+		txrd = grcan_read_reg(&regs->txrd);
+		if (unlikely(grcan_ring_sub(txwr, txrd, dma->tx.size) == 1)) {
+			netdev_tx_t txstatus;
+
+			err = grcan_txbug_workaround(dev, skb, txwr,
+						     oneshotmode, &txstatus);
+			if (err)
+				return txstatus;
+		}
+	}
+
+	/* Prepare skb for echoing. This must be after the bug workaround above
+	 * as ownership of the skb is passed on by calling can_put_echo_skb.
+	 * Returning NETDEV_TX_BUSY or accessing skb or cf after a call to
+	 * can_put_echo_skb would be an error unless other measures are
+	 * taken.
+	 */
+	priv->txdlc[slotindex] = cf->can_dlc; /* Store dlc for statistics */
+	can_put_echo_skb(skb, dev, slotindex);
+
+	/* Make sure everything is written before allowing hardware to
+	 * read from the memory
+	 */
+	wmb();
+
+	/* Update write pointer to start transmission */
+	grcan_write_reg(&regs->txwr,
+			grcan_ring_add(txwr, GRCAN_MSG_SIZE, dma->tx.size));
+
+	return NETDEV_TX_OK;
+}
+
+/* ========== Setting up sysfs interface and module parameters ========== */
+
+#define GRCAN_NOT_BOOL(unsigned_val) ((unsigned_val) > 1)
+
+#define GRCAN_MODULE_PARAM(name, mtype, valcheckf, desc)		\
+	static void grcan_sanitize_##name(struct platform_device *pd)	\
+	{								\
+		struct grcan_device_config grcan_default_config		\
+			= GRCAN_DEFAULT_DEVICE_CONFIG;			\
+		if (valcheckf(grcan_module_config.name)) {		\
+			dev_err(&pd->dev,				\
+				"Invalid module parameter value for "	\
+				#name " - setting default\n");		\
+			grcan_module_config.name =			\
+				grcan_default_config.name;		\
+		}							\
+	}								\
+	module_param_named(name, grcan_module_config.name,		\
+			   mtype, S_IRUGO);				\
+	MODULE_PARM_DESC(name, desc)
+
+#define GRCAN_CONFIG_ATTR(name, desc)					\
+	static ssize_t grcan_store_##name(struct device *sdev,		\
+					  struct device_attribute *att,	\
+					  const char *buf,		\
+					  size_t count)			\
+	{								\
+		struct net_device *dev = to_net_dev(sdev);		\
+		struct grcan_priv *priv = netdev_priv(dev);		\
+		u8 val;							\
+		int ret;						\
+		if (dev->flags & IFF_UP)				\
+			return -EBUSY;					\
+		ret = kstrtou8(buf, 0, &val);				\
+		if (ret < 0 || val > 1)					\
+			return -EINVAL;					\
+		priv->config.name = val;				\
+		return count;						\
+	}								\
+	static ssize_t grcan_show_##name(struct device *sdev,		\
+					 struct device_attribute *att,	\
+					 char *buf)			\
+	{								\
+		struct net_device *dev = to_net_dev(sdev);		\
+		struct grcan_priv *priv = netdev_priv(dev);		\
+		return sprintf(buf, "%d\n", priv->config.name);		\
+	}								\
+	static DEVICE_ATTR(name, S_IRUGO | S_IWUSR,			\
+			   grcan_show_##name,				\
+			   grcan_store_##name);				\
+	GRCAN_MODULE_PARAM(name, ushort, GRCAN_NOT_BOOL, desc)
+
+/* The following configuration options are made available both via module
+ * parameters and writable sysfs files. See the chapter about GRCAN in the
+ * documentation for the GRLIB VHDL library for further details.
+ */
+GRCAN_CONFIG_ATTR(enable0,
+		  "Configuration of physical interface 0. Determines\n"	\
+		  "the \"Enable 0\" bit of the configuration register.\n" \
+		  "Format: 0 | 1\nDefault: 0\n");
+
+GRCAN_CONFIG_ATTR(enable1,
+		  "Configuration of physical interface 1. Determines\n"	\
+		  "the \"Enable 1\" bit of the configuration register.\n" \
+		  "Format: 0 | 1\nDefault: 0\n");
+
+GRCAN_CONFIG_ATTR(select,
+		  "Select which physical interface to use.\n"	\
+		  "Format: 0 | 1\nDefault: 0\n");
+
+/* The tx and rx buffer size configuration options are only available via module
+ * parameters.
+ */
+GRCAN_MODULE_PARAM(txsize, uint, GRCAN_INVALID_BUFFER_SIZE,
+		   "Sets the size of the tx buffer.\n"			\
+		   "Format: <unsigned int> where (txsize & ~0x1fffc0) == 0\n" \
+		   "Default: 1024\n");
+GRCAN_MODULE_PARAM(rxsize, uint, GRCAN_INVALID_BUFFER_SIZE,
+		   "Sets the size of the rx buffer.\n"			\
+		   "Format: <unsigned int> where (size & ~0x1fffc0) == 0\n" \
+		   "Default: 1024\n");
+
+/* Function that makes sure that configuration done using
+ * module parameters are set to valid values
+ */
+static void grcan_sanitize_module_config(struct platform_device *ofdev)
+{
+	grcan_sanitize_enable0(ofdev);
+	grcan_sanitize_enable1(ofdev);
+	grcan_sanitize_select(ofdev);
+	grcan_sanitize_txsize(ofdev);
+	grcan_sanitize_rxsize(ofdev);
+}
+
+static const struct attribute *const sysfs_grcan_attrs[] = {
+	/* Config attrs */
+	&dev_attr_enable0.attr,
+	&dev_attr_enable1.attr,
+	&dev_attr_select.attr,
+	NULL,
+};
+
+static const struct attribute_group sysfs_grcan_group = {
+	.name	= "grcan",
+	.attrs	= (struct attribute **)sysfs_grcan_attrs,
+};
+
+/* ========== Setting up the driver ========== */
+
+static const struct net_device_ops grcan_netdev_ops = {
+	.ndo_open	= grcan_open,
+	.ndo_stop	= grcan_close,
+	.ndo_start_xmit	= grcan_start_xmit,
+};
+
+static int grcan_setup_netdev(struct platform_device *ofdev,
+			      void __iomem *base,
+			      int irq, u32 ambafreq, bool txbug)
+{
+	struct net_device *dev;
+	struct grcan_priv *priv;
+	struct grcan_registers __iomem *regs;
+	int err;
+
+	dev = alloc_candev(sizeof(struct grcan_priv), 0);
+	if (!dev)
+		return -ENOMEM;
+
+	dev->irq = irq;
+	dev->flags |= IFF_ECHO;
+	dev->netdev_ops = &grcan_netdev_ops;
+	dev->sysfs_groups[0] = &sysfs_grcan_group;
+
+	priv = netdev_priv(dev);
+	memcpy(&priv->config, &grcan_module_config,
+	       sizeof(struct grcan_device_config));
+	priv->dev = dev;
+	priv->regs = base;
+	priv->can.bittiming_const = &grcan_bittiming_const;
+	priv->can.do_set_bittiming = grcan_set_bittiming;
+	priv->can.do_set_mode = grcan_set_mode;
+	priv->can.do_get_berr_counter = grcan_get_berr_counter;
+	priv->can.clock.freq = ambafreq;
+	priv->can.ctrlmode_supported =
+		CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_ONE_SHOT;
+	priv->need_txbug_workaround = txbug;
+
+	/* Discover if triple sampling is supported by hardware */
+	regs = priv->regs;
+	grcan_set_bits(&regs->ctrl, GRCAN_CTRL_RESET);
+	grcan_set_bits(&regs->conf, GRCAN_CONF_SAM);
+	if (grcan_read_bits(&regs->conf, GRCAN_CONF_SAM)) {
+		priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES;
+		dev_dbg(&ofdev->dev, "Hardware supports triple-sampling\n");
+	}
+
+	spin_lock_init(&priv->lock);
+
+	if (priv->need_txbug_workaround) {
+		init_timer(&priv->rr_timer);
+		priv->rr_timer.function = grcan_running_reset;
+		priv->rr_timer.data = (unsigned long)dev;
+
+		init_timer(&priv->hang_timer);
+		priv->hang_timer.function = grcan_initiate_running_reset;
+		priv->hang_timer.data = (unsigned long)dev;
+	}
+
+	netif_napi_add(dev, &priv->napi, grcan_poll, GRCAN_NAPI_WEIGHT);
+
+	SET_NETDEV_DEV(dev, &ofdev->dev);
+	dev_info(&ofdev->dev, "regs=0x%p, irq=%d, clock=%d\n",
+		 priv->regs, dev->irq, priv->can.clock.freq);
+
+	err = register_candev(dev);
+	if (err)
+		goto exit_free_candev;
+
+	dev_set_drvdata(&ofdev->dev, dev);
+
+	/* Reset device to allow bit-timing to be set. No need to call
+	 * grcan_reset at this stage. That is done in grcan_open.
+	 */
+	grcan_write_reg(&regs->ctrl, GRCAN_CTRL_RESET);
+
+	return 0;
+exit_free_candev:
+	free_candev(dev);
+	return err;
+}
+
+static int __devinit grcan_probe(struct platform_device *ofdev)
+{
+	struct device_node *np = ofdev->dev.of_node;
+	struct resource *res;
+	u32 sysid, ambafreq;
+	int irq, err;
+	void __iomem *base;
+	bool txbug = true;
+
+	/* Compare GRLIB version number with the first that does not
+	 * have the tx bug (see start_xmit)
+	 */
+	err = of_property_read_u32(np, "systemid", &sysid);
+	if (!err && ((sysid & GRLIB_VERSION_MASK)
+		     >= GRCAN_TXBUG_SAFE_GRLIB_VERSION))
+		txbug = false;
+
+	err = of_property_read_u32(np, "freq", &ambafreq);
+	if (err) {
+		dev_err(&ofdev->dev, "unable to fetch \"freq\" property\n");
+		goto exit_error;
+	}
+
+	res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
+	base = devm_request_and_ioremap(&ofdev->dev, res);
+	if (!base) {
+		dev_err(&ofdev->dev, "couldn't map IO resource\n");
+		err = -EADDRNOTAVAIL;
+		goto exit_error;
+	}
+
+	irq = irq_of_parse_and_map(np, GRCAN_IRQIX_IRQ);
+	if (!irq) {
+		dev_err(&ofdev->dev, "no irq found\n");
+		err = -ENODEV;
+		goto exit_error;
+	}
+
+	grcan_sanitize_module_config(ofdev);
+
+	err = grcan_setup_netdev(ofdev, base, irq, ambafreq, txbug);
+	if (err)
+		goto exit_dispose_irq;
+
+	return 0;
+
+exit_dispose_irq:
+	irq_dispose_mapping(irq);
+exit_error:
+	dev_err(&ofdev->dev,
+		"%s socket CAN driver initialization failed with error %d\n",
+		DRV_NAME, err);
+	return err;
+}
+
+static int __devexit grcan_remove(struct platform_device *ofdev)
+{
+	struct net_device *dev = dev_get_drvdata(&ofdev->dev);
+	struct grcan_priv *priv = netdev_priv(dev);
+
+	unregister_candev(dev); /* Will in turn call grcan_close */
+
+	irq_dispose_mapping(dev->irq);
+	dev_set_drvdata(&ofdev->dev, NULL);
+	netif_napi_del(&priv->napi);
+	free_candev(dev);
+
+	return 0;
+}
+
+static struct of_device_id grcan_match[] = {
+	{.name = "GAISLER_GRCAN"},
+	{.name = "01_03d"},
+	{.name = "GAISLER_GRHCAN"},
+	{.name = "01_034"},
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, grcan_match);
+
+static struct platform_driver grcan_driver = {
+	.driver = {
+		.name = DRV_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = grcan_match,
+	},
+	.probe = grcan_probe,
+	.remove = __devexit_p(grcan_remove),
+};
+
+module_platform_driver(grcan_driver);
+
+MODULE_AUTHOR("Aeroflex Gaisler AB.");
+MODULE_DESCRIPTION("Socket CAN driver for Aeroflex Gaisler GRCAN");
+MODULE_LICENSE("GPL");
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* Re: [PATCH v8] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-11-12 14:57                                             ` [PATCH v8] " Andreas Larsson
@ 2012-11-13 21:15                                               ` Marc Kleine-Budde
  2012-11-14  7:50                                                 ` Andreas Larsson
  0 siblings, 1 reply; 41+ messages in thread
From: Marc Kleine-Budde @ 2012-11-13 21:15 UTC (permalink / raw)
  To: Andreas Larsson
  Cc: linux-can, software, Wolfgang Grandegger, devicetree-discuss

[-- Attachment #1: Type: text/plain, Size: 66357 bytes --]

On 11/12/2012 03:57 PM, Andreas Larsson wrote:
> This driver supports GRCAN and CRHCAN CAN controllers available in the GRLIB
> VHDL IP core library.
> 
> Signed-off-by: Andreas Larsson <andreas@gaisler.com>
> Acked-by: Wolfgang Grandegger <wg@grandegger.com>

looks almost ready, nitpicks inline.

Marc
> ---
> Changes since v7:
> - Enable napi before turning on interrupts
> - Remove unneeded casts, unneded checks and improper devm_ usages
> - Fix, downgrade or remove some printouts
> - Rewrite poll function so that tx gets its own budget and so that undone work
>   does not fall between the cracks when enabling interrupts
> - Don't check irq number against NO_IRQ that does not exist on all OF enabled
>   platforms
> - Document kernel parameters with MODULE_PARM_DESC
> 
>  Documentation/ABI/testing/sysfs-class-net-grcan    |   35 +
>  .../devicetree/bindings/net/can/grcan.txt          |   28 +
>  Documentation/kernel-parameters.txt                |   18 +
>  drivers/net/can/Kconfig                            |    9 +
>  drivers/net/can/Makefile                           |    1 +
>  drivers/net/can/grcan.c                            | 1768 ++++++++++++++++++++
>  6 files changed, 1859 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/ABI/testing/sysfs-class-net-grcan
>  create mode 100644 Documentation/devicetree/bindings/net/can/grcan.txt
>  create mode 100644 drivers/net/can/grcan.c
> 
> diff --git a/Documentation/ABI/testing/sysfs-class-net-grcan b/Documentation/ABI/testing/sysfs-class-net-grcan
> new file mode 100644
> index 0000000..f418c92
> --- /dev/null
> +++ b/Documentation/ABI/testing/sysfs-class-net-grcan
> @@ -0,0 +1,35 @@
> +
> +What:		/sys/class/net/<iface>/grcan/enable0
> +Date:		October 2012
> +KernelVersion:	3.8
> +Contact:	Andreas Larsson <andreas@gaisler.com>
> +Description:
> +		Hardware configuration of physical interface 0. This file reads
> +		and writes the "Enable 0" bit of the configuration register.
> +		Possible values: 0 or 1. See the GRCAN chapter of the GRLIB IP
> +		core library documentation for details. The default value is 0
> +		or set by the module parameter grcan.enable0 and can be read at
> +		/sys/module/grcan/parameters/enable0.
> +
> +What:		/sys/class/net/<iface>/grcan/enable1
> +Date:		October 2012
> +KernelVersion:	3.8
> +Contact:	Andreas Larsson <andreas@gaisler.com>
> +Description:
> +		Hardware configuration of physical interface 1. This file reads
> +		and writes the "Enable 1" bit of the configuration register.
> +		Possible values: 0 or 1. See the GRCAN chapter of the GRLIB IP
> +		core library documentation for details. The default value is 0
> +		or set by the module parameter grcan.enable1 and can be read at
> +		/sys/module/grcan/parameters/enable1.
> +
> +What:		/sys/class/net/<iface>/grcan/select
> +Date:		October 2012
> +KernelVersion:	3.8
> +Contact:	Andreas Larsson <andreas@gaisler.com>
> +Description:
> +		Configuration of which physical interface to be used. Possible
> +		values: 0 or 1. See the GRCAN chapter of the GRLIB IP core
> +		library documentation for details. The default value is 0 or is
> +		set by the module parameter grcan.select and can be read at
> +		/sys/module/grcan/parameters/select.
> diff --git a/Documentation/devicetree/bindings/net/can/grcan.txt b/Documentation/devicetree/bindings/net/can/grcan.txt
> new file mode 100644
> index 0000000..34ef349
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/can/grcan.txt
> @@ -0,0 +1,28 @@
> +Aeroflex Gaisler GRCAN and GRHCAN CAN controllers.
> +
> +The GRCAN and CRHCAN CAN controllers are available in the GRLIB VHDL IP core
> +library.
> +
> +Note: These properties are built from the AMBA plug&play in a Leon SPARC system
> +(the ordinary environment for GRCAN and GRHCAN). There are no dts files for
> +sparc.
> +
> +Required properties:
> +
> +- name : Should be "GAISLER_GRCAN", "01_03d", "GAISLER_GRHCAN" or "01_034"
> +
> +- reg : Address and length of the register set for the device
> +
> +- freq : Frequency of the external oscillator clock in Hz (the frequency of
> +	the amba bus in the ordinary case)
> +
> +- interrupts : Interrupt number for this device
> +
> +Optional properties:
> +
> +- systemid : If not present or if the value of the least significant 16 bits
> +	of this 32-bit property is smaller than GRCAN_TXBUG_SAFE_GRLIB_VERSION
> +	a bug workaround is activated.
> +
> +For further information look in the documentation for the GLIB IP core library:
> +http://www.gaisler.com/products/grlib/grip.pdf
> diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
> index 9776f06..3da4f96 100644
> --- a/Documentation/kernel-parameters.txt
> +++ b/Documentation/kernel-parameters.txt
> @@ -905,6 +905,24 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
>  	gpt		[EFI] Forces disk with valid GPT signature but
>  			invalid Protective MBR to be treated as GPT.
>  
> +	grcan.enable0=	[HW] Configuration of physical interface 0. Determines
> +			the "Enable 0" bit of the configuration register.
> +			Format: 0 | 1
> +			Default: 0
> +	grcan.enable1=	[HW] Configuration of physical interface 1. Determines
> +			the "Enable 0" bit of the configuration register.
> +			Format: 0 | 1
> +			Default: 0
> +	grcan.select=	[HW] Select which physical interface to use.
> +			Format: 0 | 1
> +			Default: 0
> +	grcan.txsize=	[HW] Sets the size of the tx buffer.
> +			Format: <unsigned int> such that (txsize & ~0x1fffc0) == 0.
> +			Default: 1024
> +	grcan.rxsize=	[HW] Sets the size of the rx buffer.
> +			Format: <unsigned int> such that (rxsize & ~0x1fffc0) == 0.
> +			Default: 1024
> +
>  	hashdist=	[KNL,NUMA] Large hashes allocated during boot
>  			are distributed across NUMA nodes.  Defaults on
>  			for 64-bit NUMA, off otherwise.
> diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
> index bb709fd..b56bd9e 100644
> --- a/drivers/net/can/Kconfig
> +++ b/drivers/net/can/Kconfig
> @@ -110,6 +110,15 @@ config PCH_CAN
>  	  is an IOH for x86 embedded processor (Intel Atom E6xx series).
>  	  This driver can access CAN bus.
>  
> +config CAN_GRCAN
> +	tristate "Aeroflex Gaisler GRCAN and GRHCAN CAN devices"
> +	depends on CAN_DEV && OF
> +	---help---
> +	  Say Y here if you want to use Aeroflex Gaisler GRCAN or GRHCAN.
> +	  Note that the driver supports little endian, even though little
> +	  endian syntheses of the cores would need some modifications on
> +	  the hardware level to work.
> +
>  source "drivers/net/can/mscan/Kconfig"
>  
>  source "drivers/net/can/sja1000/Kconfig"
> diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
> index 938be37..7de5986 100644
> --- a/drivers/net/can/Makefile
> +++ b/drivers/net/can/Makefile
> @@ -22,5 +22,6 @@ obj-$(CONFIG_CAN_BFIN)		+= bfin_can.o
>  obj-$(CONFIG_CAN_JANZ_ICAN3)	+= janz-ican3.o
>  obj-$(CONFIG_CAN_FLEXCAN)	+= flexcan.o
>  obj-$(CONFIG_PCH_CAN)		+= pch_can.o
> +obj-$(CONFIG_CAN_GRCAN)		+= grcan.o
>  
>  ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
> diff --git a/drivers/net/can/grcan.c b/drivers/net/can/grcan.c
> new file mode 100644
> index 0000000..2eafe74
> --- /dev/null
> +++ b/drivers/net/can/grcan.c
> @@ -0,0 +1,1768 @@
> +/*
> + * Socket CAN driver for Aeroflex Gaisler GRCAN and GRHCAN.
> + *
> + * 2012 (c) Aeroflex Gaisler AB
> + *
> + * This driver supports GRCAN and GRHCAN CAN controllers available in the GRLIB
> + * VHDL IP core library.
> + *
> + * Full documentation of the GRCAN core can be found here:
> + * http://www.gaisler.com/products/grlib/grip.pdf
> + *
> + * See "Documentation/devicetree/bindings/net/can/grcan.txt" for information on
> + * open firmware properties.
> + *
> + * See "Documentation/ABI/testing/sysfs-class-net-grcan" for information on the
> + * sysfs interface.
> + *
> + * See "Documentation/kernel-parameters.txt" for information on the module
> + * parameters.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as published by the
> + * Free Software Foundation; either version 2 of the License, or (at your
> + * option) any later version.
> + *
> + * Contributors: Andreas Larsson <andreas@gaisler.com>
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/interrupt.h>
> +#include <linux/netdevice.h>
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/can/dev.h>
> +#include <linux/spinlock.h>
> +
> +#include <linux/of_platform.h>
> +#include <asm/prom.h>
> +
> +#include <linux/of_irq.h>
> +
> +#include <linux/dma-mapping.h>
> +
> +#define DRV_NAME	"grcan"
> +
> +#define GRCAN_TX_BUDGET		16
> +#define GRCAN_NAPI_WEIGHT	16
> +
> +#define GRCAN_RESERVE_SIZE(slot1, slot2) (((slot2) - (slot1)) / 4 - 1)
> +
> +struct grcan_registers {
> +	u32 conf;	/* 0x00 */
> +	u32 stat;	/* 0x04 */
> +	u32 ctrl;	/* 0x08 */
> +	u32 __reserved1[GRCAN_RESERVE_SIZE(0x08, 0x18)];
> +	u32 smask;	/* 0x18 - CanMASK */
> +	u32 scode;	/* 0x1c - CanCODE */
> +	u32 __reserved2[GRCAN_RESERVE_SIZE(0x1c, 0x100)];
> +	u32 pimsr;	/* 0x100 */
> +	u32 pimr;	/* 0x104 */
> +	u32 pisr;	/* 0x108 */
> +	u32 pir;	/* 0x10C */
> +	u32 imr;	/* 0x110 */
> +	u32 picr;	/* 0x114 */
> +	u32 __reserved3[GRCAN_RESERVE_SIZE(0x114, 0x200)];
> +	u32 txctrl;	/* 0x200 */
> +	u32 txaddr;	/* 0x204 */
> +	u32 txsize;	/* 0x208 */
> +	u32 txwr;	/* 0x20C */
> +	u32 txrd;	/* 0x210 */
> +	u32 txirq;	/* 0x214 */
> +	u32 __reserved4[GRCAN_RESERVE_SIZE(0x214, 0x300)];
> +	u32 rxctrl;	/* 0x300 */
> +	u32 rxaddr;	/* 0x304 */
> +	u32 rxsize;	/* 0x308 */
> +	u32 rxwr;	/* 0x30C */
> +	u32 rxrd;	/* 0x310 */
> +	u32 rxirq;	/* 0x314 */
> +	u32 rxmask;	/* 0x318 */
> +	u32 rxcode;	/* 0x31C */
> +};
> +
> +#define GRCAN_CONF_ABORT	0x00000001
> +#define GRCAN_CONF_ENABLE0	0x00000002
> +#define GRCAN_CONF_ENABLE1	0x00000004
> +#define GRCAN_CONF_SELECT	0x00000008
> +#define GRCAN_CONF_SILENT	0x00000010
> +#define GRCAN_CONF_SAM		0x00000020 /* Available in some hardware */
> +#define GRCAN_CONF_BPR		0x00000300 /* Note: not BRP */
> +#define GRCAN_CONF_RSJ		0x00007000
> +#define GRCAN_CONF_PS1		0x00f00000
> +#define GRCAN_CONF_PS2		0x000f0000
> +#define GRCAN_CONF_SCALER	0xff000000
> +#define GRCAN_CONF_OPERATION						\
> +	(GRCAN_CONF_ABORT | GRCAN_CONF_ENABLE0 | GRCAN_CONF_ENABLE1	\
> +	 | GRCAN_CONF_SELECT | GRCAN_CONF_SILENT | GRCAN_CONF_SAM)
> +#define GRCAN_CONF_TIMING						\
> +	(GRCAN_CONF_BPR | GRCAN_CONF_RSJ | GRCAN_CONF_PS1		\
> +	 | GRCAN_CONF_PS2 | GRCAN_CONF_SCALER)
> +
> +#define GRCAN_CONF_RSJ_MIN	1
> +#define GRCAN_CONF_RSJ_MAX	4
> +#define GRCAN_CONF_PS1_MIN	1
> +#define GRCAN_CONF_PS1_MAX	15
> +#define GRCAN_CONF_PS2_MIN	2
> +#define GRCAN_CONF_PS2_MAX	8
> +#define GRCAN_CONF_SCALER_MIN	0
> +#define GRCAN_CONF_SCALER_MAX	255
> +#define GRCAN_CONF_SCALER_INC	1
> +
> +#define GRCAN_CONF_BPR_BIT	8
> +#define GRCAN_CONF_RSJ_BIT	12
> +#define GRCAN_CONF_PS1_BIT	20
> +#define GRCAN_CONF_PS2_BIT	16
> +#define GRCAN_CONF_SCALER_BIT	24
> +
> +#define GRCAN_STAT_PASS		0x000001
> +#define GRCAN_STAT_OFF		0x000002
> +#define GRCAN_STAT_OR		0x000004
> +#define GRCAN_STAT_AHBERR	0x000008
> +#define GRCAN_STAT_ACTIVE	0x000010
> +#define GRCAN_STAT_RXERRCNT	0x00ff00
> +#define GRCAN_STAT_TXERRCNT	0xff0000
> +
> +#define GRCAN_STAT_ERRCTR_RELATED	(GRCAN_STAT_PASS | GRCAN_STAT_OFF)
> +
> +#define GRCAN_STAT_RXERRCNT_BIT	8
> +#define GRCAN_STAT_TXERRCNT_BIT	16
> +
> +#define GRCAN_STAT_ERRCNT_WARNING_LIMIT	96
> +#define GRCAN_STAT_ERRCNT_PASSIVE_LIMIT	127
> +
> +#define GRCAN_CTRL_RESET	0x2
> +#define GRCAN_CTRL_ENABLE	0x1
> +
> +#define GRCAN_TXCTRL_ENABLE	0x1
> +#define GRCAN_TXCTRL_ONGOING	0x2
> +#define GRCAN_TXCTRL_SINGLE	0x4
> +
> +#define GRCAN_RXCTRL_ENABLE	0x1
> +#define GRCAN_RXCTRL_ONGOING	0x2
> +
> +/* Relative offset of IRQ sources to AMBA Plug&Play */
> +#define GRCAN_IRQIX_IRQ		0
> +#define GRCAN_IRQIX_TXSYNC	1
> +#define GRCAN_IRQIX_RXSYNC	2
> +
> +#define GRCAN_IRQ_PASS		0x00001
> +#define GRCAN_IRQ_OFF		0x00002
> +#define GRCAN_IRQ_OR		0x00004
> +#define GRCAN_IRQ_RXAHBERR	0x00008
> +#define GRCAN_IRQ_TXAHBERR	0x00010
> +#define GRCAN_IRQ_RXIRQ		0x00020
> +#define GRCAN_IRQ_TXIRQ		0x00040
> +#define GRCAN_IRQ_RXFULL	0x00080
> +#define GRCAN_IRQ_TXEMPTY	0x00100
> +#define GRCAN_IRQ_RX		0x00200
> +#define GRCAN_IRQ_TX		0x00400
> +#define GRCAN_IRQ_RXSYNC	0x00800
> +#define GRCAN_IRQ_TXSYNC	0x01000
> +#define GRCAN_IRQ_RXERRCTR	0x02000
> +#define GRCAN_IRQ_TXERRCTR	0x04000
> +#define GRCAN_IRQ_RXMISS	0x08000
> +#define GRCAN_IRQ_TXLOSS	0x10000
> +
> +#define GRCAN_IRQ_NONE	0
> +#define GRCAN_IRQ_ALL							\
> +	(GRCAN_IRQ_PASS | GRCAN_IRQ_OFF | GRCAN_IRQ_OR			\
> +	 | GRCAN_IRQ_RXAHBERR | GRCAN_IRQ_TXAHBERR			\
> +	 | GRCAN_IRQ_RXIRQ | GRCAN_IRQ_TXIRQ				\
> +	 | GRCAN_IRQ_RXFULL | GRCAN_IRQ_TXEMPTY				\
> +	 | GRCAN_IRQ_RX | GRCAN_IRQ_TX | GRCAN_IRQ_RXSYNC		\
> +	 | GRCAN_IRQ_TXSYNC | GRCAN_IRQ_RXERRCTR			\
> +	 | GRCAN_IRQ_TXERRCTR | GRCAN_IRQ_RXMISS			\
> +	 | GRCAN_IRQ_TXLOSS)
> +
> +#define GRCAN_IRQ_ERRCTR_RELATED (GRCAN_IRQ_RXERRCTR | GRCAN_IRQ_TXERRCTR \
> +				  | GRCAN_IRQ_PASS | GRCAN_IRQ_OFF)
> +#define GRCAN_IRQ_ERRORS (GRCAN_IRQ_ERRCTR_RELATED | GRCAN_IRQ_OR	\
> +			  | GRCAN_IRQ_TXAHBERR | GRCAN_IRQ_RXAHBERR	\
> +			  | GRCAN_IRQ_TXLOSS)
> +#define GRCAN_IRQ_DEFAULT (GRCAN_IRQ_RX | GRCAN_IRQ_TX | GRCAN_IRQ_ERRORS)
> +
> +#define GRCAN_MSG_SIZE		16
> +
> +#define GRCAN_MSG_IDE		0x80000000
> +#define GRCAN_MSG_RTR		0x40000000
> +#define GRCAN_MSG_BID		0x1ffc0000
> +#define GRCAN_MSG_EID		0x1fffffff
> +#define GRCAN_MSG_IDE_BIT	31
> +#define GRCAN_MSG_RTR_BIT	30
> +#define GRCAN_MSG_BID_BIT	18
> +#define GRCAN_MSG_EID_BIT	0
> +
> +#define GRCAN_MSG_DLC		0xf0000000
> +#define GRCAN_MSG_TXERRC	0x00ff0000
> +#define GRCAN_MSG_RXERRC	0x0000ff00
> +#define GRCAN_MSG_DLC_BIT	28
> +#define GRCAN_MSG_TXERRC_BIT	16
> +#define GRCAN_MSG_RXERRC_BIT	8
> +#define GRCAN_MSG_AHBERR	0x00000008
> +#define GRCAN_MSG_OR		0x00000004
> +#define GRCAN_MSG_OFF		0x00000002
> +#define GRCAN_MSG_PASS		0x00000001
> +
> +#define GRCAN_MSG_DATA_SLOT_INDEX(i) (2 + (i) / 4)
> +#define GRCAN_MSG_DATA_SHIFT(i) ((3 - (i) % 4) * 8)
> +
> +#define GRCAN_BUFFER_ALIGNMENT		1024
> +#define GRCAN_DEFAULT_BUFFER_SIZE	1024
> +#define GRCAN_VALID_TR_SIZE_MASK	0x001fffc0
> +
> +#define GRCAN_INVALID_BUFFER_SIZE(s)			\
> +	((s) == 0 || ((s) & ~GRCAN_VALID_TR_SIZE_MASK))
> +
> +#if GRCAN_INVALID_BUFFER_SIZE(GRCAN_DEFAULT_BUFFER_SIZE)
> +#error "Invalid default buffer size"
> +#endif
> +
> +struct grcan_dma_buffer {
> +	size_t size;
> +	void *buf;
> +	dma_addr_t handle;
> +};
> +
> +struct grcan_dma {
> +	size_t base_size;
> +	void *base_buf;
> +	dma_addr_t base_handle;
> +	struct grcan_dma_buffer tx;
> +	struct grcan_dma_buffer rx;
> +};
> +
> +/* GRCAN configuration parameters */
> +struct grcan_device_config {
> +	unsigned short enable0;
> +	unsigned short enable1;
> +	unsigned short select;
> +	unsigned int txsize;
> +	unsigned int rxsize;
> +};
> +
> +#define GRCAN_DEFAULT_DEVICE_CONFIG {				\
> +		.enable0	= 0,				\
> +		.enable1	= 0,				\
> +		.select		= 0,				\
> +		.txsize		= GRCAN_DEFAULT_BUFFER_SIZE,	\
> +		.rxsize		= GRCAN_DEFAULT_BUFFER_SIZE,	\
> +		}
> +
> +#define GRCAN_TXBUG_SAFE_GRLIB_VERSION	0x4100
> +#define GRLIB_VERSION_MASK		0xffff
> +
> +/* GRCAN private data structure */
> +struct grcan_priv {
> +	struct can_priv can;	/* must be the first member */
> +	struct net_device *dev;
> +	struct napi_struct napi;
> +
> +	struct grcan_registers __iomem *regs;	/* ioremap'ed registers */
> +	struct grcan_device_config config;
> +	struct grcan_dma dma;
> +
> +	struct sk_buff **echo_skb;	/* We allocate this on our own */
> +	u8 *txdlc;			/* Length of queued frames */
> +
> +	/* The echo skb pointer, pointing into echo_skb and indicating which
> +	 * frames can be echoed back. See the "Notes on the tx cyclic buffer
> +	 * handling"-comment for grcan_start_xmit for more details.
> +	 */
> +	u32 eskbp;
> +
> +	/* Lock for controlling changes to the netif tx queue state, accesses to
> +	 * the echo_skb pointer eskbp and for making sure that a running reset
> +	 * and/or a close of the interface is done without interference from
> +	 * other parts of the code.
> +	 *
> +	 * The echo_skb pointer, eskbp, should only be accessed under this lock
> +	 * as it can be changed in several places and together with decisions on
> +	 * whether to wake up the tx queue.
> +	 *
> +	 * The tx queue must never be woken up if there is a running reset or
> +	 * close in progress.
> +	 *
> +	 * A running reset (see below on need_txbug_workaround) should never be
> +	 * done if the interface is closing down and several running resets
> +	 * should never be scheduled simultaneously.
> +	 */
> +	spinlock_t lock;
> +
> +	/* Whether a workaround is needed due to a bug in older hardware. In
> +	 * this case, the driver both tries to prevent the bug from being
> +	 * triggered and recovers, if the bug nevertheless happens, by doing a
> +	 * running reset. A running reset, resets the device and continues from
> +	 * where it were without being noticeable from outside the driver (apart
> +	 * from slight delays).
> +	 */
> +	bool need_txbug_workaround;
> +
> +	/* To trigger initization of running reset and to trigger running reset
> +	 * respectively in the case of a hanged device due to a txbug.
> +	 */
> +	struct timer_list hang_timer;
> +	struct timer_list rr_timer;
> +
> +	/* To avoid waking up the netif queue and restarting timers
> +	 * when a reset is scheduled or when closing of the device is
> +	 * undergoing
> +	 */
> +	bool resetting;
> +	bool closing;
> +};
> +
> +/* Wait time for a short wait for ongoing to clear */
> +#define GRCAN_SHORTWAIT_USECS	10
> +
> +/* Limit on the number of transmitted bits of an eff frame according to the CAN
> + * specification: 1 bit start of frame, 32 bits arbitration field, 6 bits
> + * control field, 8 bytes data field, 16 bits crc field, 2 bits ACK field and 7
> + * bits end of frame
> + */
> +#define GRCAN_EFF_FRAME_MAX_BITS	(1+32+6+8*8+16+2+7)
> +
> +#if defined(__BIG_ENDIAN)
> +static inline u32 grcan_read_reg(u32 __iomem *reg)
> +{
> +	return ioread32be(reg);
> +}
> +
> +static inline void grcan_write_reg(u32 __iomem *reg, u32 val)
> +{
> +	iowrite32be(val, reg);
> +}
> +#else
> +static inline u32 grcan_read_reg(u32 __iomem *reg)
> +{
> +	return ioread32(reg);
> +}
> +
> +static inline void grcan_write_reg(u32 __iomem *reg, u32 val)
> +{
> +	iowrite32(val, reg);
> +}
> +#endif
> +
> +static inline void grcan_clear_bits(u32 __iomem *reg, u32 mask)
> +{
> +	grcan_write_reg(reg, grcan_read_reg(reg) & ~mask);
> +}
> +
> +static inline void grcan_set_bits(u32 __iomem *reg, u32 mask)
> +{
> +	grcan_write_reg(reg, grcan_read_reg(reg) | mask);
> +}
> +
> +static inline u32 grcan_read_bits(u32 __iomem *reg, u32 mask)
> +{
> +	return grcan_read_reg(reg) & mask;
> +}
> +
> +static inline void grcan_write_bits(u32 __iomem *reg, u32 value, u32 mask)
> +{
> +	u32 old = grcan_read_reg(reg);
> +
> +	grcan_write_reg(reg, (old & ~mask) | (value & mask));
> +}
> +
> +/* a and b should both be in [0,size] and a == b == size should not hold */
> +static inline u32 grcan_ring_add(u32 a, u32 b, u32 size)
> +{
> +	u32 sum = a + b;
> +
> +	if (sum < size)
> +		return sum;
> +	else
> +		return sum - size;
> +}
> +
> +/* a and b should both be in [0,size) */
> +static inline u32 grcan_ring_sub(u32 a, u32 b, u32 size)
> +{
> +	return grcan_ring_add(a, size - b, size);
> +}
> +
> +/* Available slots for new transmissions */
> +static inline u32 grcan_txspace(size_t txsize, u32 txwr, u32 eskbp)
> +{
> +	u32 slots = txsize / GRCAN_MSG_SIZE - 1;
> +	u32 used = grcan_ring_sub(txwr, eskbp, txsize) / GRCAN_MSG_SIZE;
> +
> +	return slots - used;
> +}
> +
> +/* Configuration parameters that can be set via module parameters */
> +static struct grcan_device_config grcan_module_config =
> +	GRCAN_DEFAULT_DEVICE_CONFIG;
> +
> +static struct can_bittiming_const grcan_bittiming_const = {

make it const

> +	.name		= DRV_NAME,
> +	.tseg1_min	= GRCAN_CONF_PS1_MIN + 1,
> +	.tseg1_max	= GRCAN_CONF_PS1_MAX + 1,
> +	.tseg2_min	= GRCAN_CONF_PS2_MIN,
> +	.tseg2_max	= GRCAN_CONF_PS2_MAX,
> +	.sjw_max	= GRCAN_CONF_RSJ_MAX,
> +	.brp_min	= GRCAN_CONF_SCALER_MIN + 1,
> +	.brp_max	= GRCAN_CONF_SCALER_MAX + 1,
> +	.brp_inc	= GRCAN_CONF_SCALER_INC,
> +};
> +
> +static int grcan_set_bittiming(struct net_device *dev)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	struct can_bittiming *bt = &priv->can.bittiming;
> +	u32 timing = 0;
> +	int bpr, rsj, ps1, ps2, scaler;
> +
> +	/* Should never happen - function will not be called when
> +	 * device is up
> +	 */
> +	if (grcan_read_bits(&regs->ctrl, GRCAN_CTRL_ENABLE))
> +		return -EBUSY;
> +
> +	bpr = 0; /* Note bpr and brp are different concepts */
> +	rsj = bt->sjw;
> +	ps1 = (bt->prop_seg + bt->phase_seg1) - 1; /* tseg1 - 1 */
> +	ps2 = bt->phase_seg2;
> +	scaler = (bt->brp - 1);
> +	timing |= (bpr << GRCAN_CONF_BPR_BIT) & GRCAN_CONF_BPR;
> +	timing |= (rsj << GRCAN_CONF_RSJ_BIT) & GRCAN_CONF_RSJ;
> +	timing |= (ps1 << GRCAN_CONF_PS1_BIT) & GRCAN_CONF_PS1;
> +	timing |= (ps2 << GRCAN_CONF_PS2_BIT) & GRCAN_CONF_PS2;
> +	timing |= (scaler << GRCAN_CONF_SCALER_BIT) & GRCAN_CONF_SCALER;
> +
> +	netdev_info(dev, "setting timing=0x%x\n", timing);

what about moving the sanity check before putting together the "timing"
variable and doing the netdev_info()?

> +	if (!(ps1 > ps2)) {
> +		netdev_err(dev, "PS1 > PS2 must hold: PS1=%d, PS2=%d\n",
> +			   ps1, ps2);
> +		return -EINVAL;
> +	}
> +	if (!(ps2 >= rsj)) {
> +		netdev_err(dev, "PS2 >= RSJ must hold: PS2=%d, RSJ=%d\n",
> +			   ps2, rsj);
> +		return -EINVAL;
> +	}
> +
> +	grcan_write_bits(&regs->conf, timing, GRCAN_CONF_TIMING);
> +	return 0;
> +}
> +
> +static int grcan_get_berr_counter(const struct net_device *dev,
> +				  struct can_berr_counter *bec)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	u32 status = grcan_read_reg(&regs->stat);
> +
> +	bec->txerr = (status & GRCAN_STAT_TXERRCNT) >> GRCAN_STAT_TXERRCNT_BIT;
> +	bec->rxerr = (status & GRCAN_STAT_RXERRCNT) >> GRCAN_STAT_RXERRCNT_BIT;
> +	return 0;
> +}
> +
> +static int grcan_poll(struct napi_struct *napi, int budget);
> +
> +/* Reset device, but keep configuration information */
> +static void grcan_reset(struct net_device *dev)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	u32 config = grcan_read_reg(&regs->conf);
> +
> +	grcan_set_bits(&regs->ctrl, GRCAN_CTRL_RESET);
> +	grcan_write_reg(&regs->conf, config);
> +
> +	priv->eskbp = grcan_read_reg(&regs->txrd);
> +	priv->can.state = CAN_STATE_STOPPED;
> +
> +	/* Turn off hardware filtering - regs->rxcode set to 0 by reset */
> +	grcan_write_reg(&regs->rxmask, 0);
> +}
> +
> +/* stop device without changing any configurations */
> +static void grcan_stop_hardware(struct net_device *dev)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +
> +	grcan_write_reg(&regs->imr, GRCAN_IRQ_NONE);
> +	grcan_clear_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
> +	grcan_clear_bits(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
> +	grcan_clear_bits(&regs->ctrl, GRCAN_CTRL_ENABLE);
> +}
> +
> +/* Let priv->eskbp catch up to regs->txrd and echo back the skbs if echo
> + * is true and free them otherwise.
> + *
> + * If budget is >= 0, stop after handling at most budget skbs. Otherwise,
> + * continue until priv->eskbp catches up to regs->txrd.
> + *
> + * priv->lock *must* be held when calling this function
> + */
> +static int catch_up_echo_skb(struct net_device *dev, int budget, bool echo)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	struct grcan_dma *dma = &priv->dma;
> +	struct net_device_stats *stats = &dev->stats;
> +	int i, work_done;
> +
> +	/* Updates to priv->eskbp and wake-ups of the queue needs to
> +	 * be atomic towards the reads of priv->eskbp and shut-downs
> +	 * of the queue in grcan_start_xmit.
> +	 */
> +	u32 txrd = grcan_read_reg(&regs->txrd);
> +
> +	for (work_done = 0; work_done < budget || budget < 0; work_done++) {
> +		if (priv->eskbp == txrd)
> +			break;
> +		i = priv->eskbp / GRCAN_MSG_SIZE;
> +		if (echo) {
> +			/* Normal echo of messages */
> +			stats->tx_packets++;
> +			stats->tx_bytes += priv->txdlc[i];
> +			priv->txdlc[i] = 0;
> +			can_get_echo_skb(dev, i);
> +		} else {
> +			/* For cleanup of untransmitted messages */
> +			can_free_echo_skb(dev, i);
> +		}
> +
> +		priv->eskbp = grcan_ring_add(priv->eskbp, GRCAN_MSG_SIZE,
> +					     dma->tx.size);
> +		txrd = grcan_read_reg(&regs->txrd);
> +	}
> +	return work_done;
> +}
> +
> +static void grcan_lost_one_shot_frame(struct net_device *dev)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	struct grcan_dma *dma = &priv->dma;
> +	u32 txrd;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&priv->lock, flags);
> +
> +	catch_up_echo_skb(dev, -1, true);
> +
> +	if (unlikely(grcan_read_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE))) {
> +		/* Should never happen */
> +		netdev_err(dev, "TXCTRL enabled at TXLOSS in one shot mode\n");
> +	} else {
> +		/* By the time an GRCAN_IRQ_TXLOSS is generated in
> +		 * one-shot mode there is no problem in writing
> +		 * to TXRD even in versions of the hardware in
> +		 * which GRCAN_TXCTRL_ONGOING is not cleared properly
> +		 * in one-shot mode.
> +		 */
> +
> +		/* Skip message and discard echo-skb */
> +		txrd = grcan_read_reg(&regs->txrd);
> +		txrd = grcan_ring_add(txrd, GRCAN_MSG_SIZE, dma->tx.size);
> +		grcan_write_reg(&regs->txrd, txrd);
> +		catch_up_echo_skb(dev, -1, false);
> +
> +		if (!priv->resetting && !priv->closing &&
> +		    !(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)) {
> +			netif_wake_queue(dev);
> +			grcan_set_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
> +		}
> +	}
> +
> +	spin_unlock_irqrestore(&priv->lock, flags);
> +}
> +
> +static void grcan_err(struct net_device *dev, u32 sources, u32 status)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	struct grcan_dma *dma = &priv->dma;
> +	struct net_device_stats *stats = &dev->stats;
> +	struct can_frame cf;
> +
> +	/* Zero potential error_frame */
> +	memset(&cf, 0, sizeof(cf));
> +
> +	/* Message lost interrupt. This might be due to arbitration error, but
> +	 * is also triggered when there is no one else on the can bus or when
> +	 * there is a problem with the hardware interface or the bus itself. As
> +	 * arbitration errors can not be singled out, no error frames are
> +	 * generated reporting this event as an arbitration error.
> +	 */
> +	if (sources & GRCAN_IRQ_TXLOSS) {
> +		/* Take care of failed one-shot transmit */
> +		if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT)
> +			grcan_lost_one_shot_frame(dev);
> +
> +		/* Stop printing as soon as error passive or bus off is in
> +		 * effect to limit the amount of txloss debug printouts.
> +		 */
> +		if (!(status & GRCAN_STAT_ERRCTR_RELATED)) {
> +			netdev_dbg(dev, "tx message lost\n");
> +			stats->tx_errors++;
> +		}
> +	}
> +
> +	/* Conditions dealing with the error counters. There is no interrupt for
> +	 * error warning, but there are interrupts for increases of the error
> +	 * counters.
> +	 */
> +	if ((sources & GRCAN_IRQ_ERRCTR_RELATED) ||
> +	    (status & GRCAN_STAT_ERRCTR_RELATED)) {
> +		enum can_state state = priv->can.state;
> +		enum can_state oldstate = state;
> +		u32 txerr = (status & GRCAN_STAT_TXERRCNT)
> +			>> GRCAN_STAT_TXERRCNT_BIT;
> +		u32 rxerr = (status & GRCAN_STAT_RXERRCNT)
> +			>> GRCAN_STAT_RXERRCNT_BIT;
> +
> +		/* Figure out current state */
> +		if (status & GRCAN_STAT_OFF) {
> +			state = CAN_STATE_BUS_OFF;
> +		} else if (status & GRCAN_STAT_PASS) {
> +			state = CAN_STATE_ERROR_PASSIVE;
> +		} else if (txerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT ||
> +			   rxerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT) {
> +			state = CAN_STATE_ERROR_WARNING;
> +		} else {
> +			state = CAN_STATE_ERROR_ACTIVE;
> +		}
> +
> +		/* Handle and report state changes */
> +		if (state != oldstate) {
> +			switch (state) {
> +			case CAN_STATE_BUS_OFF:
> +				netdev_dbg(dev, "bus-off\n");
> +				netif_carrier_off(dev);
> +				priv->can.can_stats.bus_off++;
> +
> +				/* Prevent the hardware from recovering from bus
> +				 * off on its own if restart is disabled.
> +				 */
> +				if (!priv->can.restart_ms)
> +					grcan_stop_hardware(dev);
> +
> +				cf.can_id |= CAN_ERR_BUSOFF;
> +				break;
> +
> +			case CAN_STATE_ERROR_PASSIVE:
> +				netdev_dbg(dev, "Error passive condition\n");
> +				priv->can.can_stats.error_passive++;
> +
> +				cf.can_id |= CAN_ERR_CRTL;
> +				if (txerr >= GRCAN_STAT_ERRCNT_PASSIVE_LIMIT)
> +					cf.data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
> +				if (rxerr >= GRCAN_STAT_ERRCNT_PASSIVE_LIMIT)
> +					cf.data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
> +				break;
> +
> +			case CAN_STATE_ERROR_WARNING:
> +				netdev_dbg(dev, "Error warning condition\n");
> +				priv->can.can_stats.error_warning++;
> +
> +				cf.can_id |= CAN_ERR_CRTL;
> +				if (txerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT)
> +					cf.data[1] |= CAN_ERR_CRTL_TX_WARNING;
> +				if (rxerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT)
> +					cf.data[1] |= CAN_ERR_CRTL_RX_WARNING;
> +				break;
> +
> +			case CAN_STATE_ERROR_ACTIVE:
> +				netdev_dbg(dev, "Error active condition\n");
> +				cf.can_id |= CAN_ERR_CRTL;
> +				break;
> +
> +			default:
> +				/* There are no others at this point */
> +				break;
> +			}
> +			cf.data[6] = txerr;
> +			cf.data[7] = rxerr;
> +			priv->can.state = state;
> +		}
> +
> +		/* Report automatic restarts */
> +		if (priv->can.restart_ms && oldstate == CAN_STATE_BUS_OFF) {
> +			unsigned long flags;
> +
> +			cf.can_id |= CAN_ERR_RESTARTED;
> +			netdev_dbg(dev, "restarted\n");
> +			priv->can.can_stats.restarts++;
> +			netif_carrier_on(dev);
> +
> +			spin_lock_irqsave(&priv->lock, flags);
> +
> +			if (!priv->resetting && !priv->closing) {
> +				u32 txwr = grcan_read_reg(&regs->txwr);
> +
> +				if (grcan_txspace(dma->tx.size, txwr,
> +						  priv->eskbp))
> +					netif_wake_queue(dev);
> +			}
> +
> +			spin_unlock_irqrestore(&priv->lock, flags);
> +		}
> +	}
> +
> +	/* Data overrun interrupt */
> +	if ((sources & GRCAN_IRQ_OR) || (status & GRCAN_STAT_OR)) {
> +		netdev_dbg(dev, "got data overrun interrupt\n");
> +		stats->rx_over_errors++;
> +		stats->rx_errors++;
> +
> +		cf.can_id |= CAN_ERR_CRTL;
> +		cf.data[1] |= CAN_ERR_CRTL_RX_OVERFLOW;
> +	}
> +
> +	/* AHB bus error interrupts (not CAN bus errors) - shut down the
> +	 * device.
> +	 */
> +	if (sources & (GRCAN_IRQ_TXAHBERR | GRCAN_IRQ_RXAHBERR) ||
> +	    (status & GRCAN_STAT_AHBERR)) {
> +		char *txrx = "";
> +		unsigned long flags;
> +
> +		if (sources & GRCAN_IRQ_TXAHBERR) {
> +			txrx = "on tx ";
> +			stats->tx_errors++;
> +		} else if (sources & GRCAN_IRQ_RXAHBERR) {
> +			txrx = "on rx ";
> +			stats->rx_errors++;
> +		}
> +		netdev_err(dev, "Fatal AHB buss error %s- halting device\n",
> +			   txrx);
> +
> +		spin_lock_irqsave(&priv->lock, flags);
> +
> +		/* Prevent anything to be enabled again and halt device */
> +		priv->closing = true;
> +		netif_stop_queue(dev);
> +		grcan_stop_hardware(dev);
> +		priv->can.state = CAN_STATE_STOPPED;
> +
> +		spin_unlock_irqrestore(&priv->lock, flags);
> +	}
> +
> +	/* Pass on error frame if something to report,
> +	 * i.e. id contains some information
> +	 */
> +	if (cf.can_id) {
> +		struct can_frame *skb_cf;
> +		struct sk_buff *skb = alloc_can_err_skb(dev, &skb_cf);
> +
> +		if (skb == NULL) {
> +			netdev_dbg(dev, "could not allocate error frame\n");
> +			return;
> +		}
> +		skb_cf->can_id |= cf.can_id;
> +		memcpy(skb_cf->data, cf.data, sizeof(cf.data));
> +
> +		netif_rx(skb);
> +	}
> +}
> +
> +static irqreturn_t grcan_interrupt(int irq, void *dev_id)
> +{
> +	struct net_device *dev = dev_id;
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	u32 sources, status;
> +
> +	/* Find out the source */
> +	sources = grcan_read_reg(&regs->pimsr);
> +	if (!sources)
> +		return IRQ_NONE;
> +	grcan_write_reg(&regs->picr, sources);
> +	status = grcan_read_reg(&regs->stat);
> +
> +	/* If we got TX progress, the device has not hanged,
> +	 * so disable the hang timer
> +	 */
> +	if (priv->need_txbug_workaround &&
> +	    (sources & (GRCAN_IRQ_TX | GRCAN_IRQ_TXLOSS))) {
> +		del_timer(&priv->hang_timer);
> +	}
> +
> +	/* Frame(s) received or transmitted */
> +	if (sources & (GRCAN_IRQ_TX | GRCAN_IRQ_RX)) {
> +		/* Disable tx/rx interrupts and schedule poll() */
> +		grcan_clear_bits(&regs->imr, GRCAN_IRQ_TX | GRCAN_IRQ_RX);
> +		napi_schedule(&priv->napi);
> +	}
> +
> +	/* (Potential) error conditions to take care of */
> +	if (sources & GRCAN_IRQ_ERRORS)
> +		grcan_err(dev, sources, status);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +/* Reset device and restart operations from where they were.
> + *
> + * This assumes that RXCTRL & RXCTRL is properly disabled and that RX
> + * is not ONGOING (TX might be stuck in ONGOING due to a harwrware bug
> + * for single shot)
> + */
> +static void grcan_running_reset(unsigned long data)
> +{
> +	struct net_device *dev = (struct net_device *)data;
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	unsigned long flags;
> +
> +	/* This temporarily messes with eskbp, so we need to lock
> +	 * priv->lock
> +	 */
> +	spin_lock_irqsave(&priv->lock, flags);
> +
> +	priv->resetting = false;
> +	del_timer(&priv->hang_timer);
> +	del_timer(&priv->rr_timer);
> +
> +	if (!priv->closing) {
> +		/* Save and reset - config register preserved by grcan_reset */
> +		u32 imr = grcan_read_reg(&regs->imr);
> +
> +		u32 txaddr = grcan_read_reg(&regs->txaddr);
> +		u32 txsize = grcan_read_reg(&regs->txsize);
> +		u32 txwr = grcan_read_reg(&regs->txwr);
> +		u32 txrd = grcan_read_reg(&regs->txrd);
> +		u32 eskbp = priv->eskbp;
> +
> +		u32 rxaddr = grcan_read_reg(&regs->rxaddr);
> +		u32 rxsize = grcan_read_reg(&regs->rxsize);
> +		u32 rxwr = grcan_read_reg(&regs->rxwr);
> +		u32 rxrd = grcan_read_reg(&regs->rxrd);
> +
> +		grcan_reset(dev);
> +
> +		/* Restore */
> +		grcan_write_reg(&regs->txaddr, txaddr);
> +		grcan_write_reg(&regs->txsize, txsize);
> +		grcan_write_reg(&regs->txwr, txwr);
> +		grcan_write_reg(&regs->txrd, txrd);
> +		priv->eskbp = eskbp;
> +
> +		grcan_write_reg(&regs->rxaddr, rxaddr);
> +		grcan_write_reg(&regs->rxsize, rxsize);
> +		grcan_write_reg(&regs->rxwr, rxwr);
> +		grcan_write_reg(&regs->rxrd, rxrd);
> +
> +		/* Turn on device again */
> +		grcan_write_reg(&regs->imr, imr);
> +		priv->can.state = CAN_STATE_ERROR_ACTIVE;
> +		grcan_write_reg(&regs->txctrl, GRCAN_TXCTRL_ENABLE
> +				| (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT
> +				   ? GRCAN_TXCTRL_SINGLE : 0));
> +		grcan_write_reg(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
> +		grcan_write_reg(&regs->ctrl, GRCAN_CTRL_ENABLE);
> +
> +		/* Start queue if there is size and listen-onle mode is not
> +		 * enabled
> +		 */
> +		if (grcan_txspace(priv->dma.tx.size, txwr, priv->eskbp) &&
> +		    !(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
> +			netif_wake_queue(dev);
> +	}
> +
> +	spin_unlock_irqrestore(&priv->lock, flags);
> +
> +	netdev_err(dev, "Device reset and restored\n");
> +}
> +
> +/* Waiting time in usecs corresponding to the transmission of three maximum
> + * sized can frames in the given bitrate (in bits/sec). Waiting for this amount
> + * of time makes sure that the can controller have time to finish sending or
> + * receiving a frame with a good margin.
> + *
> + * usecs/sec * number of frames * bits/frame / bits/sec
> + */
> +static inline u32 grcan_ongoing_wait_usecs(__u32 bitrate)
> +{
> +	return 1000000 * 3 * GRCAN_EFF_FRAME_MAX_BITS / bitrate;
> +}
> +
> +/* Set timer so that it will not fire until after a period in which the can
> + * controller have a good margin to finish transmitting a frame unless it has
> + * hanged
> + */
> +static inline void grcan_reset_timer(struct timer_list *timer, __u32 bitrate)
> +{
> +	u32 wait_jiffies = usecs_to_jiffies(grcan_ongoing_wait_usecs(bitrate));
> +
> +	mod_timer(timer, jiffies + wait_jiffies);
> +}
> +
> +/* Disable channels and schedule a running reset */
> +static void grcan_initiate_running_reset(unsigned long data)
> +{
> +	struct net_device *dev = (struct net_device *)data;
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	unsigned long flags;
> +
> +	netdev_err(dev, "Device seems hanged - reset scheduled\n");
> +
> +	spin_lock_irqsave(&priv->lock, flags);
> +
> +	/* The main body of this function must never be executed again
> +	 * until after an execution of grcan_running_reset
> +	 */
> +	if (!priv->resetting && !priv->closing) {
> +		priv->resetting = true;
> +		netif_stop_queue(dev);
> +		grcan_clear_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
> +		grcan_clear_bits(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
> +		grcan_reset_timer(&priv->rr_timer, priv->can.bittiming.bitrate);
> +	}
> +
> +	spin_unlock_irqrestore(&priv->lock, flags);
> +}
> +
> +static void grcan_free_dma_buffers(struct net_device *dev)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_dma *dma = &priv->dma;
> +
> +	dma_free_coherent(&dev->dev, dma->base_size, dma->base_buf,
> +			  dma->base_handle);
> +	memset(dma, 0, sizeof(*dma));
> +}
> +
> +static int grcan_allocate_dma_buffers(struct net_device *dev,
> +				      size_t tsize, size_t rsize)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_dma *dma = &priv->dma;
> +	struct grcan_dma_buffer *large = rsize > tsize ? &dma->rx : &dma->tx;
> +	struct grcan_dma_buffer *small = rsize > tsize ? &dma->tx : &dma->rx;
> +	size_t shift;
> +
> +	/* Need a whole number of GRCAN_BUFFER_ALIGNMENT for the large,
> +	 * i.e. first buffer
> +	 */
> +	size_t maxs = max(tsize, rsize);
> +	size_t lsize = ALIGN(maxs, GRCAN_BUFFER_ALIGNMENT);
> +
> +	/* Put the small buffer after that */
> +	size_t ssize = min(tsize, rsize);
> +
> +	/* Extra GRCAN_BUFFER_ALIGNMENT to allow for alignment */
> +	dma->base_size = lsize + ssize + GRCAN_BUFFER_ALIGNMENT;
> +	dma->base_buf = dma_alloc_coherent(&dev->dev,
> +					   dma->base_size,
> +					   &dma->base_handle,
> +					   GFP_KERNEL);
> +
> +	if (!dma->base_buf)
> +		return -ENOMEM;
> +
> +	dma->tx.size = tsize;
> +	dma->rx.size = rsize;
> +
> +	large->handle = ALIGN(dma->base_handle, GRCAN_BUFFER_ALIGNMENT);
> +	small->handle = large->handle + lsize;
> +	shift = large->handle - dma->base_handle;
> +
> +	large->buf = dma->base_buf + shift;
> +	small->buf = large->buf + lsize;
> +
> +	return 0;
> +}
> +
> +/* priv->lock *must* be held when calling this function */
> +static int grcan_start(struct net_device *dev)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	u32 confop, txctrl;
> +
> +	grcan_reset(dev);
> +
> +	grcan_write_reg(&regs->txaddr, priv->dma.tx.handle);
> +	grcan_write_reg(&regs->txsize, priv->dma.tx.size);
> +	/* regs->txwr, regs->txrd and priv->eskbp already set to 0 by reset */
> +
> +	grcan_write_reg(&regs->rxaddr, priv->dma.rx.handle);
> +	grcan_write_reg(&regs->rxsize, priv->dma.rx.size);
> +	/* regs->rxwr and regs->rxrd already set to 0 by reset */
> +
> +	/* Enable interrupts */
> +	grcan_read_reg(&regs->pir);
> +	grcan_write_reg(&regs->imr, GRCAN_IRQ_DEFAULT);
> +
> +	/* Enable interfaces, channels and device */
> +	confop = GRCAN_CONF_ABORT
> +		| (priv->config.enable0 ? GRCAN_CONF_ENABLE0 : 0)
> +		| (priv->config.enable1 ? GRCAN_CONF_ENABLE1 : 0)
> +		| (priv->config.select ? GRCAN_CONF_SELECT : 0)
> +		| (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY ?
> +		   GRCAN_CONF_SILENT : 0)
> +		| (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES ?
> +		   GRCAN_CONF_SAM : 0);
> +	grcan_write_bits(&regs->conf, confop, GRCAN_CONF_OPERATION);
> +	txctrl = GRCAN_TXCTRL_ENABLE
> +		| (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT
> +		   ? GRCAN_TXCTRL_SINGLE : 0);
> +	grcan_write_reg(&regs->txctrl, txctrl);
> +	grcan_write_reg(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
> +	grcan_write_reg(&regs->ctrl, GRCAN_CTRL_ENABLE);
> +
> +	priv->can.state = CAN_STATE_ERROR_ACTIVE;
> +
> +	return 0;
> +}
> +
> +static int grcan_set_mode(struct net_device *dev, enum can_mode mode)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	unsigned long flags;
> +	int err = 0;
> +
> +	if (mode == CAN_MODE_START) {
> +		/* This might be called to restart the device to recover from
> +		 * bus off errors
> +		 */
> +		spin_lock_irqsave(&priv->lock, flags);
> +		if (priv->closing || priv->resetting) {
> +			err = -EBUSY;
> +		} else {
> +			netdev_info(dev, "Restarting device\n");
> +			grcan_start(dev);
> +			if (!(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
> +				netif_wake_queue(dev);
> +		}
> +		spin_unlock_irqrestore(&priv->lock, flags);
> +		return err;
> +	}
> +	return -EOPNOTSUPP;
> +}
> +
> +static int grcan_open(struct net_device *dev)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_dma *dma = &priv->dma;
> +	unsigned long flags;
> +	int err;
> +
> +	/* Allocate memory */
> +	err = grcan_allocate_dma_buffers(dev, priv->config.txsize,
> +					 priv->config.rxsize);
> +	if (err) {
> +		netdev_err(dev, "could not allocate DMA buffers\n");
> +		return err;
> +	}
> +
> +	priv->echo_skb = kzalloc(dma->tx.size * sizeof(*priv->echo_skb),
> +				 GFP_KERNEL);
> +	if (!priv->echo_skb) {
> +		err = -ENOMEM;
> +		goto exit_free_dma_buffers;
> +	}
> +	priv->can.echo_skb_max = dma->tx.size;
> +	priv->can.echo_skb = priv->echo_skb;
> +
> +	priv->txdlc = kzalloc(dma->tx.size * sizeof(*priv->txdlc), GFP_KERNEL);
> +	if (!priv->txdlc) {
> +		err = -ENOMEM;
> +		goto exit_free_echo_skb;
> +	}
> +
> +	/* Get can device up */
> +	err = open_candev(dev);
> +	if (err)
> +		goto exit_free_txdlc;
> +
> +	err = request_irq(dev->irq, grcan_interrupt, IRQF_SHARED,
> +			  dev->name, dev);
> +	if (err)
> +		goto exit_close_candev;
> +
> +	spin_lock_irqsave(&priv->lock, flags);
> +
> +	napi_enable(&priv->napi);
> +	grcan_start(dev);
> +	if (!(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
> +		netif_start_queue(dev);
> +	priv->resetting = false;
> +	priv->closing = false;
> +
> +	spin_unlock_irqrestore(&priv->lock, flags);
> +
> +	return 0;
> +
> +exit_close_candev:
> +	close_candev(dev);
> +exit_free_txdlc:
> +	kfree(priv->txdlc);
> +exit_free_echo_skb:
> +	kfree(priv->echo_skb);
> +exit_free_dma_buffers:
> +	grcan_free_dma_buffers(dev);
> +	return err;
> +}
> +
> +static int grcan_close(struct net_device *dev)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	unsigned long flags;
> +
> +	napi_disable(&priv->napi);
> +
> +	spin_lock_irqsave(&priv->lock, flags);
> +
> +	priv->closing = true;
> +	if (priv->need_txbug_workaround) {
> +		del_timer_sync(&priv->hang_timer);
> +		del_timer_sync(&priv->rr_timer);
> +	}
> +	netif_stop_queue(dev);
> +	grcan_stop_hardware(dev);
> +	priv->can.state = CAN_STATE_STOPPED;
> +
> +	spin_unlock_irqrestore(&priv->lock, flags);
> +
> +	free_irq(dev->irq, dev);
> +	close_candev(dev);
> +
> +	grcan_free_dma_buffers(dev);
> +	priv->can.echo_skb_max = 0;
> +	priv->can.echo_skb = NULL;
> +	kfree(priv->echo_skb);
> +	kfree(priv->txdlc);
> +
> +	return 0;
> +}
> +
> +static void grcan_transmit_catch_up(struct net_device *dev, int budget)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	unsigned long flags;
> +	int work_done;
> +
> +	spin_lock_irqsave(&priv->lock, flags);
> +
> +	work_done = catch_up_echo_skb(dev, budget, true);
> +	if (work_done) {
> +		if (!priv->resetting && !priv->closing &&
> +		    !(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
> +			netif_wake_queue(dev);
> +
> +		/* With napi we don't get TX interrupts for a while,
> +		 * so prevent a running reset while catching up
> +		 */
> +		if (priv->need_txbug_workaround)
> +			del_timer(&priv->hang_timer);
> +	}
> +
> +	spin_unlock_irqrestore(&priv->lock, flags);
> +}
> +
> +static int grcan_receive(struct net_device *dev, int budget)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	struct grcan_dma *dma = &priv->dma;
> +	struct net_device_stats *stats = &dev->stats;
> +	struct can_frame *cf;
> +	struct sk_buff *skb;
> +	u32 wr, rd, startrd;
> +	u32 *slot;
> +	u32 i, rtr, eff, j, shift;
> +	int work_done = 0;
> +
> +	rd = grcan_read_reg(&regs->rxrd);
> +	startrd = rd;
> +	for (work_done = 0; work_done < budget; work_done++) {
> +		/* Check for packet to receive */
> +		wr = grcan_read_reg(&regs->rxwr);
> +		if (rd == wr)
> +			break;
> +
> +		/* Take care of packet */
> +		skb = alloc_can_skb(dev, &cf);
> +		if (skb == NULL) {
> +			netdev_err(dev,
> +				   "dropping frame: skb allocation failed\n");
> +			stats->rx_dropped++;
> +			continue;
> +		}
> +
> +		slot = dma->rx.buf + rd;
> +		eff = slot[0] & GRCAN_MSG_IDE;
> +		rtr = slot[0] & GRCAN_MSG_RTR;
> +		if (eff) {
> +			cf->can_id = ((slot[0] & GRCAN_MSG_EID)
> +				      >> GRCAN_MSG_EID_BIT);
> +			cf->can_id |= CAN_EFF_FLAG;
> +		} else {
> +			cf->can_id = ((slot[0] & GRCAN_MSG_BID)
> +				      >> GRCAN_MSG_BID_BIT);
> +		}
> +		cf->can_dlc = get_can_dlc((slot[1] & GRCAN_MSG_DLC)
> +					  >> GRCAN_MSG_DLC_BIT);
> +		if (rtr) {
> +			cf->can_id |= CAN_RTR_FLAG;
> +		} else {
> +			for (i = 0; i < cf->can_dlc; i++) {
> +				j = GRCAN_MSG_DATA_SLOT_INDEX(i);
> +				shift = GRCAN_MSG_DATA_SHIFT(i);
> +				cf->data[i] = (u8)(slot[j] >> shift);
> +			}
> +		}
> +		netif_receive_skb(skb);
> +
> +		/* Update statistics and read pointer */
> +		stats->rx_packets++;
> +		stats->rx_bytes += cf->can_dlc;
> +		rd = grcan_ring_add(rd, GRCAN_MSG_SIZE, dma->rx.size);
> +	}
> +
> +	/* Make sure everything is read before allowing hardware to
> +	 * use the memory
> +	 */
> +	mb();
> +
> +	/* Update read pointer - no need to check for ongoing */
> +	if (likely(rd != startrd))
> +		grcan_write_reg(&regs->rxrd, rd);
> +
> +	return work_done;
> +}
> +
> +/* priv->lock *must* be held when calling this function */
> +static inline int grcan_poll_all_done(struct net_device *dev)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	u32 txrd = grcan_read_reg(&regs->txrd);
> +	u32 rxwr = grcan_read_reg(&regs->rxwr);
> +	u32 rxrd = grcan_read_reg(&regs->rxrd);
> +
> +	return priv->eskbp == txrd && rxwr == rxrd;
> +}
> +
> +static int grcan_poll(struct napi_struct *napi, int rx_budget)
> +{
> +	struct grcan_priv *priv = container_of(napi, struct grcan_priv, napi);
> +	struct net_device *dev = priv->dev;
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	int rx_work_done;
> +	unsigned long flags;
> +
> +	/* Receive according to given budget */
> +	rx_work_done = grcan_receive(dev, rx_budget);
> +
> +	/* Catch up echo skb according to separate budget to get the benefits of
> +	 * napi for tx as well. The given rx_budget might not be appropriate for
> +	 * the tx side.
> +	 */
> +	grcan_transmit_catch_up(dev, GRCAN_TX_BUDGET);
> +
> +	spin_lock_irqsave(&priv->lock, flags);
> +
> +	if (grcan_poll_all_done(dev)) {

Just make it:
	if (work_done < budget) {
		napi_complete();
		enable_interrupts();
	}

If there are CAN frames pending, an interrupt will kick in and
reschedule the NAPI.

> +		bool complete = true;
> +
> +		if (!priv->closing) {
> +			/* Enable tx and rx interrupts again */
> +			grcan_set_bits(&regs->imr, GRCAN_IRQ_TX | GRCAN_IRQ_RX);
> +
> +			/* If more work arrived between detecting completion and
> +			 * turning on interrupts, we need to keep napi running
> +			 */
> +			if (!grcan_poll_all_done(dev)) {
> +				complete = false;
> +				grcan_clear_bits(&regs->imr,
> +						 GRCAN_IRQ_TX | GRCAN_IRQ_RX);
> +			}
> +		}
> +		if (complete)
> +			napi_complete(napi);
> +	}
> +
> +	spin_unlock_irqrestore(&priv->lock, flags);
> +
> +	return rx_work_done;
> +}
> +
> +/* Work tx bug by waiting while for the risky situation to clear. If that fails,
> + * drop a frame in one-shot mode or indicate a busy device otherwise.
> + *
> + * Returns 0 on successful wait. Otherwise it sets *netdev_tx_status to the
> + * value that should be returned by grcan_start_xmit when aborting the xmit.
> + */
> +static int grcan_txbug_workaround(struct net_device *dev, struct sk_buff *skb,
> +				  u32 txwr, u32 oneshotmode,
> +				  netdev_tx_t *netdev_tx_status)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	struct grcan_dma *dma = &priv->dma;
> +	int i;
> +	unsigned long flags;
> +
> +	/* Wait a while for ongoing to be cleared or read pointer to catch up to
> +	 * write pointer. The latter is needed due to a bug in older versions of
> +	 * GRCAN in which ONGOING is not cleared properly one-shot mode when a
> +	 * transmission fails.
> +	 */
> +	for (i = 0; i < GRCAN_SHORTWAIT_USECS; i++) {
> +		udelay(1);
> +		if (!grcan_read_bits(&regs->txctrl, GRCAN_TXCTRL_ONGOING) ||
> +		    grcan_read_reg(&regs->txrd) == txwr) {
> +			return 0;
> +		}
> +	}
> +
> +	/* Clean up, in case the situation was not resolved */
> +	spin_lock_irqsave(&priv->lock, flags);
> +	if (!priv->resetting && !priv->closing) {
> +		/* Queue might have been stopped earlier in grcan_start_xmit */
> +		if (grcan_txspace(dma->tx.size, txwr, priv->eskbp))
> +			netif_wake_queue(dev);
> +		/* Set a timer to resolve a hanged tx controller */
> +		if (!timer_pending(&priv->hang_timer))
> +			grcan_reset_timer(&priv->hang_timer,
> +					  priv->can.bittiming.bitrate);
> +	}
> +	spin_unlock_irqrestore(&priv->lock, flags);
> +
> +	if (oneshotmode) {
> +		/* In one-shot mode we should never end up here because
> +		 * then the interrupt handler increases txrd on TXLOSS,
> +		 * but it is consistent with one-shot mode to drop the
> +		 * frame in this case.
> +		 */
> +		kfree_skb(skb);
> +		*netdev_tx_status = NETDEV_TX_OK;
> +	} else {
> +		/* In normal mode the socket-can transmission queue get
> +		 * to keep the frame so that it can be retransmitted
> +		 * later
> +		 */
> +		*netdev_tx_status = NETDEV_TX_BUSY;
> +	}
> +	return -EBUSY;
> +}
> +
> +/* Notes on the tx cyclic buffer handling:
> + *
> + * regs->txwr	- the next slot for the driver to put data to be sent
> + * regs->txrd	- the next slot for the device to read data
> + * priv->eskbp	- the next slot for the driver to call can_put_echo_skb for
> + *
> + * grcan_start_xmit can enter more messages as long as regs->txwr does
> + * not reach priv->eskbp (within 1 message gap)
> + *
> + * The device sends messages until regs->txrd reaches regs->txwr
> + *
> + * The interrupt calls handler calls can_put_echo_skb until
> + * priv->eskbp reaches regs->txrd
> + */
> +static netdev_tx_t grcan_start_xmit(struct sk_buff *skb,
> +				    struct net_device *dev)
> +{
> +	struct grcan_priv *priv = netdev_priv(dev);
> +	struct grcan_registers __iomem *regs = priv->regs;
> +	struct grcan_dma *dma = &priv->dma;
> +	struct can_frame *cf = (struct can_frame *)skb->data;
> +	u32 id, txwr, txrd, space, txctrl;
> +	int slotindex;
> +	u32 *slot;
> +	u32 i, rtr, eff, dlc, tmp, err;
> +	int j, shift;
> +	unsigned long flags;
> +	u32 oneshotmode = priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT;
> +
> +	if (can_dropped_invalid_skb(dev, skb))
> +		return NETDEV_TX_OK;
> +
> +	/* Trying to transmit in silent mode will generate error interrupts, but
> +	 * this should never happen - the queue should not have been started.
> +	 */
> +	if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
> +		return NETDEV_TX_BUSY;
> +
> +	/* Reads of priv->eskbp and shut-downs of the queue needs to
> +	 * be atomic towards the updates to priv->eskbp and wake-ups
> +	 * of the queue in the interrupt handler.
> +	 */
> +	spin_lock_irqsave(&priv->lock, flags);
> +
> +	txwr = grcan_read_reg(&regs->txwr);
> +	space = grcan_txspace(dma->tx.size, txwr, priv->eskbp);
> +
> +	slotindex = txwr / GRCAN_MSG_SIZE;
> +	slot = dma->tx.buf + txwr;
> +
> +	if (unlikely(space == 1))
> +		netif_stop_queue(dev);
> +
> +	spin_unlock_irqrestore(&priv->lock, flags);
> +	/* End of critical section*/
> +
> +	/* This should never happen. If circular buffer is full, the
> +	 * netif_stop_queue should have been stopped already.
> +	 */
> +	if (unlikely(!space)) {
> +		netdev_err(dev, "No buffer space, but queue is non-stopped.\n");
> +		return NETDEV_TX_BUSY;
> +	}
> +
> +	/* Convert and write CAN message to DMA buffer */
> +	eff = cf->can_id & CAN_EFF_FLAG;
> +	rtr = cf->can_id & CAN_RTR_FLAG;
> +	id = cf->can_id & (eff ? CAN_EFF_MASK : CAN_SFF_MASK);
> +	dlc = cf->can_dlc;
> +	if (eff)
> +		tmp = (id << GRCAN_MSG_EID_BIT) & GRCAN_MSG_EID;
> +	else
> +		tmp = (id << GRCAN_MSG_BID_BIT) & GRCAN_MSG_BID;
> +	slot[0] = (eff ? GRCAN_MSG_IDE : 0) | (rtr ? GRCAN_MSG_RTR : 0) | tmp;
> +
> +	slot[1] = ((dlc << GRCAN_MSG_DLC_BIT) & GRCAN_MSG_DLC);
> +	slot[2] = 0;
> +	slot[3] = 0;
> +	for (i = 0; i < dlc; i++) {
> +		j = GRCAN_MSG_DATA_SLOT_INDEX(i);
> +		shift = GRCAN_MSG_DATA_SHIFT(i);
> +		slot[j] |= cf->data[i] << shift;
> +	}
> +
> +	/* Checking that channel has not been disabled. These cases
> +	 * should never happen
> +	 */
> +	txctrl = grcan_read_reg(&regs->txctrl);
> +	if (!(txctrl & GRCAN_TXCTRL_ENABLE))
> +		netdev_err(dev, "tx channel spuriously disabled\n");
> +
> +	if (oneshotmode && !(txctrl & GRCAN_TXCTRL_SINGLE))
> +		netdev_err(dev, "one-shot mode spuriously disabled\n");
> +
> +	/* Bug workaround for old version of grcan where updating txwr
> +	 * in the same clock cycle as the controller updates txrd to
> +	 * the current txwr could hang the can controller
> +	 */
> +	if (priv->need_txbug_workaround) {
> +		txrd = grcan_read_reg(&regs->txrd);
> +		if (unlikely(grcan_ring_sub(txwr, txrd, dma->tx.size) == 1)) {
> +			netdev_tx_t txstatus;
> +
> +			err = grcan_txbug_workaround(dev, skb, txwr,
> +						     oneshotmode, &txstatus);
> +			if (err)
> +				return txstatus;
> +		}
> +	}
> +
> +	/* Prepare skb for echoing. This must be after the bug workaround above
> +	 * as ownership of the skb is passed on by calling can_put_echo_skb.
> +	 * Returning NETDEV_TX_BUSY or accessing skb or cf after a call to
> +	 * can_put_echo_skb would be an error unless other measures are
> +	 * taken.
> +	 */
> +	priv->txdlc[slotindex] = cf->can_dlc; /* Store dlc for statistics */
> +	can_put_echo_skb(skb, dev, slotindex);
> +
> +	/* Make sure everything is written before allowing hardware to
> +	 * read from the memory
> +	 */
> +	wmb();
> +
> +	/* Update write pointer to start transmission */
> +	grcan_write_reg(&regs->txwr,
> +			grcan_ring_add(txwr, GRCAN_MSG_SIZE, dma->tx.size));
> +
> +	return NETDEV_TX_OK;
> +}
> +
> +/* ========== Setting up sysfs interface and module parameters ========== */
> +
> +#define GRCAN_NOT_BOOL(unsigned_val) ((unsigned_val) > 1)
> +
> +#define GRCAN_MODULE_PARAM(name, mtype, valcheckf, desc)		\
> +	static void grcan_sanitize_##name(struct platform_device *pd)	\
> +	{								\
> +		struct grcan_device_config grcan_default_config		\
> +			= GRCAN_DEFAULT_DEVICE_CONFIG;			\
> +		if (valcheckf(grcan_module_config.name)) {		\
> +			dev_err(&pd->dev,				\
> +				"Invalid module parameter value for "	\
> +				#name " - setting default\n");		\
> +			grcan_module_config.name =			\
> +				grcan_default_config.name;		\
> +		}							\
> +	}								\
> +	module_param_named(name, grcan_module_config.name,		\
> +			   mtype, S_IRUGO);				\
> +	MODULE_PARM_DESC(name, desc)
> +
> +#define GRCAN_CONFIG_ATTR(name, desc)					\
> +	static ssize_t grcan_store_##name(struct device *sdev,		\
> +					  struct device_attribute *att,	\
> +					  const char *buf,		\
> +					  size_t count)			\
> +	{								\
> +		struct net_device *dev = to_net_dev(sdev);		\
> +		struct grcan_priv *priv = netdev_priv(dev);		\
> +		u8 val;							\
> +		int ret;						\
> +		if (dev->flags & IFF_UP)				\
> +			return -EBUSY;					\
> +		ret = kstrtou8(buf, 0, &val);				\
> +		if (ret < 0 || val > 1)					\
> +			return -EINVAL;					\
> +		priv->config.name = val;				\
> +		return count;						\
> +	}								\
> +	static ssize_t grcan_show_##name(struct device *sdev,		\
> +					 struct device_attribute *att,	\
> +					 char *buf)			\
> +	{								\
> +		struct net_device *dev = to_net_dev(sdev);		\
> +		struct grcan_priv *priv = netdev_priv(dev);		\
> +		return sprintf(buf, "%d\n", priv->config.name);		\
> +	}								\
> +	static DEVICE_ATTR(name, S_IRUGO | S_IWUSR,			\
> +			   grcan_show_##name,				\
> +			   grcan_store_##name);				\
> +	GRCAN_MODULE_PARAM(name, ushort, GRCAN_NOT_BOOL, desc)
> +
> +/* The following configuration options are made available both via module
> + * parameters and writable sysfs files. See the chapter about GRCAN in the
> + * documentation for the GRLIB VHDL library for further details.
> + */
> +GRCAN_CONFIG_ATTR(enable0,
> +		  "Configuration of physical interface 0. Determines\n"	\
> +		  "the \"Enable 0\" bit of the configuration register.\n" \
> +		  "Format: 0 | 1\nDefault: 0\n");
> +
> +GRCAN_CONFIG_ATTR(enable1,
> +		  "Configuration of physical interface 1. Determines\n"	\
> +		  "the \"Enable 1\" bit of the configuration register.\n" \
> +		  "Format: 0 | 1\nDefault: 0\n");
> +
> +GRCAN_CONFIG_ATTR(select,
> +		  "Select which physical interface to use.\n"	\
> +		  "Format: 0 | 1\nDefault: 0\n");
> +
> +/* The tx and rx buffer size configuration options are only available via module
> + * parameters.
> + */
> +GRCAN_MODULE_PARAM(txsize, uint, GRCAN_INVALID_BUFFER_SIZE,
> +		   "Sets the size of the tx buffer.\n"			\
> +		   "Format: <unsigned int> where (txsize & ~0x1fffc0) == 0\n" \
> +		   "Default: 1024\n");
> +GRCAN_MODULE_PARAM(rxsize, uint, GRCAN_INVALID_BUFFER_SIZE,
> +		   "Sets the size of the rx buffer.\n"			\
> +		   "Format: <unsigned int> where (size & ~0x1fffc0) == 0\n" \
> +		   "Default: 1024\n");
> +
> +/* Function that makes sure that configuration done using
> + * module parameters are set to valid values
> + */
> +static void grcan_sanitize_module_config(struct platform_device *ofdev)
> +{
> +	grcan_sanitize_enable0(ofdev);
> +	grcan_sanitize_enable1(ofdev);
> +	grcan_sanitize_select(ofdev);
> +	grcan_sanitize_txsize(ofdev);
> +	grcan_sanitize_rxsize(ofdev);
> +}
> +
> +static const struct attribute *const sysfs_grcan_attrs[] = {
> +	/* Config attrs */
> +	&dev_attr_enable0.attr,
> +	&dev_attr_enable1.attr,
> +	&dev_attr_select.attr,
> +	NULL,
> +};
> +
> +static const struct attribute_group sysfs_grcan_group = {
> +	.name	= "grcan",
> +	.attrs	= (struct attribute **)sysfs_grcan_attrs,
> +};
> +
> +/* ========== Setting up the driver ========== */
> +
> +static const struct net_device_ops grcan_netdev_ops = {
> +	.ndo_open	= grcan_open,
> +	.ndo_stop	= grcan_close,
> +	.ndo_start_xmit	= grcan_start_xmit,
> +};
> +
> +static int grcan_setup_netdev(struct platform_device *ofdev,
> +			      void __iomem *base,
> +			      int irq, u32 ambafreq, bool txbug)
> +{
> +	struct net_device *dev;
> +	struct grcan_priv *priv;
> +	struct grcan_registers __iomem *regs;
> +	int err;
> +
> +	dev = alloc_candev(sizeof(struct grcan_priv), 0);
> +	if (!dev)
> +		return -ENOMEM;
> +
> +	dev->irq = irq;
> +	dev->flags |= IFF_ECHO;
> +	dev->netdev_ops = &grcan_netdev_ops;
> +	dev->sysfs_groups[0] = &sysfs_grcan_group;
> +
> +	priv = netdev_priv(dev);
> +	memcpy(&priv->config, &grcan_module_config,
> +	       sizeof(struct grcan_device_config));
> +	priv->dev = dev;
> +	priv->regs = base;
> +	priv->can.bittiming_const = &grcan_bittiming_const;
> +	priv->can.do_set_bittiming = grcan_set_bittiming;
> +	priv->can.do_set_mode = grcan_set_mode;
> +	priv->can.do_get_berr_counter = grcan_get_berr_counter;
> +	priv->can.clock.freq = ambafreq;
> +	priv->can.ctrlmode_supported =
> +		CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_ONE_SHOT;
> +	priv->need_txbug_workaround = txbug;
> +
> +	/* Discover if triple sampling is supported by hardware */
> +	regs = priv->regs;
> +	grcan_set_bits(&regs->ctrl, GRCAN_CTRL_RESET);
> +	grcan_set_bits(&regs->conf, GRCAN_CONF_SAM);
> +	if (grcan_read_bits(&regs->conf, GRCAN_CONF_SAM)) {
> +		priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES;
> +		dev_dbg(&ofdev->dev, "Hardware supports triple-sampling\n");
> +	}
> +
> +	spin_lock_init(&priv->lock);
> +
> +	if (priv->need_txbug_workaround) {
> +		init_timer(&priv->rr_timer);
> +		priv->rr_timer.function = grcan_running_reset;
> +		priv->rr_timer.data = (unsigned long)dev;
> +
> +		init_timer(&priv->hang_timer);
> +		priv->hang_timer.function = grcan_initiate_running_reset;
> +		priv->hang_timer.data = (unsigned long)dev;
> +	}
> +
> +	netif_napi_add(dev, &priv->napi, grcan_poll, GRCAN_NAPI_WEIGHT);
> +
> +	SET_NETDEV_DEV(dev, &ofdev->dev);
> +	dev_info(&ofdev->dev, "regs=0x%p, irq=%d, clock=%d\n",
> +		 priv->regs, dev->irq, priv->can.clock.freq);
> +
> +	err = register_candev(dev);
> +	if (err)
> +		goto exit_free_candev;
> +
> +	dev_set_drvdata(&ofdev->dev, dev);
> +
> +	/* Reset device to allow bit-timing to be set. No need to call
> +	 * grcan_reset at this stage. That is done in grcan_open.
> +	 */
> +	grcan_write_reg(&regs->ctrl, GRCAN_CTRL_RESET);
> +
> +	return 0;
> +exit_free_candev:
> +	free_candev(dev);
> +	return err;
> +}
> +
> +static int __devinit grcan_probe(struct platform_device *ofdev)
> +{
> +	struct device_node *np = ofdev->dev.of_node;
> +	struct resource *res;
> +	u32 sysid, ambafreq;
> +	int irq, err;
> +	void __iomem *base;
> +	bool txbug = true;
> +
> +	/* Compare GRLIB version number with the first that does not
> +	 * have the tx bug (see start_xmit)
> +	 */
> +	err = of_property_read_u32(np, "systemid", &sysid);
> +	if (!err && ((sysid & GRLIB_VERSION_MASK)
> +		     >= GRCAN_TXBUG_SAFE_GRLIB_VERSION))
> +		txbug = false;
> +
> +	err = of_property_read_u32(np, "freq", &ambafreq);
> +	if (err) {
> +		dev_err(&ofdev->dev, "unable to fetch \"freq\" property\n");
> +		goto exit_error;
> +	}
> +
> +	res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
> +	base = devm_request_and_ioremap(&ofdev->dev, res);
> +	if (!base) {
> +		dev_err(&ofdev->dev, "couldn't map IO resource\n");
> +		err = -EADDRNOTAVAIL;
> +		goto exit_error;
> +	}
> +
> +	irq = irq_of_parse_and_map(np, GRCAN_IRQIX_IRQ);
> +	if (!irq) {
> +		dev_err(&ofdev->dev, "no irq found\n");
> +		err = -ENODEV;
> +		goto exit_error;
> +	}
> +
> +	grcan_sanitize_module_config(ofdev);
> +
> +	err = grcan_setup_netdev(ofdev, base, irq, ambafreq, txbug);
> +	if (err)
> +		goto exit_dispose_irq;
> +
> +	return 0;
> +
> +exit_dispose_irq:
> +	irq_dispose_mapping(irq);
> +exit_error:
> +	dev_err(&ofdev->dev,
> +		"%s socket CAN driver initialization failed with error %d\n",
> +		DRV_NAME, err);
> +	return err;
> +}
> +
> +static int __devexit grcan_remove(struct platform_device *ofdev)
> +{
> +	struct net_device *dev = dev_get_drvdata(&ofdev->dev);
> +	struct grcan_priv *priv = netdev_priv(dev);
> +
> +	unregister_candev(dev); /* Will in turn call grcan_close */
> +
> +	irq_dispose_mapping(dev->irq);
> +	dev_set_drvdata(&ofdev->dev, NULL);
> +	netif_napi_del(&priv->napi);
> +	free_candev(dev);
> +
> +	return 0;
> +}
> +
> +static struct of_device_id grcan_match[] = {

static const struct of_device_id grcan_match[] __devinitconst = {

> +	{.name = "GAISLER_GRCAN"},
> +	{.name = "01_03d"},
> +	{.name = "GAISLER_GRHCAN"},
> +	{.name = "01_034"},
> +	{},
> +};
> +
> +MODULE_DEVICE_TABLE(of, grcan_match);
> +
> +static struct platform_driver grcan_driver = {
> +	.driver = {
> +		.name = DRV_NAME,
> +		.owner = THIS_MODULE,
> +		.of_match_table = grcan_match,
> +	},
> +	.probe = grcan_probe,
> +	.remove = __devexit_p(grcan_remove),
> +};
> +
> +module_platform_driver(grcan_driver);
> +
> +MODULE_AUTHOR("Aeroflex Gaisler AB.");
> +MODULE_DESCRIPTION("Socket CAN driver for Aeroflex Gaisler GRCAN");
> +MODULE_LICENSE("GPL");
> 


-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v8] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-11-13 21:15                                               ` Marc Kleine-Budde
@ 2012-11-14  7:50                                                 ` Andreas Larsson
  2012-11-14  8:43                                                   ` Marc Kleine-Budde
  0 siblings, 1 reply; 41+ messages in thread
From: Andreas Larsson @ 2012-11-14  7:50 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: linux-can, software, Wolfgang Grandegger, devicetree-discuss

On 11/13/2012 10:15 PM, Marc Kleine-Budde wrote:

[...]

> On 11/12/2012 03:57 PM, Andreas Larsson wrote:
>> >+	bpr = 0; /* Note bpr and brp are different concepts */
>> >+	rsj = bt->sjw;
>> >+	ps1 = (bt->prop_seg + bt->phase_seg1) - 1; /* tseg1 - 1 */
>> >+	ps2 = bt->phase_seg2;
>> >+	scaler = (bt->brp - 1);
>> >+	timing |= (bpr << GRCAN_CONF_BPR_BIT) & GRCAN_CONF_BPR;
>> >+	timing |= (rsj << GRCAN_CONF_RSJ_BIT) & GRCAN_CONF_RSJ;
>> >+	timing |= (ps1 << GRCAN_CONF_PS1_BIT) & GRCAN_CONF_PS1;
>> >+	timing |= (ps2 << GRCAN_CONF_PS2_BIT) & GRCAN_CONF_PS2;
>> >+	timing |= (scaler << GRCAN_CONF_SCALER_BIT) & GRCAN_CONF_SCALER;
>> >+
>> >+	netdev_info(dev, "setting timing=0x%x\n", timing);
> what about moving the sanity check before putting together the "timing"
> variable and doing the netdev_info()?

The idea was for the user to have the full context of the problem when getting 
the error (e.g., when using the bitrate method to set the timing parameters, the 
calculated parameters are not otherwise known to the user). But I can do that 
with a separate netdev_dbg and move the sanity check as suggested.

>> >+	if (!(ps1 > ps2)) {
>> >+		netdev_err(dev, "PS1 > PS2 must hold: PS1=%d, PS2=%d\n",
>> >+			   ps1, ps2);
>> >+		return -EINVAL;
>> >+	}
>> >+	if (!(ps2 >= rsj)) {
>> >+		netdev_err(dev, "PS2 >= RSJ must hold: PS2=%d, RSJ=%d\n",
>> >+			   ps2, rsj);
>> >+		return -EINVAL;
>> >+	}
>> >+
>> >+	grcan_write_bits(&regs->conf, timing, GRCAN_CONF_TIMING);
>> >+	return 0;
>> >+}

[...]

>> >+static int grcan_poll(struct napi_struct *napi, int rx_budget)
>> >+{
>> >+	struct grcan_priv *priv = container_of(napi, struct grcan_priv, napi);
>> >+	struct net_device *dev = priv->dev;
>> >+	struct grcan_registers __iomem *regs = priv->regs;
>> >+	int rx_work_done;
>> >+	unsigned long flags;
>> >+
>> >+	/* Receive according to given budget */
>> >+	rx_work_done = grcan_receive(dev, rx_budget);
>> >+
>> >+	/* Catch up echo skb according to separate budget to get the benefits of
>> >+	 * napi for tx as well. The given rx_budget might not be appropriate for
>> >+	 * the tx side.
>> >+	 */
>> >+	grcan_transmit_catch_up(dev, GRCAN_TX_BUDGET);
>> >+
>> >+	spin_lock_irqsave(&priv->lock, flags);
>> >+
>> >+	if (grcan_poll_all_done(dev)) {
> Just make it:
> 	if (work_done < budget) {
> 		napi_complete();
> 		enable_interrupts();
> 	}
>
> If there are CAN frames pending, an interrupt will kick in and
> reschedule the NAPI.

Sure, I can do that for the first check (and add back checking tx_work_done as 
well). That misses to call napi_complete and start interrupts in the case in 
which handling of frames are complete work_done == budget though. But on the 
other hand, then grcan_poll will be triggered once again and then detect that 
nothing is to be done if that is still the case.

However, the problem with skipping the check after turning on interrupts is that 
more frames can have arrived and/or have been sent after calculating work_done 
and before turning on interrupts. For those frames, unless I have misunderstood 
something, interrupts will not be raised and they can get stuck until (if ever) 
later frames once again trigger rescheduling of napi.

>> >+		bool complete = true;
>> >+
>> >+		if (!priv->closing) {
>> >+			/* Enable tx and rx interrupts again */
>> >+			grcan_set_bits(&regs->imr, GRCAN_IRQ_TX | GRCAN_IRQ_RX);
>> >+
>> >+			/* If more work arrived between detecting completion and
>> >+			 * turning on interrupts, we need to keep napi running
>> >+			 */
>> >+			if (!grcan_poll_all_done(dev)) {
>> >+				complete = false;
>> >+				grcan_clear_bits(&regs->imr,
>> >+						 GRCAN_IRQ_TX | GRCAN_IRQ_RX);
>> >+			}
>> >+		}
>> >+		if (complete)
>> >+			napi_complete(napi);
>> >+	}
>> >+
>> >+	spin_unlock_irqrestore(&priv->lock, flags);
>> >+
>> >+	return rx_work_done;
>> >+}


Thanks for the feedback!

Cheers,
Andreas



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v8] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-11-14  7:50                                                 ` Andreas Larsson
@ 2012-11-14  8:43                                                   ` Marc Kleine-Budde
  2012-11-14 11:02                                                     ` Andreas Larsson
  0 siblings, 1 reply; 41+ messages in thread
From: Marc Kleine-Budde @ 2012-11-14  8:43 UTC (permalink / raw)
  To: Andreas Larsson
  Cc: linux-can, software, Wolfgang Grandegger, devicetree-discuss

[-- Attachment #1: Type: text/plain, Size: 5547 bytes --]

On 11/14/2012 08:50 AM, Andreas Larsson wrote:
> On 11/13/2012 10:15 PM, Marc Kleine-Budde wrote:
> 
> [...]
> 
>> On 11/12/2012 03:57 PM, Andreas Larsson wrote:
>>> >+    bpr = 0; /* Note bpr and brp are different concepts */
>>> >+    rsj = bt->sjw;
>>> >+    ps1 = (bt->prop_seg + bt->phase_seg1) - 1; /* tseg1 - 1 */
>>> >+    ps2 = bt->phase_seg2;
>>> >+    scaler = (bt->brp - 1);
>>> >+    timing |= (bpr << GRCAN_CONF_BPR_BIT) & GRCAN_CONF_BPR;
>>> >+    timing |= (rsj << GRCAN_CONF_RSJ_BIT) & GRCAN_CONF_RSJ;
>>> >+    timing |= (ps1 << GRCAN_CONF_PS1_BIT) & GRCAN_CONF_PS1;
>>> >+    timing |= (ps2 << GRCAN_CONF_PS2_BIT) & GRCAN_CONF_PS2;
>>> >+    timing |= (scaler << GRCAN_CONF_SCALER_BIT) & GRCAN_CONF_SCALER;
>>> >+
>>> >+    netdev_info(dev, "setting timing=0x%x\n", timing);
>> what about moving the sanity check before putting together the "timing"
>> variable and doing the netdev_info()?
> 
> The idea was for the user to have the full context of the problem when
> getting the error (e.g., when using the bitrate method to set the timing
> parameters, the calculated parameters are not otherwise known to the
> user). But I can do that with a separate netdev_dbg and move the sanity
> check as suggested.

I'm worried about the first stating "setting timing", but then not
writing it to the register.

> 
>>> >+    if (!(ps1 > ps2)) {
>>> >+        netdev_err(dev, "PS1 > PS2 must hold: PS1=%d, PS2=%d\n",
>>> >+               ps1, ps2);
>>> >+        return -EINVAL;
>>> >+    }
>>> >+    if (!(ps2 >= rsj)) {
>>> >+        netdev_err(dev, "PS2 >= RSJ must hold: PS2=%d, RSJ=%d\n",
>>> >+               ps2, rsj);
>>> >+        return -EINVAL;
>>> >+    }
>>> >+
>>> >+    grcan_write_bits(&regs->conf, timing, GRCAN_CONF_TIMING);
>>> >+    return 0;
>>> >+}
> 
> [...]
> 
>>> >+static int grcan_poll(struct napi_struct *napi, int rx_budget)
>>> >+{
>>> >+    struct grcan_priv *priv = container_of(napi, struct grcan_priv,
>>> napi);
>>> >+    struct net_device *dev = priv->dev;
>>> >+    struct grcan_registers __iomem *regs = priv->regs;
>>> >+    int rx_work_done;
>>> >+    unsigned long flags;
>>> >+
>>> >+    /* Receive according to given budget */
>>> >+    rx_work_done = grcan_receive(dev, rx_budget);
>>> >+
>>> >+    /* Catch up echo skb according to separate budget to get the
>>> benefits of
>>> >+     * napi for tx as well. The given rx_budget might not be
>>> appropriate for
>>> >+     * the tx side.
>>> >+     */
>>> >+    grcan_transmit_catch_up(dev, GRCAN_TX_BUDGET);
>>> >+
>>> >+    spin_lock_irqsave(&priv->lock, flags);
>>> >+
>>> >+    if (grcan_poll_all_done(dev)) {
>> Just make it:
>>     if (work_done < budget) {
>>         napi_complete();
>>         enable_interrupts();
>>     }
>>
>> If there are CAN frames pending, an interrupt will kick in and
>> reschedule the NAPI.
> 
> Sure, I can do that for the first check (and add back checking
> tx_work_done as well). That misses to call napi_complete and start

Hmmm...Either move tx-complete handling to the interrupt handler, or
just use a budget big enough for rx and tx-complete.

> interrupts in the case in which handling of frames are complete
> work_done == budget though. But on the other hand, then grcan_poll will
> be triggered once again and then detect that nothing is to be done if
> that is still the case.
> 
> However, the problem with skipping the check after turning on interrupts
> is that more frames can have arrived and/or have been sent after
> calculating work_done and before turning on interrupts. For those
> frames, unless I have misunderstood something, interrupts will not be
> raised and they can get stuck until (if ever) later frames once again
> trigger rescheduling of napi.

No, if correctly used, NAPI is race free and no events will be lost:

Handle incoming events (rx or tx-complete) until:
a) number of handled events == budget
or
b) no more events pending.

	while (work_done < budget && interrupts_pending()) {
		work_done += handle_rx(budget - work_done);
		work_done += handle_tx(budget - work_done);
	}

Then, if you have handled less events then budget:
1) call napi_complete()
then
2) enable interrupts.

	if (work_done < budget) {
		napi_complete();
		enable_interrupts();
	}

Then, return number of handled events:

	return work_done;

> 
>>> >+        bool complete = true;
>>> >+
>>> >+        if (!priv->closing) {
>>> >+            /* Enable tx and rx interrupts again */
>>> >+            grcan_set_bits(&regs->imr, GRCAN_IRQ_TX | GRCAN_IRQ_RX);
>>> >+
>>> >+            /* If more work arrived between detecting completion and
>>> >+             * turning on interrupts, we need to keep napi running
>>> >+             */
>>> >+            if (!grcan_poll_all_done(dev)) {
>>> >+                complete = false;
>>> >+                grcan_clear_bits(&regs->imr,
>>> >+                         GRCAN_IRQ_TX | GRCAN_IRQ_RX);
>>> >+            }
>>> >+        }
>>> >+        if (complete)
>>> >+            napi_complete(napi);
>>> >+    }
>>> >+
>>> >+    spin_unlock_irqrestore(&priv->lock, flags);
>>> >+
>>> >+    return rx_work_done;
>>> >+}

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v8] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-11-14  8:43                                                   ` Marc Kleine-Budde
@ 2012-11-14 11:02                                                     ` Andreas Larsson
  2012-11-14 11:22                                                       ` Marc Kleine-Budde
  0 siblings, 1 reply; 41+ messages in thread
From: Andreas Larsson @ 2012-11-14 11:02 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: linux-can, software, Wolfgang Grandegger, devicetree-discuss

On 2012-11-14 09:43, Marc Kleine-Budde wrote:
> Handle incoming events (rx or tx-complete) until:
> a) number of handled events == budget
> or
> b) no more events pending.
>
> 	while (work_done < budget && interrupts_pending()) {
> 		work_done += handle_rx(budget - work_done);
> 		work_done += handle_tx(budget - work_done);
> 	}

That could starve handle_tx completely though under high rx pressure, but I can 
prevent that by making sure that half of the budget is held back in the first 
call to handle_rx.

> Then, if you have handled less events then budget:
> 1) call napi_complete()
> then
> 2) enable interrupts.
>
> 	if (work_done < budget) {
> 		napi_complete();
> 		enable_interrupts();
> 	}
>
> Then, return number of handled events:
>
> 	return work_done;

Any additional remarks on the following implementation of the poll function?

static int grcan_poll(struct napi_struct *napi, int budget)
{
	struct grcan_priv *priv = container_of(napi, struct grcan_priv, napi);
	struct net_device *dev = priv->dev;
	struct grcan_registers __iomem *regs = priv->regs;
	unsigned long flags;
	int work_done = 0;
	int reserved = budget / 2;

	while (work_done < budget) {
		int old_work_done = work_done;

		/* Prevent grcan_transmit_catch_up from starving by reserving
		 * part of the budget in the first iteration when calling
		 * grcan_receive.
		 */
		work_done += grcan_receive(dev, budget - reserved - work_done);
		reserved = 0;

		/* Catch up echo skb according to same budget, as
		 * grcan_transmit_catch_up can trigger echo frames being
		 * received.
		 */
		work_done += grcan_transmit_catch_up(dev, budget - work_done);

		/* Break out if nothing was done */
		if (work_done == old_work_done)
			break;
	}

	if (work_done < budget) {
		napi_complete(napi);

		/* Guarantee no interference with a running reset that otherwise
		 * could turn off interrupts.
		 */
		spin_lock_irqsave(&priv->lock, flags);

		/* Enable tx and rx interrupts again. No need to check
		 * priv->closing as napi_disable in grcan_close is waiting for
		 * scheduled napi calls to finish.
		 */
		grcan_set_bits(&regs->imr, GRCAN_IRQ_TX | GRCAN_IRQ_RX);

		spin_unlock_irqrestore(&priv->lock, flags);
	}

	return work_done;
}


Cheers,
Andreas


^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v8] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-11-14 11:02                                                     ` Andreas Larsson
@ 2012-11-14 11:22                                                       ` Marc Kleine-Budde
  2012-11-14 15:07                                                         ` Andreas Larsson
  0 siblings, 1 reply; 41+ messages in thread
From: Marc Kleine-Budde @ 2012-11-14 11:22 UTC (permalink / raw)
  To: Andreas Larsson
  Cc: linux-can, software, Wolfgang Grandegger, devicetree-discuss

[-- Attachment #1: Type: text/plain, Size: 3267 bytes --]

On 11/14/2012 12:02 PM, Andreas Larsson wrote:
> On 2012-11-14 09:43, Marc Kleine-Budde wrote:
>> Handle incoming events (rx or tx-complete) until:
>> a) number of handled events == budget
>> or
>> b) no more events pending.
>>
>>     while (work_done < budget && interrupts_pending()) {
>>         work_done += handle_rx(budget - work_done);
>>         work_done += handle_tx(budget - work_done);
>>     }
> 
> That could starve handle_tx completely though under high rx pressure,
> but I can prevent that by making sure that half of the budget is held
> back in the first call to handle_rx.

What about making the budget big enough to handle both rx and tx in one
napi call. Have a look at the marvell driver [1] for inspiration.

[1]
http://lxr.free-electrons.com/source/drivers/net/ethernet/marvell/mv643xx_eth.c#L2140

> 
>> Then, if you have handled less events then budget:
>> 1) call napi_complete()
>> then
>> 2) enable interrupts.
>>
>>     if (work_done < budget) {
>>         napi_complete();
>>         enable_interrupts();
>>     }
>>
>> Then, return number of handled events:
>>
>>     return work_done;
> 
> Any additional remarks on the following implementation of the poll
> function?
> 
> static int grcan_poll(struct napi_struct *napi, int budget)
> {
>     struct grcan_priv *priv = container_of(napi, struct grcan_priv, napi);
>     struct net_device *dev = priv->dev;
>     struct grcan_registers __iomem *regs = priv->regs;
>     unsigned long flags;
>     int work_done = 0;
>     int reserved = budget / 2;
> 
>     while (work_done < budget) {
>         int old_work_done = work_done;
> 
>         /* Prevent grcan_transmit_catch_up from starving by reserving
>          * part of the budget in the first iteration when calling
>          * grcan_receive.
>          */
>         work_done += grcan_receive(dev, budget - reserved - work_done);
>         reserved = 0;
> 
>         /* Catch up echo skb according to same budget, as
>          * grcan_transmit_catch_up can trigger echo frames being
>          * received.
>          */
>         work_done += grcan_transmit_catch_up(dev, budget - work_done);
> 
>         /* Break out if nothing was done */
>         if (work_done == old_work_done)
>             break;
>     }
> 
>     if (work_done < budget) {
>         napi_complete(napi);
> 
>         /* Guarantee no interference with a running reset that otherwise
>          * could turn off interrupts.
>          */
>         spin_lock_irqsave(&priv->lock, flags);
> 
>         /* Enable tx and rx interrupts again. No need to check
>          * priv->closing as napi_disable in grcan_close is waiting for
>          * scheduled napi calls to finish.
>          */
>         grcan_set_bits(&regs->imr, GRCAN_IRQ_TX | GRCAN_IRQ_RX);
> 
>         spin_unlock_irqrestore(&priv->lock, flags);
>     }
> 
>     return work_done;
> }
> 
> 
> Cheers,
> Andreas
> 


-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v8] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-11-14 11:22                                                       ` Marc Kleine-Budde
@ 2012-11-14 15:07                                                         ` Andreas Larsson
  2012-11-14 15:12                                                           ` Marc Kleine-Budde
  0 siblings, 1 reply; 41+ messages in thread
From: Andreas Larsson @ 2012-11-14 15:07 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: linux-can, software, Wolfgang Grandegger, devicetree-discuss

On 2012-11-14 12:22, Marc Kleine-Budde wrote:
> On 11/14/2012 12:02 PM, Andreas Larsson wrote:
>> On 2012-11-14 09:43, Marc Kleine-Budde wrote:
>>> Handle incoming events (rx or tx-complete) until:
>>> a) number of handled events == budget
>>> or
>>> b) no more events pending.
>>>
>>>      while (work_done < budget && interrupts_pending()) {
>>>          work_done += handle_rx(budget - work_done);
>>>          work_done += handle_tx(budget - work_done);
>>>      }
>>
>> That could starve handle_tx completely though under high rx pressure,
>> but I can prevent that by making sure that half of the budget is held
>> back in the first call to handle_rx.
>
> What about making the budget big enough to handle both rx and tx in one
> napi call. Have a look at the marvell driver [1] for inspiration.

Even if I set the budget to something large, unless I limit the rx side in some 
way it could go on multiple rounds around the circular buffer until it have used 
all the budget. So in some way or another, grcan_receive must be hindered from 
using all the budget.

Sorry, but I am not sure what aspect of the marvell driver poll handling you 
want me to mimic. Without having analyzed exactly how the queueing works yet, it 
seems to make sure that every function that is called from the poll function 
gets ample opportunity to do work by not letting one function hogging all the 
budget. If you want me to mimic it in the aspect of doing work in series of 16 
or something like that, sure, no problem. If it is something else you want to 
point to, please let me know what.


The simplest way to make sure that both tx and rx gets to run is to take 
inspiration from the ethoc driver [1] and just let the tx side get just as much 
budget as the rx side and be done with it. With the echo frames for can, the 
budget should be halved for each I guess to make sure no more frames are 
delivered than the budget, but apart from that I don't see the problem with such 
a simple approach.

static int ethoc_poll(struct napi_struct *napi, int budget)
{
	struct ethoc *priv = container_of(napi, struct ethoc, napi);
	int rx_work_done = 0;
	int tx_work_done = 0;

	rx_work_done = ethoc_rx(priv->netdev, budget);
	tx_work_done = ethoc_tx(priv->netdev, budget);

	if (rx_work_done < budget && tx_work_done < budget) {
		napi_complete(napi);
		ethoc_enable_irq(priv, INT_MASK_TX | INT_MASK_RX);
	}

	return rx_work_done;
}

[1]
http://lxr.free-electrons.com/source/drivers/net/ethernet/ethoc.c#L598

Cheers,
Andreas


^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v8] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-11-14 15:07                                                         ` Andreas Larsson
@ 2012-11-14 15:12                                                           ` Marc Kleine-Budde
  2012-11-15  7:47                                                             ` [PATCH v9] " Andreas Larsson
  0 siblings, 1 reply; 41+ messages in thread
From: Marc Kleine-Budde @ 2012-11-14 15:12 UTC (permalink / raw)
  To: Andreas Larsson
  Cc: linux-can, software, Wolfgang Grandegger, devicetree-discuss

[-- Attachment #1: Type: text/plain, Size: 2484 bytes --]

On 11/14/2012 04:07 PM, Andreas Larsson wrote:
> On 2012-11-14 12:22, Marc Kleine-Budde wrote:
>> On 11/14/2012 12:02 PM, Andreas Larsson wrote:
>>> On 2012-11-14 09:43, Marc Kleine-Budde wrote:
>>>> Handle incoming events (rx or tx-complete) until:
>>>> a) number of handled events == budget
>>>> or
>>>> b) no more events pending.
>>>>
>>>>      while (work_done < budget && interrupts_pending()) {
>>>>          work_done += handle_rx(budget - work_done);
>>>>          work_done += handle_tx(budget - work_done);
>>>>      }
>>>
>>> That could starve handle_tx completely though under high rx pressure,
>>> but I can prevent that by making sure that half of the budget is held
>>> back in the first call to handle_rx.
>>
>> What about making the budget big enough to handle both rx and tx in one
>> napi call. Have a look at the marvell driver [1] for inspiration.
> 
> Even if I set the budget to something large, unless I limit the rx side
> in some way it could go on multiple rounds around the circular buffer
> until it have used all the budget. So in some way or another,
> grcan_receive must be hindered from using all the budget.
> 
> Sorry, but I am not sure what aspect of the marvell driver poll handling
> you want me to mimic. Without having analyzed exactly how the queueing
> works yet, it seems to make sure that every function that is called from
> the poll function gets ample opportunity to do work by not letting one
> function hogging all the budget. If you want me to mimic it in the
> aspect of doing work in series of 16 or something like that, sure, no
> problem. If it is something else you want to point to, please let me
> know what.
> 
> 
> The simplest way to make sure that both tx and rx gets to run is to take
> inspiration from the ethoc driver [1] and just let the tx side get just
> as much budget as the rx side and be done with it. With the echo frames
> for can, the budget should be halved for each I guess to make sure no
> more frames are delivered than the budget, but apart from that I don't
> see the problem with such a simple approach.

Good point, if there already is an implementation, do it that way.

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH v9] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-11-14 15:12                                                           ` Marc Kleine-Budde
@ 2012-11-15  7:47                                                             ` Andreas Larsson
  2012-11-15 20:32                                                               ` Marc Kleine-Budde
  0 siblings, 1 reply; 41+ messages in thread
From: Andreas Larsson @ 2012-11-15  7:47 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: linux-can, Wolfgang Grandegger, devicetree-discuss, software

This driver supports GRCAN and CRHCAN CAN controllers available in the GRLIB
VHDL IP core library.

Signed-off-by: Andreas Larsson <andreas@gaisler.com>
Acked-by: Wolfgang Grandegger <wg@grandegger.com>
---
 Changes since v8:
 - Streamline grcan_poll
 - Be clear about when timing parameters actually is being set
 - Add const and __devinitconst

 Documentation/ABI/testing/sysfs-class-net-grcan    |   35 +
 .../devicetree/bindings/net/can/grcan.txt          |   28 +
 Documentation/kernel-parameters.txt                |   18 +
 drivers/net/can/Kconfig                            |    9 +
 drivers/net/can/Makefile                           |    1 +
 drivers/net/can/grcan.c                            | 1756 ++++++++++++++++++++
 6 files changed, 1847 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-class-net-grcan
 create mode 100644 Documentation/devicetree/bindings/net/can/grcan.txt
 create mode 100644 drivers/net/can/grcan.c

diff --git a/Documentation/ABI/testing/sysfs-class-net-grcan b/Documentation/ABI/testing/sysfs-class-net-grcan
new file mode 100644
index 0000000..f418c92
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-net-grcan
@@ -0,0 +1,35 @@
+
+What:		/sys/class/net/<iface>/grcan/enable0
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas@gaisler.com>
+Description:
+		Hardware configuration of physical interface 0. This file reads
+		and writes the "Enable 0" bit of the configuration register.
+		Possible values: 0 or 1. See the GRCAN chapter of the GRLIB IP
+		core library documentation for details. The default value is 0
+		or set by the module parameter grcan.enable0 and can be read at
+		/sys/module/grcan/parameters/enable0.
+
+What:		/sys/class/net/<iface>/grcan/enable1
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas@gaisler.com>
+Description:
+		Hardware configuration of physical interface 1. This file reads
+		and writes the "Enable 1" bit of the configuration register.
+		Possible values: 0 or 1. See the GRCAN chapter of the GRLIB IP
+		core library documentation for details. The default value is 0
+		or set by the module parameter grcan.enable1 and can be read at
+		/sys/module/grcan/parameters/enable1.
+
+What:		/sys/class/net/<iface>/grcan/select
+Date:		October 2012
+KernelVersion:	3.8
+Contact:	Andreas Larsson <andreas@gaisler.com>
+Description:
+		Configuration of which physical interface to be used. Possible
+		values: 0 or 1. See the GRCAN chapter of the GRLIB IP core
+		library documentation for details. The default value is 0 or is
+		set by the module parameter grcan.select and can be read at
+		/sys/module/grcan/parameters/select.
diff --git a/Documentation/devicetree/bindings/net/can/grcan.txt b/Documentation/devicetree/bindings/net/can/grcan.txt
new file mode 100644
index 0000000..34ef349
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/can/grcan.txt
@@ -0,0 +1,28 @@
+Aeroflex Gaisler GRCAN and GRHCAN CAN controllers.
+
+The GRCAN and CRHCAN CAN controllers are available in the GRLIB VHDL IP core
+library.
+
+Note: These properties are built from the AMBA plug&play in a Leon SPARC system
+(the ordinary environment for GRCAN and GRHCAN). There are no dts files for
+sparc.
+
+Required properties:
+
+- name : Should be "GAISLER_GRCAN", "01_03d", "GAISLER_GRHCAN" or "01_034"
+
+- reg : Address and length of the register set for the device
+
+- freq : Frequency of the external oscillator clock in Hz (the frequency of
+	the amba bus in the ordinary case)
+
+- interrupts : Interrupt number for this device
+
+Optional properties:
+
+- systemid : If not present or if the value of the least significant 16 bits
+	of this 32-bit property is smaller than GRCAN_TXBUG_SAFE_GRLIB_VERSION
+	a bug workaround is activated.
+
+For further information look in the documentation for the GLIB IP core library:
+http://www.gaisler.com/products/grlib/grip.pdf
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 9776f06..3da4f96 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -905,6 +905,24 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 	gpt		[EFI] Forces disk with valid GPT signature but
 			invalid Protective MBR to be treated as GPT.
 
+	grcan.enable0=	[HW] Configuration of physical interface 0. Determines
+			the "Enable 0" bit of the configuration register.
+			Format: 0 | 1
+			Default: 0
+	grcan.enable1=	[HW] Configuration of physical interface 1. Determines
+			the "Enable 0" bit of the configuration register.
+			Format: 0 | 1
+			Default: 0
+	grcan.select=	[HW] Select which physical interface to use.
+			Format: 0 | 1
+			Default: 0
+	grcan.txsize=	[HW] Sets the size of the tx buffer.
+			Format: <unsigned int> such that (txsize & ~0x1fffc0) == 0.
+			Default: 1024
+	grcan.rxsize=	[HW] Sets the size of the rx buffer.
+			Format: <unsigned int> such that (rxsize & ~0x1fffc0) == 0.
+			Default: 1024
+
 	hashdist=	[KNL,NUMA] Large hashes allocated during boot
 			are distributed across NUMA nodes.  Defaults on
 			for 64-bit NUMA, off otherwise.
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
index bb709fd..b56bd9e 100644
--- a/drivers/net/can/Kconfig
+++ b/drivers/net/can/Kconfig
@@ -110,6 +110,15 @@ config PCH_CAN
 	  is an IOH for x86 embedded processor (Intel Atom E6xx series).
 	  This driver can access CAN bus.
 
+config CAN_GRCAN
+	tristate "Aeroflex Gaisler GRCAN and GRHCAN CAN devices"
+	depends on CAN_DEV && OF
+	---help---
+	  Say Y here if you want to use Aeroflex Gaisler GRCAN or GRHCAN.
+	  Note that the driver supports little endian, even though little
+	  endian syntheses of the cores would need some modifications on
+	  the hardware level to work.
+
 source "drivers/net/can/mscan/Kconfig"
 
 source "drivers/net/can/sja1000/Kconfig"
diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
index 938be37..7de5986 100644
--- a/drivers/net/can/Makefile
+++ b/drivers/net/can/Makefile
@@ -22,5 +22,6 @@ obj-$(CONFIG_CAN_BFIN)		+= bfin_can.o
 obj-$(CONFIG_CAN_JANZ_ICAN3)	+= janz-ican3.o
 obj-$(CONFIG_CAN_FLEXCAN)	+= flexcan.o
 obj-$(CONFIG_PCH_CAN)		+= pch_can.o
+obj-$(CONFIG_CAN_GRCAN)		+= grcan.o
 
 ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/grcan.c b/drivers/net/can/grcan.c
new file mode 100644
index 0000000..391f484
--- /dev/null
+++ b/drivers/net/can/grcan.c
@@ -0,0 +1,1756 @@
+/*
+ * Socket CAN driver for Aeroflex Gaisler GRCAN and GRHCAN.
+ *
+ * 2012 (c) Aeroflex Gaisler AB
+ *
+ * This driver supports GRCAN and GRHCAN CAN controllers available in the GRLIB
+ * VHDL IP core library.
+ *
+ * Full documentation of the GRCAN core can be found here:
+ * http://www.gaisler.com/products/grlib/grip.pdf
+ *
+ * See "Documentation/devicetree/bindings/net/can/grcan.txt" for information on
+ * open firmware properties.
+ *
+ * See "Documentation/ABI/testing/sysfs-class-net-grcan" for information on the
+ * sysfs interface.
+ *
+ * See "Documentation/kernel-parameters.txt" for information on the module
+ * parameters.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Contributors: Andreas Larsson <andreas@gaisler.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/can/dev.h>
+#include <linux/spinlock.h>
+
+#include <linux/of_platform.h>
+#include <asm/prom.h>
+
+#include <linux/of_irq.h>
+
+#include <linux/dma-mapping.h>
+
+#define DRV_NAME	"grcan"
+
+#define GRCAN_NAPI_WEIGHT	32
+
+#define GRCAN_RESERVE_SIZE(slot1, slot2) (((slot2) - (slot1)) / 4 - 1)
+
+struct grcan_registers {
+	u32 conf;	/* 0x00 */
+	u32 stat;	/* 0x04 */
+	u32 ctrl;	/* 0x08 */
+	u32 __reserved1[GRCAN_RESERVE_SIZE(0x08, 0x18)];
+	u32 smask;	/* 0x18 - CanMASK */
+	u32 scode;	/* 0x1c - CanCODE */
+	u32 __reserved2[GRCAN_RESERVE_SIZE(0x1c, 0x100)];
+	u32 pimsr;	/* 0x100 */
+	u32 pimr;	/* 0x104 */
+	u32 pisr;	/* 0x108 */
+	u32 pir;	/* 0x10C */
+	u32 imr;	/* 0x110 */
+	u32 picr;	/* 0x114 */
+	u32 __reserved3[GRCAN_RESERVE_SIZE(0x114, 0x200)];
+	u32 txctrl;	/* 0x200 */
+	u32 txaddr;	/* 0x204 */
+	u32 txsize;	/* 0x208 */
+	u32 txwr;	/* 0x20C */
+	u32 txrd;	/* 0x210 */
+	u32 txirq;	/* 0x214 */
+	u32 __reserved4[GRCAN_RESERVE_SIZE(0x214, 0x300)];
+	u32 rxctrl;	/* 0x300 */
+	u32 rxaddr;	/* 0x304 */
+	u32 rxsize;	/* 0x308 */
+	u32 rxwr;	/* 0x30C */
+	u32 rxrd;	/* 0x310 */
+	u32 rxirq;	/* 0x314 */
+	u32 rxmask;	/* 0x318 */
+	u32 rxcode;	/* 0x31C */
+};
+
+#define GRCAN_CONF_ABORT	0x00000001
+#define GRCAN_CONF_ENABLE0	0x00000002
+#define GRCAN_CONF_ENABLE1	0x00000004
+#define GRCAN_CONF_SELECT	0x00000008
+#define GRCAN_CONF_SILENT	0x00000010
+#define GRCAN_CONF_SAM		0x00000020 /* Available in some hardware */
+#define GRCAN_CONF_BPR		0x00000300 /* Note: not BRP */
+#define GRCAN_CONF_RSJ		0x00007000
+#define GRCAN_CONF_PS1		0x00f00000
+#define GRCAN_CONF_PS2		0x000f0000
+#define GRCAN_CONF_SCALER	0xff000000
+#define GRCAN_CONF_OPERATION						\
+	(GRCAN_CONF_ABORT | GRCAN_CONF_ENABLE0 | GRCAN_CONF_ENABLE1	\
+	 | GRCAN_CONF_SELECT | GRCAN_CONF_SILENT | GRCAN_CONF_SAM)
+#define GRCAN_CONF_TIMING						\
+	(GRCAN_CONF_BPR | GRCAN_CONF_RSJ | GRCAN_CONF_PS1		\
+	 | GRCAN_CONF_PS2 | GRCAN_CONF_SCALER)
+
+#define GRCAN_CONF_RSJ_MIN	1
+#define GRCAN_CONF_RSJ_MAX	4
+#define GRCAN_CONF_PS1_MIN	1
+#define GRCAN_CONF_PS1_MAX	15
+#define GRCAN_CONF_PS2_MIN	2
+#define GRCAN_CONF_PS2_MAX	8
+#define GRCAN_CONF_SCALER_MIN	0
+#define GRCAN_CONF_SCALER_MAX	255
+#define GRCAN_CONF_SCALER_INC	1
+
+#define GRCAN_CONF_BPR_BIT	8
+#define GRCAN_CONF_RSJ_BIT	12
+#define GRCAN_CONF_PS1_BIT	20
+#define GRCAN_CONF_PS2_BIT	16
+#define GRCAN_CONF_SCALER_BIT	24
+
+#define GRCAN_STAT_PASS		0x000001
+#define GRCAN_STAT_OFF		0x000002
+#define GRCAN_STAT_OR		0x000004
+#define GRCAN_STAT_AHBERR	0x000008
+#define GRCAN_STAT_ACTIVE	0x000010
+#define GRCAN_STAT_RXERRCNT	0x00ff00
+#define GRCAN_STAT_TXERRCNT	0xff0000
+
+#define GRCAN_STAT_ERRCTR_RELATED	(GRCAN_STAT_PASS | GRCAN_STAT_OFF)
+
+#define GRCAN_STAT_RXERRCNT_BIT	8
+#define GRCAN_STAT_TXERRCNT_BIT	16
+
+#define GRCAN_STAT_ERRCNT_WARNING_LIMIT	96
+#define GRCAN_STAT_ERRCNT_PASSIVE_LIMIT	127
+
+#define GRCAN_CTRL_RESET	0x2
+#define GRCAN_CTRL_ENABLE	0x1
+
+#define GRCAN_TXCTRL_ENABLE	0x1
+#define GRCAN_TXCTRL_ONGOING	0x2
+#define GRCAN_TXCTRL_SINGLE	0x4
+
+#define GRCAN_RXCTRL_ENABLE	0x1
+#define GRCAN_RXCTRL_ONGOING	0x2
+
+/* Relative offset of IRQ sources to AMBA Plug&Play */
+#define GRCAN_IRQIX_IRQ		0
+#define GRCAN_IRQIX_TXSYNC	1
+#define GRCAN_IRQIX_RXSYNC	2
+
+#define GRCAN_IRQ_PASS		0x00001
+#define GRCAN_IRQ_OFF		0x00002
+#define GRCAN_IRQ_OR		0x00004
+#define GRCAN_IRQ_RXAHBERR	0x00008
+#define GRCAN_IRQ_TXAHBERR	0x00010
+#define GRCAN_IRQ_RXIRQ		0x00020
+#define GRCAN_IRQ_TXIRQ		0x00040
+#define GRCAN_IRQ_RXFULL	0x00080
+#define GRCAN_IRQ_TXEMPTY	0x00100
+#define GRCAN_IRQ_RX		0x00200
+#define GRCAN_IRQ_TX		0x00400
+#define GRCAN_IRQ_RXSYNC	0x00800
+#define GRCAN_IRQ_TXSYNC	0x01000
+#define GRCAN_IRQ_RXERRCTR	0x02000
+#define GRCAN_IRQ_TXERRCTR	0x04000
+#define GRCAN_IRQ_RXMISS	0x08000
+#define GRCAN_IRQ_TXLOSS	0x10000
+
+#define GRCAN_IRQ_NONE	0
+#define GRCAN_IRQ_ALL							\
+	(GRCAN_IRQ_PASS | GRCAN_IRQ_OFF | GRCAN_IRQ_OR			\
+	 | GRCAN_IRQ_RXAHBERR | GRCAN_IRQ_TXAHBERR			\
+	 | GRCAN_IRQ_RXIRQ | GRCAN_IRQ_TXIRQ				\
+	 | GRCAN_IRQ_RXFULL | GRCAN_IRQ_TXEMPTY				\
+	 | GRCAN_IRQ_RX | GRCAN_IRQ_TX | GRCAN_IRQ_RXSYNC		\
+	 | GRCAN_IRQ_TXSYNC | GRCAN_IRQ_RXERRCTR			\
+	 | GRCAN_IRQ_TXERRCTR | GRCAN_IRQ_RXMISS			\
+	 | GRCAN_IRQ_TXLOSS)
+
+#define GRCAN_IRQ_ERRCTR_RELATED (GRCAN_IRQ_RXERRCTR | GRCAN_IRQ_TXERRCTR \
+				  | GRCAN_IRQ_PASS | GRCAN_IRQ_OFF)
+#define GRCAN_IRQ_ERRORS (GRCAN_IRQ_ERRCTR_RELATED | GRCAN_IRQ_OR	\
+			  | GRCAN_IRQ_TXAHBERR | GRCAN_IRQ_RXAHBERR	\
+			  | GRCAN_IRQ_TXLOSS)
+#define GRCAN_IRQ_DEFAULT (GRCAN_IRQ_RX | GRCAN_IRQ_TX | GRCAN_IRQ_ERRORS)
+
+#define GRCAN_MSG_SIZE		16
+
+#define GRCAN_MSG_IDE		0x80000000
+#define GRCAN_MSG_RTR		0x40000000
+#define GRCAN_MSG_BID		0x1ffc0000
+#define GRCAN_MSG_EID		0x1fffffff
+#define GRCAN_MSG_IDE_BIT	31
+#define GRCAN_MSG_RTR_BIT	30
+#define GRCAN_MSG_BID_BIT	18
+#define GRCAN_MSG_EID_BIT	0
+
+#define GRCAN_MSG_DLC		0xf0000000
+#define GRCAN_MSG_TXERRC	0x00ff0000
+#define GRCAN_MSG_RXERRC	0x0000ff00
+#define GRCAN_MSG_DLC_BIT	28
+#define GRCAN_MSG_TXERRC_BIT	16
+#define GRCAN_MSG_RXERRC_BIT	8
+#define GRCAN_MSG_AHBERR	0x00000008
+#define GRCAN_MSG_OR		0x00000004
+#define GRCAN_MSG_OFF		0x00000002
+#define GRCAN_MSG_PASS		0x00000001
+
+#define GRCAN_MSG_DATA_SLOT_INDEX(i) (2 + (i) / 4)
+#define GRCAN_MSG_DATA_SHIFT(i) ((3 - (i) % 4) * 8)
+
+#define GRCAN_BUFFER_ALIGNMENT		1024
+#define GRCAN_DEFAULT_BUFFER_SIZE	1024
+#define GRCAN_VALID_TR_SIZE_MASK	0x001fffc0
+
+#define GRCAN_INVALID_BUFFER_SIZE(s)			\
+	((s) == 0 || ((s) & ~GRCAN_VALID_TR_SIZE_MASK))
+
+#if GRCAN_INVALID_BUFFER_SIZE(GRCAN_DEFAULT_BUFFER_SIZE)
+#error "Invalid default buffer size"
+#endif
+
+struct grcan_dma_buffer {
+	size_t size;
+	void *buf;
+	dma_addr_t handle;
+};
+
+struct grcan_dma {
+	size_t base_size;
+	void *base_buf;
+	dma_addr_t base_handle;
+	struct grcan_dma_buffer tx;
+	struct grcan_dma_buffer rx;
+};
+
+/* GRCAN configuration parameters */
+struct grcan_device_config {
+	unsigned short enable0;
+	unsigned short enable1;
+	unsigned short select;
+	unsigned int txsize;
+	unsigned int rxsize;
+};
+
+#define GRCAN_DEFAULT_DEVICE_CONFIG {				\
+		.enable0	= 0,				\
+		.enable1	= 0,				\
+		.select		= 0,				\
+		.txsize		= GRCAN_DEFAULT_BUFFER_SIZE,	\
+		.rxsize		= GRCAN_DEFAULT_BUFFER_SIZE,	\
+		}
+
+#define GRCAN_TXBUG_SAFE_GRLIB_VERSION	0x4100
+#define GRLIB_VERSION_MASK		0xffff
+
+/* GRCAN private data structure */
+struct grcan_priv {
+	struct can_priv can;	/* must be the first member */
+	struct net_device *dev;
+	struct napi_struct napi;
+
+	struct grcan_registers __iomem *regs;	/* ioremap'ed registers */
+	struct grcan_device_config config;
+	struct grcan_dma dma;
+
+	struct sk_buff **echo_skb;	/* We allocate this on our own */
+	u8 *txdlc;			/* Length of queued frames */
+
+	/* The echo skb pointer, pointing into echo_skb and indicating which
+	 * frames can be echoed back. See the "Notes on the tx cyclic buffer
+	 * handling"-comment for grcan_start_xmit for more details.
+	 */
+	u32 eskbp;
+
+	/* Lock for controlling changes to the netif tx queue state, accesses to
+	 * the echo_skb pointer eskbp and for making sure that a running reset
+	 * and/or a close of the interface is done without interference from
+	 * other parts of the code.
+	 *
+	 * The echo_skb pointer, eskbp, should only be accessed under this lock
+	 * as it can be changed in several places and together with decisions on
+	 * whether to wake up the tx queue.
+	 *
+	 * The tx queue must never be woken up if there is a running reset or
+	 * close in progress.
+	 *
+	 * A running reset (see below on need_txbug_workaround) should never be
+	 * done if the interface is closing down and several running resets
+	 * should never be scheduled simultaneously.
+	 */
+	spinlock_t lock;
+
+	/* Whether a workaround is needed due to a bug in older hardware. In
+	 * this case, the driver both tries to prevent the bug from being
+	 * triggered and recovers, if the bug nevertheless happens, by doing a
+	 * running reset. A running reset, resets the device and continues from
+	 * where it were without being noticeable from outside the driver (apart
+	 * from slight delays).
+	 */
+	bool need_txbug_workaround;
+
+	/* To trigger initization of running reset and to trigger running reset
+	 * respectively in the case of a hanged device due to a txbug.
+	 */
+	struct timer_list hang_timer;
+	struct timer_list rr_timer;
+
+	/* To avoid waking up the netif queue and restarting timers
+	 * when a reset is scheduled or when closing of the device is
+	 * undergoing
+	 */
+	bool resetting;
+	bool closing;
+};
+
+/* Wait time for a short wait for ongoing to clear */
+#define GRCAN_SHORTWAIT_USECS	10
+
+/* Limit on the number of transmitted bits of an eff frame according to the CAN
+ * specification: 1 bit start of frame, 32 bits arbitration field, 6 bits
+ * control field, 8 bytes data field, 16 bits crc field, 2 bits ACK field and 7
+ * bits end of frame
+ */
+#define GRCAN_EFF_FRAME_MAX_BITS	(1+32+6+8*8+16+2+7)
+
+#if defined(__BIG_ENDIAN)
+static inline u32 grcan_read_reg(u32 __iomem *reg)
+{
+	return ioread32be(reg);
+}
+
+static inline void grcan_write_reg(u32 __iomem *reg, u32 val)
+{
+	iowrite32be(val, reg);
+}
+#else
+static inline u32 grcan_read_reg(u32 __iomem *reg)
+{
+	return ioread32(reg);
+}
+
+static inline void grcan_write_reg(u32 __iomem *reg, u32 val)
+{
+	iowrite32(val, reg);
+}
+#endif
+
+static inline void grcan_clear_bits(u32 __iomem *reg, u32 mask)
+{
+	grcan_write_reg(reg, grcan_read_reg(reg) & ~mask);
+}
+
+static inline void grcan_set_bits(u32 __iomem *reg, u32 mask)
+{
+	grcan_write_reg(reg, grcan_read_reg(reg) | mask);
+}
+
+static inline u32 grcan_read_bits(u32 __iomem *reg, u32 mask)
+{
+	return grcan_read_reg(reg) & mask;
+}
+
+static inline void grcan_write_bits(u32 __iomem *reg, u32 value, u32 mask)
+{
+	u32 old = grcan_read_reg(reg);
+
+	grcan_write_reg(reg, (old & ~mask) | (value & mask));
+}
+
+/* a and b should both be in [0,size] and a == b == size should not hold */
+static inline u32 grcan_ring_add(u32 a, u32 b, u32 size)
+{
+	u32 sum = a + b;
+
+	if (sum < size)
+		return sum;
+	else
+		return sum - size;
+}
+
+/* a and b should both be in [0,size) */
+static inline u32 grcan_ring_sub(u32 a, u32 b, u32 size)
+{
+	return grcan_ring_add(a, size - b, size);
+}
+
+/* Available slots for new transmissions */
+static inline u32 grcan_txspace(size_t txsize, u32 txwr, u32 eskbp)
+{
+	u32 slots = txsize / GRCAN_MSG_SIZE - 1;
+	u32 used = grcan_ring_sub(txwr, eskbp, txsize) / GRCAN_MSG_SIZE;
+
+	return slots - used;
+}
+
+/* Configuration parameters that can be set via module parameters */
+static struct grcan_device_config grcan_module_config =
+	GRCAN_DEFAULT_DEVICE_CONFIG;
+
+static const struct can_bittiming_const grcan_bittiming_const = {
+	.name		= DRV_NAME,
+	.tseg1_min	= GRCAN_CONF_PS1_MIN + 1,
+	.tseg1_max	= GRCAN_CONF_PS1_MAX + 1,
+	.tseg2_min	= GRCAN_CONF_PS2_MIN,
+	.tseg2_max	= GRCAN_CONF_PS2_MAX,
+	.sjw_max	= GRCAN_CONF_RSJ_MAX,
+	.brp_min	= GRCAN_CONF_SCALER_MIN + 1,
+	.brp_max	= GRCAN_CONF_SCALER_MAX + 1,
+	.brp_inc	= GRCAN_CONF_SCALER_INC,
+};
+
+static int grcan_set_bittiming(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct can_bittiming *bt = &priv->can.bittiming;
+	u32 timing = 0;
+	int bpr, rsj, ps1, ps2, scaler;
+
+	/* Should never happen - function will not be called when
+	 * device is up
+	 */
+	if (grcan_read_bits(&regs->ctrl, GRCAN_CTRL_ENABLE))
+		return -EBUSY;
+
+	bpr = 0; /* Note bpr and brp are different concepts */
+	rsj = bt->sjw;
+	ps1 = (bt->prop_seg + bt->phase_seg1) - 1; /* tseg1 - 1 */
+	ps2 = bt->phase_seg2;
+	scaler = (bt->brp - 1);
+	netdev_dbg(dev, "Request for BPR=%d, RSJ=%d, PS1=%d, PS2=%d, SCALER=%d",
+		   bpr, rsj, ps1, ps2, scaler);
+	if (!(ps1 > ps2)) {
+		netdev_err(dev, "PS1 > PS2 must hold: PS1=%d, PS2=%d\n",
+			   ps1, ps2);
+		return -EINVAL;
+	}
+	if (!(ps2 >= rsj)) {
+		netdev_err(dev, "PS2 >= RSJ must hold: PS2=%d, RSJ=%d\n",
+			   ps2, rsj);
+		return -EINVAL;
+	}
+
+	timing |= (bpr << GRCAN_CONF_BPR_BIT) & GRCAN_CONF_BPR;
+	timing |= (rsj << GRCAN_CONF_RSJ_BIT) & GRCAN_CONF_RSJ;
+	timing |= (ps1 << GRCAN_CONF_PS1_BIT) & GRCAN_CONF_PS1;
+	timing |= (ps2 << GRCAN_CONF_PS2_BIT) & GRCAN_CONF_PS2;
+	timing |= (scaler << GRCAN_CONF_SCALER_BIT) & GRCAN_CONF_SCALER;
+	netdev_info(dev, "setting timing=0x%x\n", timing);
+	grcan_write_bits(&regs->conf, timing, GRCAN_CONF_TIMING);
+
+	return 0;
+}
+
+static int grcan_get_berr_counter(const struct net_device *dev,
+				  struct can_berr_counter *bec)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	u32 status = grcan_read_reg(&regs->stat);
+
+	bec->txerr = (status & GRCAN_STAT_TXERRCNT) >> GRCAN_STAT_TXERRCNT_BIT;
+	bec->rxerr = (status & GRCAN_STAT_RXERRCNT) >> GRCAN_STAT_RXERRCNT_BIT;
+	return 0;
+}
+
+static int grcan_poll(struct napi_struct *napi, int budget);
+
+/* Reset device, but keep configuration information */
+static void grcan_reset(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	u32 config = grcan_read_reg(&regs->conf);
+
+	grcan_set_bits(&regs->ctrl, GRCAN_CTRL_RESET);
+	grcan_write_reg(&regs->conf, config);
+
+	priv->eskbp = grcan_read_reg(&regs->txrd);
+	priv->can.state = CAN_STATE_STOPPED;
+
+	/* Turn off hardware filtering - regs->rxcode set to 0 by reset */
+	grcan_write_reg(&regs->rxmask, 0);
+}
+
+/* stop device without changing any configurations */
+static void grcan_stop_hardware(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+
+	grcan_write_reg(&regs->imr, GRCAN_IRQ_NONE);
+	grcan_clear_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
+	grcan_clear_bits(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+	grcan_clear_bits(&regs->ctrl, GRCAN_CTRL_ENABLE);
+}
+
+/* Let priv->eskbp catch up to regs->txrd and echo back the skbs if echo
+ * is true and free them otherwise.
+ *
+ * If budget is >= 0, stop after handling at most budget skbs. Otherwise,
+ * continue until priv->eskbp catches up to regs->txrd.
+ *
+ * priv->lock *must* be held when calling this function
+ */
+static int catch_up_echo_skb(struct net_device *dev, int budget, bool echo)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	struct net_device_stats *stats = &dev->stats;
+	int i, work_done;
+
+	/* Updates to priv->eskbp and wake-ups of the queue needs to
+	 * be atomic towards the reads of priv->eskbp and shut-downs
+	 * of the queue in grcan_start_xmit.
+	 */
+	u32 txrd = grcan_read_reg(&regs->txrd);
+
+	for (work_done = 0; work_done < budget || budget < 0; work_done++) {
+		if (priv->eskbp == txrd)
+			break;
+		i = priv->eskbp / GRCAN_MSG_SIZE;
+		if (echo) {
+			/* Normal echo of messages */
+			stats->tx_packets++;
+			stats->tx_bytes += priv->txdlc[i];
+			priv->txdlc[i] = 0;
+			can_get_echo_skb(dev, i);
+		} else {
+			/* For cleanup of untransmitted messages */
+			can_free_echo_skb(dev, i);
+		}
+
+		priv->eskbp = grcan_ring_add(priv->eskbp, GRCAN_MSG_SIZE,
+					     dma->tx.size);
+		txrd = grcan_read_reg(&regs->txrd);
+	}
+	return work_done;
+}
+
+static void grcan_lost_one_shot_frame(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	u32 txrd;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	catch_up_echo_skb(dev, -1, true);
+
+	if (unlikely(grcan_read_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE))) {
+		/* Should never happen */
+		netdev_err(dev, "TXCTRL enabled at TXLOSS in one shot mode\n");
+	} else {
+		/* By the time an GRCAN_IRQ_TXLOSS is generated in
+		 * one-shot mode there is no problem in writing
+		 * to TXRD even in versions of the hardware in
+		 * which GRCAN_TXCTRL_ONGOING is not cleared properly
+		 * in one-shot mode.
+		 */
+
+		/* Skip message and discard echo-skb */
+		txrd = grcan_read_reg(&regs->txrd);
+		txrd = grcan_ring_add(txrd, GRCAN_MSG_SIZE, dma->tx.size);
+		grcan_write_reg(&regs->txrd, txrd);
+		catch_up_echo_skb(dev, -1, false);
+
+		if (!priv->resetting && !priv->closing &&
+		    !(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)) {
+			netif_wake_queue(dev);
+			grcan_set_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
+		}
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static void grcan_err(struct net_device *dev, u32 sources, u32 status)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	struct net_device_stats *stats = &dev->stats;
+	struct can_frame cf;
+
+	/* Zero potential error_frame */
+	memset(&cf, 0, sizeof(cf));
+
+	/* Message lost interrupt. This might be due to arbitration error, but
+	 * is also triggered when there is no one else on the can bus or when
+	 * there is a problem with the hardware interface or the bus itself. As
+	 * arbitration errors can not be singled out, no error frames are
+	 * generated reporting this event as an arbitration error.
+	 */
+	if (sources & GRCAN_IRQ_TXLOSS) {
+		/* Take care of failed one-shot transmit */
+		if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT)
+			grcan_lost_one_shot_frame(dev);
+
+		/* Stop printing as soon as error passive or bus off is in
+		 * effect to limit the amount of txloss debug printouts.
+		 */
+		if (!(status & GRCAN_STAT_ERRCTR_RELATED)) {
+			netdev_dbg(dev, "tx message lost\n");
+			stats->tx_errors++;
+		}
+	}
+
+	/* Conditions dealing with the error counters. There is no interrupt for
+	 * error warning, but there are interrupts for increases of the error
+	 * counters.
+	 */
+	if ((sources & GRCAN_IRQ_ERRCTR_RELATED) ||
+	    (status & GRCAN_STAT_ERRCTR_RELATED)) {
+		enum can_state state = priv->can.state;
+		enum can_state oldstate = state;
+		u32 txerr = (status & GRCAN_STAT_TXERRCNT)
+			>> GRCAN_STAT_TXERRCNT_BIT;
+		u32 rxerr = (status & GRCAN_STAT_RXERRCNT)
+			>> GRCAN_STAT_RXERRCNT_BIT;
+
+		/* Figure out current state */
+		if (status & GRCAN_STAT_OFF) {
+			state = CAN_STATE_BUS_OFF;
+		} else if (status & GRCAN_STAT_PASS) {
+			state = CAN_STATE_ERROR_PASSIVE;
+		} else if (txerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT ||
+			   rxerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT) {
+			state = CAN_STATE_ERROR_WARNING;
+		} else {
+			state = CAN_STATE_ERROR_ACTIVE;
+		}
+
+		/* Handle and report state changes */
+		if (state != oldstate) {
+			switch (state) {
+			case CAN_STATE_BUS_OFF:
+				netdev_dbg(dev, "bus-off\n");
+				netif_carrier_off(dev);
+				priv->can.can_stats.bus_off++;
+
+				/* Prevent the hardware from recovering from bus
+				 * off on its own if restart is disabled.
+				 */
+				if (!priv->can.restart_ms)
+					grcan_stop_hardware(dev);
+
+				cf.can_id |= CAN_ERR_BUSOFF;
+				break;
+
+			case CAN_STATE_ERROR_PASSIVE:
+				netdev_dbg(dev, "Error passive condition\n");
+				priv->can.can_stats.error_passive++;
+
+				cf.can_id |= CAN_ERR_CRTL;
+				if (txerr >= GRCAN_STAT_ERRCNT_PASSIVE_LIMIT)
+					cf.data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
+				if (rxerr >= GRCAN_STAT_ERRCNT_PASSIVE_LIMIT)
+					cf.data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
+				break;
+
+			case CAN_STATE_ERROR_WARNING:
+				netdev_dbg(dev, "Error warning condition\n");
+				priv->can.can_stats.error_warning++;
+
+				cf.can_id |= CAN_ERR_CRTL;
+				if (txerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT)
+					cf.data[1] |= CAN_ERR_CRTL_TX_WARNING;
+				if (rxerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT)
+					cf.data[1] |= CAN_ERR_CRTL_RX_WARNING;
+				break;
+
+			case CAN_STATE_ERROR_ACTIVE:
+				netdev_dbg(dev, "Error active condition\n");
+				cf.can_id |= CAN_ERR_CRTL;
+				break;
+
+			default:
+				/* There are no others at this point */
+				break;
+			}
+			cf.data[6] = txerr;
+			cf.data[7] = rxerr;
+			priv->can.state = state;
+		}
+
+		/* Report automatic restarts */
+		if (priv->can.restart_ms && oldstate == CAN_STATE_BUS_OFF) {
+			unsigned long flags;
+
+			cf.can_id |= CAN_ERR_RESTARTED;
+			netdev_dbg(dev, "restarted\n");
+			priv->can.can_stats.restarts++;
+			netif_carrier_on(dev);
+
+			spin_lock_irqsave(&priv->lock, flags);
+
+			if (!priv->resetting && !priv->closing) {
+				u32 txwr = grcan_read_reg(&regs->txwr);
+
+				if (grcan_txspace(dma->tx.size, txwr,
+						  priv->eskbp))
+					netif_wake_queue(dev);
+			}
+
+			spin_unlock_irqrestore(&priv->lock, flags);
+		}
+	}
+
+	/* Data overrun interrupt */
+	if ((sources & GRCAN_IRQ_OR) || (status & GRCAN_STAT_OR)) {
+		netdev_dbg(dev, "got data overrun interrupt\n");
+		stats->rx_over_errors++;
+		stats->rx_errors++;
+
+		cf.can_id |= CAN_ERR_CRTL;
+		cf.data[1] |= CAN_ERR_CRTL_RX_OVERFLOW;
+	}
+
+	/* AHB bus error interrupts (not CAN bus errors) - shut down the
+	 * device.
+	 */
+	if (sources & (GRCAN_IRQ_TXAHBERR | GRCAN_IRQ_RXAHBERR) ||
+	    (status & GRCAN_STAT_AHBERR)) {
+		char *txrx = "";
+		unsigned long flags;
+
+		if (sources & GRCAN_IRQ_TXAHBERR) {
+			txrx = "on tx ";
+			stats->tx_errors++;
+		} else if (sources & GRCAN_IRQ_RXAHBERR) {
+			txrx = "on rx ";
+			stats->rx_errors++;
+		}
+		netdev_err(dev, "Fatal AHB buss error %s- halting device\n",
+			   txrx);
+
+		spin_lock_irqsave(&priv->lock, flags);
+
+		/* Prevent anything to be enabled again and halt device */
+		priv->closing = true;
+		netif_stop_queue(dev);
+		grcan_stop_hardware(dev);
+		priv->can.state = CAN_STATE_STOPPED;
+
+		spin_unlock_irqrestore(&priv->lock, flags);
+	}
+
+	/* Pass on error frame if something to report,
+	 * i.e. id contains some information
+	 */
+	if (cf.can_id) {
+		struct can_frame *skb_cf;
+		struct sk_buff *skb = alloc_can_err_skb(dev, &skb_cf);
+
+		if (skb == NULL) {
+			netdev_dbg(dev, "could not allocate error frame\n");
+			return;
+		}
+		skb_cf->can_id |= cf.can_id;
+		memcpy(skb_cf->data, cf.data, sizeof(cf.data));
+
+		netif_rx(skb);
+	}
+}
+
+static irqreturn_t grcan_interrupt(int irq, void *dev_id)
+{
+	struct net_device *dev = dev_id;
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	u32 sources, status;
+
+	/* Find out the source */
+	sources = grcan_read_reg(&regs->pimsr);
+	if (!sources)
+		return IRQ_NONE;
+	grcan_write_reg(&regs->picr, sources);
+	status = grcan_read_reg(&regs->stat);
+
+	/* If we got TX progress, the device has not hanged,
+	 * so disable the hang timer
+	 */
+	if (priv->need_txbug_workaround &&
+	    (sources & (GRCAN_IRQ_TX | GRCAN_IRQ_TXLOSS))) {
+		del_timer(&priv->hang_timer);
+	}
+
+	/* Frame(s) received or transmitted */
+	if (sources & (GRCAN_IRQ_TX | GRCAN_IRQ_RX)) {
+		/* Disable tx/rx interrupts and schedule poll(). No need for
+		 * locking as interference from a running reset at worst leads
+		 * to an extra interrupt.
+		 */
+		grcan_clear_bits(&regs->imr, GRCAN_IRQ_TX | GRCAN_IRQ_RX);
+		napi_schedule(&priv->napi);
+	}
+
+	/* (Potential) error conditions to take care of */
+	if (sources & GRCAN_IRQ_ERRORS)
+		grcan_err(dev, sources, status);
+
+	return IRQ_HANDLED;
+}
+
+/* Reset device and restart operations from where they were.
+ *
+ * This assumes that RXCTRL & RXCTRL is properly disabled and that RX
+ * is not ONGOING (TX might be stuck in ONGOING due to a harwrware bug
+ * for single shot)
+ */
+static void grcan_running_reset(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *)data;
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	unsigned long flags;
+
+	/* This temporarily messes with eskbp, so we need to lock
+	 * priv->lock
+	 */
+	spin_lock_irqsave(&priv->lock, flags);
+
+	priv->resetting = false;
+	del_timer(&priv->hang_timer);
+	del_timer(&priv->rr_timer);
+
+	if (!priv->closing) {
+		/* Save and reset - config register preserved by grcan_reset */
+		u32 imr = grcan_read_reg(&regs->imr);
+
+		u32 txaddr = grcan_read_reg(&regs->txaddr);
+		u32 txsize = grcan_read_reg(&regs->txsize);
+		u32 txwr = grcan_read_reg(&regs->txwr);
+		u32 txrd = grcan_read_reg(&regs->txrd);
+		u32 eskbp = priv->eskbp;
+
+		u32 rxaddr = grcan_read_reg(&regs->rxaddr);
+		u32 rxsize = grcan_read_reg(&regs->rxsize);
+		u32 rxwr = grcan_read_reg(&regs->rxwr);
+		u32 rxrd = grcan_read_reg(&regs->rxrd);
+
+		grcan_reset(dev);
+
+		/* Restore */
+		grcan_write_reg(&regs->txaddr, txaddr);
+		grcan_write_reg(&regs->txsize, txsize);
+		grcan_write_reg(&regs->txwr, txwr);
+		grcan_write_reg(&regs->txrd, txrd);
+		priv->eskbp = eskbp;
+
+		grcan_write_reg(&regs->rxaddr, rxaddr);
+		grcan_write_reg(&regs->rxsize, rxsize);
+		grcan_write_reg(&regs->rxwr, rxwr);
+		grcan_write_reg(&regs->rxrd, rxrd);
+
+		/* Turn on device again */
+		grcan_write_reg(&regs->imr, imr);
+		priv->can.state = CAN_STATE_ERROR_ACTIVE;
+		grcan_write_reg(&regs->txctrl, GRCAN_TXCTRL_ENABLE
+				| (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT
+				   ? GRCAN_TXCTRL_SINGLE : 0));
+		grcan_write_reg(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+		grcan_write_reg(&regs->ctrl, GRCAN_CTRL_ENABLE);
+
+		/* Start queue if there is size and listen-onle mode is not
+		 * enabled
+		 */
+		if (grcan_txspace(priv->dma.tx.size, txwr, priv->eskbp) &&
+		    !(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
+			netif_wake_queue(dev);
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	netdev_err(dev, "Device reset and restored\n");
+}
+
+/* Waiting time in usecs corresponding to the transmission of three maximum
+ * sized can frames in the given bitrate (in bits/sec). Waiting for this amount
+ * of time makes sure that the can controller have time to finish sending or
+ * receiving a frame with a good margin.
+ *
+ * usecs/sec * number of frames * bits/frame / bits/sec
+ */
+static inline u32 grcan_ongoing_wait_usecs(__u32 bitrate)
+{
+	return 1000000 * 3 * GRCAN_EFF_FRAME_MAX_BITS / bitrate;
+}
+
+/* Set timer so that it will not fire until after a period in which the can
+ * controller have a good margin to finish transmitting a frame unless it has
+ * hanged
+ */
+static inline void grcan_reset_timer(struct timer_list *timer, __u32 bitrate)
+{
+	u32 wait_jiffies = usecs_to_jiffies(grcan_ongoing_wait_usecs(bitrate));
+
+	mod_timer(timer, jiffies + wait_jiffies);
+}
+
+/* Disable channels and schedule a running reset */
+static void grcan_initiate_running_reset(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *)data;
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	unsigned long flags;
+
+	netdev_err(dev, "Device seems hanged - reset scheduled\n");
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	/* The main body of this function must never be executed again
+	 * until after an execution of grcan_running_reset
+	 */
+	if (!priv->resetting && !priv->closing) {
+		priv->resetting = true;
+		netif_stop_queue(dev);
+		grcan_clear_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
+		grcan_clear_bits(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+		grcan_reset_timer(&priv->rr_timer, priv->can.bittiming.bitrate);
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static void grcan_free_dma_buffers(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_dma *dma = &priv->dma;
+
+	dma_free_coherent(&dev->dev, dma->base_size, dma->base_buf,
+			  dma->base_handle);
+	memset(dma, 0, sizeof(*dma));
+}
+
+static int grcan_allocate_dma_buffers(struct net_device *dev,
+				      size_t tsize, size_t rsize)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_dma *dma = &priv->dma;
+	struct grcan_dma_buffer *large = rsize > tsize ? &dma->rx : &dma->tx;
+	struct grcan_dma_buffer *small = rsize > tsize ? &dma->tx : &dma->rx;
+	size_t shift;
+
+	/* Need a whole number of GRCAN_BUFFER_ALIGNMENT for the large,
+	 * i.e. first buffer
+	 */
+	size_t maxs = max(tsize, rsize);
+	size_t lsize = ALIGN(maxs, GRCAN_BUFFER_ALIGNMENT);
+
+	/* Put the small buffer after that */
+	size_t ssize = min(tsize, rsize);
+
+	/* Extra GRCAN_BUFFER_ALIGNMENT to allow for alignment */
+	dma->base_size = lsize + ssize + GRCAN_BUFFER_ALIGNMENT;
+	dma->base_buf = dma_alloc_coherent(&dev->dev,
+					   dma->base_size,
+					   &dma->base_handle,
+					   GFP_KERNEL);
+
+	if (!dma->base_buf)
+		return -ENOMEM;
+
+	dma->tx.size = tsize;
+	dma->rx.size = rsize;
+
+	large->handle = ALIGN(dma->base_handle, GRCAN_BUFFER_ALIGNMENT);
+	small->handle = large->handle + lsize;
+	shift = large->handle - dma->base_handle;
+
+	large->buf = dma->base_buf + shift;
+	small->buf = large->buf + lsize;
+
+	return 0;
+}
+
+/* priv->lock *must* be held when calling this function */
+static int grcan_start(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	u32 confop, txctrl;
+
+	grcan_reset(dev);
+
+	grcan_write_reg(&regs->txaddr, priv->dma.tx.handle);
+	grcan_write_reg(&regs->txsize, priv->dma.tx.size);
+	/* regs->txwr, regs->txrd and priv->eskbp already set to 0 by reset */
+
+	grcan_write_reg(&regs->rxaddr, priv->dma.rx.handle);
+	grcan_write_reg(&regs->rxsize, priv->dma.rx.size);
+	/* regs->rxwr and regs->rxrd already set to 0 by reset */
+
+	/* Enable interrupts */
+	grcan_read_reg(&regs->pir);
+	grcan_write_reg(&regs->imr, GRCAN_IRQ_DEFAULT);
+
+	/* Enable interfaces, channels and device */
+	confop = GRCAN_CONF_ABORT
+		| (priv->config.enable0 ? GRCAN_CONF_ENABLE0 : 0)
+		| (priv->config.enable1 ? GRCAN_CONF_ENABLE1 : 0)
+		| (priv->config.select ? GRCAN_CONF_SELECT : 0)
+		| (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY ?
+		   GRCAN_CONF_SILENT : 0)
+		| (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES ?
+		   GRCAN_CONF_SAM : 0);
+	grcan_write_bits(&regs->conf, confop, GRCAN_CONF_OPERATION);
+	txctrl = GRCAN_TXCTRL_ENABLE
+		| (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT
+		   ? GRCAN_TXCTRL_SINGLE : 0);
+	grcan_write_reg(&regs->txctrl, txctrl);
+	grcan_write_reg(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+	grcan_write_reg(&regs->ctrl, GRCAN_CTRL_ENABLE);
+
+	priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+	return 0;
+}
+
+static int grcan_set_mode(struct net_device *dev, enum can_mode mode)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+	int err = 0;
+
+	if (mode == CAN_MODE_START) {
+		/* This might be called to restart the device to recover from
+		 * bus off errors
+		 */
+		spin_lock_irqsave(&priv->lock, flags);
+		if (priv->closing || priv->resetting) {
+			err = -EBUSY;
+		} else {
+			netdev_info(dev, "Restarting device\n");
+			grcan_start(dev);
+			if (!(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
+				netif_wake_queue(dev);
+		}
+		spin_unlock_irqrestore(&priv->lock, flags);
+		return err;
+	}
+	return -EOPNOTSUPP;
+}
+
+static int grcan_open(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_dma *dma = &priv->dma;
+	unsigned long flags;
+	int err;
+
+	/* Allocate memory */
+	err = grcan_allocate_dma_buffers(dev, priv->config.txsize,
+					 priv->config.rxsize);
+	if (err) {
+		netdev_err(dev, "could not allocate DMA buffers\n");
+		return err;
+	}
+
+	priv->echo_skb = kzalloc(dma->tx.size * sizeof(*priv->echo_skb),
+				 GFP_KERNEL);
+	if (!priv->echo_skb) {
+		err = -ENOMEM;
+		goto exit_free_dma_buffers;
+	}
+	priv->can.echo_skb_max = dma->tx.size;
+	priv->can.echo_skb = priv->echo_skb;
+
+	priv->txdlc = kzalloc(dma->tx.size * sizeof(*priv->txdlc), GFP_KERNEL);
+	if (!priv->txdlc) {
+		err = -ENOMEM;
+		goto exit_free_echo_skb;
+	}
+
+	/* Get can device up */
+	err = open_candev(dev);
+	if (err)
+		goto exit_free_txdlc;
+
+	err = request_irq(dev->irq, grcan_interrupt, IRQF_SHARED,
+			  dev->name, dev);
+	if (err)
+		goto exit_close_candev;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	napi_enable(&priv->napi);
+	grcan_start(dev);
+	if (!(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
+		netif_start_queue(dev);
+	priv->resetting = false;
+	priv->closing = false;
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return 0;
+
+exit_close_candev:
+	close_candev(dev);
+exit_free_txdlc:
+	kfree(priv->txdlc);
+exit_free_echo_skb:
+	kfree(priv->echo_skb);
+exit_free_dma_buffers:
+	grcan_free_dma_buffers(dev);
+	return err;
+}
+
+static int grcan_close(struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+
+	napi_disable(&priv->napi);
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	priv->closing = true;
+	if (priv->need_txbug_workaround) {
+		del_timer_sync(&priv->hang_timer);
+		del_timer_sync(&priv->rr_timer);
+	}
+	netif_stop_queue(dev);
+	grcan_stop_hardware(dev);
+	priv->can.state = CAN_STATE_STOPPED;
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	free_irq(dev->irq, dev);
+	close_candev(dev);
+
+	grcan_free_dma_buffers(dev);
+	priv->can.echo_skb_max = 0;
+	priv->can.echo_skb = NULL;
+	kfree(priv->echo_skb);
+	kfree(priv->txdlc);
+
+	return 0;
+}
+
+static int grcan_transmit_catch_up(struct net_device *dev, int budget)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+	int work_done;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	work_done = catch_up_echo_skb(dev, budget, true);
+	if (work_done) {
+		if (!priv->resetting && !priv->closing &&
+		    !(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
+			netif_wake_queue(dev);
+
+		/* With napi we don't get TX interrupts for a while,
+		 * so prevent a running reset while catching up
+		 */
+		if (priv->need_txbug_workaround)
+			del_timer(&priv->hang_timer);
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return work_done;
+}
+
+static int grcan_receive(struct net_device *dev, int budget)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	struct net_device_stats *stats = &dev->stats;
+	struct can_frame *cf;
+	struct sk_buff *skb;
+	u32 wr, rd, startrd;
+	u32 *slot;
+	u32 i, rtr, eff, j, shift;
+	int work_done = 0;
+
+	rd = grcan_read_reg(&regs->rxrd);
+	startrd = rd;
+	for (work_done = 0; work_done < budget; work_done++) {
+		/* Check for packet to receive */
+		wr = grcan_read_reg(&regs->rxwr);
+		if (rd == wr)
+			break;
+
+		/* Take care of packet */
+		skb = alloc_can_skb(dev, &cf);
+		if (skb == NULL) {
+			netdev_err(dev,
+				   "dropping frame: skb allocation failed\n");
+			stats->rx_dropped++;
+			continue;
+		}
+
+		slot = dma->rx.buf + rd;
+		eff = slot[0] & GRCAN_MSG_IDE;
+		rtr = slot[0] & GRCAN_MSG_RTR;
+		if (eff) {
+			cf->can_id = ((slot[0] & GRCAN_MSG_EID)
+				      >> GRCAN_MSG_EID_BIT);
+			cf->can_id |= CAN_EFF_FLAG;
+		} else {
+			cf->can_id = ((slot[0] & GRCAN_MSG_BID)
+				      >> GRCAN_MSG_BID_BIT);
+		}
+		cf->can_dlc = get_can_dlc((slot[1] & GRCAN_MSG_DLC)
+					  >> GRCAN_MSG_DLC_BIT);
+		if (rtr) {
+			cf->can_id |= CAN_RTR_FLAG;
+		} else {
+			for (i = 0; i < cf->can_dlc; i++) {
+				j = GRCAN_MSG_DATA_SLOT_INDEX(i);
+				shift = GRCAN_MSG_DATA_SHIFT(i);
+				cf->data[i] = (u8)(slot[j] >> shift);
+			}
+		}
+		netif_receive_skb(skb);
+
+		/* Update statistics and read pointer */
+		stats->rx_packets++;
+		stats->rx_bytes += cf->can_dlc;
+		rd = grcan_ring_add(rd, GRCAN_MSG_SIZE, dma->rx.size);
+	}
+
+	/* Make sure everything is read before allowing hardware to
+	 * use the memory
+	 */
+	mb();
+
+	/* Update read pointer - no need to check for ongoing */
+	if (likely(rd != startrd))
+		grcan_write_reg(&regs->rxrd, rd);
+
+	return work_done;
+}
+
+static int grcan_poll(struct napi_struct *napi, int budget)
+{
+	struct grcan_priv *priv = container_of(napi, struct grcan_priv, napi);
+	struct net_device *dev = priv->dev;
+	struct grcan_registers __iomem *regs = priv->regs;
+	unsigned long flags;
+	int tx_work_done, rx_work_done;
+	int rx_budget = budget / 2;
+	int tx_budget = budget - rx_budget;
+
+	/* Half of the budget for receiveing messages */
+	rx_work_done = grcan_receive(dev, rx_budget);
+
+	/* Half of the budget for transmitting messages as that can trigger echo
+	 * frames being received
+	 */
+	tx_work_done = grcan_transmit_catch_up(dev, tx_budget);
+
+	if (rx_work_done < rx_budget && tx_work_done < tx_budget) {
+		napi_complete(napi);
+
+		/* Guarantee no interference with a running reset that otherwise
+		 * could turn off interrupts.
+		 */
+		spin_lock_irqsave(&priv->lock, flags);
+
+		/* Enable tx and rx interrupts again. No need to check
+		 * priv->closing as napi_disable in grcan_close is waiting for
+		 * scheduled napi calls to finish.
+		 */
+		grcan_set_bits(&regs->imr, GRCAN_IRQ_TX | GRCAN_IRQ_RX);
+
+		spin_unlock_irqrestore(&priv->lock, flags);
+	}
+
+	return rx_work_done + tx_work_done;
+}
+
+/* Work tx bug by waiting while for the risky situation to clear. If that fails,
+ * drop a frame in one-shot mode or indicate a busy device otherwise.
+ *
+ * Returns 0 on successful wait. Otherwise it sets *netdev_tx_status to the
+ * value that should be returned by grcan_start_xmit when aborting the xmit.
+ */
+static int grcan_txbug_workaround(struct net_device *dev, struct sk_buff *skb,
+				  u32 txwr, u32 oneshotmode,
+				  netdev_tx_t *netdev_tx_status)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	int i;
+	unsigned long flags;
+
+	/* Wait a while for ongoing to be cleared or read pointer to catch up to
+	 * write pointer. The latter is needed due to a bug in older versions of
+	 * GRCAN in which ONGOING is not cleared properly one-shot mode when a
+	 * transmission fails.
+	 */
+	for (i = 0; i < GRCAN_SHORTWAIT_USECS; i++) {
+		udelay(1);
+		if (!grcan_read_bits(&regs->txctrl, GRCAN_TXCTRL_ONGOING) ||
+		    grcan_read_reg(&regs->txrd) == txwr) {
+			return 0;
+		}
+	}
+
+	/* Clean up, in case the situation was not resolved */
+	spin_lock_irqsave(&priv->lock, flags);
+	if (!priv->resetting && !priv->closing) {
+		/* Queue might have been stopped earlier in grcan_start_xmit */
+		if (grcan_txspace(dma->tx.size, txwr, priv->eskbp))
+			netif_wake_queue(dev);
+		/* Set a timer to resolve a hanged tx controller */
+		if (!timer_pending(&priv->hang_timer))
+			grcan_reset_timer(&priv->hang_timer,
+					  priv->can.bittiming.bitrate);
+	}
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	if (oneshotmode) {
+		/* In one-shot mode we should never end up here because
+		 * then the interrupt handler increases txrd on TXLOSS,
+		 * but it is consistent with one-shot mode to drop the
+		 * frame in this case.
+		 */
+		kfree_skb(skb);
+		*netdev_tx_status = NETDEV_TX_OK;
+	} else {
+		/* In normal mode the socket-can transmission queue get
+		 * to keep the frame so that it can be retransmitted
+		 * later
+		 */
+		*netdev_tx_status = NETDEV_TX_BUSY;
+	}
+	return -EBUSY;
+}
+
+/* Notes on the tx cyclic buffer handling:
+ *
+ * regs->txwr	- the next slot for the driver to put data to be sent
+ * regs->txrd	- the next slot for the device to read data
+ * priv->eskbp	- the next slot for the driver to call can_put_echo_skb for
+ *
+ * grcan_start_xmit can enter more messages as long as regs->txwr does
+ * not reach priv->eskbp (within 1 message gap)
+ *
+ * The device sends messages until regs->txrd reaches regs->txwr
+ *
+ * The interrupt calls handler calls can_put_echo_skb until
+ * priv->eskbp reaches regs->txrd
+ */
+static netdev_tx_t grcan_start_xmit(struct sk_buff *skb,
+				    struct net_device *dev)
+{
+	struct grcan_priv *priv = netdev_priv(dev);
+	struct grcan_registers __iomem *regs = priv->regs;
+	struct grcan_dma *dma = &priv->dma;
+	struct can_frame *cf = (struct can_frame *)skb->data;
+	u32 id, txwr, txrd, space, txctrl;
+	int slotindex;
+	u32 *slot;
+	u32 i, rtr, eff, dlc, tmp, err;
+	int j, shift;
+	unsigned long flags;
+	u32 oneshotmode = priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT;
+
+	if (can_dropped_invalid_skb(dev, skb))
+		return NETDEV_TX_OK;
+
+	/* Trying to transmit in silent mode will generate error interrupts, but
+	 * this should never happen - the queue should not have been started.
+	 */
+	if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
+		return NETDEV_TX_BUSY;
+
+	/* Reads of priv->eskbp and shut-downs of the queue needs to
+	 * be atomic towards the updates to priv->eskbp and wake-ups
+	 * of the queue in the interrupt handler.
+	 */
+	spin_lock_irqsave(&priv->lock, flags);
+
+	txwr = grcan_read_reg(&regs->txwr);
+	space = grcan_txspace(dma->tx.size, txwr, priv->eskbp);
+
+	slotindex = txwr / GRCAN_MSG_SIZE;
+	slot = dma->tx.buf + txwr;
+
+	if (unlikely(space == 1))
+		netif_stop_queue(dev);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+	/* End of critical section*/
+
+	/* This should never happen. If circular buffer is full, the
+	 * netif_stop_queue should have been stopped already.
+	 */
+	if (unlikely(!space)) {
+		netdev_err(dev, "No buffer space, but queue is non-stopped.\n");
+		return NETDEV_TX_BUSY;
+	}
+
+	/* Convert and write CAN message to DMA buffer */
+	eff = cf->can_id & CAN_EFF_FLAG;
+	rtr = cf->can_id & CAN_RTR_FLAG;
+	id = cf->can_id & (eff ? CAN_EFF_MASK : CAN_SFF_MASK);
+	dlc = cf->can_dlc;
+	if (eff)
+		tmp = (id << GRCAN_MSG_EID_BIT) & GRCAN_MSG_EID;
+	else
+		tmp = (id << GRCAN_MSG_BID_BIT) & GRCAN_MSG_BID;
+	slot[0] = (eff ? GRCAN_MSG_IDE : 0) | (rtr ? GRCAN_MSG_RTR : 0) | tmp;
+
+	slot[1] = ((dlc << GRCAN_MSG_DLC_BIT) & GRCAN_MSG_DLC);
+	slot[2] = 0;
+	slot[3] = 0;
+	for (i = 0; i < dlc; i++) {
+		j = GRCAN_MSG_DATA_SLOT_INDEX(i);
+		shift = GRCAN_MSG_DATA_SHIFT(i);
+		slot[j] |= cf->data[i] << shift;
+	}
+
+	/* Checking that channel has not been disabled. These cases
+	 * should never happen
+	 */
+	txctrl = grcan_read_reg(&regs->txctrl);
+	if (!(txctrl & GRCAN_TXCTRL_ENABLE))
+		netdev_err(dev, "tx channel spuriously disabled\n");
+
+	if (oneshotmode && !(txctrl & GRCAN_TXCTRL_SINGLE))
+		netdev_err(dev, "one-shot mode spuriously disabled\n");
+
+	/* Bug workaround for old version of grcan where updating txwr
+	 * in the same clock cycle as the controller updates txrd to
+	 * the current txwr could hang the can controller
+	 */
+	if (priv->need_txbug_workaround) {
+		txrd = grcan_read_reg(&regs->txrd);
+		if (unlikely(grcan_ring_sub(txwr, txrd, dma->tx.size) == 1)) {
+			netdev_tx_t txstatus;
+
+			err = grcan_txbug_workaround(dev, skb, txwr,
+						     oneshotmode, &txstatus);
+			if (err)
+				return txstatus;
+		}
+	}
+
+	/* Prepare skb for echoing. This must be after the bug workaround above
+	 * as ownership of the skb is passed on by calling can_put_echo_skb.
+	 * Returning NETDEV_TX_BUSY or accessing skb or cf after a call to
+	 * can_put_echo_skb would be an error unless other measures are
+	 * taken.
+	 */
+	priv->txdlc[slotindex] = cf->can_dlc; /* Store dlc for statistics */
+	can_put_echo_skb(skb, dev, slotindex);
+
+	/* Make sure everything is written before allowing hardware to
+	 * read from the memory
+	 */
+	wmb();
+
+	/* Update write pointer to start transmission */
+	grcan_write_reg(&regs->txwr,
+			grcan_ring_add(txwr, GRCAN_MSG_SIZE, dma->tx.size));
+
+	return NETDEV_TX_OK;
+}
+
+/* ========== Setting up sysfs interface and module parameters ========== */
+
+#define GRCAN_NOT_BOOL(unsigned_val) ((unsigned_val) > 1)
+
+#define GRCAN_MODULE_PARAM(name, mtype, valcheckf, desc)		\
+	static void grcan_sanitize_##name(struct platform_device *pd)	\
+	{								\
+		struct grcan_device_config grcan_default_config		\
+			= GRCAN_DEFAULT_DEVICE_CONFIG;			\
+		if (valcheckf(grcan_module_config.name)) {		\
+			dev_err(&pd->dev,				\
+				"Invalid module parameter value for "	\
+				#name " - setting default\n");		\
+			grcan_module_config.name =			\
+				grcan_default_config.name;		\
+		}							\
+	}								\
+	module_param_named(name, grcan_module_config.name,		\
+			   mtype, S_IRUGO);				\
+	MODULE_PARM_DESC(name, desc)
+
+#define GRCAN_CONFIG_ATTR(name, desc)					\
+	static ssize_t grcan_store_##name(struct device *sdev,		\
+					  struct device_attribute *att,	\
+					  const char *buf,		\
+					  size_t count)			\
+	{								\
+		struct net_device *dev = to_net_dev(sdev);		\
+		struct grcan_priv *priv = netdev_priv(dev);		\
+		u8 val;							\
+		int ret;						\
+		if (dev->flags & IFF_UP)				\
+			return -EBUSY;					\
+		ret = kstrtou8(buf, 0, &val);				\
+		if (ret < 0 || val > 1)					\
+			return -EINVAL;					\
+		priv->config.name = val;				\
+		return count;						\
+	}								\
+	static ssize_t grcan_show_##name(struct device *sdev,		\
+					 struct device_attribute *att,	\
+					 char *buf)			\
+	{								\
+		struct net_device *dev = to_net_dev(sdev);		\
+		struct grcan_priv *priv = netdev_priv(dev);		\
+		return sprintf(buf, "%d\n", priv->config.name);		\
+	}								\
+	static DEVICE_ATTR(name, S_IRUGO | S_IWUSR,			\
+			   grcan_show_##name,				\
+			   grcan_store_##name);				\
+	GRCAN_MODULE_PARAM(name, ushort, GRCAN_NOT_BOOL, desc)
+
+/* The following configuration options are made available both via module
+ * parameters and writable sysfs files. See the chapter about GRCAN in the
+ * documentation for the GRLIB VHDL library for further details.
+ */
+GRCAN_CONFIG_ATTR(enable0,
+		  "Configuration of physical interface 0. Determines\n"	\
+		  "the \"Enable 0\" bit of the configuration register.\n" \
+		  "Format: 0 | 1\nDefault: 0\n");
+
+GRCAN_CONFIG_ATTR(enable1,
+		  "Configuration of physical interface 1. Determines\n"	\
+		  "the \"Enable 1\" bit of the configuration register.\n" \
+		  "Format: 0 | 1\nDefault: 0\n");
+
+GRCAN_CONFIG_ATTR(select,
+		  "Select which physical interface to use.\n"	\
+		  "Format: 0 | 1\nDefault: 0\n");
+
+/* The tx and rx buffer size configuration options are only available via module
+ * parameters.
+ */
+GRCAN_MODULE_PARAM(txsize, uint, GRCAN_INVALID_BUFFER_SIZE,
+		   "Sets the size of the tx buffer.\n"			\
+		   "Format: <unsigned int> where (txsize & ~0x1fffc0) == 0\n" \
+		   "Default: 1024\n");
+GRCAN_MODULE_PARAM(rxsize, uint, GRCAN_INVALID_BUFFER_SIZE,
+		   "Sets the size of the rx buffer.\n"			\
+		   "Format: <unsigned int> where (size & ~0x1fffc0) == 0\n" \
+		   "Default: 1024\n");
+
+/* Function that makes sure that configuration done using
+ * module parameters are set to valid values
+ */
+static void grcan_sanitize_module_config(struct platform_device *ofdev)
+{
+	grcan_sanitize_enable0(ofdev);
+	grcan_sanitize_enable1(ofdev);
+	grcan_sanitize_select(ofdev);
+	grcan_sanitize_txsize(ofdev);
+	grcan_sanitize_rxsize(ofdev);
+}
+
+static const struct attribute *const sysfs_grcan_attrs[] = {
+	/* Config attrs */
+	&dev_attr_enable0.attr,
+	&dev_attr_enable1.attr,
+	&dev_attr_select.attr,
+	NULL,
+};
+
+static const struct attribute_group sysfs_grcan_group = {
+	.name	= "grcan",
+	.attrs	= (struct attribute **)sysfs_grcan_attrs,
+};
+
+/* ========== Setting up the driver ========== */
+
+static const struct net_device_ops grcan_netdev_ops = {
+	.ndo_open	= grcan_open,
+	.ndo_stop	= grcan_close,
+	.ndo_start_xmit	= grcan_start_xmit,
+};
+
+static int grcan_setup_netdev(struct platform_device *ofdev,
+			      void __iomem *base,
+			      int irq, u32 ambafreq, bool txbug)
+{
+	struct net_device *dev;
+	struct grcan_priv *priv;
+	struct grcan_registers __iomem *regs;
+	int err;
+
+	dev = alloc_candev(sizeof(struct grcan_priv), 0);
+	if (!dev)
+		return -ENOMEM;
+
+	dev->irq = irq;
+	dev->flags |= IFF_ECHO;
+	dev->netdev_ops = &grcan_netdev_ops;
+	dev->sysfs_groups[0] = &sysfs_grcan_group;
+
+	priv = netdev_priv(dev);
+	memcpy(&priv->config, &grcan_module_config,
+	       sizeof(struct grcan_device_config));
+	priv->dev = dev;
+	priv->regs = base;
+	priv->can.bittiming_const = &grcan_bittiming_const;
+	priv->can.do_set_bittiming = grcan_set_bittiming;
+	priv->can.do_set_mode = grcan_set_mode;
+	priv->can.do_get_berr_counter = grcan_get_berr_counter;
+	priv->can.clock.freq = ambafreq;
+	priv->can.ctrlmode_supported =
+		CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_ONE_SHOT;
+	priv->need_txbug_workaround = txbug;
+
+	/* Discover if triple sampling is supported by hardware */
+	regs = priv->regs;
+	grcan_set_bits(&regs->ctrl, GRCAN_CTRL_RESET);
+	grcan_set_bits(&regs->conf, GRCAN_CONF_SAM);
+	if (grcan_read_bits(&regs->conf, GRCAN_CONF_SAM)) {
+		priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES;
+		dev_dbg(&ofdev->dev, "Hardware supports triple-sampling\n");
+	}
+
+	spin_lock_init(&priv->lock);
+
+	if (priv->need_txbug_workaround) {
+		init_timer(&priv->rr_timer);
+		priv->rr_timer.function = grcan_running_reset;
+		priv->rr_timer.data = (unsigned long)dev;
+
+		init_timer(&priv->hang_timer);
+		priv->hang_timer.function = grcan_initiate_running_reset;
+		priv->hang_timer.data = (unsigned long)dev;
+	}
+
+	netif_napi_add(dev, &priv->napi, grcan_poll, GRCAN_NAPI_WEIGHT);
+
+	SET_NETDEV_DEV(dev, &ofdev->dev);
+	dev_info(&ofdev->dev, "regs=0x%p, irq=%d, clock=%d\n",
+		 priv->regs, dev->irq, priv->can.clock.freq);
+
+	err = register_candev(dev);
+	if (err)
+		goto exit_free_candev;
+
+	dev_set_drvdata(&ofdev->dev, dev);
+
+	/* Reset device to allow bit-timing to be set. No need to call
+	 * grcan_reset at this stage. That is done in grcan_open.
+	 */
+	grcan_write_reg(&regs->ctrl, GRCAN_CTRL_RESET);
+
+	return 0;
+exit_free_candev:
+	free_candev(dev);
+	return err;
+}
+
+static int __devinit grcan_probe(struct platform_device *ofdev)
+{
+	struct device_node *np = ofdev->dev.of_node;
+	struct resource *res;
+	u32 sysid, ambafreq;
+	int irq, err;
+	void __iomem *base;
+	bool txbug = true;
+
+	/* Compare GRLIB version number with the first that does not
+	 * have the tx bug (see start_xmit)
+	 */
+	err = of_property_read_u32(np, "systemid", &sysid);
+	if (!err && ((sysid & GRLIB_VERSION_MASK)
+		     >= GRCAN_TXBUG_SAFE_GRLIB_VERSION))
+		txbug = false;
+
+	err = of_property_read_u32(np, "freq", &ambafreq);
+	if (err) {
+		dev_err(&ofdev->dev, "unable to fetch \"freq\" property\n");
+		goto exit_error;
+	}
+
+	res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
+	base = devm_request_and_ioremap(&ofdev->dev, res);
+	if (!base) {
+		dev_err(&ofdev->dev, "couldn't map IO resource\n");
+		err = -EADDRNOTAVAIL;
+		goto exit_error;
+	}
+
+	irq = irq_of_parse_and_map(np, GRCAN_IRQIX_IRQ);
+	if (!irq) {
+		dev_err(&ofdev->dev, "no irq found\n");
+		err = -ENODEV;
+		goto exit_error;
+	}
+
+	grcan_sanitize_module_config(ofdev);
+
+	err = grcan_setup_netdev(ofdev, base, irq, ambafreq, txbug);
+	if (err)
+		goto exit_dispose_irq;
+
+	return 0;
+
+exit_dispose_irq:
+	irq_dispose_mapping(irq);
+exit_error:
+	dev_err(&ofdev->dev,
+		"%s socket CAN driver initialization failed with error %d\n",
+		DRV_NAME, err);
+	return err;
+}
+
+static int __devexit grcan_remove(struct platform_device *ofdev)
+{
+	struct net_device *dev = dev_get_drvdata(&ofdev->dev);
+	struct grcan_priv *priv = netdev_priv(dev);
+
+	unregister_candev(dev); /* Will in turn call grcan_close */
+
+	irq_dispose_mapping(dev->irq);
+	dev_set_drvdata(&ofdev->dev, NULL);
+	netif_napi_del(&priv->napi);
+	free_candev(dev);
+
+	return 0;
+}
+
+static struct of_device_id grcan_match[] __devinitconst = {
+	{.name = "GAISLER_GRCAN"},
+	{.name = "01_03d"},
+	{.name = "GAISLER_GRHCAN"},
+	{.name = "01_034"},
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, grcan_match);
+
+static struct platform_driver grcan_driver = {
+	.driver = {
+		.name = DRV_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = grcan_match,
+	},
+	.probe = grcan_probe,
+	.remove = __devexit_p(grcan_remove),
+};
+
+module_platform_driver(grcan_driver);
+
+MODULE_AUTHOR("Aeroflex Gaisler AB.");
+MODULE_DESCRIPTION("Socket CAN driver for Aeroflex Gaisler GRCAN");
+MODULE_LICENSE("GPL");
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* Re: [PATCH v9] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-11-15  7:47                                                             ` [PATCH v9] " Andreas Larsson
@ 2012-11-15 20:32                                                               ` Marc Kleine-Budde
  2012-11-16  6:17                                                                 ` Andreas Larsson
  0 siblings, 1 reply; 41+ messages in thread
From: Marc Kleine-Budde @ 2012-11-15 20:32 UTC (permalink / raw)
  To: Andreas Larsson
  Cc: linux-can, Wolfgang Grandegger, devicetree-discuss, software

[-- Attachment #1: Type: text/plain, Size: 637 bytes --]

On 11/15/2012 08:47 AM, Andreas Larsson wrote:
> This driver supports GRCAN and CRHCAN CAN controllers available in the GRLIB
> VHDL IP core library.
> 
> Signed-off-by: Andreas Larsson <andreas@gaisler.com>
> Acked-by: Wolfgang Grandegger <wg@grandegger.com>

Applied to can-next/master - and included in the pull-reqeust I just
sent to David.

Marc
-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v9] can: grcan: Add device driver for GRCAN and GRHCAN cores
  2012-11-15 20:32                                                               ` Marc Kleine-Budde
@ 2012-11-16  6:17                                                                 ` Andreas Larsson
  0 siblings, 0 replies; 41+ messages in thread
From: Andreas Larsson @ 2012-11-16  6:17 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: linux-can, Wolfgang Grandegger, devicetree-discuss, software

On 2012-11-15 21:32, Marc Kleine-Budde wrote:
> On 11/15/2012 08:47 AM, Andreas Larsson wrote:
>> This driver supports GRCAN and CRHCAN CAN controllers available in the GRLIB
>> VHDL IP core library.
>>
>> Signed-off-by: Andreas Larsson <andreas@gaisler.com>
>> Acked-by: Wolfgang Grandegger <wg@grandegger.com>
>
> Applied to can-next/master - and included in the pull-reqeust I just
> sent to David.

Thank you, both for applying it and for the feedback.

Cheers,
Andreas


^ permalink raw reply	[flat|nested] 41+ messages in thread

end of thread, other threads:[~2012-11-16  6:17 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-10-02 14:38 [PATCH] can: grcan: Add device driver for GRCAN and GRHCAN cores Andreas Larsson
2012-10-04  9:45 ` Marc Kleine-Budde
2012-10-11 10:04   ` Marc Kleine-Budde
2012-10-11 11:22     ` Andreas Larsson
2012-10-11 11:28       ` Marc Kleine-Budde
2012-10-11 12:08         ` Andreas Larsson
2012-10-23  9:57     ` [PATCH v2] " Andreas Larsson
2012-10-23 16:26       ` Wolfgang Grandegger
2012-10-24 13:31         ` Andreas Larsson
2012-10-30  9:06           ` [PATCH v3] " Andreas Larsson
2012-10-30 10:07             ` Wolfgang Grandegger
2012-10-30 16:24               ` Andreas Larsson
2012-10-31 12:51                 ` Wolfgang Grandegger
2012-10-31 16:33                   ` Andreas Larsson
2012-10-31 16:39                     ` [PATCH v4] " Andreas Larsson
2012-10-31 20:21                     ` [PATCH v3] " Wolfgang Grandegger
2012-11-01 16:08                       ` Andreas Larsson
2012-11-02 14:23                         ` [PATCH v5] " Andreas Larsson
2012-11-05  9:28                         ` [PATCH v3] " Wolfgang Grandegger
2012-11-07  7:32                           ` Andreas Larsson
2012-11-07 11:15                             ` Wolfgang Grandegger
2012-11-07 12:55                               ` Andreas Larsson
2012-11-07 15:20                                 ` [PATCH v6] " Andreas Larsson
2012-11-08  8:29                                   ` Wolfgang Grandegger
2012-11-08  9:27                                     ` Marc Kleine-Budde
2012-11-08 10:37                                       ` Andreas Larsson
     [not found]                                       ` <509B7B1E.5040509-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
2012-11-08 13:10                                         ` [PATCH v7] " Andreas Larsson
2012-11-09  0:01                                           ` Marc Kleine-Budde
2012-11-12 14:57                                             ` [PATCH v8] " Andreas Larsson
2012-11-13 21:15                                               ` Marc Kleine-Budde
2012-11-14  7:50                                                 ` Andreas Larsson
2012-11-14  8:43                                                   ` Marc Kleine-Budde
2012-11-14 11:02                                                     ` Andreas Larsson
2012-11-14 11:22                                                       ` Marc Kleine-Budde
2012-11-14 15:07                                                         ` Andreas Larsson
2012-11-14 15:12                                                           ` Marc Kleine-Budde
2012-11-15  7:47                                                             ` [PATCH v9] " Andreas Larsson
2012-11-15 20:32                                                               ` Marc Kleine-Budde
2012-11-16  6:17                                                                 ` Andreas Larsson
2012-11-08 10:33                                     ` [PATCH v6] " Andreas Larsson
2012-10-30  9:29           ` [PATCH v2] " Wolfgang Grandegger

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.