netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next v2 0/4] can: cc770: add support for the Bosch CC770 and Intel AN82527
@ 2011-11-25  9:43 Wolfgang Grandegger
  2011-11-25  9:43 ` [PATCH net-next v2 1/4] can: cc770: add driver core " Wolfgang Grandegger
                   ` (3 more replies)
  0 siblings, 4 replies; 66+ messages in thread
From: Wolfgang Grandegger @ 2011-11-25  9:43 UTC (permalink / raw)
  To: netdev
  Cc: linux-can, socketcan-users, IreneV, Stanislav Yelenskiy,
	Wolfgang Grandegger

Already since a while we have support for the Bosch CC770 and Intel
AN82527 CAN controllers in our out-of-tree Socket-CAN repository.

In the meantime I found a TQM855L board with two AN82527 on it,
which allowed me to provide and test a generic platform driver
as well.

Changes since v1:

- remove version.h includes
- some minor corrections in the ISA bus driver
- add platform header file to the driver core
- add generic platform driver
- add and update device tree nodes for tqm8xx and tqm8548

It would be nice if somebody else could test the driver, especially
the ISA driver (I don't have hardware at hand).

Wolfgang.

Wolfgang Grandegger (4):
  can: cc770: add driver core for the Bosch CC770 and Intel AN82527
  can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  can: cc770: add platform bus driver for the CC770 and AN82527
  powerpc: tqm8548/tqm8xx: add and update CAN device nodes

 .../devicetree/bindings/net/can/cc770.txt          |   56 ++
 arch/powerpc/boot/dts/tqm8548-bigflash.dts         |   19 +-
 arch/powerpc/boot/dts/tqm8548.dts                  |   19 +-
 arch/powerpc/boot/dts/tqm8xx.dts                   |   25 +
 drivers/net/can/Kconfig                            |    2 +
 drivers/net/can/Makefile                           |    1 +
 drivers/net/can/cc770/Kconfig                      |   21 +
 drivers/net/can/cc770/Makefile                     |    9 +
 drivers/net/can/cc770/cc770.c                      |  895 ++++++++++++++++++++
 drivers/net/can/cc770/cc770.h                      |  234 +++++
 drivers/net/can/cc770/cc770_isa.c                  |  336 ++++++++
 drivers/net/can/cc770/cc770_platform.c             |  289 +++++++
 include/linux/can/platform/cc770.h                 |   33 +
 13 files changed, 1929 insertions(+), 10 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/can/cc770.txt
 create mode 100644 drivers/net/can/cc770/Kconfig
 create mode 100644 drivers/net/can/cc770/Makefile
 create mode 100644 drivers/net/can/cc770/cc770.c
 create mode 100644 drivers/net/can/cc770/cc770.h
 create mode 100644 drivers/net/can/cc770/cc770_isa.c
 create mode 100644 drivers/net/can/cc770/cc770_platform.c
 create mode 100644 include/linux/can/platform/cc770.h

-- 
1.7.4.1


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

* [PATCH net-next v2 1/4] can: cc770: add driver core for the Bosch CC770 and Intel AN82527
  2011-11-25  9:43 [PATCH net-next v2 0/4] can: cc770: add support for the Bosch CC770 and Intel AN82527 Wolfgang Grandegger
@ 2011-11-25  9:43 ` Wolfgang Grandegger
       [not found]   ` <1322214204-1121-2-git-send-email-wg-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
  2011-11-28 11:28   ` [Socketcan-users] " Marc Kleine-Budde
  2011-11-25  9:43 ` [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527 Wolfgang Grandegger
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 66+ messages in thread
From: Wolfgang Grandegger @ 2011-11-25  9:43 UTC (permalink / raw)
  To: netdev
  Cc: linux-can, socketcan-users, IreneV, Stanislav Yelenskiy,
	Wolfgang Grandegger

Signed-off-by: Wolfgang Grandegger <wg@grandegger.com>
---
 drivers/net/can/Kconfig            |    2 +
 drivers/net/can/Makefile           |    1 +
 drivers/net/can/cc770/Kconfig      |    3 +
 drivers/net/can/cc770/Makefile     |    7 +
 drivers/net/can/cc770/cc770.c      |  895 ++++++++++++++++++++++++++++++++++++
 drivers/net/can/cc770/cc770.h      |  234 ++++++++++
 include/linux/can/platform/cc770.h |   33 ++
 7 files changed, 1175 insertions(+), 0 deletions(-)
 create mode 100644 drivers/net/can/cc770/Kconfig
 create mode 100644 drivers/net/can/cc770/Makefile
 create mode 100644 drivers/net/can/cc770/cc770.c
 create mode 100644 drivers/net/can/cc770/cc770.h
 create mode 100644 include/linux/can/platform/cc770.h

diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
index f6c98fb..ab45758 100644
--- a/drivers/net/can/Kconfig
+++ b/drivers/net/can/Kconfig
@@ -116,6 +116,8 @@ source "drivers/net/can/sja1000/Kconfig"
 
 source "drivers/net/can/c_can/Kconfig"
 
+source "drivers/net/can/cc770/Kconfig"
+
 source "drivers/net/can/usb/Kconfig"
 
 source "drivers/net/can/softing/Kconfig"
diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
index 24ebfe8..938be37 100644
--- a/drivers/net/can/Makefile
+++ b/drivers/net/can/Makefile
@@ -14,6 +14,7 @@ obj-y				+= softing/
 obj-$(CONFIG_CAN_SJA1000)	+= sja1000/
 obj-$(CONFIG_CAN_MSCAN)		+= mscan/
 obj-$(CONFIG_CAN_C_CAN)		+= c_can/
+obj-$(CONFIG_CAN_CC770)		+= cc770/
 obj-$(CONFIG_CAN_AT91)		+= at91_can.o
 obj-$(CONFIG_CAN_TI_HECC)	+= ti_hecc.o
 obj-$(CONFIG_CAN_MCP251X)	+= mcp251x.o
diff --git a/drivers/net/can/cc770/Kconfig b/drivers/net/can/cc770/Kconfig
new file mode 100644
index 0000000..225131b
--- /dev/null
+++ b/drivers/net/can/cc770/Kconfig
@@ -0,0 +1,3 @@
+menuconfig CAN_CC770
+	tristate "Bosch CC770 and Intel AN82527 devices"
+	depends on CAN_DEV && HAS_IOMEM
diff --git a/drivers/net/can/cc770/Makefile b/drivers/net/can/cc770/Makefile
new file mode 100644
index 0000000..34e8180
--- /dev/null
+++ b/drivers/net/can/cc770/Makefile
@@ -0,0 +1,7 @@
+#
+#  Makefile for the Bosch CC770 CAN controller drivers.
+#
+
+obj-$(CONFIG_CAN_CC770) += cc770.o
+
+ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c
new file mode 100644
index 0000000..47a6965
--- /dev/null
+++ b/drivers/net/can/cc770/cc770.c
@@ -0,0 +1,895 @@
+/*
+ * cc770.c - Bosch CC770 and Intel AN82527 network device driver
+ *
+ * Copyright (C) 2009, 2011 Wolfgang Grandegger <wg@grandegger.com>
+ *
+ * Derived from the old Socket-CAN i82527 driver:
+ *
+ * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Volkswagen nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * Alternatively, provided that this notice is retained in full, this
+ * software may be distributed under the terms of the GNU General
+ * Public License ("GPL") version 2, in which case the provisions of the
+ * GPL apply INSTEAD OF those given above.
+ *
+ * The provided data structures and external interfaces from this code
+ * are not restricted to be used by modules with a GPL compatible license.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Send feedback to <socketcan-users@lists.berlios.de>
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/if_ether.h>
+#include <linux/skbuff.h>
+#include <linux/delay.h>
+
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/error.h>
+#include <linux/can/dev.h>
+#include <linux/can/platform/cc770.h>
+
+#include "cc770.h"
+
+#define DRV_NAME  "cc770"
+
+MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION(DRV_NAME "CAN netdevice driver");
+
+/*
+ * The CC770 is a CAN controller from Bosch, which is 100% compatible
+ * with the AN82527 from Intel, but with "bugs" being fixed and some
+ * additional functionality, mainly:
+ *
+ * 1. RX and TX error counters are readable.
+ * 2. Support of silent (listen-only) mode.
+ * 3. Message object 15 can receive all types of frames, also RTR and EFF.
+ *
+ * Details are available from Bosch's "CC770_Product_Info_2007-01.pdf",
+ * which explains in detail the compatibility between the CC770 and the
+ * 82527. This driver use the additional functionality 3. on real CC770
+ * devices. Unfortunately, the CC770 does still not store the message
+ * identifier of received remote transmission request frames and
+ * therefore it's set to 0.
+ *
+ * The message objects 1..14 can be used for TX and RX while the message
+ * objects 15 is optimized for RX. It has a shadow register for reliable
+ * data receiption under heavy bus load. Therefore it makes sense to use
+ * this message object for the needed use case. The frame type (EFF/SFF)
+ * for the message object 15 can be defined via kernel module parameter
+ * "msgobj15_eff". If not equal 0, it will receive 29-bit EFF frames,
+ * otherwise 11 bit SFF messages.
+ */
+static int msgobj15_eff;
+module_param(msgobj15_eff, int, S_IRUGO);
+MODULE_PARM_DESC(msgobj15_eff, "Extended 29-bit frames for message object 15 "
+		 "(default: 11-bit standard frames)");
+
+static int i82527_compat;
+module_param(i82527_compat, int, S_IRUGO);
+MODULE_PARM_DESC(i82527_compat, "Strict Intel 82527 comptibility mode "
+		 "without using additional functions");
+
+/*
+ * This driver uses the last 5 message objects 11..15. The definitions
+ * and structure below allows to configure and assign them to the real
+ * message object.
+ */
+static unsigned char cc770_obj_flags[CC770_OBJ_MAX] = {
+	[CC770_OBJ_RX0] = CC770_OBJ_FLAG_RX,
+	[CC770_OBJ_RX1] = CC770_OBJ_FLAG_RX | CC770_OBJ_FLAG_EFF,
+	[CC770_OBJ_RX_RTR0] = CC770_OBJ_FLAG_RX | CC770_OBJ_FLAG_RTR,
+	[CC770_OBJ_RX_RTR1] = CC770_OBJ_FLAG_RX | CC770_OBJ_FLAG_RTR |
+			      CC770_OBJ_FLAG_EFF,
+	[CC770_OBJ_TX] = 0,
+};
+
+static struct can_bittiming_const cc770_bittiming_const = {
+	.name = DRV_NAME,
+	.tseg1_min = 1,
+	.tseg1_max = 16,
+	.tseg2_min = 1,
+	.tseg2_max = 8,
+	.sjw_max = 4,
+	.brp_min = 1,
+	.brp_max = 64,
+	.brp_inc = 1,
+};
+
+static inline int intid2obj(unsigned int intid)
+{
+	if (intid == 2)
+		return 0;
+	else
+		return MSGOBJ_LAST + 2 - intid;
+}
+
+static void enable_all_objs(const struct net_device *dev)
+{
+	struct cc770_priv *priv = netdev_priv(dev);
+	u8 msgcfg;
+	unsigned char obj_flags;
+	unsigned int o, mo;
+
+	for (o = 0; o <  CC770_OBJ_MAX; o++) {
+		obj_flags = priv->obj_flags[o];
+		mo = obj2msgobj(o);
+
+		if (obj_flags & CC770_OBJ_FLAG_RX) {
+			/*
+			 * We don't need extra objects for RTR and EFF if
+			 * the additional CC770 functions are enabled.
+			 */
+			if (priv->control_normal_mode & CTRL_EAF) {
+				if (o > 0)
+					continue;
+				netdev_dbg(dev, "Message object %d for "
+					   "RX data, RTR, SFF and EFF\n", mo);
+			} else {
+				netdev_dbg(dev,
+					   "Message object %d for RX %s %s\n",
+					   mo, obj_flags & CC770_OBJ_FLAG_RTR ?
+					   "RTR" : "data",
+					   obj_flags & CC770_OBJ_FLAG_EFF ?
+					   "EFF" : "SFF");
+			}
+
+			if (obj_flags & CC770_OBJ_FLAG_EFF)
+				msgcfg = MSGCFG_XTD;
+			else
+				msgcfg = 0;
+			if (obj_flags & CC770_OBJ_FLAG_RTR)
+				msgcfg |= MSGCFG_DIR;
+
+			cc770_write_reg(priv, msgobj[mo].config, msgcfg);
+			cc770_write_reg(priv, msgobj[mo].ctrl0,
+					MSGVAL_SET | TXIE_RES |
+					RXIE_SET | INTPND_RES);
+
+			if (obj_flags & CC770_OBJ_FLAG_RTR)
+				cc770_write_reg(priv, msgobj[mo].ctrl1,
+						NEWDAT_RES | CPUUPD_SET |
+						TXRQST_RES | RMTPND_RES);
+			else
+				cc770_write_reg(priv, msgobj[mo].ctrl1,
+						NEWDAT_RES | MSGLST_RES |
+						TXRQST_RES | RMTPND_RES);
+		} else {
+			netdev_dbg(dev, "Message object %d for "
+				   "TX data, RTR, SFF and EFF\n", mo);
+
+			cc770_write_reg(priv, msgobj[mo].ctrl1,
+					RMTPND_RES | TXRQST_RES |
+					CPUUPD_RES | NEWDAT_RES);
+			cc770_write_reg(priv, msgobj[mo].ctrl0,
+					MSGVAL_RES | TXIE_RES |
+					RXIE_RES | INTPND_RES);
+		}
+	}
+}
+
+static void disable_all_objs(const struct cc770_priv *priv)
+{
+	int i, mo;
+
+	for (i = 0; i <  CC770_OBJ_MAX; i++) {
+		mo = obj2msgobj(i);
+
+		if (priv->obj_flags[i] & CC770_OBJ_FLAG_RX) {
+			if (i > 0 && priv->control_normal_mode & CTRL_EAF)
+				continue;
+
+			cc770_write_reg(priv, msgobj[mo].ctrl1,
+					NEWDAT_RES | MSGLST_RES |
+					TXRQST_RES | RMTPND_RES);
+			cc770_write_reg(priv, msgobj[mo].ctrl0,
+					MSGVAL_RES | TXIE_RES |
+					RXIE_RES | INTPND_RES);
+		} else {
+			/* Clear message object for send */
+			cc770_write_reg(priv, msgobj[mo].ctrl1,
+					RMTPND_RES | TXRQST_RES |
+					CPUUPD_RES | NEWDAT_RES);
+			cc770_write_reg(priv, msgobj[mo].ctrl0,
+					MSGVAL_RES | TXIE_RES |
+					RXIE_RES | INTPND_RES);
+		}
+	}
+}
+
+static void set_reset_mode(struct net_device *dev)
+{
+	struct cc770_priv *priv = netdev_priv(dev);
+
+	/* Enable configuration and puts chip in bus-off, disable interrupts */
+	cc770_write_reg(priv, control, CTRL_CCE | CTRL_INI);
+
+	priv->can.state = CAN_STATE_STOPPED;
+
+	/* Clear interrupts */
+	cc770_read_reg(priv, interrupt);
+
+	/* Clear status register */
+	cc770_write_reg(priv, status, 0);
+
+	/* Disable all used message objects */
+	disable_all_objs(priv);
+}
+
+static void set_normal_mode(struct net_device *dev)
+{
+	struct cc770_priv *priv = netdev_priv(dev);
+
+	/* Clear interrupts */
+	cc770_read_reg(priv, interrupt);
+
+	/* Clear status register and pre-set last error code */
+	cc770_write_reg(priv, status, STAT_LEC_MASK);
+
+	/* Enable all used message objects*/
+	enable_all_objs(dev);
+
+	/*
+	 * Clear bus-off, interrupts only for errors,
+	 * not for status change
+	 */
+	cc770_write_reg(priv, control, priv->control_normal_mode);
+
+	priv->can.state = CAN_STATE_ERROR_ACTIVE;
+}
+
+static void chipset_init(struct cc770_priv *priv)
+{
+	int mo, id, data;
+
+	/* Enable configuration and put chip in bus-off, disable interrupts */
+	cc770_write_reg(priv, control, (CTRL_CCE | CTRL_INI));
+
+	/* Set CLKOUT divider and slew rates */
+	cc770_write_reg(priv, clkout, priv->clkout);
+
+	/* Configure CPU interface / CLKOUT enable */
+	cc770_write_reg(priv, cpu_interface, priv->cpu_interface);
+
+	/* Set bus configuration  */
+	cc770_write_reg(priv, bus_config, priv->bus_config);
+
+	/* Clear interrupts */
+	cc770_read_reg(priv, interrupt);
+
+	/* Clear status register */
+	cc770_write_reg(priv, status, 0);
+
+	/* Clear and invalidate message objects */
+	for (mo = MSGOBJ_FIRST; mo <= MSGOBJ_LAST; mo++) {
+		cc770_write_reg(priv, msgobj[mo].ctrl0,
+				INTPND_UNC | RXIE_RES |
+				TXIE_RES | MSGVAL_RES);
+		cc770_write_reg(priv, msgobj[mo].ctrl0,
+				INTPND_RES | RXIE_RES |
+				TXIE_RES | MSGVAL_RES);
+		cc770_write_reg(priv, msgobj[mo].ctrl1,
+				NEWDAT_RES | MSGLST_RES |
+				TXRQST_RES | RMTPND_RES);
+		for (data = 0; data < 8; data++)
+			cc770_write_reg(priv, msgobj[mo].data[data], 0);
+		for (id = 0; id < 4; id++)
+			cc770_write_reg(priv, msgobj[mo].id[id], 0);
+		cc770_write_reg(priv, msgobj[mo].config, 0);
+	}
+
+	/* Set all global ID masks to "don't care" */
+	cc770_write_reg(priv, global_mask_std[0], 0);
+	cc770_write_reg(priv, global_mask_std[1], 0);
+	cc770_write_reg(priv, global_mask_ext[0], 0);
+	cc770_write_reg(priv, global_mask_ext[1], 0);
+	cc770_write_reg(priv, global_mask_ext[2], 0);
+	cc770_write_reg(priv, global_mask_ext[3], 0);
+
+}
+
+static int cc770_probe_chip(struct net_device *dev)
+{
+	struct cc770_priv *priv = netdev_priv(dev);
+
+	/* Enable configuration, put chip in bus-off, disable ints */
+	cc770_write_reg(priv, control, CTRL_CCE | CTRL_EAF | CTRL_INI);
+	/* Configure cpu interface / CLKOUT disable */
+	cc770_write_reg(priv, cpu_interface, priv->cpu_interface);
+
+	/*
+	 * Check if hardware reset is still inactive or maybe there
+	 * is no chip in this address space
+	 */
+	if (cc770_read_reg(priv, cpu_interface) & CPUIF_RST) {
+		netdev_info(dev, "probing @0x%p failed (reset)\n",
+			    priv->reg_base);
+		return 0;
+	}
+
+	/* Write and read back test pattern */
+	cc770_write_reg(priv, msgobj[1].data[1], 0x25);
+	cc770_write_reg(priv, msgobj[2].data[3], 0x52);
+	cc770_write_reg(priv, msgobj[10].data[6], 0xc3);
+	if ((cc770_read_reg(priv, msgobj[1].data[1]) != 0x25) ||
+	    (cc770_read_reg(priv, msgobj[2].data[3]) != 0x52) ||
+	    (cc770_read_reg(priv, msgobj[10].data[6]) != 0xc3)) {
+		netdev_info(dev, "probing @0x%p failed (pattern)\n",
+			    priv->reg_base);
+		return 0;
+	}
+
+	/* Check if this chip is a CC770 supporting additional functions */
+	if (cc770_read_reg(priv, control) & CTRL_EAF)
+		priv->control_normal_mode |= CTRL_EAF;
+
+	return 1;
+}
+
+static void cc770_start(struct net_device *dev)
+{
+	struct cc770_priv *priv = netdev_priv(dev);
+
+	/* leave reset mode */
+	if (priv->can.state != CAN_STATE_STOPPED)
+		set_reset_mode(dev);
+
+	/* leave reset mode */
+	set_normal_mode(dev);
+}
+
+static int cc770_set_mode(struct net_device *dev, enum can_mode mode)
+{
+	struct cc770_priv *priv = netdev_priv(dev);
+
+	if (!priv->open_time)
+		return -EINVAL;
+
+	switch (mode) {
+	case CAN_MODE_START:
+		cc770_start(dev);
+		if (netif_queue_stopped(dev))
+			netif_wake_queue(dev);
+		break;
+
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+static int cc770_set_bittiming(struct net_device *dev)
+{
+	struct cc770_priv *priv = netdev_priv(dev);
+	struct can_bittiming *bt = &priv->can.bittiming;
+	u8 btr0, btr1;
+
+	btr0 = ((bt->brp - 1) & 0x3f) | (((bt->sjw - 1) & 0x3) << 6);
+	btr1 = ((bt->prop_seg + bt->phase_seg1 - 1) & 0xf) |
+		(((bt->phase_seg2 - 1) & 0x7) << 4);
+	if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
+		btr1 |= 0x80;
+
+	netdev_info(dev, "setting BTR0=0x%02x BTR1=0x%02x\n", btr0, btr1);
+
+	cc770_write_reg(priv, bit_timing_0, btr0);
+	cc770_write_reg(priv, bit_timing_1, btr1);
+
+	return 0;
+}
+
+static netdev_tx_t cc770_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct cc770_priv *priv = netdev_priv(dev);
+	struct net_device_stats *stats = &dev->stats;
+	struct can_frame *cf = (struct can_frame *)skb->data;
+	unsigned int mo = obj2msgobj(CC770_OBJ_TX);
+	u8 dlc, rtr;
+	u32 id;
+	int i;
+
+	if (can_dropped_invalid_skb(dev, skb))
+		return NETDEV_TX_OK;
+
+	if ((cc770_read_reg(priv,
+			    msgobj[mo].ctrl1) & TXRQST_UNC) == TXRQST_SET) {
+		netdev_err(dev, "TX register is still occupied!\n");
+		return NETDEV_TX_BUSY;
+	}
+
+	netif_stop_queue(dev);
+
+	dlc = cf->can_dlc;
+	id = cf->can_id;
+	if (cf->can_id & CAN_RTR_FLAG)
+		rtr = 0;
+	else
+		rtr = MSGCFG_DIR;
+	cc770_write_reg(priv, msgobj[mo].ctrl1,
+			RMTPND_RES | TXRQST_RES | CPUUPD_SET | NEWDAT_RES);
+	cc770_write_reg(priv, msgobj[mo].ctrl0,
+			MSGVAL_SET | TXIE_SET | RXIE_RES | INTPND_RES);
+	if (id & CAN_EFF_FLAG) {
+		id &= CAN_EFF_MASK;
+		cc770_write_reg(priv, msgobj[mo].config,
+				(dlc << 4) + rtr + MSGCFG_XTD);
+		cc770_write_reg(priv, msgobj[mo].id[3],
+				(id << 3) & 0xFFU);
+		cc770_write_reg(priv, msgobj[mo].id[2],
+				(id >> 5) & 0xFFU);
+		cc770_write_reg(priv, msgobj[mo].id[1],
+				(id >> 13) & 0xFFU);
+		cc770_write_reg(priv, msgobj[mo].id[0],
+				(id >> 21) & 0xFFU);
+	} else {
+		id &= CAN_SFF_MASK;
+		cc770_write_reg(priv, msgobj[mo].config,
+				(dlc << 4) + rtr);
+		cc770_write_reg(priv, msgobj[mo].id[0],
+				(id >> 3) & 0xFFU);
+		cc770_write_reg(priv, msgobj[mo].id[1],
+				(id << 5) & 0xFFU);
+	}
+
+	dlc &= 0x0f;		/* restore length only */
+	for (i = 0; i < dlc; i++)
+		cc770_write_reg(priv, msgobj[mo].data[i], cf->data[i]);
+
+	cc770_write_reg(priv, msgobj[mo].ctrl1,
+			RMTPND_RES | TXRQST_SET | CPUUPD_RES | NEWDAT_UNC);
+
+	stats->tx_bytes += dlc;
+
+	can_put_echo_skb(skb, dev, 0);
+
+	/*
+	 * HM: We had some cases of repeated IRQs so make sure the
+	 * INT is acknowledged I know it's already further up, but
+	 * doing again fixed the issue
+	 */
+	cc770_write_reg(priv, msgobj[mo].ctrl0,
+			MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);
+
+	return NETDEV_TX_OK;
+}
+
+static void cc770_rx(struct net_device *dev, unsigned int mo, u8 ctrl1)
+{
+	struct cc770_priv *priv = netdev_priv(dev);
+	struct net_device_stats *stats = &dev->stats;
+	struct can_frame *cf;
+	struct sk_buff *skb;
+	u8 config;
+	u32 id;
+	int i;
+
+	skb = alloc_can_skb(dev, &cf);
+	if (skb == NULL)
+		return;
+
+	config = cc770_read_reg(priv, msgobj[mo].config);
+
+	if (ctrl1 & RMTPND_SET) {
+		/*
+		 * Unfortunately, the chip does not store the real message
+		 * identifier of the received remote transmission request
+		 * frame. Therefore we set it to 0.
+		 */
+		cf->can_id = CAN_RTR_FLAG;
+		if (config & MSGCFG_XTD)
+			cf->can_id |= CAN_EFF_FLAG;
+		cf->can_dlc = 0;
+	} else {
+		if (config & MSGCFG_XTD) {
+			id = cc770_read_reg(priv, msgobj[mo].id[3]);
+			id |= cc770_read_reg(priv, msgobj[mo].id[2]) << 8;
+			id |= cc770_read_reg(priv, msgobj[mo].id[1]) << 16;
+			id |= cc770_read_reg(priv, msgobj[mo].id[0]) << 24;
+			id >>= 3;
+			id |= CAN_EFF_FLAG;
+		} else {
+			id = cc770_read_reg(priv, msgobj[mo].id[1]);
+			id |= cc770_read_reg(priv, msgobj[mo].id[0]) << 8;
+			id >>= 5;
+		}
+
+		cf->can_id = id;
+		cf->can_dlc = get_can_dlc((config & 0xf0) >> 4);
+		for (i = 0; i < cf->can_dlc; i++)
+			cf->data[i] = cc770_read_reg(priv, msgobj[mo].data[i]);
+	}
+	netif_rx(skb);
+
+	stats->rx_packets++;
+	stats->rx_bytes += cf->can_dlc;
+}
+
+static int cc770_err(struct net_device *dev, u8 status)
+{
+	struct cc770_priv *priv = netdev_priv(dev);
+	struct net_device_stats *stats = &dev->stats;
+	struct can_frame *cf;
+	struct sk_buff *skb;
+	u8 lec;
+
+	netdev_dbg(dev, "status interrupt (%#x)\n", status);
+
+	skb = alloc_can_err_skb(dev, &cf);
+	if (skb == NULL)
+		return -ENOMEM;
+
+	if (status & STAT_BOFF) {
+		/* Disable interrupts */
+		cc770_write_reg(priv, control, CTRL_INI);
+		cf->can_id |= CAN_ERR_BUSOFF;
+		priv->can.state = CAN_STATE_BUS_OFF;
+		can_bus_off(dev);
+	} else if (status & STAT_WARN) {
+		cf->can_id |= CAN_ERR_CRTL;
+		cf->data[1] = CAN_ERR_CRTL_RX_WARNING | CAN_ERR_CRTL_TX_WARNING;
+		priv->can.state = CAN_STATE_ERROR_WARNING;
+		priv->can.can_stats.error_warning++;
+	}
+
+	lec = status & STAT_LEC_MASK;
+	if (lec < 7 && lec > 0) {
+		if (lec == STAT_LEC_ACK) {
+			cf->can_id |= CAN_ERR_ACK;
+		} else {
+			cf->can_id |= CAN_ERR_PROT;
+			switch (lec) {
+			case STAT_LEC_STUFF:
+				cf->data[2] |= CAN_ERR_PROT_STUFF;
+				break;
+			case STAT_LEC_FORM:
+				cf->data[2] |= CAN_ERR_PROT_FORM;
+				break;
+			case STAT_LEC_BIT1:
+				cf->data[2] |= CAN_ERR_PROT_BIT1;
+				break;
+			case STAT_LEC_BIT0:
+				cf->data[2] |= CAN_ERR_PROT_BIT0;
+				break;
+			case STAT_LEC_CRC:
+				cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ;
+				break;
+			}
+		}
+	}
+
+	netif_rx(skb);
+
+	stats->rx_packets++;
+	stats->rx_bytes += cf->can_dlc;
+
+	return 0;
+}
+
+static int cc770_status_interrupt(struct net_device *dev)
+{
+	struct cc770_priv *priv = netdev_priv(dev);
+	u8 status;
+
+	status = cc770_read_reg(priv, status);
+	/* Reset the status register including RXOK and TXOK */
+	cc770_write_reg(priv, status, STAT_LEC_MASK);
+
+	if (status & (STAT_WARN | STAT_BOFF) ||
+	    (status & STAT_LEC_MASK) != STAT_LEC_MASK) {
+		cc770_err(dev, status);
+		return status & STAT_BOFF;
+	}
+
+	return 0;
+}
+
+static void cc770_rx_interrupt(struct net_device *dev, unsigned int o)
+{
+	struct cc770_priv *priv = netdev_priv(dev);
+	struct net_device_stats *stats = &dev->stats;
+	unsigned int mo = obj2msgobj(o);
+	u8 ctrl1;
+
+	while (1) {
+		ctrl1 = cc770_read_reg(priv, msgobj[mo].ctrl1);
+
+		if (!(ctrl1 & NEWDAT_SET))  {
+			/* Check for RTR if additional functions are enabled */
+			if (priv->control_normal_mode & CTRL_EAF) {
+				if (!(cc770_read_reg(priv, msgobj[mo].ctrl0) &
+				      INTPND_SET))
+					break;
+			} else {
+				break;
+			}
+		}
+
+		if (ctrl1 & MSGLST_SET) {
+			stats->rx_over_errors++;
+			stats->rx_errors++;
+		}
+		if (mo < MSGOBJ_LAST)
+			cc770_write_reg(priv, msgobj[mo].ctrl1,
+					NEWDAT_RES | MSGLST_RES |
+					TXRQST_UNC | RMTPND_UNC);
+		cc770_rx(dev, mo, ctrl1);
+
+		cc770_write_reg(priv, msgobj[mo].ctrl0,
+				MSGVAL_SET | TXIE_RES |
+				RXIE_SET | INTPND_RES);
+		cc770_write_reg(priv, msgobj[mo].ctrl1,
+				NEWDAT_RES | MSGLST_RES |
+				TXRQST_RES | RMTPND_RES);
+	}
+}
+
+static void cc770_rtr_interrupt(struct net_device *dev, unsigned int o)
+{
+	struct cc770_priv *priv = netdev_priv(dev);
+	unsigned int mo = obj2msgobj(o);
+	u8 ctrl0, ctrl1;
+
+	while (1) {
+		ctrl0 = cc770_read_reg(priv, msgobj[mo].ctrl0);
+		if (!(ctrl0 & INTPND_SET))
+			break;
+
+		ctrl1 = cc770_read_reg(priv, msgobj[mo].ctrl1);
+		cc770_rx(dev, mo, ctrl1);
+
+		cc770_write_reg(priv, msgobj[mo].ctrl0,
+				MSGVAL_SET | TXIE_RES |
+				RXIE_SET | INTPND_RES);
+		cc770_write_reg(priv, msgobj[mo].ctrl1,
+				NEWDAT_RES | CPUUPD_SET |
+				TXRQST_RES | RMTPND_RES);
+	}
+}
+
+static void cc770_tx_interrupt(struct net_device *dev, unsigned int o)
+{
+	struct cc770_priv *priv = netdev_priv(dev);
+	struct net_device_stats *stats = &dev->stats;
+	unsigned int mo = obj2msgobj(o);
+
+	/* Nothing more to send, switch off interrupts */
+	cc770_write_reg(priv, msgobj[mo].ctrl0,
+			MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES);
+	/*
+	 * We had some cases of repeated IRQ so make sure the
+	 * INT is acknowledged
+	 */
+	cc770_write_reg(priv, msgobj[mo].ctrl0,
+			MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);
+
+	stats->tx_packets++;
+	can_get_echo_skb(dev, 0);
+	netif_wake_queue(dev);
+}
+
+irqreturn_t cc770_interrupt(int irq, void *dev_id)
+{
+	struct net_device *dev = (struct net_device *)dev_id;
+	struct cc770_priv *priv = netdev_priv(dev);
+	u8 intid;
+	int o, n = 0;
+
+	/* Shared interrupts and IRQ off? */
+	if (priv->can.state == CAN_STATE_STOPPED)
+		return IRQ_NONE;
+
+	if (priv->pre_irq)
+		priv->pre_irq(priv);
+
+	while (n < CC770_MAX_IRQ) {
+		/* Read the highest pending interrupt request */
+		intid = cc770_read_reg(priv, interrupt);
+		if (!intid)
+			break;
+		n++;
+
+		if (intid == 1) {
+			/* Exit in case of bus-off */
+			if (cc770_status_interrupt(dev))
+				break;
+		} else {
+			o = intid2obj(intid);
+
+			if (o >= CC770_OBJ_MAX) {
+				netdev_err(dev, "Unexpected interrupt id %d\n",
+					   intid);
+				continue;
+			}
+
+			if (priv->obj_flags[o] & CC770_OBJ_FLAG_RTR)
+				cc770_rtr_interrupt(dev, o);
+			else if (priv->obj_flags[o] & CC770_OBJ_FLAG_RX)
+				cc770_rx_interrupt(dev, o);
+			else
+				cc770_tx_interrupt(dev, o);
+		}
+	}
+
+	if (priv->post_irq)
+		priv->post_irq(priv);
+
+	if (n >= CC770_MAX_IRQ)
+		netdev_dbg(dev, "%d messages handled in ISR", n);
+
+	return (n) ? IRQ_HANDLED : IRQ_NONE;
+}
+
+static int cc770_open(struct net_device *dev)
+{
+	struct cc770_priv *priv = netdev_priv(dev);
+	int err;
+
+	/* set chip into reset mode */
+	set_reset_mode(dev);
+
+	/* common open */
+	err = open_candev(dev);
+	if (err)
+		return err;
+
+	err = request_irq(dev->irq, &cc770_interrupt, priv->irq_flags,
+			  dev->name, (void *)dev);
+	if (err) {
+		close_candev(dev);
+		return -EAGAIN;
+	}
+
+	/* init and start chip */
+	cc770_start(dev);
+	priv->open_time = jiffies;
+
+	netif_start_queue(dev);
+
+	return 0;
+}
+
+static int cc770_close(struct net_device *dev)
+{
+	struct cc770_priv *priv = netdev_priv(dev);
+
+	netif_stop_queue(dev);
+	set_reset_mode(dev);
+
+	free_irq(dev->irq, (void *)dev);
+	close_candev(dev);
+
+	priv->open_time = 0;
+
+	return 0;
+}
+
+struct net_device *alloc_cc770dev(int sizeof_priv)
+{
+	struct net_device *dev;
+	struct cc770_priv *priv;
+
+	dev = alloc_candev(sizeof(struct cc770_priv) + sizeof_priv,
+			   CC770_ECHO_SKB_MAX);
+	if (!dev)
+		return NULL;
+
+	priv = netdev_priv(dev);
+
+	priv->dev = dev;
+	priv->can.bittiming_const = &cc770_bittiming_const;
+	priv->can.do_set_bittiming = cc770_set_bittiming;
+	priv->can.do_set_mode = cc770_set_mode;
+	priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
+
+	memcpy(priv->obj_flags, cc770_obj_flags, sizeof(cc770_obj_flags));
+
+	if (sizeof_priv)
+		priv->priv = (void *)priv + sizeof(struct cc770_priv);
+
+	return dev;
+}
+EXPORT_SYMBOL_GPL(alloc_cc770dev);
+
+void free_cc770dev(struct net_device *dev)
+{
+	free_candev(dev);
+}
+EXPORT_SYMBOL_GPL(free_cc770dev);
+
+static const struct net_device_ops cc770_netdev_ops = {
+	.ndo_open = cc770_open,
+	.ndo_stop = cc770_close,
+	.ndo_start_xmit = cc770_start_xmit,
+};
+
+int register_cc770dev(struct net_device *dev)
+{
+	struct cc770_priv *priv = netdev_priv(dev);
+
+	if (!cc770_probe_chip(dev))
+		return -ENODEV;
+
+	dev->netdev_ops = &cc770_netdev_ops;
+
+	dev->flags |= IFF_ECHO;	/* we support local echo */
+
+	/* Should we use additional functions? */
+	if (!i82527_compat && priv->control_normal_mode & CTRL_EAF) {
+		priv->control_normal_mode = CTRL_IE | CTRL_EAF | CTRL_EIE;
+		netdev_dbg(dev, "i82527 mode with additional functions\n");
+	} else {
+		priv->control_normal_mode = CTRL_IE | CTRL_EIE;
+		netdev_dbg(dev, "strict i82527 compatibility mode\n");
+	}
+
+	chipset_init(priv);
+	set_reset_mode(dev);
+
+	return register_candev(dev);
+}
+EXPORT_SYMBOL_GPL(register_cc770dev);
+
+void unregister_cc770dev(struct net_device *dev)
+{
+	set_reset_mode(dev);
+	unregister_candev(dev);
+}
+EXPORT_SYMBOL_GPL(unregister_cc770dev);
+
+static __init int cc770_init(void)
+{
+	if (msgobj15_eff) {
+		cc770_obj_flags[CC770_OBJ_RX0] |= CC770_OBJ_FLAG_EFF;
+		cc770_obj_flags[CC770_OBJ_RX1] &= ~CC770_OBJ_FLAG_EFF;
+	}
+
+	pr_info("%s CAN netdevice driver\n", DRV_NAME);
+
+	return 0;
+}
+module_init(cc770_init);
+
+static __exit void cc770_exit(void)
+{
+	pr_info("%s: driver removed\n", DRV_NAME);
+}
+module_exit(cc770_exit);
diff --git a/drivers/net/can/cc770/cc770.h b/drivers/net/can/cc770/cc770.h
new file mode 100644
index 0000000..c6b5800
--- /dev/null
+++ b/drivers/net/can/cc770/cc770.h
@@ -0,0 +1,234 @@
+/*
+ * cc770.h - Bosch CC770 and Intel AN82527 network device driver
+ *
+ * Copyright (C) 2009, 2011 Wolfgang Grandegger <wg@grandegger.com>
+ *
+ * Derived from the old Socket-CAN i82527 driver:
+ *
+ * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Volkswagen nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * Alternatively, provided that this notice is retained in full, this
+ * software may be distributed under the terms of the GNU General
+ * Public License ("GPL") version 2, in which case the provisions of the
+ * GPL apply INSTEAD OF those given above.
+ *
+ * The provided data structures and external interfaces from this code
+ * are not restricted to be used by modules with a GPL compatible license.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Send feedback to <socketcan-users@lists.berlios.de>
+ */
+
+#ifndef CC770_DEV_H
+#define CC770_DEV_H
+
+#include <linux/can/dev.h>
+
+struct cc770_msgobj {
+	u8 ctrl0;
+	u8 ctrl1;
+	u8 id[4];
+	u8 config;
+	u8 data[8];
+	u8 dontuse;		/* padding */
+} __attribute__ ((packed));
+
+struct cc770_regs {
+	union {
+		struct cc770_msgobj msgobj[16]; /* Message object 1..15 */
+		struct {
+			u8 control;		/* Control Register */
+			u8 status;		/* Status Register */
+			u8 cpu_interface;	/* CPU Interface Register */
+			u8 dontuse1;
+			u8 high_speed_read[2];	/* High Speed Read */
+			u8 global_mask_std[2];	/* Standard Global Mask */
+			u8 global_mask_ext[4];	/* Extended Global Mask */
+			u8 msg15_mask[4];	/* Message 15 Mask */
+			u8 dontuse2[15];
+			u8 clkout;		/* Clock Out Register */
+			u8 dontuse3[15];
+			u8 bus_config;		/* Bus Configuration Register */
+			u8 dontuse4[15];
+			u8 bit_timing_0;	/* Bit Timing Register byte 0 */
+			u8 dontuse5[15];
+			u8 bit_timing_1;	/* Bit Timing Register byte 1 */
+			u8 dontuse6[15];
+			u8 interrupt;		/* Interrupt Register */
+			u8 dontuse7[15];
+			u8 rx_error_counter;	/* Receive Error Counter */
+			u8 dontuse8[15];
+			u8 tx_error_counter;	/* Transmit Error Counter */
+			u8 dontuse9[31];
+			u8 p1_conf;
+			u8 dontuse10[15];
+			u8 p2_conf;
+			u8 dontuse11[15];
+			u8 p1_in;
+			u8 dontuse12[15];
+			u8 p2_in;
+			u8 dontuse13[15];
+			u8 p1_out;
+			u8 dontuse14[15];
+			u8 p2_out;
+			u8 dontuse15[15];
+			u8 serial_reset_addr;
+		};
+	};
+} __attribute__ ((packed));
+
+/* Control Register (0x00) */
+#define CTRL_INI	0x01	/* Initialization */
+#define CTRL_IE		0x02	/* Interrupt Enable */
+#define CTRL_SIE	0x04	/* Status Interrupt Enable */
+#define CTRL_EIE	0x08	/* Error Interrupt Enable */
+#define CTRL_EAF	0x20	/* Enable additional functions */
+#define CTRL_CCE	0x40	/* Change Configuration Enable */
+
+/* Status Register (0x01) */
+#define STAT_LEC_STUFF	0x01	/* Stuff error */
+#define STAT_LEC_FORM	0x02	/* Form error */
+#define STAT_LEC_ACK	0x03	/* Acknowledgement error */
+#define STAT_LEC_BIT1	0x04	/* Bit1 error */
+#define STAT_LEC_BIT0	0x05	/* Bit0 error */
+#define STAT_LEC_CRC	0x06	/* CRC error */
+#define STAT_LEC_MASK	0x07	/* Last Error Code mask */
+#define STAT_TXOK	0x08	/* Transmit Message Successfully */
+#define STAT_RXOK	0x10	/* Receive Message Successfully */
+#define STAT_WAKE	0x20	/* Wake Up Status */
+#define STAT_WARN	0x40	/* Warning Status */
+#define STAT_BOFF	0x80	/* Bus Off Status */
+
+/*
+ * CPU Interface Register (0x02)
+ * Clock Out Register (0x1f)
+ * Bus Configuration Register (0x2f)
+ *
+ * see include/linux/can/platform/cc770.h
+ */
+
+/* Message Control Register 0 (Base Address + 0x0) */
+#define INTPND_RES	0x01	/* No Interrupt pending */
+#define INTPND_SET	0x02	/* Interrupt pending */
+#define INTPND_UNC	0x03
+#define RXIE_RES	0x04	/* Receive Interrupt Disable */
+#define RXIE_SET	0x08	/* Receive Interrupt Enable */
+#define RXIE_UNC	0x0c
+#define TXIE_RES	0x10	/* Transmit Interrupt Disable */
+#define TXIE_SET	0x20	/* Transmit Interrupt Enable */
+#define TXIE_UNC	0x30
+#define MSGVAL_RES	0x40	/* Message Invalid */
+#define MSGVAL_SET	0x80	/* Message Valid */
+#define MSGVAL_UNC	0xc0
+
+/* Message Control Register 1 (Base Address + 0x01) */
+#define NEWDAT_RES	0x01	/* No New Data */
+#define NEWDAT_SET	0x02	/* New Data */
+#define NEWDAT_UNC	0x03
+#define MSGLST_RES	0x04	/* No Message Lost */
+#define MSGLST_SET	0x08	/* Message Lost */
+#define MSGLST_UNC	0x0c
+#define CPUUPD_RES	0x04	/* No CPU Updating */
+#define CPUUPD_SET	0x08	/* CPU Updating */
+#define CPUUPD_UNC	0x0c
+#define TXRQST_RES	0x10	/* No Transmission Request */
+#define TXRQST_SET	0x20	/* Transmission Request */
+#define TXRQST_UNC	0x30
+#define RMTPND_RES	0x40	/* No Remote Request Pending */
+#define RMTPND_SET	0x80	/* Remote Request Pending */
+#define RMTPND_UNC	0xc0
+
+/* Message Configuration Register (Base Address + 0x06) */
+#define MSGCFG_XTD	0x04	/* Extended Identifier */
+#define MSGCFG_DIR	0x08	/* Direction is Transmit */
+
+#define MSGOBJ_FIRST	1
+#define MSGOBJ_LAST	15
+
+#define CC770_IO_SIZE	0x100
+#define CC770_MAX_IRQ	20	/* max. number of interrupts handled in ISR */
+
+#define CC770_ECHO_SKB_MAX	1
+
+#define cc770_read_reg(priv, member)					\
+	priv->read_reg(priv, offsetof(struct cc770_regs, member))
+
+#define cc770_write_reg(priv, member, value)				\
+	priv->write_reg(priv, offsetof(struct cc770_regs, member), value)
+
+/*
+ * Message objects and flags used by this driver
+ */
+#define CC770_OBJ_FLAG_RX 	0x01
+#define CC770_OBJ_FLAG_RTR	0x02
+#define CC770_OBJ_FLAG_EFF	0x04
+
+enum {
+	CC770_OBJ_RX0 = 0,	/* for receiving normal messages */
+	CC770_OBJ_RX1,		/* for receiving normal messages */
+	CC770_OBJ_RX_RTR0,	/* for receiving remote transmission requests */
+	CC770_OBJ_RX_RTR1,	/* for receiving remote transmission requests */
+	CC770_OBJ_TX,		/* for sending messages */
+	CC770_OBJ_MAX
+};
+
+#define obj2msgobj(o)	(MSGOBJ_LAST - (o)) /* message object 11..15 */
+
+/*
+ * CC770 private data structure
+ */
+struct cc770_priv {
+	struct can_priv can;	/* must be the first member */
+	int open_time;
+	struct sk_buff *echo_skb;
+
+	/* the lower-layer is responsible for appropriate locking */
+	u8 (*read_reg)(const struct cc770_priv *priv, int reg);
+	void (*write_reg)(const struct cc770_priv *priv, int reg, u8 val);
+	void (*pre_irq)(const struct cc770_priv *priv);
+	void (*post_irq)(const struct cc770_priv *priv);
+
+	void *priv;		/* for board-specific data */
+	struct net_device *dev;
+
+	void __iomem *reg_base;	/* ioremap'ed address to registers */
+	unsigned long irq_flags;	/* for request_irq() */
+
+	unsigned char obj_flags[CC770_OBJ_MAX];
+	u8 control_normal_mode;	/* Control register for normal mode */
+	u8 cpu_interface;	/* CPU interface register */
+	u8 clkout;		/* Clock out register */
+	u8 bus_config;		/* Bus conffiguration register */
+};
+
+struct net_device *alloc_cc770dev(int sizeof_priv);
+void free_cc770dev(struct net_device *dev);
+int register_cc770dev(struct net_device *dev);
+void unregister_cc770dev(struct net_device *dev);
+
+#endif /* CC770_DEV_H */
diff --git a/include/linux/can/platform/cc770.h b/include/linux/can/platform/cc770.h
new file mode 100644
index 0000000..c4ed994
--- /dev/null
+++ b/include/linux/can/platform/cc770.h
@@ -0,0 +1,33 @@
+#ifndef _CAN_PLATFORM_CC770_H_
+#define _CAN_PLATFORM_CC770_H_
+
+/* CPU Interface Register (0x02) */
+#define CPUIF_CEN	0x01	/* Clock Out Enable */
+#define CPUIF_MUX	0x04	/* Multiplex */
+#define CPUIF_SLP	0x08	/* Sleep */
+#define CPUIF_PWD	0x10	/* Power Down Mode */
+#define CPUIF_DMC	0x20	/* Divide Memory Clock */
+#define CPUIF_DSC	0x40	/* Divide System Clock */
+#define CPUIF_RST	0x80	/* Hardware Reset Status */
+
+/* Clock Out Register (0x1f) */
+#define CLKOUT_CD_MASK  0x0f	/* Clock Divider mask */
+#define CLKOUT_SL_MASK	0x30	/* Slew Rate mask */
+#define CLKOUT_SL_SHIFT	4
+
+/* Bus Configuration Register (0x2f) */
+#define BUSCFG_DR0	0x01	/* Disconnect RX0 Input / Select RX input */
+#define BUSCFG_DR1	0x02	/* Disconnect RX1 Input / Silent mode */
+#define BUSCFG_DT1	0x08	/* Disconnect TX1 Output */
+#define BUSCFG_POL	0x20	/* Polarity dominant or recessive */
+#define BUSCFG_CBY	0x40	/* Input Comparator Bypass */
+
+struct cc770_platform_data {
+	u32 osc_freq;	/* CAN bus oscillator frequency in Hz */
+
+	u8 cir;	 	/* CPU Interface Register */
+	u8 cor;		/* Clock Out Register */
+	u8 bcr;		/* Bus Configuration Register */
+};
+
+#endif	/* !_CAN_PLATFORM_CC770_H_ */
-- 
1.7.4.1

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

* [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2011-11-25  9:43 [PATCH net-next v2 0/4] can: cc770: add support for the Bosch CC770 and Intel AN82527 Wolfgang Grandegger
  2011-11-25  9:43 ` [PATCH net-next v2 1/4] can: cc770: add driver core " Wolfgang Grandegger
@ 2011-11-25  9:43 ` Wolfgang Grandegger
       [not found]   ` <1322214204-1121-3-git-send-email-wg-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
  2011-11-28 12:09   ` Marc Kleine-Budde
  2011-11-25  9:43 ` [PATCH net-next v2 3/4] can: cc770: add platform " Wolfgang Grandegger
  2011-11-25  9:43 ` [PATCH net-next v2 4/4] powerpc: tqm8548/tqm8xx: add and update CAN device nodes Wolfgang Grandegger
  3 siblings, 2 replies; 66+ messages in thread
From: Wolfgang Grandegger @ 2011-11-25  9:43 UTC (permalink / raw)
  To: netdev
  Cc: linux-can, socketcan-users, IreneV, Stanislav Yelenskiy,
	Wolfgang Grandegger

This patch adds support for legacy Bosch CC770 and Intel AN82527 CAN
controllers on the ISA or PC-104 bus. The I/O port or memory address
and the IRQ number must be specified via module parameters:

  insmod cc770_isa.ko port=0x310,0x380 irq=7,11

for ISA devices using I/O ports or:

  insmod cc770_isa.ko mem=0xd1000,0xd1000 irq=7,11

for memory mapped ISA devices.

Indirect access via address and data port is supported as well:

  insmod cc770_isa.ko port=0x310,0x380 indirect=1 irq=7,11

Furthermore, the following mode parameter can be defined:

  clk: External oscillator clock frequency (default=16000000 [16 MHz])
  cir: CPU interface register (default=0x40 [DSC])
  ocr, Bus configuration register (default=0x40 [CBY])
  cor, Clockout register (default=0x00)

Note: for clk, cir, bcr and cor, the first argument re-defines the
default for all other devices, e.g.:

  insmod cc770_isa.ko mem=0xd1000,0xd1000 irq=7,11 clk=24000000

is equivalent to

  insmod cc770_isa.ko mem=0xd1000,0xd1000 irq=7,11 clk=24000000,24000000

Signed-off-by: Wolfgang Grandegger <wg@grandegger.com>
---
 drivers/net/can/cc770/Kconfig     |   11 ++
 drivers/net/can/cc770/Makefile    |    1 +
 drivers/net/can/cc770/cc770_isa.c |  336 +++++++++++++++++++++++++++++++++++++
 3 files changed, 348 insertions(+), 0 deletions(-)
 create mode 100644 drivers/net/can/cc770/cc770_isa.c

diff --git a/drivers/net/can/cc770/Kconfig b/drivers/net/can/cc770/Kconfig
index 225131b..28e4d48 100644
--- a/drivers/net/can/cc770/Kconfig
+++ b/drivers/net/can/cc770/Kconfig
@@ -1,3 +1,14 @@
 menuconfig CAN_CC770
 	tristate "Bosch CC770 and Intel AN82527 devices"
 	depends on CAN_DEV && HAS_IOMEM
+
+if CAN_CC770
+
+config CAN_CC770_ISA
+	tristate "ISA Bus based legacy CC770 driver"
+	---help---
+	  This driver adds legacy support for CC770 and AN82527 chips
+	  connected to the ISA bus using I/O port, memory mapped or
+	  indirect access.
+
+endif
diff --git a/drivers/net/can/cc770/Makefile b/drivers/net/can/cc770/Makefile
index 34e8180..872ecff 100644
--- a/drivers/net/can/cc770/Makefile
+++ b/drivers/net/can/cc770/Makefile
@@ -3,5 +3,6 @@
 #
 
 obj-$(CONFIG_CAN_CC770) += cc770.o
+obj-$(CONFIG_CAN_CC770_ISA) += cc770_isa.o
 
 ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/cc770/cc770_isa.c b/drivers/net/can/cc770/cc770_isa.c
new file mode 100644
index 0000000..3aaecd5
--- /dev/null
+++ b/drivers/net/can/cc770/cc770_isa.c
@@ -0,0 +1,336 @@
+/*
+ * Copyright (C) 2009, 2011 Wolfgang Grandegger <wg@grandegger.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/can.h>
+#include <linux/can/dev.h>
+
+#include "cc770.h"
+
+#define DRV_NAME "cc770_isa"
+
+#define MAXDEV 8
+
+MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
+MODULE_DESCRIPTION("Socket-CAN driver for CC770 on the ISA bus");
+MODULE_LICENSE("GPL v2");
+
+#define CLK_DEFAULT	16000000	/* 16 MHz */
+#define COR_DEFAULT	0x00
+#define BCR_DEFAULT	BUSCFG_CBY
+
+static unsigned long port[MAXDEV];
+static unsigned long mem[MAXDEV];
+static int __devinitdata irq[MAXDEV];
+static int __devinitdata clk[MAXDEV];
+static u8 __devinitdata cir[MAXDEV] = {[0 ... (MAXDEV - 1)] = 0xff};
+static u8 __devinitdata cor[MAXDEV] = {[0 ... (MAXDEV - 1)] = 0xff};
+static u8 __devinitdata bcr[MAXDEV] = {[0 ... (MAXDEV - 1)] = 0xff};
+static int __devinitdata indirect[MAXDEV] = {[0 ... (MAXDEV - 1)] = -1};
+
+module_param_array(port, ulong, NULL, S_IRUGO);
+MODULE_PARM_DESC(port, "I/O port number");
+
+module_param_array(mem, ulong, NULL, S_IRUGO);
+MODULE_PARM_DESC(mem, "I/O memory address");
+
+module_param_array(indirect, int, NULL, S_IRUGO);
+MODULE_PARM_DESC(indirect, "Indirect access via address and data port");
+
+module_param_array(irq, int, NULL, S_IRUGO);
+MODULE_PARM_DESC(irq, "IRQ number");
+
+module_param_array(clk, int, NULL, S_IRUGO);
+MODULE_PARM_DESC(clk, "External oscillator clock frequency "
+		 "(default=16000000 [16 MHz])");
+
+module_param_array(cir, byte, NULL, S_IRUGO);
+MODULE_PARM_DESC(cir, "CPU interface register (default=0x40 [DSC])");
+
+module_param_array(cor, byte, NULL, S_IRUGO);
+MODULE_PARM_DESC(cor, "Clockout register (default=0x00)");
+
+module_param_array(bcr, byte, NULL, S_IRUGO);
+MODULE_PARM_DESC(bcr, "Bus configuration register (default=0x40 [CBY])");
+
+#define CC770_IOSIZE          0x20
+#define CC770_IOSIZE_INDIRECT 0x02
+
+static struct platform_device *cc770_isa_devs[MAXDEV];
+
+static u8 cc770_isa_mem_read_reg(const struct cc770_priv *priv, int reg)
+{
+	return readb(priv->reg_base + reg);
+}
+
+static void cc770_isa_mem_write_reg(const struct cc770_priv *priv,
+				      int reg, u8 val)
+{
+	writeb(val, priv->reg_base + reg);
+}
+
+static u8 cc770_isa_port_read_reg(const struct cc770_priv *priv, int reg)
+{
+	return inb((unsigned long)priv->reg_base + reg);
+}
+
+static void cc770_isa_port_write_reg(const struct cc770_priv *priv,
+				       int reg, u8 val)
+{
+	outb(val, (unsigned long)priv->reg_base + reg);
+}
+
+static u8 cc770_isa_port_read_reg_indirect(const struct cc770_priv *priv,
+					     int reg)
+{
+	unsigned long base = (unsigned long)priv->reg_base;
+
+	outb(reg, base);
+	return inb(base + 1);
+}
+
+static void cc770_isa_port_write_reg_indirect(const struct cc770_priv *priv,
+						int reg, u8 val)
+{
+	unsigned long base = (unsigned long)priv->reg_base;
+
+	outb(reg, base);
+	outb(val, base + 1);
+}
+
+static int __devinit cc770_isa_probe(struct platform_device *pdev)
+{
+	struct net_device *dev;
+	struct cc770_priv *priv;
+	void __iomem *base = NULL;
+	int iosize = CC770_IOSIZE;
+	int idx = pdev->id;
+	int err;
+	u32 clktmp;
+
+	dev_dbg(&pdev->dev, "probing idx=%d: port=%#lx, mem=%#lx, irq=%d\n",
+		idx, port[idx], mem[idx], irq[idx]);
+	if (mem[idx]) {
+		if (!request_mem_region(mem[idx], iosize, DRV_NAME)) {
+			err = -EBUSY;
+			goto exit;
+		}
+		base = ioremap_nocache(mem[idx], iosize);
+		if (!base) {
+			err = -ENOMEM;
+			goto exit_release;
+		}
+	} else {
+		if (indirect[idx] > 0 ||
+		    (indirect[idx] == -1 && indirect[0] > 0))
+			iosize = CC770_IOSIZE_INDIRECT;
+		if (!request_region(port[idx], iosize, DRV_NAME)) {
+			err = -EBUSY;
+			goto exit;
+		}
+	}
+
+	dev = alloc_cc770dev(0);
+	if (!dev) {
+		err = -ENOMEM;
+		goto exit_unmap;
+	}
+	priv = netdev_priv(dev);
+
+	dev->irq = irq[idx];
+	priv->irq_flags = IRQF_SHARED;
+	if (mem[idx]) {
+		priv->reg_base = base;
+		dev->base_addr = mem[idx];
+		priv->read_reg = cc770_isa_mem_read_reg;
+		priv->write_reg = cc770_isa_mem_write_reg;
+	} else {
+		priv->reg_base = (void __iomem *)port[idx];
+		dev->base_addr = port[idx];
+
+		if (iosize == CC770_IOSIZE_INDIRECT) {
+			priv->read_reg = cc770_isa_port_read_reg_indirect;
+			priv->write_reg = cc770_isa_port_write_reg_indirect;
+		} else {
+			priv->read_reg = cc770_isa_port_read_reg;
+			priv->write_reg = cc770_isa_port_write_reg;
+		}
+	}
+
+	if (clk[idx])
+		clktmp = clk[idx];
+	else if (clk[0])
+		clktmp = clk[0];
+	else
+		clktmp = CLK_DEFAULT;
+	priv->can.clock.freq = clktmp;
+
+	if (cir[idx] != 0xff) {
+		priv->cpu_interface = cir[idx] & 0xff;
+	} else if (cir[0] != 0xff) {
+		priv->cpu_interface = cir[0] & 0xff;
+	} else {
+		/* The system clock may not exceed 10 MHz */
+		if (clktmp > 10000000) {
+			priv->cpu_interface |= CPUIF_DSC;
+			clktmp /= 2;
+		}
+		/* The memory clock may not exceed 8 MHz */
+		if (clktmp > 8000000)
+			priv->cpu_interface |= CPUIF_DMC;
+	}
+
+	if (priv->cpu_interface & CPUIF_DSC)
+		priv->can.clock.freq /= 2;
+
+	if (bcr[idx] != 0xff)
+		priv->bus_config = bcr[idx] & 0xff;
+	else if (bcr[0] != 0xff)
+		priv->bus_config = bcr[0] & 0xff;
+	else
+		priv->bus_config = BCR_DEFAULT;
+
+	if (cor[idx] != 0xff)
+		priv->clkout = cor[idx];
+	else if (cor[0] != 0xff)
+		priv->clkout = cor[0] & 0xff;
+	else
+		priv->clkout = COR_DEFAULT;
+
+	dev_set_drvdata(&pdev->dev, dev);
+	SET_NETDEV_DEV(dev, &pdev->dev);
+
+	err = register_cc770dev(dev);
+	if (err) {
+		dev_err(&pdev->dev, "registering %s failed (err=%d)\n",
+			DRV_NAME, err);
+		goto exit_unmap;
+	}
+
+	dev_info(&pdev->dev, "%s device registered (reg_base=0x%p, irq=%d)\n",
+		 DRV_NAME, priv->reg_base, dev->irq);
+	return 0;
+
+ exit_unmap:
+	if (mem[idx])
+		iounmap(base);
+ exit_release:
+	if (mem[idx])
+		release_mem_region(mem[idx], iosize);
+	else
+		release_region(port[idx], iosize);
+ exit:
+	return err;
+}
+
+static int __devexit cc770_isa_remove(struct platform_device *pdev)
+{
+	struct net_device *dev = dev_get_drvdata(&pdev->dev);
+	struct cc770_priv *priv = netdev_priv(dev);
+	int idx = pdev->id;
+
+	unregister_cc770dev(dev);
+	dev_set_drvdata(&pdev->dev, NULL);
+
+	if (mem[idx]) {
+		iounmap(priv->reg_base);
+		release_mem_region(mem[idx], CC770_IOSIZE);
+	} else {
+		if (priv->read_reg == cc770_isa_port_read_reg_indirect)
+			release_region(port[idx], CC770_IOSIZE_INDIRECT);
+		else
+			release_region(port[idx], CC770_IOSIZE);
+	}
+	free_cc770dev(dev);
+
+	return 0;
+}
+
+static struct platform_driver cc770_isa_driver = {
+	.probe = cc770_isa_probe,
+	.remove = __devexit_p(cc770_isa_remove),
+	.driver = {
+		.name = DRV_NAME,
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init cc770_isa_init(void)
+{
+	int idx, err;
+
+	for (idx = 0; idx < MAXDEV; idx++) {
+		if ((port[idx] || mem[idx]) && irq[idx]) {
+			cc770_isa_devs[idx] =
+				platform_device_alloc(DRV_NAME, idx);
+			if (!cc770_isa_devs[idx]) {
+				err = -ENOMEM;
+				goto exit_free_devices;
+			}
+			err = platform_device_add(cc770_isa_devs[idx]);
+			if (err) {
+				platform_device_put(cc770_isa_devs[idx]);
+				goto exit_free_devices;
+			}
+			pr_debug("%s: platform device %d: port=%#lx, mem=%#lx, "
+				 "irq=%d\n",
+				 DRV_NAME, idx, port[idx], mem[idx], irq[idx]);
+		} else if (idx == 0 || port[idx] || mem[idx]) {
+				pr_err("%s: insufficient parameters supplied\n",
+				       DRV_NAME);
+				err = -EINVAL;
+				goto exit_free_devices;
+		}
+	}
+
+	err = platform_driver_register(&cc770_isa_driver);
+	if (err)
+		goto exit_free_devices;
+
+	pr_info("Legacy %s driver for max. %d devices registered\n",
+		DRV_NAME, MAXDEV);
+
+	return 0;
+
+exit_free_devices:
+	while (--idx >= 0) {
+		if (cc770_isa_devs[idx])
+			platform_device_unregister(cc770_isa_devs[idx]);
+	}
+
+	return err;
+}
+module_init(cc770_isa_init);
+
+static void __exit cc770_isa_exit(void)
+{
+	int idx;
+
+	platform_driver_unregister(&cc770_isa_driver);
+	for (idx = 0; idx < MAXDEV; idx++) {
+		if (cc770_isa_devs[idx])
+			platform_device_unregister(cc770_isa_devs[idx]);
+	}
+}
+module_exit(cc770_isa_exit);
-- 
1.7.4.1

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

* [PATCH net-next v2 3/4] can: cc770: add platform bus driver for the CC770 and AN82527
  2011-11-25  9:43 [PATCH net-next v2 0/4] can: cc770: add support for the Bosch CC770 and Intel AN82527 Wolfgang Grandegger
  2011-11-25  9:43 ` [PATCH net-next v2 1/4] can: cc770: add driver core " Wolfgang Grandegger
  2011-11-25  9:43 ` [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527 Wolfgang Grandegger
@ 2011-11-25  9:43 ` Wolfgang Grandegger
  2011-11-25  9:43 ` [PATCH net-next v2 4/4] powerpc: tqm8548/tqm8xx: add and update CAN device nodes Wolfgang Grandegger
  3 siblings, 0 replies; 66+ messages in thread
From: Wolfgang Grandegger @ 2011-11-25  9:43 UTC (permalink / raw)
  To: netdev
  Cc: linux-can, socketcan-users, IreneV, Stanislav Yelenskiy,
	Wolfgang Grandegger, Devicetree-discuss, linuxppc-dev,
	Kumar Gala

This driver works with both, static platform data and device tree
bindings. It has been tested on a TQM855L board with two AN82527
CAN controllers on the local bus.

CC: Devicetree-discuss@lists.ozlabs.org
CC: linuxppc-dev@ozlabs.org
CC: Kumar Gala <galak@kernel.crashing.org>
Signed-off-by: Wolfgang Grandegger <wg@grandegger.com>
---
 .../devicetree/bindings/net/can/cc770.txt          |   56 ++++
 drivers/net/can/cc770/Kconfig                      |    7 +
 drivers/net/can/cc770/Makefile                     |    1 +
 drivers/net/can/cc770/cc770_platform.c             |  289 ++++++++++++++++++++
 4 files changed, 353 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/can/cc770.txt
 create mode 100644 drivers/net/can/cc770/cc770_platform.c

diff --git a/Documentation/devicetree/bindings/net/can/cc770.txt b/Documentation/devicetree/bindings/net/can/cc770.txt
new file mode 100644
index 0000000..01e282d
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/can/cc770.txt
@@ -0,0 +1,56 @@
+Memory mapped Bosch CC770 and Intel AN82527 CAN controller
+
+Note: The CC770 is a CAN controller from Bosch, which is 100%
+compatible with the old AN82527 from Intel, but with "bugs" being fixed.
+
+Required properties:
+
+- compatible : should be "bosch,cc770" for the CC770 and "intc,82527"
+	for the AN82527.
+
+- reg : should specify the chip select, address offset and size required
+	to map the registers of the controller. The size is usually 0x80.
+
+- interrupts : property with a value describing the interrupt source
+	(number and sensitivity) required for the controller.
+
+Optional properties:
+
+- bosch,external-clock-frequency : frequency of the external oscillator
+	clock in Hz. Note that the internal clock frequency used by the
+	controller is half of that value. If not specified, a default
+	value of 16000000 (16 MHz) is used.
+
+- bosch,clock-out-frequency : slock frequency in Hz on the CLKOUT pin.
+	If not specified or if the specified value is 0, the CLKOUT pin
+	will be disabled.
+
+- bosch,slew-rate : slew rate of the CLKOUT signal. If not specified,
+	a resonable value will be calculated.
+
+- bosch,disconnect-rx0-input : see data sheet.
+
+- bosch,disconnect-rx1-input : see data sheet.
+
+- bosch,disconnect-tx1-output : see data sheet.
+
+- bosch,polarity-dominant : see data sheet.
+
+- bosch,divide-memory-clock : see data sheet.
+
+- bosch,iso-low-speed-mux : see data sheet.
+
+For further information, please have a look to the CC770 or AN82527.
+
+Examples:
+
+can@3,100 {
+	compatible = "bosch,cc770";
+	reg = <3 0x100 0x80>;
+	interrupts = <2 0>;
+	interrupt-parent = <&mpic>;
+	bosch,external-clock-frequency = <16000000>;
+};
+
+
+
diff --git a/drivers/net/can/cc770/Kconfig b/drivers/net/can/cc770/Kconfig
index 28e4d48..22c07a8 100644
--- a/drivers/net/can/cc770/Kconfig
+++ b/drivers/net/can/cc770/Kconfig
@@ -11,4 +11,11 @@ config CAN_CC770_ISA
 	  connected to the ISA bus using I/O port, memory mapped or
 	  indirect access.
 
+config CAN_CC770_PLATFORM
+	tristate "Generic Platform Bus based CC770 driver"
+	---help---
+	  This driver adds support for the CC770 and AN82527 chips
+	  connected to the "platform bus" (Linux abstraction for directly
+	  to the processor attached devices).
+
 endif
diff --git a/drivers/net/can/cc770/Makefile b/drivers/net/can/cc770/Makefile
index 872ecff..9fb8321 100644
--- a/drivers/net/can/cc770/Makefile
+++ b/drivers/net/can/cc770/Makefile
@@ -4,5 +4,6 @@
 
 obj-$(CONFIG_CAN_CC770) += cc770.o
 obj-$(CONFIG_CAN_CC770_ISA) += cc770_isa.o
+obj-$(CONFIG_CAN_CC770_PLATFORM) += cc770_platform.o
 
 ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/cc770/cc770_platform.c b/drivers/net/can/cc770/cc770_platform.c
new file mode 100644
index 0000000..a33f91d
--- /dev/null
+++ b/drivers/net/can/cc770/cc770_platform.c
@@ -0,0 +1,289 @@
+/*
+ * Driver for CC770 and AN82527 CAN controllers on the platform bus
+ *
+ * Copyright (C) 2009, 2011 Wolfgang Grandegger <wg@grandegger.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * If platform data are used you should have similar definitions
+ * in your board-specific code:
+ *
+ *   static struct cc770_platform_data myboard_cc770_pdata = {
+ *           .osc_freq = 16000000,
+ *           .cir = 0x41,
+ *           .cor = 0x20,
+ *           .bcr = 0x40,
+ *   };
+ *
+ * Please see include/linux/can/platform/cc770.h for description of
+ * above fields.
+ *
+ * If the device tree is used, you need a CAN node definition in your
+ * DTS file similar to:
+ *
+ *   can@3,100 {
+ *           compatible = "bosch,cc770";
+ *           reg = <3 0x100 0x80>;
+ *           interrupts = <2 0>;
+ *           interrupt-parent = <&mpic>;
+ *           bosch,external-clock-frequency = <16000000>;
+ *   };
+ *
+ * See "Documentation/devicetree/bindings/net/can/cc770.txt" for further
+ * information.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/platform/cc770.h>
+
+#include <linux/of_platform.h>
+
+#include "cc770.h"
+
+#define DRV_NAME "cc770_platform"
+
+MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
+MODULE_DESCRIPTION("Socket-CAN driver for CC770 on the platform bus");
+MODULE_LICENSE("GPL v2");
+
+#define CC770_PLATFORM_CAN_CLOCK  16000000
+
+static u8 cc770_platform_read_reg(const struct cc770_priv *priv, int reg)
+{
+	return in_8(priv->reg_base + reg);
+}
+
+static void cc770_platform_write_reg(const struct cc770_priv *priv, int reg,
+				     u8 val)
+{
+	out_8(priv->reg_base + reg, val);
+}
+
+static int __devinit cc770_get_of_node_data(struct platform_device *pdev,
+					    struct cc770_priv *priv)
+{
+	struct device_node *np = pdev->dev.of_node;
+	const u32 *prop;
+	int prop_size;
+	u32 clkext;
+
+	prop = of_get_property(np, "bosch,external-clock-frequency",
+			       &prop_size);
+	if (prop && (prop_size ==  sizeof(u32)))
+		clkext = *prop;
+	else
+		clkext = CC770_PLATFORM_CAN_CLOCK; /* default */
+	priv->can.clock.freq = clkext;
+
+	/* The system clock may not exceed 10 MHz */
+	if (priv->can.clock.freq > 10000000) {
+		priv->cpu_interface |= CPUIF_DSC;
+		priv->can.clock.freq /= 2;
+	}
+
+	/* The memory clock may not exceed 8 MHz */
+	if (priv->can.clock.freq > 8000000)
+		priv->cpu_interface |= CPUIF_DMC;
+
+	if (of_get_property(np, "bosch,divide-memory-clock", NULL))
+		priv->cpu_interface |= CPUIF_DMC;
+	if (of_get_property(np, "bosch,iso-low-speed-mux", NULL))
+		priv->cpu_interface |= CPUIF_MUX;
+
+	if (!of_get_property(np, "bosch,no-comperator-bypass", NULL))
+		priv->bus_config |= BUSCFG_CBY;
+	if (of_get_property(np, "bosch,disconnect-rx0-input", NULL))
+		priv->bus_config |= BUSCFG_DR0;
+	if (of_get_property(np, "bosch,disconnect-rx1-input", NULL))
+		priv->bus_config |= BUSCFG_DR1;
+	if (of_get_property(np, "bosch,disconnect-tx1-output", NULL))
+		priv->bus_config |= BUSCFG_DT1;
+	if (of_get_property(np, "bosch,polarity-dominant", NULL))
+		priv->bus_config |= BUSCFG_POL;
+
+	prop = of_get_property(np, "bosch,clock-out-frequency", &prop_size);
+	if (prop && (prop_size == sizeof(u32)) && *prop > 0) {
+		u32 cdv = clkext / *prop;
+		int slew;
+
+		if (cdv > 0 && cdv < 16) {
+			priv->cpu_interface |= CPUIF_CEN;
+			priv->clkout |= (cdv - 1) & CLKOUT_CD_MASK;
+
+			prop = of_get_property(np, "bosch,slew-rate",
+					       &prop_size);
+			if (prop && (prop_size == sizeof(u32))) {
+				slew = *prop;
+			} else {
+				/* Determine default slew rate */
+				slew = (CLKOUT_SL_MASK >>
+					CLKOUT_SL_SHIFT) -
+					((cdv * clkext - 1) / 8000000);
+				if (slew < 0)
+					slew = 0;
+			}
+			priv->clkout |= (slew << CLKOUT_SL_SHIFT) &
+				CLKOUT_SL_MASK;
+		} else {
+			dev_dbg(&pdev->dev, "invalid clock-out-frequency\n");
+		}
+	}
+
+	return 0;
+}
+
+static int __devinit cc770_get_platform_data(struct platform_device *pdev,
+					     struct cc770_priv *priv)
+{
+
+	struct cc770_platform_data *pdata = pdev->dev.platform_data;
+
+	priv->can.clock.freq = pdata->osc_freq;
+	if (priv->cpu_interface | CPUIF_DSC)
+		priv->can.clock.freq /= 2;
+	priv->clkout = pdata->cor;
+	priv->bus_config = pdata->bcr;
+	priv->cpu_interface = pdata->cir;
+
+	return 0;
+}
+
+static int __devinit cc770_platform_probe(struct platform_device *pdev)
+{
+	struct net_device *dev;
+	struct cc770_priv *priv;
+	struct resource *mem;
+	resource_size_t mem_size;
+	void __iomem *base;
+	int err, irq;
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	irq = platform_get_irq(pdev, 0);
+	if (!mem || irq <= 0)
+		return -ENODEV;
+
+	mem_size = resource_size(mem);
+	if (!request_mem_region(mem->start, mem_size, pdev->name))
+		return -EBUSY;
+
+	base = ioremap(mem->start, mem_size);
+	if (!base) {
+		err = -ENOMEM;
+		goto exit_release_mem;
+	}
+
+	dev = alloc_cc770dev(0);
+	if (!dev) {
+		err = -ENOMEM;
+		goto exit_unmap_mem;
+	}
+
+	dev->irq = irq;
+	priv = netdev_priv(dev);
+	priv->read_reg = cc770_platform_read_reg;
+	priv->write_reg = cc770_platform_write_reg;
+	priv->irq_flags = IRQF_SHARED;
+	priv->reg_base = base;
+
+	if (pdev->dev.of_node)
+		err = cc770_get_of_node_data(pdev, priv);
+	else if (pdev->dev.platform_data)
+		err = cc770_get_platform_data(pdev, priv);
+	else
+		err = -ENODEV;
+	if (err)
+		goto exit_free_cc770;
+
+	dev_dbg(&pdev->dev,
+		 "reg_base=0x%p irq=%d clock=%d cpu_interface=0x%02x "
+		 "bus_config=0x%02x clkout=0x%02x\n",
+		 priv->reg_base, dev->irq, priv->can.clock.freq,
+		 priv->cpu_interface, priv->bus_config, priv->clkout);
+
+	dev_set_drvdata(&pdev->dev, dev);
+	SET_NETDEV_DEV(dev, &pdev->dev);
+
+	err = register_cc770dev(dev);
+	if (err) {
+		dev_err(&pdev->dev,
+			"couldn't register CC700 device (err=%d)\n", err);
+		goto exit_free_cc770;
+	}
+
+	return 0;
+
+exit_free_cc770:
+	free_cc770dev(dev);
+exit_unmap_mem:
+	iounmap(base);
+exit_release_mem:
+	release_mem_region(mem->start, mem_size);
+
+	return err;
+}
+
+static int __devexit cc770_platform_remove(struct platform_device *pdev)
+{
+	struct net_device *dev = dev_get_drvdata(&pdev->dev);
+	struct cc770_priv *priv = netdev_priv(dev);
+	struct resource *mem;
+
+	unregister_cc770dev(dev);
+	iounmap(priv->reg_base);
+	free_cc770dev(dev);
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (mem)
+		release_mem_region(mem->start, resource_size(mem));
+	else
+		dev_err(&pdev->dev, "couldn't release mem region");
+
+	return 0;
+}
+
+static struct of_device_id __devinitdata cc770_platform_table[] = {
+	{.compatible = "bosch,cc770"}, /* CC770 from Bosch */
+	{.compatible = "intc,82527"},  /* AN82527 from Intel CP */
+	{},
+};
+
+static struct platform_driver cc770_platform_driver = {
+	.driver = {
+		.name = DRV_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = cc770_platform_table,
+	},
+	.probe = cc770_platform_probe,
+	.remove = __devexit_p(cc770_platform_remove),
+};
+
+static int __init cc770_platform_init(void)
+{
+	return platform_driver_register(&cc770_platform_driver);
+}
+module_init(cc770_platform_init);
+
+static void __exit cc770_platform_exit(void)
+{
+	platform_driver_unregister(&cc770_platform_driver);
+}
+module_exit(cc770_platform_exit);
-- 
1.7.4.1


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

* [PATCH net-next v2 4/4] powerpc: tqm8548/tqm8xx: add and update CAN device nodes
  2011-11-25  9:43 [PATCH net-next v2 0/4] can: cc770: add support for the Bosch CC770 and Intel AN82527 Wolfgang Grandegger
                   ` (2 preceding siblings ...)
  2011-11-25  9:43 ` [PATCH net-next v2 3/4] can: cc770: add platform " Wolfgang Grandegger
@ 2011-11-25  9:43 ` Wolfgang Grandegger
  3 siblings, 0 replies; 66+ messages in thread
From: Wolfgang Grandegger @ 2011-11-25  9:43 UTC (permalink / raw)
  To: netdev
  Cc: linux-can, socketcan-users, IreneV, Stanislav Yelenskiy,
	Wolfgang Grandegger, devicetree-discuss, linuxppc-dev,
	Kumar Gala

This patch enables or updates support for the CC770 and AN82527
CAN controller on the TQM8548 and TQM8xx boards.

CC: devicetree-discuss@lists.ozlabs.org
CC: linuxppc-dev@ozlabs.org
CC: Kumar Gala <galak@kernel.crashing.org>
Signed-off-by: Wolfgang Grandegger <wg@grandegger.com>
---
 arch/powerpc/boot/dts/tqm8548-bigflash.dts |   19 ++++++++++++++-----
 arch/powerpc/boot/dts/tqm8548.dts          |   19 ++++++++++++++-----
 arch/powerpc/boot/dts/tqm8xx.dts           |   25 +++++++++++++++++++++++++
 3 files changed, 53 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/boot/dts/tqm8548-bigflash.dts b/arch/powerpc/boot/dts/tqm8548-bigflash.dts
index 9452c3c..d918752 100644
--- a/arch/powerpc/boot/dts/tqm8548-bigflash.dts
+++ b/arch/powerpc/boot/dts/tqm8548-bigflash.dts
@@ -352,7 +352,7 @@
 		ranges = <
 			0 0x0 0xfc000000 0x04000000	// NOR FLASH bank 1
 			1 0x0 0xf8000000 0x08000000	// NOR FLASH bank 0
-			2 0x0 0xa3000000 0x00008000	// CAN (2 x i82527)
+			2 0x0 0xa3000000 0x00008000	// CAN (2 x CC770)
 			3 0x0 0xa3010000 0x00008000	// NAND FLASH
 
 		>;
@@ -393,18 +393,27 @@
 		};
 
 		/* Note: CAN support needs be enabled in U-Boot */
-		can0@2,0 {
-			compatible = "intel,82527"; // Bosch CC770
+		can@2,0 {
+			compatible = "bosch,cc770"; // Bosch CC770
 			reg = <2 0x0 0x100>;
 			interrupts = <4 1>;
 			interrupt-parent = <&mpic>;
+			bosch,external-clock-frequency = <16000000>;
+			bosch,disconnect-rx1-input;
+			bosch,disconnect-tx1-output;
+			bosch,iso-low-speed-mux;
+			bosch,clock-out-frequency = <16000000>;
 		};
 
-		can1@2,100 {
-			compatible = "intel,82527"; // Bosch CC770
+		can@2,100 {
+			compatible = "bosch,cc770"; // Bosch CC770
 			reg = <2 0x100 0x100>;
 			interrupts = <4 1>;
 			interrupt-parent = <&mpic>;
+			bosch,external-clock-frequency = <16000000>;
+			bosch,disconnect-rx1-input;
+			bosch,disconnect-tx1-output;
+			bosch,iso-low-speed-mux;
 		};
 
 		/* Note: NAND support needs to be enabled in U-Boot */
diff --git a/arch/powerpc/boot/dts/tqm8548.dts b/arch/powerpc/boot/dts/tqm8548.dts
index 619776f..988d887 100644
--- a/arch/powerpc/boot/dts/tqm8548.dts
+++ b/arch/powerpc/boot/dts/tqm8548.dts
@@ -352,7 +352,7 @@
 		ranges = <
 			0 0x0 0xfc000000 0x04000000	// NOR FLASH bank 1
 			1 0x0 0xf8000000 0x08000000	// NOR FLASH bank 0
-			2 0x0 0xe3000000 0x00008000	// CAN (2 x i82527)
+			2 0x0 0xe3000000 0x00008000	// CAN (2 x CC770)
 			3 0x0 0xe3010000 0x00008000	// NAND FLASH
 
 		>;
@@ -393,18 +393,27 @@
 		};
 
 		/* Note: CAN support needs be enabled in U-Boot */
-		can0@2,0 {
-			compatible = "intel,82527"; // Bosch CC770
+		can@2,0 {
+			compatible = "bosch,cc770"; // Bosch CC770
 			reg = <2 0x0 0x100>;
 			interrupts = <4 1>;
 			interrupt-parent = <&mpic>;
+			bosch,external-clock-frequency = <16000000>;
+			bosch,disconnect-rx1-input;
+			bosch,disconnect-tx1-output;
+			bosch,iso-low-speed-mux;
+			bosch,clock-out-frequency = <16000000>;
 		};
 
-		can1@2,100 {
-			compatible = "intel,82527"; // Bosch CC770
+		can@2,100 {
+			compatible = "bosch,cc770"; // Bosch CC770
 			reg = <2 0x100 0x100>;
 			interrupts = <4 1>;
 			interrupt-parent = <&mpic>;
+			bosch,external-clock-frequency = <16000000>;
+			bosch,disconnect-rx1-input;
+			bosch,disconnect-tx1-output;
+			bosch,iso-low-speed-mux;
 		};
 
 		/* Note: NAND support needs to be enabled in U-Boot */
diff --git a/arch/powerpc/boot/dts/tqm8xx.dts b/arch/powerpc/boot/dts/tqm8xx.dts
index f6da7ec..c3dba25 100644
--- a/arch/powerpc/boot/dts/tqm8xx.dts
+++ b/arch/powerpc/boot/dts/tqm8xx.dts
@@ -57,6 +57,7 @@
 
 		ranges = <
 			0x0 0x0 0x40000000 0x800000
+			0x3 0x0 0xc0000000 0x200
 		>;
 
 		flash@0,0 {
@@ -67,6 +68,30 @@
 			bank-width = <4>;
 			device-width = <2>;
 		};
+
+		/* Note: CAN support needs be enabled in U-Boot */
+		can@3,0 {
+			compatible = "intc,82527";
+			reg = <3 0x0 0x80>;
+			interrupts = <8 1>;
+			interrupt-parent = <&PIC>;
+			bosch,external-clock-frequency = <16000000>;
+			bosch,disconnect-rx1-input;
+			bosch,disconnect-tx1-output;
+			bosch,iso-low-speed-mux;
+			bosch,clock-out-frequency = <16000000>;
+		};
+
+		can@3,100 {
+			compatible = "intc,82527";
+			reg = <3 0x100 0x80>;
+			interrupts = <8 1>;
+			interrupt-parent = <&PIC>;
+			bosch,external-clock-frequency = <16000000>;
+			bosch,disconnect-rx1-input;
+			bosch,disconnect-tx1-output;
+			bosch,iso-low-speed-mux;
+		};
 	};
 
 	soc@fff00000 {
-- 
1.7.4.1


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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
       [not found]   ` <1322214204-1121-3-git-send-email-wg-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
@ 2011-11-26 14:59     ` Oliver Hartkopp
  2011-11-28  8:56       ` Wolfgang Zarre
  0 siblings, 1 reply; 66+ messages in thread
From: Oliver Hartkopp @ 2011-11-26 14:59 UTC (permalink / raw)
  To: Wolfgang Grandegger, Wolfgang Zarre
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	socketcan-users-0fE9KPoRgkgATYTw5x5z8w,
	linux-can-u79uwXL29TY76Z2rM5mHXA

Hello Wolfgang,

many thanks for posting this driver. Indeed this is the last from the missing
drivers in the SVN ...

I added Wolfgang Zarre to the list of recipients who tested your CC770 driver
recently:

http://old.nabble.com/Compile-Fails-On-2.6.39-2-td32259346.html

Maybe he can check this latest version and can send a "Tested-by:"

@Wolfgang Zarre: The entire patch set from Wolfgang Grandegger is here:

http://patchwork.ozlabs.org/patch/127653/
http://patchwork.ozlabs.org/patch/127651/
http://patchwork.ozlabs.org/patch/127654/
http://patchwork.ozlabs.org/patch/127652/

Just a nitpick in the description:

> Furthermore, the following mode parameter can be defined:

> 
>   clk: External oscillator clock frequency (default=16000000 [16 MHz])
>   cir: CPU interface register (default=0x40 [DSC])
>   ocr, Bus configuration register (default=0x40 [CBY])


-> bcr: CPU ...

>   cor, Clockout register (default=0x00)


-> cor: Clockout ...

Regards,
Oliver

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

* Re: [PATCH net-next v2 1/4] can: cc770: add driver core for the Bosch CC770 and Intel AN82527
       [not found]   ` <1322214204-1121-2-git-send-email-wg-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
@ 2011-11-26 15:11     ` Oliver Hartkopp
  0 siblings, 0 replies; 66+ messages in thread
From: Oliver Hartkopp @ 2011-11-26 15:11 UTC (permalink / raw)
  To: Wolfgang Grandegger
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, linux-can-u79uwXL29TY76Z2rM5mHXA,
	socketcan-users-0fE9KPoRgkgATYTw5x5z8w, Wolfgang Zarre

Hello Wolfgang,

if you come to the point to re-post this patchset you may change this header
information just to a standard GPL header as you used for cc770_isa.c

No need to mention

- Derived from the old Socket-CAN i82527 driver:
- Copyright (c) 2002-2007 Volkswagen Group Electronic Research
- Send feedback to <socketcan-users-0fE9KPoRgkgATYTw5x5z8w@public.gmane.org>

You really reworked the i82527 driver that much, that it is ok to present it
as your originated work ... my driver really wasn't that cool to mention it
here ;-)

Thanks & best regards,
Oliver


> --- /dev/null
> +++ b/drivers/net/can/cc770/cc770.c
> @@ -0,0 +1,895 @@
> +/*
> + * cc770.c - Bosch CC770 and Intel AN82527 network device driver
> + *
> + * Copyright (C) 2009, 2011 Wolfgang Grandegger <wg-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
> + *
> + * Derived from the old Socket-CAN i82527 driver:
> + *
> + * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + * 1. Redistributions of source code must retain the above copyright
> + *    notice, this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + *    notice, this list of conditions and the following disclaimer in the
> + *    documentation and/or other materials provided with the distribution.
> + * 3. Neither the name of Volkswagen nor the names of its contributors
> + *    may be used to endorse or promote products derived from this software
> + *    without specific prior written permission.
> + *
> + * Alternatively, provided that this notice is retained in full, this
> + * software may be distributed under the terms of the GNU General
> + * Public License ("GPL") version 2, in which case the provisions of the
> + * GPL apply INSTEAD OF those given above.
> + *
> + * The provided data structures and external interfaces from this code
> + * are not restricted to be used by modules with a GPL compatible license.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
> + * DAMAGE.
> + *
> + * Send feedback to <socketcan-users-0fE9KPoRgkgATYTw5x5z8w@public.gmane.org>
> + */
> +

> diff --git a/drivers/net/can/cc770/cc770.h b/drivers/net/can/cc770/cc770.h
> new file mode 100644


dito

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2011-11-26 14:59     ` Oliver Hartkopp
@ 2011-11-28  8:56       ` Wolfgang Zarre
  2011-11-28  9:17         ` Wolfgang Grandegger
  0 siblings, 1 reply; 66+ messages in thread
From: Wolfgang Zarre @ 2011-11-28  8:56 UTC (permalink / raw)
  To: Oliver Hartkopp
  Cc: Wolfgang Grandegger, netdev, linux-can, socketcan-users, IreneV,
	Stanislav Yelenskiy

Hello Oliver,

> Hello Wolfgang,
>
> many thanks for posting this driver. Indeed this is the last from the missing
> drivers in the SVN ...

@Wolfgang

The same her, thanks a lot.

>
> I added Wolfgang Zarre to the list of recipients who tested your CC770 driver
> recently:
>
> http://old.nabble.com/Compile-Fails-On-2.6.39-2-td32259346.html
>
> Maybe he can check this latest version and can send a "Tested-by:"
>
> @Wolfgang Zarre: The entire patch set from Wolfgang Grandegger is here:
>
> http://patchwork.ozlabs.org/patch/127653/
> http://patchwork.ozlabs.org/patch/127651/
> http://patchwork.ozlabs.org/patch/127654/
> http://patchwork.ozlabs.org/patch/127652/

In fact a month ago we discovered a problem with the previous isa driver but were not
able to reproduce it.

Last Friday during a test run we got the same problem and with some further tests I
was able to reproduce and started with some investigation.

So the patches came in quite handy and even not to waste time I was applying the
patches to an updated svn tree but had to do some manual corrections to get it
compiled.

So far the driver is functioning quite good and I was hoping that our problem would
be solved as well.

But unfortunately that is not the case and it would be great if somebody would have
an idea or similar experience and maybe a solution.

In use:
ISA card: B&R with CC770 (40007) Series Bosch CAN Controller - LQFP-44
Kernel: 2.6.39.4
Module: modprobe cc770_isa irq=0xa port=0x384 indirect=1
Commands: ip link set can0 up type can bitrate 500000;ip link set can0 txqueuelen 2000

dmesg:
[190911.144337] CAN device driver interface
[190911.153316] cc770 CAN netdevice driver
[190911.159708] cc770_isa: platform device 0: port=0x384, mem=0x0, irq=10
[190911.159740] cc770_isa cc770_isa.0: probing idx=0: port=0x384, mem=0x0, irq=10
[190911.159799] cc770_isa cc770_isa.0: (unregistered net_device): i82527 mode with additional functions
[190911.161338] cc770_isa cc770_isa.0: cc770_isa device registered (reg_base=0x00000384, irq=10)
[190911.161384] Legacy cc770_isa driver for max. 8 devices registered
[190912.173762] cc770_isa cc770_isa.0: can0: setting BTR0=0x00 BTR1=0x1c
[190912.173835] cc770_isa cc770_isa.0: can0: Message object 15 for RX data, RTR, SFF and EFF
[190912.173852] cc770_isa cc770_isa.0: can0: Message object 11 for TX data, RTR, SFF and EFF


Description of problem:
After a while sending quite some telegrams the driver of a sudden stops transmitting
and the queue is running full but still capable to receive telegrams.
This issue is not depending on the amount of transmitted telegrams and also no logfile
entries.

Further it is possible to recover with ip link set down and up again.


>
> Just a nitpick in the description:
>
>> Furthermore, the following mode parameter can be defined:
>
>>
>>    clk: External oscillator clock frequency (default=16000000 [16 MHz])
>>    cir: CPU interface register (default=0x40 [DSC])
>>    ocr, Bus configuration register (default=0x40 [CBY])
>
>
> ->  bcr: CPU ...
>
>>    cor, Clockout register (default=0x00)
>
>
> ->  cor: Clockout ...
>
> Regards,
> Oliver

Thanks in advance.

Regards
Wolfgang

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2011-11-28  8:56       ` Wolfgang Zarre
@ 2011-11-28  9:17         ` Wolfgang Grandegger
  2011-11-28 12:03           ` Wolfgang Zarre
  0 siblings, 1 reply; 66+ messages in thread
From: Wolfgang Grandegger @ 2011-11-28  9:17 UTC (permalink / raw)
  To: info
  Cc: Oliver Hartkopp, netdev, linux-can, socketcan-users, IreneV,
	Stanislav Yelenskiy

On 11/28/2011 09:56 AM, Wolfgang Zarre wrote:
> Hello Oliver,
> 
>> Hello Wolfgang,
>>
>> many thanks for posting this driver. Indeed this is the last from the
>> missing
>> drivers in the SVN ...
> 
> @Wolfgang
> 
> The same her, thanks a lot.
> 
>>
>> I added Wolfgang Zarre to the list of recipients who tested your CC770
>> driver
>> recently:
>>
>> http://old.nabble.com/Compile-Fails-On-2.6.39-2-td32259346.html
>>
>> Maybe he can check this latest version and can send a "Tested-by:"
>>
>> @Wolfgang Zarre: The entire patch set from Wolfgang Grandegger is here:
>>
>> http://patchwork.ozlabs.org/patch/127653/
>> http://patchwork.ozlabs.org/patch/127651/
>> http://patchwork.ozlabs.org/patch/127654/
>> http://patchwork.ozlabs.org/patch/127652/
> 
> In fact a month ago we discovered a problem with the previous isa driver
> but were not
> able to reproduce it.
> 
> Last Friday during a test run we got the same problem and with some
> further tests I
> was able to reproduce and started with some investigation.
> 
> So the patches came in quite handy and even not to waste time I was
> applying the
> patches to an updated svn tree but had to do some manual corrections to
> get it
> compiled.
> 
> So far the driver is functioning quite good and I was hoping that our
> problem would
> be solved as well.

Well, I do not remember any fix... apart from

> But unfortunately that is not the case and it would be great if somebody
> would have
> an idea or similar experience and maybe a solution.
> 
> In use:
> ISA card: B&R with CC770 (40007) Series Bosch CAN Controller - LQFP-44
> Kernel: 2.6.39.4
> Module: modprobe cc770_isa irq=0xa port=0x384 indirect=1
> Commands: ip link set can0 up type can bitrate 500000;ip link set can0
> txqueuelen 2000

... using a reasonable default for bcr of 0x40. But you may need to
provide better values for cir, bcr and cor.

> dmesg:
> [190911.144337] CAN device driver interface
> [190911.153316] cc770 CAN netdevice driver
> [190911.159708] cc770_isa: platform device 0: port=0x384, mem=0x0, irq=10
> [190911.159740] cc770_isa cc770_isa.0: probing idx=0: port=0x384,
> mem=0x0, irq=10
> [190911.159799] cc770_isa cc770_isa.0: (unregistered net_device): i82527
> mode with additional functions
> [190911.161338] cc770_isa cc770_isa.0: cc770_isa device registered
> (reg_base=0x00000384, irq=10)
> [190911.161384] Legacy cc770_isa driver for max. 8 devices registered
> [190912.173762] cc770_isa cc770_isa.0: can0: setting BTR0=0x00 BTR1=0x1c
> [190912.173835] cc770_isa cc770_isa.0: can0: Message object 15 for RX
> data, RTR, SFF and EFF
> [190912.173852] cc770_isa cc770_isa.0: can0: Message object 11 for TX
> data, RTR, SFF and EFF
> 
> 
> Description of problem:
> After a while sending quite some telegrams the driver of a sudden stops
> transmitting
> and the queue is running full but still capable to receive telegrams.
> This issue is not depending on the amount of transmitted telegrams and
> also no logfile
> entries.

What do you get with "candump -t d any,0:0,#FFFFFFFF"? What does "ip -d
-s link show" show?

Wolfgang.


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

* Re: [Socketcan-users] [PATCH net-next v2 1/4] can: cc770: add driver core for the Bosch CC770 and Intel AN82527
  2011-11-25  9:43 ` [PATCH net-next v2 1/4] can: cc770: add driver core " Wolfgang Grandegger
       [not found]   ` <1322214204-1121-2-git-send-email-wg-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
@ 2011-11-28 11:28   ` Marc Kleine-Budde
  2011-11-28 13:52     ` Wolfgang Grandegger
       [not found]     ` <4ED3704D.5020903-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
  1 sibling, 2 replies; 66+ messages in thread
From: Marc Kleine-Budde @ 2011-11-28 11:28 UTC (permalink / raw)
  To: Wolfgang Grandegger; +Cc: netdev, socketcan-users, linux-can

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

On 11/25/2011 10:43 AM, Wolfgang Grandegger wrote:
> Signed-off-by: Wolfgang Grandegger <wg@grandegger.com>
> ---
>  drivers/net/can/Kconfig            |    2 +
>  drivers/net/can/Makefile           |    1 +
>  drivers/net/can/cc770/Kconfig      |    3 +
>  drivers/net/can/cc770/Makefile     |    7 +
>  drivers/net/can/cc770/cc770.c      |  895 ++++++++++++++++++++++++++++++++++++
>  drivers/net/can/cc770/cc770.h      |  234 ++++++++++
>  include/linux/can/platform/cc770.h |   33 ++
>  7 files changed, 1175 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/net/can/cc770/Kconfig
>  create mode 100644 drivers/net/can/cc770/Makefile
>  create mode 100644 drivers/net/can/cc770/cc770.c
>  create mode 100644 drivers/net/can/cc770/cc770.h
>  create mode 100644 include/linux/can/platform/cc770.h

I don't know the hardware, but the code looks good to me, some comments:
- The driver doesn't use NAPI, can this be added
- The rx-handlers have a while(1) loop
  For NAPI you have to add accounting, for the non NAPI case it would
  be good, too.
- I think you can move a large number of lines from the .h file into
  the driver. Code that's not used in the different binding drivers.

More comments inline (mostly nitpicking)

Marc
> 
> diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
> index f6c98fb..ab45758 100644
> --- a/drivers/net/can/Kconfig
> +++ b/drivers/net/can/Kconfig
> @@ -116,6 +116,8 @@ source "drivers/net/can/sja1000/Kconfig"
>  
>  source "drivers/net/can/c_can/Kconfig"
>  
> +source "drivers/net/can/cc770/Kconfig"
> +
>  source "drivers/net/can/usb/Kconfig"
>  
>  source "drivers/net/can/softing/Kconfig"
> diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
> index 24ebfe8..938be37 100644
> --- a/drivers/net/can/Makefile
> +++ b/drivers/net/can/Makefile
> @@ -14,6 +14,7 @@ obj-y				+= softing/
>  obj-$(CONFIG_CAN_SJA1000)	+= sja1000/
>  obj-$(CONFIG_CAN_MSCAN)		+= mscan/
>  obj-$(CONFIG_CAN_C_CAN)		+= c_can/
> +obj-$(CONFIG_CAN_CC770)		+= cc770/
>  obj-$(CONFIG_CAN_AT91)		+= at91_can.o
>  obj-$(CONFIG_CAN_TI_HECC)	+= ti_hecc.o
>  obj-$(CONFIG_CAN_MCP251X)	+= mcp251x.o
> diff --git a/drivers/net/can/cc770/Kconfig b/drivers/net/can/cc770/Kconfig
> new file mode 100644
> index 0000000..225131b
> --- /dev/null
> +++ b/drivers/net/can/cc770/Kconfig
> @@ -0,0 +1,3 @@
> +menuconfig CAN_CC770
> +	tristate "Bosch CC770 and Intel AN82527 devices"
> +	depends on CAN_DEV && HAS_IOMEM
> diff --git a/drivers/net/can/cc770/Makefile b/drivers/net/can/cc770/Makefile
> new file mode 100644
> index 0000000..34e8180
> --- /dev/null
> +++ b/drivers/net/can/cc770/Makefile
> @@ -0,0 +1,7 @@
> +#
> +#  Makefile for the Bosch CC770 CAN controller drivers.
> +#
> +
> +obj-$(CONFIG_CAN_CC770) += cc770.o
> +
> +ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
> diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c
> new file mode 100644
> index 0000000..47a6965
> --- /dev/null
> +++ b/drivers/net/can/cc770/cc770.c
> @@ -0,0 +1,895 @@
> +/*
> + * cc770.c - Bosch CC770 and Intel AN82527 network device driver
> + *
> + * Copyright (C) 2009, 2011 Wolfgang Grandegger <wg@grandegger.com>
> + *
> + * Derived from the old Socket-CAN i82527 driver:
> + *
> + * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + * 1. Redistributions of source code must retain the above copyright
> + *    notice, this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + *    notice, this list of conditions and the following disclaimer in the
> + *    documentation and/or other materials provided with the distribution.
> + * 3. Neither the name of Volkswagen nor the names of its contributors
> + *    may be used to endorse or promote products derived from this software
> + *    without specific prior written permission.
> + *
> + * Alternatively, provided that this notice is retained in full, this
> + * software may be distributed under the terms of the GNU General
> + * Public License ("GPL") version 2, in which case the provisions of the
> + * GPL apply INSTEAD OF those given above.
> + *
> + * The provided data structures and external interfaces from this code
> + * are not restricted to be used by modules with a GPL compatible license.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
> + * DAMAGE.
> + *
> + * Send feedback to <socketcan-users@lists.berlios.de>

please remove :)

> + */
> +
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/kernel.h>
> +#include <linux/sched.h>
> +#include <linux/types.h>
> +#include <linux/fcntl.h>
> +#include <linux/interrupt.h>
> +#include <linux/ptrace.h>
> +#include <linux/string.h>
> +#include <linux/errno.h>
> +#include <linux/netdevice.h>
> +#include <linux/if_arp.h>
> +#include <linux/if_ether.h>
> +#include <linux/skbuff.h>
> +#include <linux/delay.h>
> +
> +#include <linux/can.h>
> +#include <linux/can/dev.h>
> +#include <linux/can/error.h>
> +#include <linux/can/dev.h>
> +#include <linux/can/platform/cc770.h>
> +
> +#include "cc770.h"

Can you move all the definitions that are not needed in the other
drivers (e.g. ISA, etc.) into this .c file?

> +
> +#define DRV_NAME  "cc770"
> +
> +MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
> +MODULE_LICENSE("GPL v2");
> +MODULE_DESCRIPTION(DRV_NAME "CAN netdevice driver");
> +
> +/*
> + * The CC770 is a CAN controller from Bosch, which is 100% compatible
> + * with the AN82527 from Intel, but with "bugs" being fixed and some
> + * additional functionality, mainly:
> + *
> + * 1. RX and TX error counters are readable.
> + * 2. Support of silent (listen-only) mode.
> + * 3. Message object 15 can receive all types of frames, also RTR and EFF.
> + *
> + * Details are available from Bosch's "CC770_Product_Info_2007-01.pdf",
> + * which explains in detail the compatibility between the CC770 and the
> + * 82527. This driver use the additional functionality 3. on real CC770
> + * devices. Unfortunately, the CC770 does still not store the message
> + * identifier of received remote transmission request frames and
> + * therefore it's set to 0.
> + *
> + * The message objects 1..14 can be used for TX and RX while the message
> + * objects 15 is optimized for RX. It has a shadow register for reliable
> + * data receiption under heavy bus load. Therefore it makes sense to use
> + * this message object for the needed use case. The frame type (EFF/SFF)
> + * for the message object 15 can be defined via kernel module parameter
> + * "msgobj15_eff". If not equal 0, it will receive 29-bit EFF frames,
> + * otherwise 11 bit SFF messages.
> + */
> +static int msgobj15_eff;
> +module_param(msgobj15_eff, int, S_IRUGO);
> +MODULE_PARM_DESC(msgobj15_eff, "Extended 29-bit frames for message object 15 "
> +		 "(default: 11-bit standard frames)");
> +
> +static int i82527_compat;
> +module_param(i82527_compat, int, S_IRUGO);
> +MODULE_PARM_DESC(i82527_compat, "Strict Intel 82527 comptibility mode "
> +		 "without using additional functions");
> +
> +/*
> + * This driver uses the last 5 message objects 11..15. The definitions
> + * and structure below allows to configure and assign them to the real
> + * message object.
> + */
> +static unsigned char cc770_obj_flags[CC770_OBJ_MAX] = {
> +	[CC770_OBJ_RX0] = CC770_OBJ_FLAG_RX,
> +	[CC770_OBJ_RX1] = CC770_OBJ_FLAG_RX | CC770_OBJ_FLAG_EFF,
> +	[CC770_OBJ_RX_RTR0] = CC770_OBJ_FLAG_RX | CC770_OBJ_FLAG_RTR,
> +	[CC770_OBJ_RX_RTR1] = CC770_OBJ_FLAG_RX | CC770_OBJ_FLAG_RTR |
> +			      CC770_OBJ_FLAG_EFF,
> +	[CC770_OBJ_TX] = 0,
> +};

Is is worth the trouble making this a per device instance option? In a
OF-Tree world should this become an "attribute" (or what's the correct
of-tree word for it?)

> +
> +static struct can_bittiming_const cc770_bittiming_const = {
> +	.name = DRV_NAME,
> +	.tseg1_min = 1,
> +	.tseg1_max = 16,
> +	.tseg2_min = 1,
> +	.tseg2_max = 8,
> +	.sjw_max = 4,
> +	.brp_min = 1,
> +	.brp_max = 64,
> +	.brp_inc = 1,
> +};
> +
> +static inline int intid2obj(unsigned int intid)
> +{
> +	if (intid == 2)
> +		return 0;
> +	else
> +		return MSGOBJ_LAST + 2 - intid;
> +}
> +
> +static void enable_all_objs(const struct net_device *dev)
> +{
> +	struct cc770_priv *priv = netdev_priv(dev);
> +	u8 msgcfg;
> +	unsigned char obj_flags;
> +	unsigned int o, mo;
> +
> +	for (o = 0; o <  CC770_OBJ_MAX; o++) {
                         ^^^^^^^^^^^^^

what about ARRAY_SIZE(priv->obj_flags)

nitpick:
o is probalby short for object, but usually we use "i" for a for loop

> +		obj_flags = priv->obj_flags[o];
> +		mo = obj2msgobj(o);
> +
> +		if (obj_flags & CC770_OBJ_FLAG_RX) {
> +			/*
> +			 * We don't need extra objects for RTR and EFF if
> +			 * the additional CC770 functions are enabled.
> +			 */
> +			if (priv->control_normal_mode & CTRL_EAF) {
> +				if (o > 0)
> +					continue;
> +				netdev_dbg(dev, "Message object %d for "
> +					   "RX data, RTR, SFF and EFF\n", mo);
> +			} else {
> +				netdev_dbg(dev,
> +					   "Message object %d for RX %s %s\n",
> +					   mo, obj_flags & CC770_OBJ_FLAG_RTR ?
> +					   "RTR" : "data",
> +					   obj_flags & CC770_OBJ_FLAG_EFF ?
> +					   "EFF" : "SFF");
> +			}
> +
> +			if (obj_flags & CC770_OBJ_FLAG_EFF)
> +				msgcfg = MSGCFG_XTD;
> +			else
> +				msgcfg = 0;
> +			if (obj_flags & CC770_OBJ_FLAG_RTR)
> +				msgcfg |= MSGCFG_DIR;
> +
> +			cc770_write_reg(priv, msgobj[mo].config, msgcfg);
> +			cc770_write_reg(priv, msgobj[mo].ctrl0,
> +					MSGVAL_SET | TXIE_RES |
> +					RXIE_SET | INTPND_RES);
> +
> +			if (obj_flags & CC770_OBJ_FLAG_RTR)
> +				cc770_write_reg(priv, msgobj[mo].ctrl1,
> +						NEWDAT_RES | CPUUPD_SET |
> +						TXRQST_RES | RMTPND_RES);
> +			else
> +				cc770_write_reg(priv, msgobj[mo].ctrl1,
> +						NEWDAT_RES | MSGLST_RES |
> +						TXRQST_RES | RMTPND_RES);
> +		} else {
> +			netdev_dbg(dev, "Message object %d for "
> +				   "TX data, RTR, SFF and EFF\n", mo);
> +
> +			cc770_write_reg(priv, msgobj[mo].ctrl1,
> +					RMTPND_RES | TXRQST_RES |
> +					CPUUPD_RES | NEWDAT_RES);
> +			cc770_write_reg(priv, msgobj[mo].ctrl0,
> +					MSGVAL_RES | TXIE_RES |
> +					RXIE_RES | INTPND_RES);
> +		}
> +	}
> +}
> +
> +static void disable_all_objs(const struct cc770_priv *priv)
> +{
> +	int i, mo;

here you use "i"

> +
> +	for (i = 0; i <  CC770_OBJ_MAX; i++) {

ARRAY_SIZE?

> +		mo = obj2msgobj(i);
> +
> +		if (priv->obj_flags[i] & CC770_OBJ_FLAG_RX) {
> +			if (i > 0 && priv->control_normal_mode & CTRL_EAF)
> +				continue;
> +
> +			cc770_write_reg(priv, msgobj[mo].ctrl1,
> +					NEWDAT_RES | MSGLST_RES |
> +					TXRQST_RES | RMTPND_RES);
> +			cc770_write_reg(priv, msgobj[mo].ctrl0,
> +					MSGVAL_RES | TXIE_RES |
> +					RXIE_RES | INTPND_RES);
> +		} else {
> +			/* Clear message object for send */
> +			cc770_write_reg(priv, msgobj[mo].ctrl1,
> +					RMTPND_RES | TXRQST_RES |
> +					CPUUPD_RES | NEWDAT_RES);
> +			cc770_write_reg(priv, msgobj[mo].ctrl0,
> +					MSGVAL_RES | TXIE_RES |
> +					RXIE_RES | INTPND_RES);
> +		}
> +	}
> +}
> +
> +static void set_reset_mode(struct net_device *dev)
> +{
> +	struct cc770_priv *priv = netdev_priv(dev);
> +
> +	/* Enable configuration and puts chip in bus-off, disable interrupts */
> +	cc770_write_reg(priv, control, CTRL_CCE | CTRL_INI);
> +
> +	priv->can.state = CAN_STATE_STOPPED;
> +
> +	/* Clear interrupts */
> +	cc770_read_reg(priv, interrupt);
> +
> +	/* Clear status register */
> +	cc770_write_reg(priv, status, 0);
> +
> +	/* Disable all used message objects */
> +	disable_all_objs(priv);
> +}
> +
> +static void set_normal_mode(struct net_device *dev)
> +{
> +	struct cc770_priv *priv = netdev_priv(dev);
> +
> +	/* Clear interrupts */
> +	cc770_read_reg(priv, interrupt);
> +
> +	/* Clear status register and pre-set last error code */
> +	cc770_write_reg(priv, status, STAT_LEC_MASK);
> +
> +	/* Enable all used message objects*/
> +	enable_all_objs(dev);
> +
> +	/*
> +	 * Clear bus-off, interrupts only for errors,
> +	 * not for status change
> +	 */
> +	cc770_write_reg(priv, control, priv->control_normal_mode);
> +
> +	priv->can.state = CAN_STATE_ERROR_ACTIVE;
> +}
> +
> +static void chipset_init(struct cc770_priv *priv)
> +{
> +	int mo, id, data;
> +
> +	/* Enable configuration and put chip in bus-off, disable interrupts */
> +	cc770_write_reg(priv, control, (CTRL_CCE | CTRL_INI));
> +
> +	/* Set CLKOUT divider and slew rates */
> +	cc770_write_reg(priv, clkout, priv->clkout);
> +
> +	/* Configure CPU interface / CLKOUT enable */
> +	cc770_write_reg(priv, cpu_interface, priv->cpu_interface);
> +
> +	/* Set bus configuration  */
> +	cc770_write_reg(priv, bus_config, priv->bus_config);
> +
> +	/* Clear interrupts */
> +	cc770_read_reg(priv, interrupt);
> +
> +	/* Clear status register */
> +	cc770_write_reg(priv, status, 0);
> +
> +	/* Clear and invalidate message objects */
> +	for (mo = MSGOBJ_FIRST; mo <= MSGOBJ_LAST; mo++) {
> +		cc770_write_reg(priv, msgobj[mo].ctrl0,
> +				INTPND_UNC | RXIE_RES |
> +				TXIE_RES | MSGVAL_RES);
> +		cc770_write_reg(priv, msgobj[mo].ctrl0,
> +				INTPND_RES | RXIE_RES |
> +				TXIE_RES | MSGVAL_RES);
> +		cc770_write_reg(priv, msgobj[mo].ctrl1,
> +				NEWDAT_RES | MSGLST_RES |
> +				TXRQST_RES | RMTPND_RES);
> +		for (data = 0; data < 8; data++)
> +			cc770_write_reg(priv, msgobj[mo].data[data], 0);
> +		for (id = 0; id < 4; id++)
> +			cc770_write_reg(priv, msgobj[mo].id[id], 0);
> +		cc770_write_reg(priv, msgobj[mo].config, 0);
> +	}
> +
> +	/* Set all global ID masks to "don't care" */
> +	cc770_write_reg(priv, global_mask_std[0], 0);
> +	cc770_write_reg(priv, global_mask_std[1], 0);
> +	cc770_write_reg(priv, global_mask_ext[0], 0);
> +	cc770_write_reg(priv, global_mask_ext[1], 0);
> +	cc770_write_reg(priv, global_mask_ext[2], 0);
> +	cc770_write_reg(priv, global_mask_ext[3], 0);
> +
> +}
> +
> +static int cc770_probe_chip(struct net_device *dev)

nitpick: This chip returns 1 on success and 0 on failure, IMHO unusual
return value. Why not make it return -ENODEV in case of failure?

> +{
> +	struct cc770_priv *priv = netdev_priv(dev);
> +
> +	/* Enable configuration, put chip in bus-off, disable ints */
> +	cc770_write_reg(priv, control, CTRL_CCE | CTRL_EAF | CTRL_INI);
> +	/* Configure cpu interface / CLKOUT disable */
> +	cc770_write_reg(priv, cpu_interface, priv->cpu_interface);
> +
> +	/*
> +	 * Check if hardware reset is still inactive or maybe there
> +	 * is no chip in this address space
> +	 */
> +	if (cc770_read_reg(priv, cpu_interface) & CPUIF_RST) {
> +		netdev_info(dev, "probing @0x%p failed (reset)\n",
> +			    priv->reg_base);
> +		return 0;
> +	}
> +
> +	/* Write and read back test pattern */

Are these Hex numbers arbitrary values?

> +	cc770_write_reg(priv, msgobj[1].data[1], 0x25);
> +	cc770_write_reg(priv, msgobj[2].data[3], 0x52);
> +	cc770_write_reg(priv, msgobj[10].data[6], 0xc3);
> +	if ((cc770_read_reg(priv, msgobj[1].data[1]) != 0x25) ||
> +	    (cc770_read_reg(priv, msgobj[2].data[3]) != 0x52) ||
> +	    (cc770_read_reg(priv, msgobj[10].data[6]) != 0xc3)) {
> +		netdev_info(dev, "probing @0x%p failed (pattern)\n",
> +			    priv->reg_base);
> +		return 0;
> +	}
> +
> +	/* Check if this chip is a CC770 supporting additional functions */
> +	if (cc770_read_reg(priv, control) & CTRL_EAF)
> +		priv->control_normal_mode |= CTRL_EAF;
> +
> +	return 1;
> +}
> +
> +static void cc770_start(struct net_device *dev)
> +{
> +	struct cc770_priv *priv = netdev_priv(dev);
> +
> +	/* leave reset mode */
> +	if (priv->can.state != CAN_STATE_STOPPED)
> +		set_reset_mode(dev);
> +
> +	/* leave reset mode */
> +	set_normal_mode(dev);
> +}
> +
> +static int cc770_set_mode(struct net_device *dev, enum can_mode mode)
> +{
> +	struct cc770_priv *priv = netdev_priv(dev);
> +
> +	if (!priv->open_time)
> +		return -EINVAL;
> +
> +	switch (mode) {
> +	case CAN_MODE_START:
> +		cc770_start(dev);
> +		if (netif_queue_stopped(dev))
> +			netif_wake_queue(dev);

The "if (netif_queue_stopped(dev))" is not needed.

> +		break;
> +
> +	default:
> +		return -EOPNOTSUPP;
> +	}
> +
> +	return 0;
> +}
> +
> +static int cc770_set_bittiming(struct net_device *dev)
> +{
> +	struct cc770_priv *priv = netdev_priv(dev);
> +	struct can_bittiming *bt = &priv->can.bittiming;
> +	u8 btr0, btr1;
> +
> +	btr0 = ((bt->brp - 1) & 0x3f) | (((bt->sjw - 1) & 0x3) << 6);
> +	btr1 = ((bt->prop_seg + bt->phase_seg1 - 1) & 0xf) |
> +		(((bt->phase_seg2 - 1) & 0x7) << 4);
> +	if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
> +		btr1 |= 0x80;
> +
> +	netdev_info(dev, "setting BTR0=0x%02x BTR1=0x%02x\n", btr0, btr1);
> +
> +	cc770_write_reg(priv, bit_timing_0, btr0);
> +	cc770_write_reg(priv, bit_timing_1, btr1);
> +
> +	return 0;
> +}
> +
> +static netdev_tx_t cc770_start_xmit(struct sk_buff *skb, struct net_device *dev)
> +{
> +	struct cc770_priv *priv = netdev_priv(dev);
> +	struct net_device_stats *stats = &dev->stats;
> +	struct can_frame *cf = (struct can_frame *)skb->data;
> +	unsigned int mo = obj2msgobj(CC770_OBJ_TX);
> +	u8 dlc, rtr;
> +	u32 id;
> +	int i;
> +
> +	if (can_dropped_invalid_skb(dev, skb))
> +		return NETDEV_TX_OK;
> +
> +	if ((cc770_read_reg(priv,
> +			    msgobj[mo].ctrl1) & TXRQST_UNC) == TXRQST_SET) {
> +		netdev_err(dev, "TX register is still occupied!\n");
> +		return NETDEV_TX_BUSY;
> +	}
> +
> +	netif_stop_queue(dev);
> +
> +	dlc = cf->can_dlc;
> +	id = cf->can_id;
> +	if (cf->can_id & CAN_RTR_FLAG)
> +		rtr = 0;
> +	else
> +		rtr = MSGCFG_DIR;
> +	cc770_write_reg(priv, msgobj[mo].ctrl1,
> +			RMTPND_RES | TXRQST_RES | CPUUPD_SET | NEWDAT_RES);
> +	cc770_write_reg(priv, msgobj[mo].ctrl0,
> +			MSGVAL_SET | TXIE_SET | RXIE_RES | INTPND_RES);
> +	if (id & CAN_EFF_FLAG) {
> +		id &= CAN_EFF_MASK;
> +		cc770_write_reg(priv, msgobj[mo].config,
> +				(dlc << 4) + rtr + MSGCFG_XTD);

+ is the same as | here, but IMHO bitwise or is more common coding styele.

> +		cc770_write_reg(priv, msgobj[mo].id[3],
> +				(id << 3) & 0xFFU);
> +		cc770_write_reg(priv, msgobj[mo].id[2],
> +				(id >> 5) & 0xFFU);
> +		cc770_write_reg(priv, msgobj[mo].id[1],
> +				(id >> 13) & 0xFFU);
> +		cc770_write_reg(priv, msgobj[mo].id[0],
> +				(id >> 21) & 0xFFU);

msgobj[].id[] is an u8, so & 0xff is not needed.

> +	} else {
> +		id &= CAN_SFF_MASK;
> +		cc770_write_reg(priv, msgobj[mo].config,
> +				(dlc << 4) + rtr);
> +		cc770_write_reg(priv, msgobj[mo].id[0],
> +				(id >> 3) & 0xFFU);
> +		cc770_write_reg(priv, msgobj[mo].id[1],
> +				(id << 5) & 0xFFU);
dito
> +	}
> +
> +	dlc &= 0x0f;		/* restore length only */

is this needed? The dlc should be valid.

> +	for (i = 0; i < dlc; i++)
> +		cc770_write_reg(priv, msgobj[mo].data[i], cf->data[i]);
> +
> +	cc770_write_reg(priv, msgobj[mo].ctrl1,
> +			RMTPND_RES | TXRQST_SET | CPUUPD_RES | NEWDAT_UNC);
> +
> +	stats->tx_bytes += dlc;
> +
> +	can_put_echo_skb(skb, dev, 0);
> +
> +	/*
> +	 * HM: We had some cases of repeated IRQs so make sure the

Who is HM?

> +	 * INT is acknowledged I know it's already further up, but
> +	 * doing again fixed the issue
> +	 */
> +	cc770_write_reg(priv, msgobj[mo].ctrl0,
> +			MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);
> +
> +	return NETDEV_TX_OK;
> +}
> +
> +static void cc770_rx(struct net_device *dev, unsigned int mo, u8 ctrl1)
> +{
> +	struct cc770_priv *priv = netdev_priv(dev);
> +	struct net_device_stats *stats = &dev->stats;
> +	struct can_frame *cf;
> +	struct sk_buff *skb;
> +	u8 config;
> +	u32 id;
> +	int i;
> +
> +	skb = alloc_can_skb(dev, &cf);
> +	if (skb == NULL)
!skb
> +		return;
> +
> +	config = cc770_read_reg(priv, msgobj[mo].config);
> +
> +	if (ctrl1 & RMTPND_SET) {
> +		/*
> +		 * Unfortunately, the chip does not store the real message
> +		 * identifier of the received remote transmission request
> +		 * frame. Therefore we set it to 0.

What a bug!

> +		 */
> +		cf->can_id = CAN_RTR_FLAG;
> +		if (config & MSGCFG_XTD)
> +			cf->can_id |= CAN_EFF_FLAG;
> +		cf->can_dlc = 0;
> +	} else {
> +		if (config & MSGCFG_XTD) {
> +			id = cc770_read_reg(priv, msgobj[mo].id[3]);
> +			id |= cc770_read_reg(priv, msgobj[mo].id[2]) << 8;
> +			id |= cc770_read_reg(priv, msgobj[mo].id[1]) << 16;
> +			id |= cc770_read_reg(priv, msgobj[mo].id[0]) << 24;
> +			id >>= 3;
> +			id |= CAN_EFF_FLAG;
> +		} else {
> +			id = cc770_read_reg(priv, msgobj[mo].id[1]);
> +			id |= cc770_read_reg(priv, msgobj[mo].id[0]) << 8;
> +			id >>= 5;
> +		}
> +
> +		cf->can_id = id;
> +		cf->can_dlc = get_can_dlc((config & 0xf0) >> 4);
> +		for (i = 0; i < cf->can_dlc; i++)
> +			cf->data[i] = cc770_read_reg(priv, msgobj[mo].data[i]);
> +	}
> +	netif_rx(skb);
> +
> +	stats->rx_packets++;
> +	stats->rx_bytes += cf->can_dlc;
> +}
> +
> +static int cc770_err(struct net_device *dev, u8 status)
> +{
> +	struct cc770_priv *priv = netdev_priv(dev);
> +	struct net_device_stats *stats = &dev->stats;
> +	struct can_frame *cf;
> +	struct sk_buff *skb;
> +	u8 lec;
> +
> +	netdev_dbg(dev, "status interrupt (%#x)\n", status);
> +
> +	skb = alloc_can_err_skb(dev, &cf);
> +	if (skb == NULL)
!skb
> +		return -ENOMEM;
> +
> +	if (status & STAT_BOFF) {
> +		/* Disable interrupts */
> +		cc770_write_reg(priv, control, CTRL_INI);
> +		cf->can_id |= CAN_ERR_BUSOFF;
> +		priv->can.state = CAN_STATE_BUS_OFF;
> +		can_bus_off(dev);
> +	} else if (status & STAT_WARN) {
> +		cf->can_id |= CAN_ERR_CRTL;
> +		cf->data[1] = CAN_ERR_CRTL_RX_WARNING | CAN_ERR_CRTL_TX_WARNING;
> +		priv->can.state = CAN_STATE_ERROR_WARNING;
> +		priv->can.can_stats.error_warning++;
> +	}
> +
> +	lec = status & STAT_LEC_MASK;
> +	if (lec < 7 && lec > 0) {
> +		if (lec == STAT_LEC_ACK) {
> +			cf->can_id |= CAN_ERR_ACK;
> +		} else {
> +			cf->can_id |= CAN_ERR_PROT;
> +			switch (lec) {
> +			case STAT_LEC_STUFF:
> +				cf->data[2] |= CAN_ERR_PROT_STUFF;
> +				break;
> +			case STAT_LEC_FORM:
> +				cf->data[2] |= CAN_ERR_PROT_FORM;
> +				break;
> +			case STAT_LEC_BIT1:
> +				cf->data[2] |= CAN_ERR_PROT_BIT1;
> +				break;
> +			case STAT_LEC_BIT0:
> +				cf->data[2] |= CAN_ERR_PROT_BIT0;
> +				break;
> +			case STAT_LEC_CRC:
> +				cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ;
> +				break;
> +			}
> +		}
> +	}
> +
> +	netif_rx(skb);
> +
> +	stats->rx_packets++;
> +	stats->rx_bytes += cf->can_dlc;
> +
> +	return 0;
> +}
> +
> +static int cc770_status_interrupt(struct net_device *dev)
> +{
> +	struct cc770_priv *priv = netdev_priv(dev);
> +	u8 status;
> +
> +	status = cc770_read_reg(priv, status);
> +	/* Reset the status register including RXOK and TXOK */
> +	cc770_write_reg(priv, status, STAT_LEC_MASK);
> +
> +	if (status & (STAT_WARN | STAT_BOFF) ||
> +	    (status & STAT_LEC_MASK) != STAT_LEC_MASK) {
> +		cc770_err(dev, status);
> +		return status & STAT_BOFF;
> +	}
> +
> +	return 0;
> +}
> +
> +static void cc770_rx_interrupt(struct net_device *dev, unsigned int o)
> +{
> +	struct cc770_priv *priv = netdev_priv(dev);
> +	struct net_device_stats *stats = &dev->stats;
> +	unsigned int mo = obj2msgobj(o);
> +	u8 ctrl1;
> +
> +	while (1) {

What about limiting this?

> +		ctrl1 = cc770_read_reg(priv, msgobj[mo].ctrl1);
> +
> +		if (!(ctrl1 & NEWDAT_SET))  {
> +			/* Check for RTR if additional functions are enabled */
> +			if (priv->control_normal_mode & CTRL_EAF) {
> +				if (!(cc770_read_reg(priv, msgobj[mo].ctrl0) &
> +				      INTPND_SET))
> +					break;
> +			} else {
> +				break;
> +			}
> +		}
> +
> +		if (ctrl1 & MSGLST_SET) {
> +			stats->rx_over_errors++;
> +			stats->rx_errors++;
> +		}
> +		if (mo < MSGOBJ_LAST)
> +			cc770_write_reg(priv, msgobj[mo].ctrl1,
> +					NEWDAT_RES | MSGLST_RES |
> +					TXRQST_UNC | RMTPND_UNC);
> +		cc770_rx(dev, mo, ctrl1);
> +
> +		cc770_write_reg(priv, msgobj[mo].ctrl0,
> +				MSGVAL_SET | TXIE_RES |
> +				RXIE_SET | INTPND_RES);
> +		cc770_write_reg(priv, msgobj[mo].ctrl1,
> +				NEWDAT_RES | MSGLST_RES |
> +				TXRQST_RES | RMTPND_RES);
> +	}
> +}
> +
> +static void cc770_rtr_interrupt(struct net_device *dev, unsigned int o)
> +{
> +	struct cc770_priv *priv = netdev_priv(dev);
> +	unsigned int mo = obj2msgobj(o);
> +	u8 ctrl0, ctrl1;
> +
> +	while (1) {

dito...?

> +		ctrl0 = cc770_read_reg(priv, msgobj[mo].ctrl0);
> +		if (!(ctrl0 & INTPND_SET))
> +			break;
> +
> +		ctrl1 = cc770_read_reg(priv, msgobj[mo].ctrl1);
> +		cc770_rx(dev, mo, ctrl1);
> +
> +		cc770_write_reg(priv, msgobj[mo].ctrl0,
> +				MSGVAL_SET | TXIE_RES |
> +				RXIE_SET | INTPND_RES);
> +		cc770_write_reg(priv, msgobj[mo].ctrl1,
> +				NEWDAT_RES | CPUUPD_SET |
> +				TXRQST_RES | RMTPND_RES);
> +	}
> +}
> +
> +static void cc770_tx_interrupt(struct net_device *dev, unsigned int o)
> +{
> +	struct cc770_priv *priv = netdev_priv(dev);
> +	struct net_device_stats *stats = &dev->stats;
> +	unsigned int mo = obj2msgobj(o);
> +
> +	/* Nothing more to send, switch off interrupts */
> +	cc770_write_reg(priv, msgobj[mo].ctrl0,
> +			MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES);
> +	/*
> +	 * We had some cases of repeated IRQ so make sure the
> +	 * INT is acknowledged
> +	 */
> +	cc770_write_reg(priv, msgobj[mo].ctrl0,
> +			MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);
> +
> +	stats->tx_packets++;
> +	can_get_echo_skb(dev, 0);
> +	netif_wake_queue(dev);
> +}
> +
> +irqreturn_t cc770_interrupt(int irq, void *dev_id)
> +{
> +	struct net_device *dev = (struct net_device *)dev_id;
> +	struct cc770_priv *priv = netdev_priv(dev);
> +	u8 intid;
> +	int o, n = 0;
> +
> +	/* Shared interrupts and IRQ off? */
> +	if (priv->can.state == CAN_STATE_STOPPED)
> +		return IRQ_NONE;
> +
> +	if (priv->pre_irq)
> +		priv->pre_irq(priv);
> +
> +	while (n < CC770_MAX_IRQ) {
> +		/* Read the highest pending interrupt request */
> +		intid = cc770_read_reg(priv, interrupt);
> +		if (!intid)
> +			break;
> +		n++;
> +
> +		if (intid == 1) {
> +			/* Exit in case of bus-off */
> +			if (cc770_status_interrupt(dev))
> +				break;
> +		} else {
> +			o = intid2obj(intid);
> +
> +			if (o >= CC770_OBJ_MAX) {
> +				netdev_err(dev, "Unexpected interrupt id %d\n",
> +					   intid);
> +				continue;
> +			}
> +
> +			if (priv->obj_flags[o] & CC770_OBJ_FLAG_RTR)
> +				cc770_rtr_interrupt(dev, o);
> +			else if (priv->obj_flags[o] & CC770_OBJ_FLAG_RX)
> +				cc770_rx_interrupt(dev, o);
> +			else
> +				cc770_tx_interrupt(dev, o);
> +		}
> +	}
> +
> +	if (priv->post_irq)
> +		priv->post_irq(priv);
> +
> +	if (n >= CC770_MAX_IRQ)
> +		netdev_dbg(dev, "%d messages handled in ISR", n);
> +
> +	return (n) ? IRQ_HANDLED : IRQ_NONE;
> +}
> +
> +static int cc770_open(struct net_device *dev)
> +{
> +	struct cc770_priv *priv = netdev_priv(dev);
> +	int err;
> +
> +	/* set chip into reset mode */
> +	set_reset_mode(dev);
> +
> +	/* common open */
> +	err = open_candev(dev);
> +	if (err)
> +		return err;
> +
> +	err = request_irq(dev->irq, &cc770_interrupt, priv->irq_flags,
> +			  dev->name, (void *)dev);

the (void *) cast ist not needed

> +	if (err) {
> +		close_candev(dev);
> +		return -EAGAIN;
> +	}
> +
> +	/* init and start chip */
> +	cc770_start(dev);
> +	priv->open_time = jiffies;

open_time is used to track if the netdev is open, right? Can we use
"ndev->flags & IFF_UP" instead?

> +
> +	netif_start_queue(dev);
> +
> +	return 0;
> +}
> +
> +static int cc770_close(struct net_device *dev)
> +{
> +	struct cc770_priv *priv = netdev_priv(dev);
> +
> +	netif_stop_queue(dev);
> +	set_reset_mode(dev);
> +
> +	free_irq(dev->irq, (void *)dev);
cast not needed
> +	close_candev(dev);
> +
> +	priv->open_time = 0;
> +
> +	return 0;
> +}
> +
> +struct net_device *alloc_cc770dev(int sizeof_priv)
> +{
> +	struct net_device *dev;
> +	struct cc770_priv *priv;
> +
> +	dev = alloc_candev(sizeof(struct cc770_priv) + sizeof_priv,
> +			   CC770_ECHO_SKB_MAX);
> +	if (!dev)
> +		return NULL;
> +
> +	priv = netdev_priv(dev);
> +
> +	priv->dev = dev;
> +	priv->can.bittiming_const = &cc770_bittiming_const;
> +	priv->can.do_set_bittiming = cc770_set_bittiming;
> +	priv->can.do_set_mode = cc770_set_mode;
> +	priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
> +
> +	memcpy(priv->obj_flags, cc770_obj_flags, sizeof(cc770_obj_flags));
> +
> +	if (sizeof_priv)
> +		priv->priv = (void *)priv + sizeof(struct cc770_priv);
> +
> +	return dev;
> +}
> +EXPORT_SYMBOL_GPL(alloc_cc770dev);
> +
> +void free_cc770dev(struct net_device *dev)
> +{
> +	free_candev(dev);
> +}
> +EXPORT_SYMBOL_GPL(free_cc770dev);
> +
> +static const struct net_device_ops cc770_netdev_ops = {
> +	.ndo_open = cc770_open,
> +	.ndo_stop = cc770_close,
> +	.ndo_start_xmit = cc770_start_xmit,
> +};
> +
> +int register_cc770dev(struct net_device *dev)
> +{
> +	struct cc770_priv *priv = netdev_priv(dev);
> +
> +	if (!cc770_probe_chip(dev))
> +		return -ENODEV;
> +
> +	dev->netdev_ops = &cc770_netdev_ops;
> +
> +	dev->flags |= IFF_ECHO;	/* we support local echo */
> +
> +	/* Should we use additional functions? */
> +	if (!i82527_compat && priv->control_normal_mode & CTRL_EAF) {
> +		priv->control_normal_mode = CTRL_IE | CTRL_EAF | CTRL_EIE;
> +		netdev_dbg(dev, "i82527 mode with additional functions\n");
> +	} else {
> +		priv->control_normal_mode = CTRL_IE | CTRL_EIE;
> +		netdev_dbg(dev, "strict i82527 compatibility mode\n");
> +	}
> +
> +	chipset_init(priv);
> +	set_reset_mode(dev);
> +
> +	return register_candev(dev);
> +}
> +EXPORT_SYMBOL_GPL(register_cc770dev);
> +
> +void unregister_cc770dev(struct net_device *dev)
> +{
> +	set_reset_mode(dev);
> +	unregister_candev(dev);
> +}
> +EXPORT_SYMBOL_GPL(unregister_cc770dev);
> +
> +static __init int cc770_init(void)
> +{
> +	if (msgobj15_eff) {
> +		cc770_obj_flags[CC770_OBJ_RX0] |= CC770_OBJ_FLAG_EFF;
> +		cc770_obj_flags[CC770_OBJ_RX1] &= ~CC770_OBJ_FLAG_EFF;
> +	}
> +
> +	pr_info("%s CAN netdevice driver\n", DRV_NAME);

You can add a #define pr_fmt(fmt), to get rid of the "%s", DRV_NAME.

> +
> +	return 0;
> +}
> +module_init(cc770_init);
> +
> +static __exit void cc770_exit(void)
> +{
> +	pr_info("%s: driver removed\n", DRV_NAME);
> +}
> +module_exit(cc770_exit);
> diff --git a/drivers/net/can/cc770/cc770.h b/drivers/net/can/cc770/cc770.h
> new file mode 100644
> index 0000000..c6b5800
> --- /dev/null
> +++ b/drivers/net/can/cc770/cc770.h
> @@ -0,0 +1,234 @@
> +/*
> + * cc770.h - Bosch CC770 and Intel AN82527 network device driver
> + *
> + * Copyright (C) 2009, 2011 Wolfgang Grandegger <wg@grandegger.com>
> + *
> + * Derived from the old Socket-CAN i82527 driver:
> + *
> + * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + * 1. Redistributions of source code must retain the above copyright
> + *    notice, this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + *    notice, this list of conditions and the following disclaimer in the
> + *    documentation and/or other materials provided with the distribution.
> + * 3. Neither the name of Volkswagen nor the names of its contributors
> + *    may be used to endorse or promote products derived from this software
> + *    without specific prior written permission.
> + *
> + * Alternatively, provided that this notice is retained in full, this
> + * software may be distributed under the terms of the GNU General
> + * Public License ("GPL") version 2, in which case the provisions of the
> + * GPL apply INSTEAD OF those given above.
> + *
> + * The provided data structures and external interfaces from this code
> + * are not restricted to be used by modules with a GPL compatible license.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
> + * DAMAGE.
> + *
> + * Send feedback to <socketcan-users@lists.berlios.de>

please remove

> + */
> +
> +#ifndef CC770_DEV_H
> +#define CC770_DEV_H
> +
> +#include <linux/can/dev.h>
> +
> +struct cc770_msgobj {
> +	u8 ctrl0;
> +	u8 ctrl1;
> +	u8 id[4];
> +	u8 config;
> +	u8 data[8];
> +	u8 dontuse;		/* padding */
> +} __attribute__ ((packed));
> +
> +struct cc770_regs {
> +	union {
> +		struct cc770_msgobj msgobj[16]; /* Message object 1..15 */
> +		struct {
> +			u8 control;		/* Control Register */
> +			u8 status;		/* Status Register */
> +			u8 cpu_interface;	/* CPU Interface Register */
> +			u8 dontuse1;
> +			u8 high_speed_read[2];	/* High Speed Read */
> +			u8 global_mask_std[2];	/* Standard Global Mask */
> +			u8 global_mask_ext[4];	/* Extended Global Mask */
> +			u8 msg15_mask[4];	/* Message 15 Mask */
> +			u8 dontuse2[15];
> +			u8 clkout;		/* Clock Out Register */
> +			u8 dontuse3[15];
> +			u8 bus_config;		/* Bus Configuration Register */
> +			u8 dontuse4[15];
> +			u8 bit_timing_0;	/* Bit Timing Register byte 0 */
> +			u8 dontuse5[15];
> +			u8 bit_timing_1;	/* Bit Timing Register byte 1 */
> +			u8 dontuse6[15];
> +			u8 interrupt;		/* Interrupt Register */
> +			u8 dontuse7[15];
> +			u8 rx_error_counter;	/* Receive Error Counter */
> +			u8 dontuse8[15];
> +			u8 tx_error_counter;	/* Transmit Error Counter */
> +			u8 dontuse9[31];
> +			u8 p1_conf;
> +			u8 dontuse10[15];
> +			u8 p2_conf;
> +			u8 dontuse11[15];
> +			u8 p1_in;
> +			u8 dontuse12[15];
> +			u8 p2_in;
> +			u8 dontuse13[15];
> +			u8 p1_out;
> +			u8 dontuse14[15];
> +			u8 p2_out;
> +			u8 dontuse15[15];
> +			u8 serial_reset_addr;
> +		};
> +	};
> +} __attribute__ ((packed));
> +
> +/* Control Register (0x00) */
> +#define CTRL_INI	0x01	/* Initialization */
> +#define CTRL_IE		0x02	/* Interrupt Enable */
> +#define CTRL_SIE	0x04	/* Status Interrupt Enable */
> +#define CTRL_EIE	0x08	/* Error Interrupt Enable */
> +#define CTRL_EAF	0x20	/* Enable additional functions */
> +#define CTRL_CCE	0x40	/* Change Configuration Enable */
> +
> +/* Status Register (0x01) */
> +#define STAT_LEC_STUFF	0x01	/* Stuff error */
> +#define STAT_LEC_FORM	0x02	/* Form error */
> +#define STAT_LEC_ACK	0x03	/* Acknowledgement error */
> +#define STAT_LEC_BIT1	0x04	/* Bit1 error */
> +#define STAT_LEC_BIT0	0x05	/* Bit0 error */
> +#define STAT_LEC_CRC	0x06	/* CRC error */
> +#define STAT_LEC_MASK	0x07	/* Last Error Code mask */
> +#define STAT_TXOK	0x08	/* Transmit Message Successfully */
> +#define STAT_RXOK	0x10	/* Receive Message Successfully */
> +#define STAT_WAKE	0x20	/* Wake Up Status */
> +#define STAT_WARN	0x40	/* Warning Status */
> +#define STAT_BOFF	0x80	/* Bus Off Status */
> +
> +/*
> + * CPU Interface Register (0x02)
> + * Clock Out Register (0x1f)
> + * Bus Configuration Register (0x2f)
> + *
> + * see include/linux/can/platform/cc770.h
> + */
> +
> +/* Message Control Register 0 (Base Address + 0x0) */
> +#define INTPND_RES	0x01	/* No Interrupt pending */
> +#define INTPND_SET	0x02	/* Interrupt pending */
> +#define INTPND_UNC	0x03
> +#define RXIE_RES	0x04	/* Receive Interrupt Disable */
> +#define RXIE_SET	0x08	/* Receive Interrupt Enable */
> +#define RXIE_UNC	0x0c
> +#define TXIE_RES	0x10	/* Transmit Interrupt Disable */
> +#define TXIE_SET	0x20	/* Transmit Interrupt Enable */
> +#define TXIE_UNC	0x30
> +#define MSGVAL_RES	0x40	/* Message Invalid */
> +#define MSGVAL_SET	0x80	/* Message Valid */
> +#define MSGVAL_UNC	0xc0
> +
> +/* Message Control Register 1 (Base Address + 0x01) */
> +#define NEWDAT_RES	0x01	/* No New Data */
> +#define NEWDAT_SET	0x02	/* New Data */
> +#define NEWDAT_UNC	0x03
> +#define MSGLST_RES	0x04	/* No Message Lost */
> +#define MSGLST_SET	0x08	/* Message Lost */
> +#define MSGLST_UNC	0x0c
> +#define CPUUPD_RES	0x04	/* No CPU Updating */
> +#define CPUUPD_SET	0x08	/* CPU Updating */
> +#define CPUUPD_UNC	0x0c
> +#define TXRQST_RES	0x10	/* No Transmission Request */
> +#define TXRQST_SET	0x20	/* Transmission Request */
> +#define TXRQST_UNC	0x30
> +#define RMTPND_RES	0x40	/* No Remote Request Pending */
> +#define RMTPND_SET	0x80	/* Remote Request Pending */
> +#define RMTPND_UNC	0xc0
> +
> +/* Message Configuration Register (Base Address + 0x06) */
> +#define MSGCFG_XTD	0x04	/* Extended Identifier */
> +#define MSGCFG_DIR	0x08	/* Direction is Transmit */
> +
> +#define MSGOBJ_FIRST	1
> +#define MSGOBJ_LAST	15
> +
> +#define CC770_IO_SIZE	0x100
> +#define CC770_MAX_IRQ	20	/* max. number of interrupts handled in ISR */
> +
> +#define CC770_ECHO_SKB_MAX	1
> +
> +#define cc770_read_reg(priv, member)					\
> +	priv->read_reg(priv, offsetof(struct cc770_regs, member))
> +
> +#define cc770_write_reg(priv, member, value)				\
> +	priv->write_reg(priv, offsetof(struct cc770_regs, member), value)
> +
> +/*
> + * Message objects and flags used by this driver
> + */
> +#define CC770_OBJ_FLAG_RX 	0x01
> +#define CC770_OBJ_FLAG_RTR	0x02
> +#define CC770_OBJ_FLAG_EFF	0x04
> +
> +enum {
> +	CC770_OBJ_RX0 = 0,	/* for receiving normal messages */
> +	CC770_OBJ_RX1,		/* for receiving normal messages */
> +	CC770_OBJ_RX_RTR0,	/* for receiving remote transmission requests */
> +	CC770_OBJ_RX_RTR1,	/* for receiving remote transmission requests */
> +	CC770_OBJ_TX,		/* for sending messages */
> +	CC770_OBJ_MAX
> +};
> +
> +#define obj2msgobj(o)	(MSGOBJ_LAST - (o)) /* message object 11..15 */
> +
> +/*
> + * CC770 private data structure
> + */
> +struct cc770_priv {
> +	struct can_priv can;	/* must be the first member */
> +	int open_time;
> +	struct sk_buff *echo_skb;
> +
> +	/* the lower-layer is responsible for appropriate locking */
> +	u8 (*read_reg)(const struct cc770_priv *priv, int reg);
> +	void (*write_reg)(const struct cc770_priv *priv, int reg, u8 val);
> +	void (*pre_irq)(const struct cc770_priv *priv);
> +	void (*post_irq)(const struct cc770_priv *priv);
> +
> +	void *priv;		/* for board-specific data */
> +	struct net_device *dev;
> +
> +	void __iomem *reg_base;	/* ioremap'ed address to registers */
> +	unsigned long irq_flags;	/* for request_irq() */
> +
> +	unsigned char obj_flags[CC770_OBJ_MAX];
> +	u8 control_normal_mode;	/* Control register for normal mode */
> +	u8 cpu_interface;	/* CPU interface register */
> +	u8 clkout;		/* Clock out register */
> +	u8 bus_config;		/* Bus conffiguration register */
> +};
> +
> +struct net_device *alloc_cc770dev(int sizeof_priv);
> +void free_cc770dev(struct net_device *dev);
> +int register_cc770dev(struct net_device *dev);
> +void unregister_cc770dev(struct net_device *dev);
> +
> +#endif /* CC770_DEV_H */
> diff --git a/include/linux/can/platform/cc770.h b/include/linux/can/platform/cc770.h
> new file mode 100644
> index 0000000..c4ed994
> --- /dev/null
> +++ b/include/linux/can/platform/cc770.h
> @@ -0,0 +1,33 @@
> +#ifndef _CAN_PLATFORM_CC770_H_
> +#define _CAN_PLATFORM_CC770_H_
> +
> +/* CPU Interface Register (0x02) */
> +#define CPUIF_CEN	0x01	/* Clock Out Enable */
> +#define CPUIF_MUX	0x04	/* Multiplex */
> +#define CPUIF_SLP	0x08	/* Sleep */
> +#define CPUIF_PWD	0x10	/* Power Down Mode */
> +#define CPUIF_DMC	0x20	/* Divide Memory Clock */
> +#define CPUIF_DSC	0x40	/* Divide System Clock */
> +#define CPUIF_RST	0x80	/* Hardware Reset Status */
> +
> +/* Clock Out Register (0x1f) */
> +#define CLKOUT_CD_MASK  0x0f	/* Clock Divider mask */
> +#define CLKOUT_SL_MASK	0x30	/* Slew Rate mask */
> +#define CLKOUT_SL_SHIFT	4
> +
> +/* Bus Configuration Register (0x2f) */
> +#define BUSCFG_DR0	0x01	/* Disconnect RX0 Input / Select RX input */
> +#define BUSCFG_DR1	0x02	/* Disconnect RX1 Input / Silent mode */
> +#define BUSCFG_DT1	0x08	/* Disconnect TX1 Output */
> +#define BUSCFG_POL	0x20	/* Polarity dominant or recessive */
> +#define BUSCFG_CBY	0x40	/* Input Comparator Bypass */
> +
> +struct cc770_platform_data {
> +	u32 osc_freq;	/* CAN bus oscillator frequency in Hz */
> +
> +	u8 cir;	 	/* CPU Interface Register */
> +	u8 cor;		/* Clock Out Register */
> +	u8 bcr;		/* Bus Configuration Register */
> +};
> +
> +#endif	/* !_CAN_PLATFORM_CC770_H_ */


-- 
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: 262 bytes --]

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2011-11-28  9:17         ` Wolfgang Grandegger
@ 2011-11-28 12:03           ` Wolfgang Zarre
       [not found]             ` <4ED37885.8080909-PyqsHJVlJN8AvxtiuMwx3w@public.gmane.org>
  0 siblings, 1 reply; 66+ messages in thread
From: Wolfgang Zarre @ 2011-11-28 12:03 UTC (permalink / raw)
  To: Wolfgang Grandegger
  Cc: Oliver Hartkopp, netdev, linux-can, socketcan-users, IreneV,
	Stanislav Yelenskiy

Hello Wolfgang,

> On 11/28/2011 09:56 AM, Wolfgang Zarre wrote:
>> Hello Oliver,
>>
>>> Hello Wolfgang,
>>>
>>> many thanks for posting this driver. Indeed this is the last from the
>>> missing
>>> drivers in the SVN ...
>>
>> @Wolfgang
>>
>> The same her, thanks a lot.
>>
>>>
>>> I added Wolfgang Zarre to the list of recipients who tested your CC770
>>> driver
>>> recently:
>>>
>>> http://old.nabble.com/Compile-Fails-On-2.6.39-2-td32259346.html
>>>
>>> Maybe he can check this latest version and can send a "Tested-by:"
>>>
>>> @Wolfgang Zarre: The entire patch set from Wolfgang Grandegger is here:
>>>
>>> http://patchwork.ozlabs.org/patch/127653/
>>> http://patchwork.ozlabs.org/patch/127651/
>>> http://patchwork.ozlabs.org/patch/127654/
>>> http://patchwork.ozlabs.org/patch/127652/
>>
>> In fact a month ago we discovered a problem with the previous isa driver
>> but were not
>> able to reproduce it.
>>
>> Last Friday during a test run we got the same problem and with some
>> further tests I
>> was able to reproduce and started with some investigation.
>>
>> So the patches came in quite handy and even not to waste time I was
>> applying the
>> patches to an updated svn tree but had to do some manual corrections to
>> get it
>> compiled.
>>
>> So far the driver is functioning quite good and I was hoping that our
>> problem would
>> be solved as well.
>
> Well, I do not remember any fix... apart from

Of course not, was never reported because we couldn't reproduce.

>
>> But unfortunately that is not the case and it would be great if somebody
>> would have
>> an idea or similar experience and maybe a solution.
>>
>> In use:
>> ISA card: B&R with CC770 (40007) Series Bosch CAN Controller - LQFP-44
>> Kernel: 2.6.39.4
>> Module: modprobe cc770_isa irq=0xa port=0x384 indirect=1
>> Commands: ip link set can0 up type can bitrate 500000;ip link set can0
>> txqueuelen 2000
>
> ... using a reasonable default for bcr of 0x40. But you may need to
> provide better values for cir, bcr and cor.
>

OMG, sorry that I was bothering You but You are absolutely right and with Your
statement You brought be back on track and You made my day. Thank You !!!!!!

I just took the values for cpu and bus I was using in my lincan driver and funny
enough now it's working absolutely perfect.

Module: modprobe cc770_isa irq=0xa port=0x384 indirect=1 cir=0x61 bcr=0x4A

Was just sending 50000 telegrams, perfect and no problem at all.

Thanks a lot again!!!!


>> dmesg:
>> [190911.144337] CAN device driver interface
>> [190911.153316] cc770 CAN netdevice driver
>> [190911.159708] cc770_isa: platform device 0: port=0x384, mem=0x0, irq=10
>> [190911.159740] cc770_isa cc770_isa.0: probing idx=0: port=0x384,
>> mem=0x0, irq=10
>> [190911.159799] cc770_isa cc770_isa.0: (unregistered net_device): i82527
>> mode with additional functions
>> [190911.161338] cc770_isa cc770_isa.0: cc770_isa device registered
>> (reg_base=0x00000384, irq=10)
>> [190911.161384] Legacy cc770_isa driver for max. 8 devices registered
>> [190912.173762] cc770_isa cc770_isa.0: can0: setting BTR0=0x00 BTR1=0x1c
>> [190912.173835] cc770_isa cc770_isa.0: can0: Message object 15 for RX
>> data, RTR, SFF and EFF
>> [190912.173852] cc770_isa cc770_isa.0: can0: Message object 11 for TX
>> data, RTR, SFF and EFF
>>
>>
>> Description of problem:
>> After a while sending quite some telegrams the driver of a sudden stops
>> transmitting
>> and the queue is running full but still capable to receive telegrams.
>> This issue is not depending on the amount of transmitted telegrams and
>> also no logfile
>> entries.
>
> What do you get with "candump -t d any,0:0,#FFFFFFFF"? What does "ip -d
> -s link show" show?
>
> Wolfgang.
>

Wolfgang



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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2011-11-25  9:43 ` [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527 Wolfgang Grandegger
       [not found]   ` <1322214204-1121-3-git-send-email-wg-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
@ 2011-11-28 12:09   ` Marc Kleine-Budde
       [not found]     ` <4ED379F3.1070206-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
  1 sibling, 1 reply; 66+ messages in thread
From: Marc Kleine-Budde @ 2011-11-28 12:09 UTC (permalink / raw)
  To: Wolfgang Grandegger
  Cc: netdev, linux-can, socketcan-users, IreneV, Stanislav Yelenskiy

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

On 11/25/2011 10:43 AM, Wolfgang Grandegger wrote:
> This patch adds support for legacy Bosch CC770 and Intel AN82527 CAN
> controllers on the ISA or PC-104 bus. The I/O port or memory address
> and the IRQ number must be specified via module parameters:
> 
>   insmod cc770_isa.ko port=0x310,0x380 irq=7,11
> 
> for ISA devices using I/O ports or:
> 
>   insmod cc770_isa.ko mem=0xd1000,0xd1000 irq=7,11
> 
> for memory mapped ISA devices.
> 
> Indirect access via address and data port is supported as well:
> 
>   insmod cc770_isa.ko port=0x310,0x380 indirect=1 irq=7,11
> 
> Furthermore, the following mode parameter can be defined:
> 
>   clk: External oscillator clock frequency (default=16000000 [16 MHz])
>   cir: CPU interface register (default=0x40 [DSC])
>   ocr, Bus configuration register (default=0x40 [CBY])
>   cor, Clockout register (default=0x00)
> 
> Note: for clk, cir, bcr and cor, the first argument re-defines the
> default for all other devices, e.g.:
> 
>   insmod cc770_isa.ko mem=0xd1000,0xd1000 irq=7,11 clk=24000000
> 
> is equivalent to
> 
>   insmod cc770_isa.ko mem=0xd1000,0xd1000 irq=7,11 clk=24000000,24000000
> 
> Signed-off-by: Wolfgang Grandegger <wg@grandegger.com>

Some nitpicking inside.

Marc
> ---
>  drivers/net/can/cc770/Kconfig     |   11 ++
>  drivers/net/can/cc770/Makefile    |    1 +
>  drivers/net/can/cc770/cc770_isa.c |  336 +++++++++++++++++++++++++++++++++++++
>  3 files changed, 348 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/net/can/cc770/cc770_isa.c
> 
> diff --git a/drivers/net/can/cc770/Kconfig b/drivers/net/can/cc770/Kconfig
> index 225131b..28e4d48 100644
> --- a/drivers/net/can/cc770/Kconfig
> +++ b/drivers/net/can/cc770/Kconfig
> @@ -1,3 +1,14 @@
>  menuconfig CAN_CC770
>  	tristate "Bosch CC770 and Intel AN82527 devices"
>  	depends on CAN_DEV && HAS_IOMEM
> +
> +if CAN_CC770
> +
> +config CAN_CC770_ISA
> +	tristate "ISA Bus based legacy CC770 driver"
> +	---help---
> +	  This driver adds legacy support for CC770 and AN82527 chips
> +	  connected to the ISA bus using I/O port, memory mapped or
> +	  indirect access.
> +
> +endif
> diff --git a/drivers/net/can/cc770/Makefile b/drivers/net/can/cc770/Makefile
> index 34e8180..872ecff 100644
> --- a/drivers/net/can/cc770/Makefile
> +++ b/drivers/net/can/cc770/Makefile
> @@ -3,5 +3,6 @@
>  #
>  
>  obj-$(CONFIG_CAN_CC770) += cc770.o
> +obj-$(CONFIG_CAN_CC770_ISA) += cc770_isa.o
>  
>  ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
> diff --git a/drivers/net/can/cc770/cc770_isa.c b/drivers/net/can/cc770/cc770_isa.c
> new file mode 100644
> index 0000000..3aaecd5
> --- /dev/null
> +++ b/drivers/net/can/cc770/cc770_isa.c
> @@ -0,0 +1,336 @@
> +/*
> + * Copyright (C) 2009, 2011 Wolfgang Grandegger <wg@grandegger.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the version 2 of the GNU General Public License
> + * as published by the Free Software Foundation
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

Please remove the address.

> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/interrupt.h>
> +#include <linux/netdevice.h>
> +#include <linux/delay.h>
> +#include <linux/irq.h>
> +#include <linux/io.h>
> +#include <linux/can.h>
> +#include <linux/can/dev.h>
> +
> +#include "cc770.h"
> +
> +#define DRV_NAME "cc770_isa"
> +
> +#define MAXDEV 8
> +
> +MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
> +MODULE_DESCRIPTION("Socket-CAN driver for CC770 on the ISA bus");
> +MODULE_LICENSE("GPL v2");
> +
> +#define CLK_DEFAULT	16000000	/* 16 MHz */
> +#define COR_DEFAULT	0x00
> +#define BCR_DEFAULT	BUSCFG_CBY
> +
> +static unsigned long port[MAXDEV];
> +static unsigned long mem[MAXDEV];
> +static int __devinitdata irq[MAXDEV];
> +static int __devinitdata clk[MAXDEV];
> +static u8 __devinitdata cir[MAXDEV] = {[0 ... (MAXDEV - 1)] = 0xff};
> +static u8 __devinitdata cor[MAXDEV] = {[0 ... (MAXDEV - 1)] = 0xff};
> +static u8 __devinitdata bcr[MAXDEV] = {[0 ... (MAXDEV - 1)] = 0xff};
> +static int __devinitdata indirect[MAXDEV] = {[0 ... (MAXDEV - 1)] = -1};
> +
> +module_param_array(port, ulong, NULL, S_IRUGO);
> +MODULE_PARM_DESC(port, "I/O port number");
> +
> +module_param_array(mem, ulong, NULL, S_IRUGO);
> +MODULE_PARM_DESC(mem, "I/O memory address");
> +
> +module_param_array(indirect, int, NULL, S_IRUGO);
> +MODULE_PARM_DESC(indirect, "Indirect access via address and data port");
> +
> +module_param_array(irq, int, NULL, S_IRUGO);
> +MODULE_PARM_DESC(irq, "IRQ number");
> +
> +module_param_array(clk, int, NULL, S_IRUGO);
> +MODULE_PARM_DESC(clk, "External oscillator clock frequency "
> +		 "(default=16000000 [16 MHz])");
> +
> +module_param_array(cir, byte, NULL, S_IRUGO);
> +MODULE_PARM_DESC(cir, "CPU interface register (default=0x40 [DSC])");
> +
> +module_param_array(cor, byte, NULL, S_IRUGO);
> +MODULE_PARM_DESC(cor, "Clockout register (default=0x00)");
> +
> +module_param_array(bcr, byte, NULL, S_IRUGO);
> +MODULE_PARM_DESC(bcr, "Bus configuration register (default=0x40 [CBY])");
> +
> +#define CC770_IOSIZE          0x20
> +#define CC770_IOSIZE_INDIRECT 0x02
> +
> +static struct platform_device *cc770_isa_devs[MAXDEV];
> +
> +static u8 cc770_isa_mem_read_reg(const struct cc770_priv *priv, int reg)
> +{
> +	return readb(priv->reg_base + reg);
> +}
> +
> +static void cc770_isa_mem_write_reg(const struct cc770_priv *priv,
> +				      int reg, u8 val)
> +{
> +	writeb(val, priv->reg_base + reg);
> +}
> +
> +static u8 cc770_isa_port_read_reg(const struct cc770_priv *priv, int reg)
> +{
> +	return inb((unsigned long)priv->reg_base + reg);
> +}
> +
> +static void cc770_isa_port_write_reg(const struct cc770_priv *priv,
> +				       int reg, u8 val)
> +{
> +	outb(val, (unsigned long)priv->reg_base + reg);
> +}
> +
> +static u8 cc770_isa_port_read_reg_indirect(const struct cc770_priv *priv,
> +					     int reg)
> +{
> +	unsigned long base = (unsigned long)priv->reg_base;
> +
> +	outb(reg, base);
> +	return inb(base + 1);
> +}
> +
> +static void cc770_isa_port_write_reg_indirect(const struct cc770_priv *priv,
> +						int reg, u8 val)
> +{
> +	unsigned long base = (unsigned long)priv->reg_base;
> +
> +	outb(reg, base);
> +	outb(val, base + 1);
> +}
> +
> +static int __devinit cc770_isa_probe(struct platform_device *pdev)
> +{
> +	struct net_device *dev;
> +	struct cc770_priv *priv;
> +	void __iomem *base = NULL;
> +	int iosize = CC770_IOSIZE;
> +	int idx = pdev->id;
> +	int err;
> +	u32 clktmp;
> +
> +	dev_dbg(&pdev->dev, "probing idx=%d: port=%#lx, mem=%#lx, irq=%d\n",
> +		idx, port[idx], mem[idx], irq[idx]);
> +	if (mem[idx]) {
> +		if (!request_mem_region(mem[idx], iosize, DRV_NAME)) {
> +			err = -EBUSY;
> +			goto exit;
> +		}
> +		base = ioremap_nocache(mem[idx], iosize);
> +		if (!base) {
> +			err = -ENOMEM;
> +			goto exit_release;
> +		}
> +	} else {
> +		if (indirect[idx] > 0 ||
> +		    (indirect[idx] == -1 && indirect[0] > 0))
> +			iosize = CC770_IOSIZE_INDIRECT;
> +		if (!request_region(port[idx], iosize, DRV_NAME)) {
> +			err = -EBUSY;
> +			goto exit;
> +		}
> +	}
> +
> +	dev = alloc_cc770dev(0);MAXDEV
> +	if (!dev) {
> +		err = -ENOMEM;
> +		goto exit_unmap;
> +	}
> +	priv = netdev_priv(dev);
> +
> +	dev->irq = irq[idx];
> +	priv->irq_flags = IRQF_SHARED;
> +	if (mem[idx]) {
> +		priv->reg_base = base;
> +		dev->base_addr = mem[idx];
> +		priv->read_reg = cc770_isa_mem_read_reg;
> +		priv->write_reg = cc770_isa_mem_write_reg;
> +	} else {
> +		priv->reg_base = (void __iomem *)port[idx];
> +		dev->base_addr = port[idx];
> +
> +		if (iosize == CC770_IOSIZE_INDIRECT) {
> +			priv->read_reg = cc770_isa_port_read_reg_indirect;
> +			priv->write_reg = cc770_isa_port_write_reg_indirect;
> +		} else {
> +			priv->read_reg = cc770_isa_port_read_reg;
> +			priv->write_reg = cc770_isa_port_write_reg;
> +		}
> +	}
> +
> +	if (clk[idx])
> +		clktmp = clk[idx];
> +	else if (clk[0])
> +		clktmp = clk[0];
> +	else
> +		clktmp = CLK_DEFAULT;
> +	priv->can.clock.freq = clktmp;
> +
> +	if (cir[idx] != 0xff) {
> +		priv->cpu_interface = cir[idx] & 0xff;
> +	} else if (cir[0] != 0xff) {
> +		priv->cpu_interface = cir[0] & 0xff;
> +	} else {
> +		/* The system clock may not exceed 10 MHz */
> +		if (clktmp > 10000000) {
> +			priv->cpu_interface |= CPUIF_DSC;
> +			clktmp /= 2;
> +		}
> +		/* The memory clock may not exceed 8 MHz */
> +		if (clktmp > 8000000)
> +			priv->cpu_interface |= CPUIF_DMC;
> +	}
> +
> +	if (priv->cpu_interface & CPUIF_DSC)
> +		priv->can.clock.freq /= 2;
> +
> +	if (bcr[idx] != 0xff)
> +		priv->bus_config = bcr[idx] & 0xff;
> +	else if (bcr[0] != 0xff)
> +		priv->bus_config = bcr[0] & 0xff;
bus_config is u8
> +	else
> +		priv->bus_config = BCR_DEFAULT;
> +
> +	if (cor[idx] != 0xff)
> +		priv->clkout = cor[idx];
> +	else if (cor[0] != 0xff)
> +		priv->clkout = cor[0] & 0xff;
> +	else
> +		priv->clkout = COR_DEFAULT;
> +
> +	dev_set_drvdata(&pdev->dev, dev);
> +	SET_NETDEV_DEV(dev, &pdev->dev);
> +
> +	err = register_cc770dev(dev);
> +	if (err) {
> +		dev_err(&pdev->dev, "registering %s failed (err=%d)\n",
> +			DRV_NAME, err);
> +		goto exit_unmap;
> +	}
> +
> +	dev_info(&pdev->dev, "%s device registered (reg_base=0x%p, irq=%d)\n",
> +		 DRV_NAME, priv->reg_base, dev->irq);
> +	return 0;
> +
> + exit_unmap:
> +	if (mem[idx])
> +		iounmap(base);
> + exit_release:
> +	if (mem[idx])
> +		release_mem_region(mem[idx], iosize);
> +	else
> +		release_region(port[idx], iosize);
> + exit:
> +	return err;
> +}
> +
> +static int __devexit cc770_isa_remove(struct platform_device *pdev)
> +{
> +	struct net_device *dev = dev_get_drvdata(&pdev->dev);
> +	struct cc770_priv *priv = netdev_priv(dev);
> +	int idx = pdev->id;
> +
> +	unregister_cc770dev(dev);
> +	dev_set_drvdata(&pdev->dev, NULL);
> +
> +	if (mem[idx]) {
> +		iounmap(priv->reg_base);
> +		release_mem_region(mem[idx], CC770_IOSIZE);
> +	} else {
> +		if (priv->read_reg == cc770_isa_port_read_reg_indirect)
> +			release_region(port[idx], CC770_IOSIZE_INDIRECT);
> +		else
> +			release_region(port[idx], CC770_IOSIZE);
> +	}
> +	free_cc770dev(dev);
> +
> +	return 0;
> +}
> +
> +static struct platform_driver cc770_isa_driver = {
> +	.probe = cc770_isa_probe,
> +	.remove = __devexit_p(cc770_isa_remove),
> +	.driver = {
> +		.name = DRV_NAME,
> +		.owner = THIS_MODULE,
> +	},
> +};
> +
> +static int __init cc770_isa_init(void)
> +{
> +	int idx, err;
> +
> +	for (idx = 0; idx < MAXDEV; idx++) {
ARRAY_SIZE?
> +		if ((port[idx] || mem[idx]) && irq[idx]) {
> +			cc770_isa_devs[idx] =
> +				platform_device_alloc(DRV_NAME, idx);
> +			if (!cc770_isa_devs[idx]) {
> +				err = -ENOMEM;
> +				goto exit_free_devices;
> +			}
> +			err = platform_device_add(cc770_isa_devs[idx]);
> +			if (err) {
> +				platform_device_put(cc770_isa_devs[idx]);
> +				goto exit_free_devices;
> +			}
> +			pr_debug("%s: platform device %d: port=%#lx, mem=%#lx, "
> +				 "irq=%d\n",
> +				 DRV_NAME, idx, port[idx], mem[idx], irq[idx]);
> +		} else if (idx == 0 || port[idx] || mem[idx]) {
> +				pr_err("%s: insufficient parameters supplied\n",
> +				       DRV_NAME);
> +				err = -EINVAL;
> +				goto exit_free_devices;
> +		}
> +	}
> +
> +	err = platform_driver_register(&cc770_isa_driver);
> +	if (err)
> +		goto exit_free_devices;
> +
> +	pr_info("Legacy %s driver for max. %d devices registered\n",
> +		DRV_NAME, MAXDEV);
> +
> +	return 0;
> +
> +exit_free_devices:
> +	while (--idx >= 0) {
> +		if (cc770_isa_devs[idx])
> +			platform_device_unregister(cc770_isa_devs[idx]);
> +	}
> +
> +	return err;
> +}
> +module_init(cc770_isa_init);
> +
> +static void __exit cc770_isa_exit(void)
> +{
> +	int idx;
> +
> +	platform_driver_unregister(&cc770_isa_driver);
> +	for (idx = 0; idx < MAXDEV; idx++) {
ARRAY_SIZE
> +		if (cc770_isa_devs[idx])
> +			platform_device_unregister(cc770_isa_devs[idx]);
> +	}
> +}
> +module_exit(cc770_isa_exit);


-- 
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: 262 bytes --]

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

* Re: [Socketcan-users] [PATCH net-next v2 1/4] can: cc770: add driver core for the Bosch CC770 and Intel AN82527
  2011-11-28 11:28   ` [Socketcan-users] " Marc Kleine-Budde
@ 2011-11-28 13:52     ` Wolfgang Grandegger
       [not found]       ` <4ED3922A.50704-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
       [not found]     ` <4ED3704D.5020903-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
  1 sibling, 1 reply; 66+ messages in thread
From: Wolfgang Grandegger @ 2011-11-28 13:52 UTC (permalink / raw)
  To: Marc Kleine-Budde; +Cc: netdev, socketcan-users, linux-can

Hi Marc,

thanks for reviewing...

On 11/28/2011 12:28 PM, Marc Kleine-Budde wrote:
> On 11/25/2011 10:43 AM, Wolfgang Grandegger wrote:
>> Signed-off-by: Wolfgang Grandegger <wg@grandegger.com>
>> ---
>>  drivers/net/can/Kconfig            |    2 +
>>  drivers/net/can/Makefile           |    1 +
>>  drivers/net/can/cc770/Kconfig      |    3 +
>>  drivers/net/can/cc770/Makefile     |    7 +
>>  drivers/net/can/cc770/cc770.c      |  895 ++++++++++++++++++++++++++++++++++++
>>  drivers/net/can/cc770/cc770.h      |  234 ++++++++++
>>  include/linux/can/platform/cc770.h |   33 ++
>>  7 files changed, 1175 insertions(+), 0 deletions(-)
>>  create mode 100644 drivers/net/can/cc770/Kconfig
>>  create mode 100644 drivers/net/can/cc770/Makefile
>>  create mode 100644 drivers/net/can/cc770/cc770.c
>>  create mode 100644 drivers/net/can/cc770/cc770.h
>>  create mode 100644 include/linux/can/platform/cc770.h
> 
> I don't know the hardware, but the code looks good to me, some comments:
> - The driver doesn't use NAPI, can this be added

In principle yes but there is little benefit. This CAN controller does
buffer not more than two messages (on msg object 15) and bus errors are
not reported individually, therefore no irq flooding.

> - The rx-handlers have a while(1) loop

Yes, they should be limited.

>   For NAPI you have to add accounting, for the non NAPI case it would
>   be good, too.
> - I think you can move a large number of lines from the .h file into
>   the driver. Code that's not used in the different binding drivers.

Well, not sure if it's worth the effort.

...

>> diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c
>> new file mode 100644
>> index 0000000..47a6965
>> --- /dev/null
>> +++ b/drivers/net/can/cc770/cc770.c
>> @@ -0,0 +1,895 @@
>> +/*
>> + * cc770.c - Bosch CC770 and Intel AN82527 network device driver
>> + *
>> + * Copyright (C) 2009, 2011 Wolfgang Grandegger <wg@grandegger.com>
>> + *
>> + * Derived from the old Socket-CAN i82527 driver:
>> + *
>> + * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
>> + * All rights reserved.
>> + *
>> + * Redistribution and use in source and binary forms, with or without
>> + * modification, are permitted provided that the following conditions
>> + * are met:
>> + * 1. Redistributions of source code must retain the above copyright
>> + *    notice, this list of conditions and the following disclaimer.
>> + * 2. Redistributions in binary form must reproduce the above copyright
>> + *    notice, this list of conditions and the following disclaimer in the
>> + *    documentation and/or other materials provided with the distribution.
>> + * 3. Neither the name of Volkswagen nor the names of its contributors
>> + *    may be used to endorse or promote products derived from this software
>> + *    without specific prior written permission.
>> + *
>> + * Alternatively, provided that this notice is retained in full, this
>> + * software may be distributed under the terms of the GNU General
>> + * Public License ("GPL") version 2, in which case the provisions of the
>> + * GPL apply INSTEAD OF those given above.
>> + *
>> + * The provided data structures and external interfaces from this code
>> + * are not restricted to be used by modules with a GPL compatible license.
>> + *
>> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
>> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
>> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
>> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
>> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
>> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
>> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
>> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
>> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
>> + * DAMAGE.
>> + *
>> + * Send feedback to <socketcan-users@lists.berlios.de>
> 
> please remove :)

Already done in v3.

>> +#include <linux/module.h>
>> +#include <linux/init.h>
>> +#include <linux/kernel.h>
>> +#include <linux/sched.h>
>> +#include <linux/types.h>
>> +#include <linux/fcntl.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/ptrace.h>
>> +#include <linux/string.h>
>> +#include <linux/errno.h>
>> +#include <linux/netdevice.h>
>> +#include <linux/if_arp.h>
>> +#include <linux/if_ether.h>
>> +#include <linux/skbuff.h>
>> +#include <linux/delay.h>
>> +
>> +#include <linux/can.h>
>> +#include <linux/can/dev.h>
>> +#include <linux/can/error.h>
>> +#include <linux/can/dev.h>
>> +#include <linux/can/platform/cc770.h>
>> +
>> +#include "cc770.h"
> 
> Can you move all the definitions that are not needed in the other
> drivers (e.g. ISA, etc.) into this .c file?

Makes sense if the bus drivers are not allowed to access chips
registers, which is currently not the case...

>> +
>> +#define DRV_NAME  "cc770"
>> +
>> +MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
>> +MODULE_LICENSE("GPL v2");
>> +MODULE_DESCRIPTION(DRV_NAME "CAN netdevice driver");
>> +
>> +/*
>> + * The CC770 is a CAN controller from Bosch, which is 100% compatible
>> + * with the AN82527 from Intel, but with "bugs" being fixed and some
>> + * additional functionality, mainly:
>> + *
>> + * 1. RX and TX error counters are readable.
>> + * 2. Support of silent (listen-only) mode.
>> + * 3. Message object 15 can receive all types of frames, also RTR and EFF.
>> + *
>> + * Details are available from Bosch's "CC770_Product_Info_2007-01.pdf",
>> + * which explains in detail the compatibility between the CC770 and the
>> + * 82527. This driver use the additional functionality 3. on real CC770
>> + * devices. Unfortunately, the CC770 does still not store the message
>> + * identifier of received remote transmission request frames and
>> + * therefore it's set to 0.
>> + *
>> + * The message objects 1..14 can be used for TX and RX while the message
>> + * objects 15 is optimized for RX. It has a shadow register for reliable
>> + * data receiption under heavy bus load. Therefore it makes sense to use
>> + * this message object for the needed use case. The frame type (EFF/SFF)
>> + * for the message object 15 can be defined via kernel module parameter
>> + * "msgobj15_eff". If not equal 0, it will receive 29-bit EFF frames,
>> + * otherwise 11 bit SFF messages.
>> + */
>> +static int msgobj15_eff;
>> +module_param(msgobj15_eff, int, S_IRUGO);
>> +MODULE_PARM_DESC(msgobj15_eff, "Extended 29-bit frames for message object 15 "
>> +		 "(default: 11-bit standard frames)");
>> +
>> +static int i82527_compat;
>> +module_param(i82527_compat, int, S_IRUGO);
>> +MODULE_PARM_DESC(i82527_compat, "Strict Intel 82527 comptibility mode "
>> +		 "without using additional functions");
>> +
>> +/*
>> + * This driver uses the last 5 message objects 11..15. The definitions
>> + * and structure below allows to configure and assign them to the real
>> + * message object.
>> + */
>> +static unsigned char cc770_obj_flags[CC770_OBJ_MAX] = {
>> +	[CC770_OBJ_RX0] = CC770_OBJ_FLAG_RX,
>> +	[CC770_OBJ_RX1] = CC770_OBJ_FLAG_RX | CC770_OBJ_FLAG_EFF,
>> +	[CC770_OBJ_RX_RTR0] = CC770_OBJ_FLAG_RX | CC770_OBJ_FLAG_RTR,
>> +	[CC770_OBJ_RX_RTR1] = CC770_OBJ_FLAG_RX | CC770_OBJ_FLAG_RTR |
>> +			      CC770_OBJ_FLAG_EFF,
>> +	[CC770_OBJ_TX] = 0,
>> +};
> 
> Is is worth the trouble making this a per device instance option? In a
> OF-Tree world should this become an "attribute" (or what's the correct
> of-tree word for it?)

Well, only msg object 15 does have double buffering and should therefore
be used for bulk data reception. Therefore we have for the i82527 the
module parameter:

  MODULE_PARM_DESC(msgobj15_eff,
	           "Extended 29-bit frames for message object 15 "
	 	   "(default: 11-bit standard frames)");

For TX we currently use just one object. Anyway, the device tree is not
the right place to define such parameters because it's too static. The
user may want to select it at runtime depending on the application, if
at all. We can change it when there is a *real* requirement.

>> +	for (o = 0; o <  CC770_OBJ_MAX; o++) {
>                          ^^^^^^^^^^^^^
> 
> what about ARRAY_SIZE(priv->obj_flags)

CC770_OBJ_MAX is not derived from a static array definition but as show
below:

  enum {
	CC770_OBJ_RX0 = 0,	/* for receiving normal messages */
	CC770_OBJ_RX1,		/* for receiving normal messages */
	CC770_OBJ_RX_RTR0,	/* for receiving remote transmission requests */
	CC770_OBJ_RX_RTR1,	/* for receiving remote transmission requests */
	CC770_OBJ_TX,		/* for sending messages */
	CC770_OBJ_MAX  <================
  };


> nitpick:
> o is probalby short for object, but usually we use "i" for a for loop
> 
>> +		obj_flags = priv->obj_flags[o];
>> +		mo = obj2msgobj(o);
>> +
>> +		if (obj_flags & CC770_OBJ_FLAG_RX) {
>> +			/*
>> +			 * We don't need extra objects for RTR and EFF if
>> +			 * the additional CC770 functions are enabled.
>> +			 */
>> +			if (priv->control_normal_mode & CTRL_EAF) {
>> +				if (o > 0)
>> +					continue;
>> +				netdev_dbg(dev, "Message object %d for "
>> +					   "RX data, RTR, SFF and EFF\n", mo);
>> +			} else {
>> +				netdev_dbg(dev,
>> +					   "Message object %d for RX %s %s\n",
>> +					   mo, obj_flags & CC770_OBJ_FLAG_RTR ?
>> +					   "RTR" : "data",
>> +					   obj_flags & CC770_OBJ_FLAG_EFF ?
>> +					   "EFF" : "SFF");
>> +			}
>> +
>> +			if (obj_flags & CC770_OBJ_FLAG_EFF)
>> +				msgcfg = MSGCFG_XTD;
>> +			else
>> +				msgcfg = 0;
>> +			if (obj_flags & CC770_OBJ_FLAG_RTR)
>> +				msgcfg |= MSGCFG_DIR;
>> +
>> +			cc770_write_reg(priv, msgobj[mo].config, msgcfg);
>> +			cc770_write_reg(priv, msgobj[mo].ctrl0,
>> +					MSGVAL_SET | TXIE_RES |
>> +					RXIE_SET | INTPND_RES);
>> +
>> +			if (obj_flags & CC770_OBJ_FLAG_RTR)
>> +				cc770_write_reg(priv, msgobj[mo].ctrl1,
>> +						NEWDAT_RES | CPUUPD_SET |
>> +						TXRQST_RES | RMTPND_RES);
>> +			else
>> +				cc770_write_reg(priv, msgobj[mo].ctrl1,
>> +						NEWDAT_RES | MSGLST_RES |
>> +						TXRQST_RES | RMTPND_RES);
>> +		} else {
>> +			netdev_dbg(dev, "Message object %d for "
>> +				   "TX data, RTR, SFF and EFF\n", mo);
>> +
>> +			cc770_write_reg(priv, msgobj[mo].ctrl1,
>> +					RMTPND_RES | TXRQST_RES |
>> +					CPUUPD_RES | NEWDAT_RES);
>> +			cc770_write_reg(priv, msgobj[mo].ctrl0,
>> +					MSGVAL_RES | TXIE_RES |
>> +					RXIE_RES | INTPND_RES);
>> +		}
>> +	}
>> +}
>> +
>> +static void disable_all_objs(const struct cc770_priv *priv)
>> +{
>> +	int i, mo;
> 
> here you use "i"

OK, will fix.

>> +static int cc770_probe_chip(struct net_device *dev)
> 
> nitpick: This chip returns 1 on success and 0 on failure, IMHO unusual
> return value. Why not make it return -ENODEV in case of failure?

OK, will fix.

...

> Are these Hex numbers arbitrary values?

Looks like. Not really a clever probing, though. A comment would be
useful, at least.

>> +	cc770_write_reg(priv, msgobj[1].data[1], 0x25);
>> +	cc770_write_reg(priv, msgobj[2].data[3], 0x52);
>> +	cc770_write_reg(priv, msgobj[10].data[6], 0xc3);
>> +	if ((cc770_read_reg(priv, msgobj[1].data[1]) != 0x25) ||
>> +	    (cc770_read_reg(priv, msgobj[2].data[3]) != 0x52) ||
>> +	    (cc770_read_reg(priv, msgobj[10].data[6]) != 0xc3)) {
>> +		netdev_info(dev, "probing @0x%p failed (pattern)\n",
>> +			    priv->reg_base);
>> +		return 0;
>> +	}
>> +
>> +	/* Check if this chip is a CC770 supporting additional functions */
>> +	if (cc770_read_reg(priv, control) & CTRL_EAF)
>> +		priv->control_normal_mode |= CTRL_EAF;
>> +
>> +	return 1;
>> +}
>> +
>> +static void cc770_start(struct net_device *dev)
>> +{
>> +	struct cc770_priv *priv = netdev_priv(dev);
>> +
>> +	/* leave reset mode */
>> +	if (priv->can.state != CAN_STATE_STOPPED)
>> +		set_reset_mode(dev);
>> +
>> +	/* leave reset mode */
>> +	set_normal_mode(dev);
>> +}
>> +
>> +static int cc770_set_mode(struct net_device *dev, enum can_mode mode)
>> +{
>> +	struct cc770_priv *priv = netdev_priv(dev);
>> +
>> +	if (!priv->open_time)
>> +		return -EINVAL;
>> +
>> +	switch (mode) {
>> +	case CAN_MODE_START:
>> +		cc770_start(dev);
>> +		if (netif_queue_stopped(dev))
>> +			netif_wake_queue(dev);
> 
> The "if (netif_queue_stopped(dev))" is not needed.

OK.

>> +	if (id & CAN_EFF_FLAG) {
>> +		id &= CAN_EFF_MASK;
>> +		cc770_write_reg(priv, msgobj[mo].config,
>> +				(dlc << 4) + rtr + MSGCFG_XTD);
> 
> + is the same as | here, but IMHO bitwise or is more common coding styele.

OK, will fix.

>> +		cc770_write_reg(priv, msgobj[mo].id[3],
>> +				(id << 3) & 0xFFU);
>> +		cc770_write_reg(priv, msgobj[mo].id[2],
>> +				(id >> 5) & 0xFFU);
>> +		cc770_write_reg(priv, msgobj[mo].id[1],
>> +				(id >> 13) & 0xFFU);
>> +		cc770_write_reg(priv, msgobj[mo].id[0],
>> +				(id >> 21) & 0xFFU);
> 
> msgobj[].id[] is an u8, so & 0xff is not needed.

OK.

>> +	} else {
>> +		id &= CAN_SFF_MASK;
>> +		cc770_write_reg(priv, msgobj[mo].config,
>> +				(dlc << 4) + rtr);
>> +		cc770_write_reg(priv, msgobj[mo].id[0],
>> +				(id >> 3) & 0xFFU);
>> +		cc770_write_reg(priv, msgobj[mo].id[1],
>> +				(id << 5) & 0xFFU);
> dito
>> +	}
>> +
>> +	dlc &= 0x0f;		/* restore length only */
> 
> is this needed? The dlc should be valid.

No, can_dropped_invalid_skb() already does the check before.

>> +	for (i = 0; i < dlc; i++)
>> +		cc770_write_reg(priv, msgobj[mo].data[i], cf->data[i]);
>> +
>> +	cc770_write_reg(priv, msgobj[mo].ctrl1,
>> +			RMTPND_RES | TXRQST_SET | CPUUPD_RES | NEWDAT_UNC);
>> +
>> +	stats->tx_bytes += dlc;
>> +
>> +	can_put_echo_skb(skb, dev, 0);
>> +
>> +	/*
>> +	 * HM: We had some cases of repeated IRQs so make sure the
> 
> Who is HM?

Don't know ;-(.

>> +	if (ctrl1 & RMTPND_SET) {
>> +		/*
>> +		 * Unfortunately, the chip does not store the real message
>> +		 * identifier of the received remote transmission request
>> +		 * frame. Therefore we set it to 0.
> 
> What a bug!

Well, it's a basic CAN controller, which is usually handled in a
different way (a CAN id is handled by a dedicated msg object).

>> +	skb = alloc_can_err_skb(dev, &cf);
>> +	if (skb == NULL)
> !skb

Ok, will change.

>> +static void cc770_rx_interrupt(struct net_device *dev, unsigned int o)
>> +{
>> +	struct cc770_priv *priv = netdev_priv(dev);
>> +	struct net_device_stats *stats = &dev->stats;
>> +	unsigned int mo = obj2msgobj(o);
>> +	u8 ctrl1;
>> +
>> +	while (1) {
> 
> What about limiting this?

It does make sense.

>> +	err = request_irq(dev->irq, &cc770_interrupt, priv->irq_flags,
>> +			  dev->name, (void *)dev);
> 
> the (void *) cast ist not needed

OK.


>> +	if (err) {
>> +		close_candev(dev);
>> +		return -EAGAIN;
>> +	}
>> +
>> +	/* init and start chip */
>> +	cc770_start(dev);
>> +	priv->open_time = jiffies;
> 
> open_time is used to track if the netdev is open, right? Can we use
> "ndev->flags & IFF_UP" instead?

Probably, we have similar code in the sja1000.c but not in any other
driver. It is just used in cc770_set_mode(). I guess it's not needed at
all. I will remove it therefore. Need to check if there is a race with
can_restart(), though.

>> +
>> +	netif_start_queue(dev);
>> +
>> +	return 0;
>> +}
>> +
>> +static int cc770_close(struct net_device *dev)
>> +{
>> +	struct cc770_priv *priv = netdev_priv(dev);
>> +
>> +	netif_stop_queue(dev);
>> +	set_reset_mode(dev);
>> +
>> +	free_irq(dev->irq, (void *)dev);
> cast not needed

OK.

...

>> +static __init int cc770_init(void)
>> +{
>> +	if (msgobj15_eff) {
>> +		cc770_obj_flags[CC770_OBJ_RX0] |= CC770_OBJ_FLAG_EFF;
>> +		cc770_obj_flags[CC770_OBJ_RX1] &= ~CC770_OBJ_FLAG_EFF;
>> +	}
>> +
>> +	pr_info("%s CAN netdevice driver\n", DRV_NAME);
> 
> You can add a #define pr_fmt(fmt), to get rid of the "%s", DRV_NAME.

Will add:

  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

>> diff --git a/drivers/net/can/cc770/cc770.h b/drivers/net/can/cc770/cc770.h
>> new file mode 100644
>> index 0000000..c6b5800
>> --- /dev/null
>> +++ b/drivers/net/can/cc770/cc770.h
>> @@ -0,0 +1,234 @@
>> +/*
>> + * cc770.h - Bosch CC770 and Intel AN82527 network device driver
>> + *
>> + * Copyright (C) 2009, 2011 Wolfgang Grandegger <wg@grandegger.com>
>> + *
>> + * Derived from the old Socket-CAN i82527 driver:
>> + *
>> + * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
>> + * All rights reserved.
>> + *
>> + * Redistribution and use in source and binary forms, with or without
>> + * modification, are permitted provided that the following conditions
>> + * are met:
>> + * 1. Redistributions of source code must retain the above copyright
>> + *    notice, this list of conditions and the following disclaimer.
>> + * 2. Redistributions in binary form must reproduce the above copyright
>> + *    notice, this list of conditions and the following disclaimer in the
>> + *    documentation and/or other materials provided with the distribution.
>> + * 3. Neither the name of Volkswagen nor the names of its contributors
>> + *    may be used to endorse or promote products derived from this software
>> + *    without specific prior written permission.
>> + *
>> + * Alternatively, provided that this notice is retained in full, this
>> + * software may be distributed under the terms of the GNU General
>> + * Public License ("GPL") version 2, in which case the provisions of the
>> + * GPL apply INSTEAD OF those given above.
>> + *
>> + * The provided data structures and external interfaces from this code
>> + * are not restricted to be used by modules with a GPL compatible license.
>> + *
>> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
>> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
>> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
>> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
>> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
>> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
>> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
>> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
>> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
>> + * DAMAGE.
>> + *
>> + * Send feedback to <socketcan-users@lists.berlios.de>
> 
> please remove

Already done in v3.

Wolfgang.

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
       [not found]     ` <4ED379F3.1070206-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
@ 2011-11-28 13:59       ` Wolfgang Grandegger
  2011-11-28 14:03         ` David Laight
  0 siblings, 1 reply; 66+ messages in thread
From: Wolfgang Grandegger @ 2011-11-28 13:59 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	socketcan-users-0fE9KPoRgkgATYTw5x5z8w,
	linux-can-u79uwXL29TY76Z2rM5mHXA

On 11/28/2011 01:09 PM, Marc Kleine-Budde wrote:
> On 11/25/2011 10:43 AM, Wolfgang Grandegger wrote:
>> This patch adds support for legacy Bosch CC770 and Intel AN82527 CAN
>> controllers on the ISA or PC-104 bus. The I/O port or memory address
>> and the IRQ number must be specified via module parameters:
>>
>>   insmod cc770_isa.ko port=0x310,0x380 irq=7,11
>>
>> for ISA devices using I/O ports or:
>>
>>   insmod cc770_isa.ko mem=0xd1000,0xd1000 irq=7,11
>>
>> for memory mapped ISA devices.
>>
>> Indirect access via address and data port is supported as well:
>>
>>   insmod cc770_isa.ko port=0x310,0x380 indirect=1 irq=7,11
>>
>> Furthermore, the following mode parameter can be defined:
>>
>>   clk: External oscillator clock frequency (default=16000000 [16 MHz])
>>   cir: CPU interface register (default=0x40 [DSC])
>>   ocr, Bus configuration register (default=0x40 [CBY])
>>   cor, Clockout register (default=0x00)
>>
>> Note: for clk, cir, bcr and cor, the first argument re-defines the
>> default for all other devices, e.g.:
>>
>>   insmod cc770_isa.ko mem=0xd1000,0xd1000 irq=7,11 clk=24000000
>>
>> is equivalent to
>>
>>   insmod cc770_isa.ko mem=0xd1000,0xd1000 irq=7,11 clk=24000000,24000000
>>
>> Signed-off-by: Wolfgang Grandegger <wg-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
> 
> Some nitpicking inside.
> 
> Marc
>> ---
>>  drivers/net/can/cc770/Kconfig     |   11 ++
>>  drivers/net/can/cc770/Makefile    |    1 +
>>  drivers/net/can/cc770/cc770_isa.c |  336 +++++++++++++++++++++++++++++++++++++
>>  3 files changed, 348 insertions(+), 0 deletions(-)
>>  create mode 100644 drivers/net/can/cc770/cc770_isa.c
>>
>> diff --git a/drivers/net/can/cc770/Kconfig b/drivers/net/can/cc770/Kconfig
>> index 225131b..28e4d48 100644
>> --- a/drivers/net/can/cc770/Kconfig
>> +++ b/drivers/net/can/cc770/Kconfig
>> @@ -1,3 +1,14 @@
>>  menuconfig CAN_CC770
>>  	tristate "Bosch CC770 and Intel AN82527 devices"
>>  	depends on CAN_DEV && HAS_IOMEM
>> +
>> +if CAN_CC770
>> +
>> +config CAN_CC770_ISA
>> +	tristate "ISA Bus based legacy CC770 driver"
>> +	---help---
>> +	  This driver adds legacy support for CC770 and AN82527 chips
>> +	  connected to the ISA bus using I/O port, memory mapped or
>> +	  indirect access.
>> +
>> +endif
>> diff --git a/drivers/net/can/cc770/Makefile b/drivers/net/can/cc770/Makefile
>> index 34e8180..872ecff 100644
>> --- a/drivers/net/can/cc770/Makefile
>> +++ b/drivers/net/can/cc770/Makefile
>> @@ -3,5 +3,6 @@
>>  #
>>  
>>  obj-$(CONFIG_CAN_CC770) += cc770.o
>> +obj-$(CONFIG_CAN_CC770_ISA) += cc770_isa.o
>>  
>>  ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
>> diff --git a/drivers/net/can/cc770/cc770_isa.c b/drivers/net/can/cc770/cc770_isa.c
...
>> +	for (idx = 0; idx < MAXDEV; idx++) {
> ARRAY_SIZE?

Well, I think ARRAY_SIZE is useful to derive the number of elements from
a static array of the type:

  static const int array[] = { 1, 2, 3, 4, }

but not if its declared as:

  static array[MAXDEV]:

... or have I missed something?

I'm fine with all other comments.

Wolfgang.

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

* Re: [PATCH net-next v2 1/4] can: cc770: add driver core for the Bosch CC770 and Intel AN82527
       [not found]       ` <4ED3922A.50704-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
@ 2011-11-28 14:01         ` Marc Kleine-Budde
  2011-11-28 14:01           ` [Socketcan-users] " David Laight
       [not found]           ` <4ED3941D.3070302-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
  0 siblings, 2 replies; 66+ messages in thread
From: Marc Kleine-Budde @ 2011-11-28 14:01 UTC (permalink / raw)
  To: Wolfgang Grandegger
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	socketcan-users-0fE9KPoRgkgATYTw5x5z8w,
	linux-can-u79uwXL29TY76Z2rM5mHXA


[-- Attachment #1.1: Type: text/plain, Size: 2360 bytes --]

On 11/28/2011 02:52 PM, Wolfgang Grandegger wrote:

[...]

>>> +/*
>>> + * This driver uses the last 5 message objects 11..15. The definitions
>>> + * and structure below allows to configure and assign them to the real
>>> + * message object.
>>> + */
>>> +static unsigned char cc770_obj_flags[CC770_OBJ_MAX] = {
>>> +	[CC770_OBJ_RX0] = CC770_OBJ_FLAG_RX,
>>> +	[CC770_OBJ_RX1] = CC770_OBJ_FLAG_RX | CC770_OBJ_FLAG_EFF,
>>> +	[CC770_OBJ_RX_RTR0] = CC770_OBJ_FLAG_RX | CC770_OBJ_FLAG_RTR,
>>> +	[CC770_OBJ_RX_RTR1] = CC770_OBJ_FLAG_RX | CC770_OBJ_FLAG_RTR |
>>> +			      CC770_OBJ_FLAG_EFF,
>>> +	[CC770_OBJ_TX] = 0,
>>> +};
>>
>> Is is worth the trouble making this a per device instance option? In a
>> OF-Tree world should this become an "attribute" (or what's the correct
>> of-tree word for it?)
> 
> Well, only msg object 15 does have double buffering and should therefore
> be used for bulk data reception. Therefore we have for the i82527 the
> module parameter:
> 
>   MODULE_PARM_DESC(msgobj15_eff,
> 	           "Extended 29-bit frames for message object 15 "
> 	 	   "(default: 11-bit standard frames)");
> 
> For TX we currently use just one object. Anyway, the device tree is not
> the right place to define such parameters because it's too static. The
> user may want to select it at runtime depending on the application, if
> at all. We can change it when there is a *real* requirement.

Fine with me.

>>> +	for (o = 0; o <  CC770_OBJ_MAX; o++) {
>>                          ^^^^^^^^^^^^^
>>
>> what about ARRAY_SIZE(priv->obj_flags)
> 
> CC770_OBJ_MAX is not derived from a static array definition but as show
> below:

Okay...

>   enum {
> 	CC770_OBJ_RX0 = 0,	/* for receiving normal messages */
> 	CC770_OBJ_RX1,		/* for receiving normal messages */
> 	CC770_OBJ_RX_RTR0,	/* for receiving remote transmission requests */
> 	CC770_OBJ_RX_RTR1,	/* for receiving remote transmission requests */
> 	CC770_OBJ_TX,		/* for sending messages */
> 	CC770_OBJ_MAX  <================

...then add a "," here :P

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 #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 262 bytes --]

[-- Attachment #2: Type: text/plain, Size: 191 bytes --]

_______________________________________________
Socketcan-users mailing list
Socketcan-users-0fE9KPoRgkgATYTw5x5z8w@public.gmane.org
https://lists.berlios.de/mailman/listinfo/socketcan-users

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

* RE: [Socketcan-users] [PATCH net-next v2 1/4] can: cc770: add driver core for the Bosch CC770 and Intel AN82527
  2011-11-28 14:01         ` Marc Kleine-Budde
@ 2011-11-28 14:01           ` David Laight
       [not found]           ` <4ED3941D.3070302-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
  1 sibling, 0 replies; 66+ messages in thread
From: David Laight @ 2011-11-28 14:01 UTC (permalink / raw)
  To: Marc Kleine-Budde, Wolfgang Grandegger; +Cc: netdev, socketcan-users, linux-can

 
> >   enum {
> > 	CC770_OBJ_RX0 = 0,	/* for receiving normal messages */
> > 	CC770_OBJ_RX1,		/* for receiving normal messages */
> > 	CC770_OBJ_RX_RTR0,	/* for receiving remote transmission
requests */
> > 	CC770_OBJ_RX_RTR1,	/* for receiving remote transmission
requests */
> > 	CC770_OBJ_TX,		/* for sending messages */
> > 	CC770_OBJ_MAX  <================
> 
> ...then add a "," here :P

Not if the code might have to go through the C++ compiler.
C++ doesn't allow a trailing , in enums (some compilers
will error this....).

	David



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

* RE: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2011-11-28 13:59       ` Wolfgang Grandegger
@ 2011-11-28 14:03         ` David Laight
       [not found]           ` <AE90C24D6B3A694183C094C60CF0A2F6D8AEE9-CgBM+Bx2aUAnGFn1LkZF6NBPR1lH4CV8@public.gmane.org>
  0 siblings, 1 reply; 66+ messages in thread
From: David Laight @ 2011-11-28 14:03 UTC (permalink / raw)
  To: Wolfgang Grandegger, Marc Kleine-Budde
  Cc: netdev, linux-can, socketcan-users, IreneV, Stanislav Yelenskiy

 
...
> >> +	for (idx = 0; idx < MAXDEV; idx++) {
> > ARRAY_SIZE?
> 
> Well, I think ARRAY_SIZE is useful to derive the number of 
> elements from a static array of the type:
> 
>   static const int array[] = { 1, 2, 3, 4, }
> 
> but not if its declared as:
> 
>   static array[MAXDEV]:
> 
> ... or have I missed something?

Yes - if you use ARRAY_SIZE() then someone reading the code
doesn't need to find the array definition to ensure the loop
upper bound is correct.

	David

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
       [not found]           ` <AE90C24D6B3A694183C094C60CF0A2F6D8AEE9-CgBM+Bx2aUAnGFn1LkZF6NBPR1lH4CV8@public.gmane.org>
@ 2011-11-28 14:09             ` Marc Kleine-Budde
       [not found]               ` <4ED3960F.4040508-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
  0 siblings, 1 reply; 66+ messages in thread
From: Marc Kleine-Budde @ 2011-11-28 14:09 UTC (permalink / raw)
  To: David Laight
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, linux-can-u79uwXL29TY76Z2rM5mHXA,
	socketcan-users-0fE9KPoRgkgATYTw5x5z8w, Wolfgang Grandegger


[-- Attachment #1.1: Type: text/plain, Size: 862 bytes --]

On 11/28/2011 03:03 PM, David Laight wrote:
>>>> +	for (idx = 0; idx < MAXDEV; idx++) {
>>> ARRAY_SIZE?
>>
>> Well, I think ARRAY_SIZE is useful to derive the number of 
>> elements from a static array of the type:
>>
>>   static const int array[] = { 1, 2, 3, 4, }
>>
>> but not if its declared as:
>>
>>   static array[MAXDEV]:
>>
>> ... or have I missed something?
> 
> Yes - if you use ARRAY_SIZE() then someone reading the code
> doesn't need to find the array definition to ensure the loop
> upper bound is correct.

Yep, that
was my intention, too.

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 #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 262 bytes --]

[-- Attachment #2: Type: text/plain, Size: 191 bytes --]

_______________________________________________
Socketcan-users mailing list
Socketcan-users-0fE9KPoRgkgATYTw5x5z8w@public.gmane.org
https://lists.berlios.de/mailman/listinfo/socketcan-users

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

* Re: [PATCH net-next v2 1/4] can: cc770: add driver core for the Bosch CC770 and Intel AN82527
       [not found]           ` <4ED3941D.3070302-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
@ 2011-11-28 14:10             ` Wolfgang Grandegger
       [not found]               ` <4ED3966E.7080609-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
  0 siblings, 1 reply; 66+ messages in thread
From: Wolfgang Grandegger @ 2011-11-28 14:10 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	socketcan-users-0fE9KPoRgkgATYTw5x5z8w,
	linux-can-u79uwXL29TY76Z2rM5mHXA

On 11/28/2011 03:01 PM, Marc Kleine-Budde wrote:
> On 11/28/2011 02:52 PM, Wolfgang Grandegger wrote:
> 
> [...]
> 
>>>> +/*
>>>> + * This driver uses the last 5 message objects 11..15. The definitions
>>>> + * and structure below allows to configure and assign them to the real
>>>> + * message object.
>>>> + */
>>>> +static unsigned char cc770_obj_flags[CC770_OBJ_MAX] = {
>>>> +	[CC770_OBJ_RX0] = CC770_OBJ_FLAG_RX,
>>>> +	[CC770_OBJ_RX1] = CC770_OBJ_FLAG_RX | CC770_OBJ_FLAG_EFF,
>>>> +	[CC770_OBJ_RX_RTR0] = CC770_OBJ_FLAG_RX | CC770_OBJ_FLAG_RTR,
>>>> +	[CC770_OBJ_RX_RTR1] = CC770_OBJ_FLAG_RX | CC770_OBJ_FLAG_RTR |
>>>> +			      CC770_OBJ_FLAG_EFF,
>>>> +	[CC770_OBJ_TX] = 0,
>>>> +};
>>>
>>> Is is worth the trouble making this a per device instance option? In a
>>> OF-Tree world should this become an "attribute" (or what's the correct
>>> of-tree word for it?)
>>
>> Well, only msg object 15 does have double buffering and should therefore
>> be used for bulk data reception. Therefore we have for the i82527 the
>> module parameter:
>>
>>   MODULE_PARM_DESC(msgobj15_eff,
>> 	           "Extended 29-bit frames for message object 15 "
>> 	 	   "(default: 11-bit standard frames)");
>>
>> For TX we currently use just one object. Anyway, the device tree is not
>> the right place to define such parameters because it's too static. The
>> user may want to select it at runtime depending on the application, if
>> at all. We can change it when there is a *real* requirement.
> 
> Fine with me.
> 
>>>> +	for (o = 0; o <  CC770_OBJ_MAX; o++) {
>>>                          ^^^^^^^^^^^^^
>>>
>>> what about ARRAY_SIZE(priv->obj_flags)
>>
>> CC770_OBJ_MAX is not derived from a static array definition but as show
>> below:
> 
> Okay...
> 
>>   enum {
>> 	CC770_OBJ_RX0 = 0,	/* for receiving normal messages */
>> 	CC770_OBJ_RX1,		/* for receiving normal messages */
>> 	CC770_OBJ_RX_RTR0,	/* for receiving remote transmission requests */
>> 	CC770_OBJ_RX_RTR1,	/* for receiving remote transmission requests */
>> 	CC770_OBJ_TX,		/* for sending messages */
>> 	CC770_OBJ_MAX  <================
> 
> ...then add a "," here :P

Why?

Wolfgang.

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

* Re: [PATCH net-next v2 1/4] can: cc770: add driver core for the Bosch CC770 and Intel AN82527
       [not found]               ` <4ED3966E.7080609-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
@ 2011-11-28 14:18                 ` Marc Kleine-Budde
  0 siblings, 0 replies; 66+ messages in thread
From: Marc Kleine-Budde @ 2011-11-28 14:18 UTC (permalink / raw)
  To: Wolfgang Grandegger
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	socketcan-users-0fE9KPoRgkgATYTw5x5z8w,
	linux-can-u79uwXL29TY76Z2rM5mHXA


[-- Attachment #1.1: Type: text/plain, Size: 1114 bytes --]

On 11/28/2011 03:10 PM, Wolfgang Grandegger wrote:

>>>   enum {
>>> 	CC770_OBJ_RX0 = 0,	/* for receiving normal messages */
>>> 	CC770_OBJ_RX1,		/* for receiving normal messages */
>>> 	CC770_OBJ_RX_RTR0,	/* for receiving remote transmission requests */
>>> 	CC770_OBJ_RX_RTR1,	/* for receiving remote transmission requests */
>>> 	CC770_OBJ_TX,		/* for sending messages */
>>> 	CC770_OBJ_MAX  <================
>>
>> ...then add a "," here :P
> 
> Why?

Okay - here the following argument will be not valid :), because OBJ_MAX
will and has always to be the last element in the enum.

But if you don't have a _MAX argument and a new element will be added to
the enum, you'll have to change two lines: 1. add the missing "," 2. add
the new element. Diff will look better if the last element always has a ",".

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 #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 262 bytes --]

[-- Attachment #2: Type: text/plain, Size: 191 bytes --]

_______________________________________________
Socketcan-users mailing list
Socketcan-users-0fE9KPoRgkgATYTw5x5z8w@public.gmane.org
https://lists.berlios.de/mailman/listinfo/socketcan-users

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
       [not found]               ` <4ED3960F.4040508-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
@ 2011-11-28 15:10                 ` Wolfgang Grandegger
  0 siblings, 0 replies; 66+ messages in thread
From: Wolfgang Grandegger @ 2011-11-28 15:10 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, linux-can-u79uwXL29TY76Z2rM5mHXA,
	David Laight, socketcan-users-0fE9KPoRgkgATYTw5x5z8w

On 11/28/2011 03:09 PM, Marc Kleine-Budde wrote:
> On 11/28/2011 03:03 PM, David Laight wrote:
>>>>> +	for (idx = 0; idx < MAXDEV; idx++) {
>>>> ARRAY_SIZE?
>>>
>>> Well, I think ARRAY_SIZE is useful to derive the number of 
>>> elements from a static array of the type:
>>>
>>>   static const int array[] = { 1, 2, 3, 4, }
>>>
>>> but not if its declared as:
>>>
>>>   static array[MAXDEV]:
>>>
>>> ... or have I missed something?
>>
>> Yes - if you use ARRAY_SIZE() then someone reading the code
>> doesn't need to find the array definition to ensure the loop
>> upper bound is correct.
> 
> Yep, that
> was my intention, too.

OK, I see, and as we are all just human beings ...

Wolfgang.

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
       [not found]             ` <4ED37885.8080909-PyqsHJVlJN8AvxtiuMwx3w@public.gmane.org>
@ 2011-11-28 16:06               ` Oliver Hartkopp
       [not found]                 ` <4ED3B198.2040308-fJ+pQTUTwRTk1uMJSBkQmQ@public.gmane.org>
  0 siblings, 1 reply; 66+ messages in thread
From: Oliver Hartkopp @ 2011-11-28 16:06 UTC (permalink / raw)
  To: info-PyqsHJVlJN8AvxtiuMwx3w, Wolfgang Grandegger
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	socketcan-users-0fE9KPoRgkgATYTw5x5z8w,
	linux-can-u79uwXL29TY76Z2rM5mHXA


>> ... using a reasonable default for bcr of 0x40. But you may need to
>> provide better values for cir, bcr and cor.
>>
> 
> OMG, sorry that I was bothering You but You are absolutely right and with Your
> statement You brought be back on track and You made my day. Thank You !!!!!!
> 
> I just took the values for cpu and bus I was using in my lincan driver and funny
> enough now it's working absolutely perfect.
> 
> Module: modprobe cc770_isa irq=0xa port=0x384 indirect=1 cir=0x61 bcr=0x4A
> 
> Was just sending 50000 telegrams, perfect and no problem at all.
> 
> Thanks a lot again!!!!
> 


This looks like a Tested-by :-)

Thanks Wolfgang (who ever feels addressed)

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
       [not found]                 ` <4ED3B198.2040308-fJ+pQTUTwRTk1uMJSBkQmQ@public.gmane.org>
@ 2011-11-29  9:16                   ` Wolfgang Grandegger
       [not found]                     ` <4ED4A2EC.40103-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
  0 siblings, 1 reply; 66+ messages in thread
From: Wolfgang Grandegger @ 2011-11-29  9:16 UTC (permalink / raw)
  To: Oliver Hartkopp
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, linux-can-u79uwXL29TY76Z2rM5mHXA,
	socketcan-users-0fE9KPoRgkgATYTw5x5z8w,
	info-PyqsHJVlJN8AvxtiuMwx3w

On 11/28/2011 05:06 PM, Oliver Hartkopp wrote:
> 
>>> ... using a reasonable default for bcr of 0x40. But you may need to
>>> provide better values for cir, bcr and cor.
>>>
>>
>> OMG, sorry that I was bothering You but You are absolutely right and with Your
>> statement You brought be back on track and You made my day. Thank You !!!!!!
>>
>> I just took the values for cpu and bus I was using in my lincan driver and funny
>> enough now it's working absolutely perfect.
>>
>> Module: modprobe cc770_isa irq=0xa port=0x384 indirect=1 cir=0x61 bcr=0x4A
>>
>> Was just sending 50000 telegrams, perfect and no problem at all.
>>
>> Thanks a lot again!!!!
>>
> 
> 
> This looks like a Tested-by :-)

Wolfgang, I just sent out v4. Any chance to give this patch a try? It
would be best to use a recent kernel version but I could also adapt the
patch to your kernel version, 2.6.39, I think!?

As you are using a CC770 chip, I'm especially interested in the relevant
kernel log (dmesg) and "ip -d -s link show".

Thanks,

Wolfgang.

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

* Re: [PATCH net-next v2 1/4] can: cc770: add driver core for the Bosch CC770 and Intel AN82527
       [not found]     ` <4ED3704D.5020903-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
@ 2011-11-29  9:20       ` Wolfgang Grandegger
  0 siblings, 0 replies; 66+ messages in thread
From: Wolfgang Grandegger @ 2011-11-29  9:20 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	socketcan-users-0fE9KPoRgkgATYTw5x5z8w,
	linux-can-u79uwXL29TY76Z2rM5mHXA

Hi Marc,

On 11/28/2011 12:28 PM, Marc Kleine-Budde wrote:
> On 11/25/2011 10:43 AM, Wolfgang Grandegger wrote:
>> Signed-off-by: Wolfgang Grandegger <wg-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
>> ---
>>  drivers/net/can/Kconfig            |    2 +
>>  drivers/net/can/Makefile           |    1 +
>>  drivers/net/can/cc770/Kconfig      |    3 +
>>  drivers/net/can/cc770/Makefile     |    7 +
>>  drivers/net/can/cc770/cc770.c      |  895 ++++++++++++++++++++++++++++++++++++
>>  drivers/net/can/cc770/cc770.h      |  234 ++++++++++
>>  include/linux/can/platform/cc770.h |   33 ++
>>  7 files changed, 1175 insertions(+), 0 deletions(-)
>>  create mode 100644 drivers/net/can/cc770/Kconfig
>>  create mode 100644 drivers/net/can/cc770/Makefile
>>  create mode 100644 drivers/net/can/cc770/cc770.c
>>  create mode 100644 drivers/net/can/cc770/cc770.h
>>  create mode 100644 include/linux/can/platform/cc770.h
> 
> I don't know the hardware, but the code looks good to me, some comments:
> - The driver doesn't use NAPI, can this be added
> - The rx-handlers have a while(1) loop
>   For NAPI you have to add accounting, for the non NAPI case it would
>   be good, too.
> - I think you can move a large number of lines from the .h file into
>   the driver. Code that's not used in the different binding drivers.
> 
> More comments inline (mostly nitpicking)

I just sent out v4. For the sake of readability, I finally did not move
most of the head definitions in cc770.h into cc770.c and used the
variable name "o" consistently for the message object index (instead of
using "i").

Wolfgang.

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
       [not found]                     ` <4ED4A2EC.40103-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
@ 2011-12-04 18:47                       ` Wolfgang Zarre
  2011-12-04 18:56                         ` Wolfgang Grandegger
  0 siblings, 1 reply; 66+ messages in thread
From: Wolfgang Zarre @ 2011-12-04 18:47 UTC (permalink / raw)
  To: Wolfgang Grandegger
  Cc: Oliver Hartkopp, linux-can-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	socketcan-users-0fE9KPoRgkgATYTw5x5z8w

Hello Wolfgang,

> On 11/28/2011 05:06 PM, Oliver Hartkopp wrote:
>>
>>>> ... using a reasonable default for bcr of 0x40. But you may need to
>>>> provide better values for cir, bcr and cor.
>>>>
>>>
>>> OMG, sorry that I was bothering You but You are absolutely right and with Your
>>> statement You brought be back on track and You made my day. Thank You !!!!!!
>>>
>>> I just took the values for cpu and bus I was using in my lincan driver and funny
>>> enough now it's working absolutely perfect.
>>>
>>> Module: modprobe cc770_isa irq=0xa port=0x384 indirect=1 cir=0x61 bcr=0x4A
>>>
>>> Was just sending 50000 telegrams, perfect and no problem at all.
>>>
>>> Thanks a lot again!!!!
>>>
>>
>>
>> This looks like a Tested-by :-)
>
> Wolfgang, I just sent out v4. Any chance to give this patch a try? It
> would be best to use a recent kernel version but I could also adapt the
> patch to your kernel version, 2.6.39, I think!?

Sorry for my delayed reply, but wasn't earlier possible.
Yes, of course, as long as I have the hardware available I can do some tests, even
on a recent kernel due the fact having the project so far completed, just another
test run on the 9th of December.

Due the flood of emails I lost now track which version You would be interested in
and maybe also which kernel version, so, please let me know and maybe were I may
download the patches.

>
> As you are using a CC770 chip, I'm especially interested in the relevant
> kernel log (dmesg) and "ip -d -s link show".

Should be not a problem at all.

>
> Thanks,
>
> Wolfgang.

Wolfgang

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2011-12-04 18:47                       ` Wolfgang Zarre
@ 2011-12-04 18:56                         ` Wolfgang Grandegger
       [not found]                           ` <4EDBC25D.50405-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
  0 siblings, 1 reply; 66+ messages in thread
From: Wolfgang Grandegger @ 2011-12-04 18:56 UTC (permalink / raw)
  To: info
  Cc: Oliver Hartkopp, netdev, linux-can, socketcan-users, IreneV,
	Stanislav Yelenskiy

Hi Wolfgang,

On 12/04/2011 07:47 PM, Wolfgang Zarre wrote:
> Hello Wolfgang,
...
>> Wolfgang, I just sent out v4. Any chance to give this patch a try? It
>> would be best to use a recent kernel version but I could also adapt the
>> patch to your kernel version, 2.6.39, I think!?
> 
> Sorry for my delayed reply, but wasn't earlier possible.
> Yes, of course, as long as I have the hardware available I can do some
> tests, even
> on a recent kernel due the fact having the project so far completed,
> just another
> test run on the 9th of December.
> 
> Due the flood of emails I lost now track which version You would be
> interested in
> and maybe also which kernel version, so, please let me know and maybe
> were I may
> download the patches.

Well, yes, I was spinning too fast but the patches have been accepted in
the meantime (actually v6 made it). So you just need to clone the most
recent version of Dave's net-next tree.

>> As you are using a CC770 chip, I'm especially interested in the relevant
>> kernel log (dmesg) and "ip -d -s link show".
> 
> Should be not a problem at all.

Great, thanks.

Wolfgang.

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
       [not found]                           ` <4EDBC25D.50405-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
@ 2011-12-06 21:08                             ` Wolfgang Zarre
       [not found]                               ` <4EDE8435.5080100-PyqsHJVlJN8AvxtiuMwx3w@public.gmane.org>
  0 siblings, 1 reply; 66+ messages in thread
From: Wolfgang Zarre @ 2011-12-06 21:08 UTC (permalink / raw)
  To: Wolfgang Grandegger
  Cc: Oliver Hartkopp, linux-can-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	socketcan-users-0fE9KPoRgkgATYTw5x5z8w

Hello Wolfgang,

> Hi Wolfgang,
>
> On 12/04/2011 07:47 PM, Wolfgang Zarre wrote:
>> Hello Wolfgang,
> ...
>>> Wolfgang, I just sent out v4. Any chance to give this patch a try? It
>>> would be best to use a recent kernel version but I could also adapt the
>>> patch to your kernel version, 2.6.39, I think!?
>>
>> Sorry for my delayed reply, but wasn't earlier possible.
>> Yes, of course, as long as I have the hardware available I can do some
>> tests, even
>> on a recent kernel due the fact having the project so far completed,
>> just another
>> test run on the 9th of December.
>>
>> Due the flood of emails I lost now track which version You would be
>> interested in
>> and maybe also which kernel version, so, please let me know and maybe
>> were I may
>> download the patches.
>
> Well, yes, I was spinning too fast but the patches have been accepted in
> the meantime (actually v6 made it). So you just need to clone the most
> recent version of Dave's net-next tree.
>
>>> As you are using a CC770 chip, I'm especially interested in the relevant
>>> kernel log (dmesg) and "ip -d -s link show".
>>
>> Should be not a problem at all.
>
> Great, thanks.

Ok, here we go:

uname -r: 3.2.0-rc4

modprobe cc770_isa irq=0xa port=0x384 indirect=1 cir=0x61 bcr=0x4A
ip link set can0 up type can bitrate 500000;

kern.log
Dec  6 20:42:19 svserv01 kernel: [ 2111.900735] CAN device driver interface
Dec  6 20:42:19 svserv01 kernel: [ 2111.903072] cc770: CAN netdevice driver
Dec  6 20:42:19 svserv01 kernel: [ 2111.904692] cc770_isa: platform device 0: port=0x384, mem=0x0, irq=10
Dec  6 20:42:19 svserv01 kernel: [ 2111.904726] cc770_isa cc770_isa.0: probing idx=0: port=0x384, mem=0x0, irq=10
Dec  6 20:42:19 svserv01 kernel: [ 2111.904779] cc770_isa cc770_isa.0: (unregistered net_device): i82527 mode with additional functions
Dec  6 20:42:19 svserv01 kernel: [ 2111.906407] cc770_isa cc770_isa.0: device registered (reg_base=0x00000384, irq=10)
Dec  6 20:42:19 svserv01 kernel: [ 2111.906457] cc770_isa: driver for max. 8 devices registered
   6 20:44:17 svserv01 kernel: [ 2229.886845] cc770_isa cc770_isa.0: can0: setting BTR0=0x00 BTR1=0x1c
Dec  6 20:44:17 svserv01 kernel: [ 2229.886920] cc770_isa cc770_isa.0: can0: Message object 15 for RX data, RTR, SFF and EFF
Dec  6 20:44:17 svserv01 kernel: [ 2229.886937] cc770_isa cc770_isa.0: can0: Message object 11 for TX data, RTR, SFF and EFF
Dec  6 20:52:40 svserv01 kernel: [ 2733.172845] can: controller area network core (rev 20090105 abi 8)
Dec  6 20:52:40 svserv01 kernel: [ 2733.172967] NET: Registered protocol family 29
Dec  6 20:52:40 svserv01 kernel: [ 2733.178187] can: raw protocol (rev 20090105)


ip -d -s link show
4: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN qlen 10
     link/can
     can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0
     bitrate 500000 sample-point 0.875
     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
     clock 8000000
     re-started bus-errors arbit-lost error-warn error-pass bus-off
     0          0          0          0          0          0
     RX: bytes  packets  errors  dropped overrun mcast
     0          0        0       0       0       0
     TX: bytes  packets  errors  dropped carrier collsns
     0          0        0       0       0       0


After rebooting the PLC with proprietary buggy kernel:
4: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN qlen 10
     link/can
     can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0
     bitrate 500000 sample-point 0.875
     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
     clock 8000000
     re-started bus-errors arbit-lost error-warn error-pass bus-off
     0          0          0          0          0          0
     RX: bytes  packets  errors  dropped overrun mcast
     414        267      0       267     0       0
     TX: bytes  packets  errors  dropped carrier collsns
     0          0        0       0       0       0



After sending 100,000 PDO's with 13ms displacement:
4: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN qlen 10
     link/can
     can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0
     bitrate 500000 sample-point 0.875
     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
     clock 8000000
     re-started bus-errors arbit-lost error-warn error-pass bus-off
     0          0          0          0          0          0
     RX: bytes  packets  errors  dropped overrun mcast
     4544       4284     0       331     0       0
     TX: bytes  packets  errors  dropped carrier collsns
     802660     202653   0       0       0       0


The dropped ones of RX may be the not processed input packages and therefore ok.

Let me know if You need more or some other tests.

>
> Wolfgang.

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
       [not found]                               ` <4EDE8435.5080100-PyqsHJVlJN8AvxtiuMwx3w@public.gmane.org>
@ 2011-12-07 13:42                                 ` Wolfgang Grandegger
  2011-12-09 10:26                                   ` Wolfgang Grandegger
  0 siblings, 1 reply; 66+ messages in thread
From: Wolfgang Grandegger @ 2011-12-07 13:42 UTC (permalink / raw)
  To: info-PyqsHJVlJN8AvxtiuMwx3w
  Cc: Oliver Hartkopp, linux-can-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	socketcan-users-0fE9KPoRgkgATYTw5x5z8w

Hi Wolfgang,

On 12/06/2011 10:08 PM, Wolfgang Zarre wrote:
> Hello Wolfgang,
> 
>> Hi Wolfgang,
>>
>> On 12/04/2011 07:47 PM, Wolfgang Zarre wrote:
...
>>>
>>> Should be not a problem at all.
>>
>> Great, thanks.
> 
> Ok, here we go:
> 
> uname -r: 3.2.0-rc4
> 
> modprobe cc770_isa irq=0xa port=0x384 indirect=1 cir=0x61 bcr=0x4A
> ip link set can0 up type can bitrate 500000;
> 
> kern.log
> Dec  6 20:42:19 svserv01 kernel: [ 2111.900735] CAN device driver interface
> Dec  6 20:42:19 svserv01 kernel: [ 2111.903072] cc770: CAN netdevice driver
> Dec  6 20:42:19 svserv01 kernel: [ 2111.904692] cc770_isa: platform
> device 0: port=0x384, mem=0x0, irq=10
> Dec  6 20:42:19 svserv01 kernel: [ 2111.904726] cc770_isa cc770_isa.0:
> probing idx=0: port=0x384, mem=0x0, irq=10
> Dec  6 20:42:19 svserv01 kernel: [ 2111.904779] cc770_isa cc770_isa.0:
> (unregistered net_device): i82527 mode with additional functions
> Dec  6 20:42:19 svserv01 kernel: [ 2111.906407] cc770_isa cc770_isa.0:
> device registered (reg_base=0x00000384, irq=10)
> Dec  6 20:42:19 svserv01 kernel: [ 2111.906457] cc770_isa: driver for
> max. 8 devices registered
>   6 20:44:17 svserv01 kernel: [ 2229.886845] cc770_isa cc770_isa.0:
> can0: setting BTR0=0x00 BTR1=0x1c
> Dec  6 20:44:17 svserv01 kernel: [ 2229.886920] cc770_isa cc770_isa.0:
> can0: Message object 15 for RX data, RTR, SFF and EFF
> Dec  6 20:44:17 svserv01 kernel: [ 2229.886937] cc770_isa cc770_isa.0:
> can0: Message object 11 for TX data, RTR, SFF and EFF
> Dec  6 20:52:40 svserv01 kernel: [ 2733.172845] can: controller area
> network core (rev 20090105 abi 8)
> Dec  6 20:52:40 svserv01 kernel: [ 2733.172967] NET: Registered protocol
> family 29
> Dec  6 20:52:40 svserv01 kernel: [ 2733.178187] can: raw protocol (rev
> 20090105)
> 
> 
> ip -d -s link show
> 4: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN
> qlen 10
>     link/can
>     can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0
>     bitrate 500000 sample-point 0.875
>     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
>     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
>     clock 8000000
>     re-started bus-errors arbit-lost error-warn error-pass bus-off
>     0          0          0          0          0          0
>     RX: bytes  packets  errors  dropped overrun mcast
>     0          0        0       0       0       0
>     TX: bytes  packets  errors  dropped carrier collsns
>     0          0        0       0       0       0
> 
> 
> After rebooting the PLC with proprietary buggy kernel:
> 4: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN
> qlen 10
>     link/can
>     can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0
>     bitrate 500000 sample-point 0.875
>     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
>     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
>     clock 8000000
>     re-started bus-errors arbit-lost error-warn error-pass bus-off
>     0          0          0          0          0          0
>     RX: bytes  packets  errors  dropped overrun mcast
>     414        267      0       267     0       0
>     TX: bytes  packets  errors  dropped carrier collsns
>     0          0        0       0       0       0
> 
> 
> 
> After sending 100,000 PDO's with 13ms displacement:
> 4: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN
> qlen 10
>     link/can
>     can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0
>     bitrate 500000 sample-point 0.875
>     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
>     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
>     clock 8000000
>     re-started bus-errors arbit-lost error-warn error-pass bus-off
>     0          0          0          0          0          0
>     RX: bytes  packets  errors  dropped overrun mcast
>     4544       4284     0       331     0       0
>     TX: bytes  packets  errors  dropped carrier collsns
>     802660     202653   0       0       0       0
> 
> 
> The dropped ones of RX may be the not processed input packages and
> therefore ok.
> 
> Let me know if You need more or some other tests.

You could provoke some state changes or bus-off conditions to see if the
berr-counter shows reasonable results. I'm currently consolidating and
unifying error state and bus-off handling. Would be nice if you could do
some further tests when I have the patches ready...

Thanks for testing.

Wolfgang.

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2011-12-07 13:42                                 ` Wolfgang Grandegger
@ 2011-12-09 10:26                                   ` Wolfgang Grandegger
  2011-12-11 18:33                                     ` Wolfgang Zarre
  0 siblings, 1 reply; 66+ messages in thread
From: Wolfgang Grandegger @ 2011-12-09 10:26 UTC (permalink / raw)
  To: info
  Cc: Oliver Hartkopp, netdev, linux-can, socketcan-users, IreneV,
	Stanislav Yelenskiy

On 12/07/2011 02:42 PM, Wolfgang Grandegger wrote:
> Hi Wolfgang,
> 
> On 12/06/2011 10:08 PM, Wolfgang Zarre wrote:
>> Hello Wolfgang,
>>
>>> Hi Wolfgang,
>>>
>>> On 12/04/2011 07:47 PM, Wolfgang Zarre wrote:
> ...
>>>>
>>>> Should be not a problem at all.
>>>
>>> Great, thanks.
>>
>> Ok, here we go:
>>
>> uname -r: 3.2.0-rc4
>>
>> modprobe cc770_isa irq=0xa port=0x384 indirect=1 cir=0x61 bcr=0x4A
>> ip link set can0 up type can bitrate 500000;
>>
>> kern.log
>> Dec  6 20:42:19 svserv01 kernel: [ 2111.900735] CAN device driver interface
>> Dec  6 20:42:19 svserv01 kernel: [ 2111.903072] cc770: CAN netdevice driver
>> Dec  6 20:42:19 svserv01 kernel: [ 2111.904692] cc770_isa: platform
>> device 0: port=0x384, mem=0x0, irq=10
>> Dec  6 20:42:19 svserv01 kernel: [ 2111.904726] cc770_isa cc770_isa.0:
>> probing idx=0: port=0x384, mem=0x0, irq=10
>> Dec  6 20:42:19 svserv01 kernel: [ 2111.904779] cc770_isa cc770_isa.0:
>> (unregistered net_device): i82527 mode with additional functions
>> Dec  6 20:42:19 svserv01 kernel: [ 2111.906407] cc770_isa cc770_isa.0:
>> device registered (reg_base=0x00000384, irq=10)
>> Dec  6 20:42:19 svserv01 kernel: [ 2111.906457] cc770_isa: driver for
>> max. 8 devices registered
>>   6 20:44:17 svserv01 kernel: [ 2229.886845] cc770_isa cc770_isa.0:
>> can0: setting BTR0=0x00 BTR1=0x1c
>> Dec  6 20:44:17 svserv01 kernel: [ 2229.886920] cc770_isa cc770_isa.0:
>> can0: Message object 15 for RX data, RTR, SFF and EFF
>> Dec  6 20:44:17 svserv01 kernel: [ 2229.886937] cc770_isa cc770_isa.0:
>> can0: Message object 11 for TX data, RTR, SFF and EFF
>> Dec  6 20:52:40 svserv01 kernel: [ 2733.172845] can: controller area
>> network core (rev 20090105 abi 8)
>> Dec  6 20:52:40 svserv01 kernel: [ 2733.172967] NET: Registered protocol
>> family 29
>> Dec  6 20:52:40 svserv01 kernel: [ 2733.178187] can: raw protocol (rev
>> 20090105)
>>
>>
>> ip -d -s link show
>> 4: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN
>> qlen 10
>>     link/can
>>     can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0
>>     bitrate 500000 sample-point 0.875
>>     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
>>     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
>>     clock 8000000
>>     re-started bus-errors arbit-lost error-warn error-pass bus-off
>>     0          0          0          0          0          0
>>     RX: bytes  packets  errors  dropped overrun mcast
>>     0          0        0       0       0       0
>>     TX: bytes  packets  errors  dropped carrier collsns
>>     0          0        0       0       0       0
>>
>>
>> After rebooting the PLC with proprietary buggy kernel:
>> 4: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN
>> qlen 10
>>     link/can
>>     can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0
>>     bitrate 500000 sample-point 0.875
>>     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
>>     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
>>     clock 8000000
>>     re-started bus-errors arbit-lost error-warn error-pass bus-off
>>     0          0          0          0          0          0
>>     RX: bytes  packets  errors  dropped overrun mcast
>>     414        267      0       267     0       0
>>     TX: bytes  packets  errors  dropped carrier collsns
>>     0          0        0       0       0       0
>>
>>
>>
>> After sending 100,000 PDO's with 13ms displacement:
>> 4: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN
>> qlen 10
>>     link/can
>>     can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0
>>     bitrate 500000 sample-point 0.875
>>     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
>>     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
>>     clock 8000000
>>     re-started bus-errors arbit-lost error-warn error-pass bus-off
>>     0          0          0          0          0          0
>>     RX: bytes  packets  errors  dropped overrun mcast
>>     4544       4284     0       331     0       0
>>     TX: bytes  packets  errors  dropped carrier collsns
>>     802660     202653   0       0       0       0
>>
>>
>> The dropped ones of RX may be the not processed input packages and
>> therefore ok.
>>
>> Let me know if You need more or some other tests.
> 
> You could provoke some state changes or bus-off conditions to see if the
> berr-counter shows reasonable results. I'm currently consolidating and
> unifying error state and bus-off handling. Would be nice if you could do
> some further tests when I have the patches ready...

I just pushed the mentioned modifications to the "devel" branch of my
"wg-linux-can-next" [1] repository. You can get it as shown below:

  $ git clone --reference=<some-recent-net-next-tree> \
      git://gitorious.org/~wgrandegger/linux-can/wg-linux-can-next.git
  $ git checkout -b devel devel

[1] https://gitorious.org/~wgrandegger/linux-can/wg-linux-can-next

Wolfgang.

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2011-12-09 10:26                                   ` Wolfgang Grandegger
@ 2011-12-11 18:33                                     ` Wolfgang Zarre
       [not found]                                       ` <4EE4F76E.3000506-PyqsHJVlJN8AvxtiuMwx3w@public.gmane.org>
  0 siblings, 1 reply; 66+ messages in thread
From: Wolfgang Zarre @ 2011-12-11 18:33 UTC (permalink / raw)
  To: Wolfgang Grandegger
  Cc: Oliver Hartkopp, netdev, linux-can, socketcan-users, IreneV,
	Stanislav Yelenskiy

Hello Wolfgang,
> On 12/07/2011 02:42 PM, Wolfgang Grandegger wrote:
>> Hi Wolfgang,
>>
>> On 12/06/2011 10:08 PM, Wolfgang Zarre wrote:
>>> Hello Wolfgang,
>>>
>>>> Hi Wolfgang,
>>>>
>>>> On 12/04/2011 07:47 PM, Wolfgang Zarre wrote:
>> ...
>>>>>
>>>>> Should be not a problem at all.
>>>>
>>>> Great, thanks.
>>>
>>> Ok, here we go:
>>>
>>> uname -r: 3.2.0-rc4
>>>
>>> modprobe cc770_isa irq=0xa port=0x384 indirect=1 cir=0x61 bcr=0x4A
>>> ip link set can0 up type can bitrate 500000;
>>>
>>> kern.log
>>> Dec  6 20:42:19 svserv01 kernel: [ 2111.900735] CAN device driver interface
>>> Dec  6 20:42:19 svserv01 kernel: [ 2111.903072] cc770: CAN netdevice driver
>>> Dec  6 20:42:19 svserv01 kernel: [ 2111.904692] cc770_isa: platform
>>> device 0: port=0x384, mem=0x0, irq=10
>>> Dec  6 20:42:19 svserv01 kernel: [ 2111.904726] cc770_isa cc770_isa.0:
>>> probing idx=0: port=0x384, mem=0x0, irq=10
>>> Dec  6 20:42:19 svserv01 kernel: [ 2111.904779] cc770_isa cc770_isa.0:
>>> (unregistered net_device): i82527 mode with additional functions
>>> Dec  6 20:42:19 svserv01 kernel: [ 2111.906407] cc770_isa cc770_isa.0:
>>> device registered (reg_base=0x00000384, irq=10)
>>> Dec  6 20:42:19 svserv01 kernel: [ 2111.906457] cc770_isa: driver for
>>> max. 8 devices registered
>>>    6 20:44:17 svserv01 kernel: [ 2229.886845] cc770_isa cc770_isa.0:
>>> can0: setting BTR0=0x00 BTR1=0x1c
>>> Dec  6 20:44:17 svserv01 kernel: [ 2229.886920] cc770_isa cc770_isa.0:
>>> can0: Message object 15 for RX data, RTR, SFF and EFF
>>> Dec  6 20:44:17 svserv01 kernel: [ 2229.886937] cc770_isa cc770_isa.0:
>>> can0: Message object 11 for TX data, RTR, SFF and EFF
>>> Dec  6 20:52:40 svserv01 kernel: [ 2733.172845] can: controller area
>>> network core (rev 20090105 abi 8)
>>> Dec  6 20:52:40 svserv01 kernel: [ 2733.172967] NET: Registered protocol
>>> family 29
>>> Dec  6 20:52:40 svserv01 kernel: [ 2733.178187] can: raw protocol (rev
>>> 20090105)
>>>
>>>
>>> ip -d -s link show
>>> 4: can0:<NOARP,UP,LOWER_UP,ECHO>  mtu 16 qdisc pfifo_fast state UNKNOWN
>>> qlen 10
>>>      link/can
>>>      can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0
>>>      bitrate 500000 sample-point 0.875
>>>      tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
>>>      cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
>>>      clock 8000000
>>>      re-started bus-errors arbit-lost error-warn error-pass bus-off
>>>      0          0          0          0          0          0
>>>      RX: bytes  packets  errors  dropped overrun mcast
>>>      0          0        0       0       0       0
>>>      TX: bytes  packets  errors  dropped carrier collsns
>>>      0          0        0       0       0       0
>>>
>>>
>>> After rebooting the PLC with proprietary buggy kernel:
>>> 4: can0:<NOARP,UP,LOWER_UP,ECHO>  mtu 16 qdisc pfifo_fast state UNKNOWN
>>> qlen 10
>>>      link/can
>>>      can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0
>>>      bitrate 500000 sample-point 0.875
>>>      tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
>>>      cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
>>>      clock 8000000
>>>      re-started bus-errors arbit-lost error-warn error-pass bus-off
>>>      0          0          0          0          0          0
>>>      RX: bytes  packets  errors  dropped overrun mcast
>>>      414        267      0       267     0       0
>>>      TX: bytes  packets  errors  dropped carrier collsns
>>>      0          0        0       0       0       0
>>>
>>>
>>>
>>> After sending 100,000 PDO's with 13ms displacement:
>>> 4: can0:<NOARP,UP,LOWER_UP,ECHO>  mtu 16 qdisc pfifo_fast state UNKNOWN
>>> qlen 10
>>>      link/can
>>>      can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0
>>>      bitrate 500000 sample-point 0.875
>>>      tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
>>>      cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
>>>      clock 8000000
>>>      re-started bus-errors arbit-lost error-warn error-pass bus-off
>>>      0          0          0          0          0          0
>>>      RX: bytes  packets  errors  dropped overrun mcast
>>>      4544       4284     0       331     0       0
>>>      TX: bytes  packets  errors  dropped carrier collsns
>>>      802660     202653   0       0       0       0
>>>
>>>
>>> The dropped ones of RX may be the not processed input packages and
>>> therefore ok.
>>>
>>> Let me know if You need more or some other tests.
>>
>> You could provoke some state changes or bus-off conditions to see if the
>> berr-counter shows reasonable results. I'm currently consolidating and
>> unifying error state and bus-off handling. Would be nice if you could do
>> some further tests when I have the patches ready...
>
> I just pushed the mentioned modifications to the "devel" branch of my
> "wg-linux-can-next" [1] repository. You can get it as shown below:
>
>    $ git clone --reference=<some-recent-net-next-tree>  \
>        git://gitorious.org/~wgrandegger/linux-can/wg-linux-can-next.git
>    $ git checkout -b devel devel
>
> [1] https://gitorious.org/~wgrandegger/linux-can/wg-linux-can-next
>
> Wolfgang.

OK, I was trying so far and You will find below the results.
Just FYI the states on the PLC side couldn't be verified because the function
provided by the manufacturer is not working at all and CAN analyser was not
available.

We are running CANopen and therefore the PLC will send automatically a heartbeat.

I produced the bus-off state through a short circuit between L/H which was
working as expected.

A bit odd was that on the second try I had to reload the module
because a ip down/up was not enough.

Let me know if You would need further tests or different procedure.



Starting procedure:
Cable disconnected
Restarting PC with new driver
Restarting PLC
Connecting cable
modprobe cc770_isa irq=0xa port=0x384 indirect=1 cir=0x61 bcr=0x4A
dmesg:
[  221.996751] CAN device driver interface
[  222.036036] cc770: CAN netdevice driver
[  222.054260] cc770_isa: platform device 0: port=0x384, mem=0x0, irq=10
[  222.054293] cc770_isa cc770_isa.0: probing idx=0: port=0x384, mem=0x0, irq=10
[  222.054343] cc770_isa cc770_isa.0: (unregistered net_device): i82527 mode with additional functions
[  222.055925] cc770_isa cc770_isa.0: device registered (reg_base=0x00000384, irq=10)
[  222.055972] cc770_isa: driver for max. 8 devices registered

ip -d -s link show can0
4: can0: <NOARP,ECHO> mtu 16 qdisc noop state DOWN qlen 10
     link/can
     can state STOPPED (berr-counter tx 92 rx 103) restart-ms 0
     bitrate 0 sample-point 0.000
     tq 0 prop-seg 0 phase-seg1 0 phase-seg2 0 sjw 0
     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
     clock 8000000
     re-started bus-errors arbit-lost error-warn error-pass bus-off
     0          0          0          0          0          0
     RX: bytes  packets  errors  dropped overrun mcast
     0          0        0       0       0       0
     TX: bytes  packets  errors  dropped carrier collsns
     0          0        0       0       0       0

ip link set can0 up type can bitrate 500000
dmesg:
[  287.871983] cc770_isa cc770_isa.0: can0: setting BTR0=0x00 BTR1=0x1c
[  287.872103] cc770_isa cc770_isa.0: can0: Message object 15 for RX data, RTR, SFF and EFF
[  287.872119] cc770_isa cc770_isa.0: can0: Message object 11 for TX data, RTR, SFF and EFF

ip -d -s link show can0
4: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN qlen 10
     link/can
     can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0
     bitrate 500000 sample-point 0.875
     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
     clock 8000000
     re-started bus-errors arbit-lost error-warn error-pass bus-off
     0          0          0          0          0          0
     RX: bytes  packets  errors  dropped overrun mcast
     0          0        0       0       0       0
     TX: bytes  packets  errors  dropped carrier collsns
     0          0        0       0       0       0

PLC stays in unknown CAN state (as usual )
Rebooting PLC

dmesg:
[  466.169054] can: controller area network core (rev 20090105 abi 8)
[  466.169178] NET: Registered protocol family 29
[  466.174339] can: raw protocol (rev 20090105)


PLC is sending heartbeat
Starting PC heartbeats

ip -d -s link show can0
4: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN qlen 10
     link/can
     can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0
     bitrate 500000 sample-point 0.875
     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
     clock 8000000
     re-started bus-errors arbit-lost error-warn error-pass bus-off
     0          0          0          0          0          0
     RX: bytes  packets  errors  dropped overrun mcast
     513        365      0       0       0       0
     TX: bytes  packets  errors  dropped carrier collsns
     20         20       0       0       0       0


Producing L/H short circuit for 2 seconds
dmesg:
[  885.409058] cc770_isa cc770_isa.0: can0: status interrupt (0x5b)
[  885.420475] cc770_isa cc770_isa.0: can0: status interrupt (0xc5)
[  885.420496] cc770_isa cc770_isa.0: can0: bus-off

ip -d -s link show can0
4: can0: <NO-CARRIER,NOARP,UP,ECHO> mtu 16 qdisc pfifo_fast state DOWN qlen 10
     link/can
     can state BUS-OFF (berr-counter tx 92 rx 103) restart-ms 0
     bitrate 500000 sample-point 0.875
     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
     clock 8000000
     re-started bus-errors arbit-lost error-warn error-pass bus-off
     0          0          0          1          0          1
     RX: bytes  packets  errors  dropped overrun mcast
     544        382      0       0       0       0
     TX: bytes  packets  errors  dropped carrier collsns
     30         29       0       0       0       0

Sending and receiving stops.

Trying to recover on PC:
ip link set can0 down;
ip -d -s link show can0
4: can0: <NOARP,ECHO> mtu 16 qdisc pfifo_fast state DOWN qlen 10
     link/can
     can state STOPPED (berr-counter tx 92 rx 103) restart-ms 0
     bitrate 500000 sample-point 0.875
     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
     clock 8000000
     re-started bus-errors arbit-lost error-warn error-pass bus-off
     0          0          0          1          0          1
     RX: bytes  packets  errors  dropped overrun mcast
     544        382      0       0       0       0
     TX: bytes  packets  errors  dropped carrier collsns
     30         29       0       1       0       0

ip link set can0 up type can bitrate 500000;
dmesg:
[ 1090.937778] cc770_isa cc770_isa.0: can0: setting BTR0=0x00 BTR1=0x1c
[ 1090.937869] cc770_isa cc770_isa.0: can0: Message object 15 for RX data, RTR, SFF and EFF
[ 1090.937885] cc770_isa cc770_isa.0: can0: Message object 11 for TX data, RTR, SFF and EFF
[ 1090.938050] ADDRCONF(NETDEV_CHANGE): can0: link becomes ready
[ 1090.940769] cc770_isa cc770_isa.0: can0: status interrupt (0x5)

ip -d -s link show can0
4: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP qlen 10
     link/can
     can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0
     bitrate 500000 sample-point 0.875
     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
     clock 8000000
     re-started bus-errors arbit-lost error-warn error-pass bus-off
     0          0          0          1          0          1
     RX: bytes  packets  errors  dropped overrun mcast
     552        383      0       0       0       0
     TX: bytes  packets  errors  dropped carrier collsns
     30         29       0       1       0       0

PLC in unknown state but not sending heartbeat,
Rebooting PLC
PLC sends heartbeat but PC cannot send (buffer overrun)

ip -d -s link show can0
4: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP qlen 10
     link/can
     can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0
     bitrate 500000 sample-point 0.875
     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
     clock 8000000
     re-started bus-errors arbit-lost error-warn error-pass bus-off
     0          0          0          1          0          1
     RX: bytes  packets  errors  dropped overrun mcast
     582        398      0       0       0       0
     TX: bytes  packets  errors  dropped carrier collsns
     30         29       0       1       0       0


Reloading driver

modprobe -r cc770_isa
dmesg:
[ 1457.133359] cc770: driver removed

modprobe cc770_isa irq=0xa port=0x384 indirect=1 cir=0x61 bcr=0x4A
dmesg:
[ 1474.051479] CAN device driver interface
[ 1474.053180] cc770: CAN netdevice driver
[ 1474.054416] cc770_isa: platform device 0: port=0x384, mem=0x0, irq=10
[ 1474.054449] cc770_isa cc770_isa.0: probing idx=0: port=0x384, mem=0x0, irq=10
[ 1474.054500] cc770_isa cc770_isa.0: (unregistered net_device): i82527 mode with additional functions
[ 1474.056097] cc770_isa cc770_isa.0: device registered (reg_base=0x00000384, irq=10)
[ 1474.056146] cc770_isa: driver for max. 8 devices registered

ip link set can0 up type can bitrate 500000;
[ 1484.586697] cc770_isa cc770_isa.0: can0: setting BTR0=0x00 BTR1=0x1c
[ 1484.586775] cc770_isa cc770_isa.0: can0: Message object 15 for RX data, RTR, SFF and EFF
[ 1484.586791] cc770_isa cc770_isa.0: can0: Message object 11 for TX data, RTR, SFF and EFF

Receiving and sending heartbeat
ip -d -s link show can0
5: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN qlen 10
     link/can
     can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0
     bitrate 500000 sample-point 0.875
     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
     clock 8000000
     re-started bus-errors arbit-lost error-warn error-pass bus-off
     0          0          0          0          0          0
     RX: bytes  packets  errors  dropped overrun mcast
     158        157      0       0       0       0
     TX: bytes  packets  errors  dropped carrier collsns
     16         16       0       0       0       0


-----------------------------------------

Producing L/H short circuit again for 2 seconds

dmesg:
[ 1719.018116] cc770_isa cc770_isa.0: can0: status interrupt (0x5b)

ip -d -s link show can0
5: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN qlen 10
     link/can
     can state ERROR-WARNING (berr-counter tx 128 rx 128) restart-ms 0
     bitrate 500000 sample-point 0.875
     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
     clock 8000000
     re-started bus-errors arbit-lost error-warn error-pass bus-off
     0          0          0          1          0          0
     RX: bytes  packets  errors  dropped overrun mcast
     271        263      0       0       0       0
     TX: bytes  packets  errors  dropped carrier collsns
     88         87       0       0       0       0


Sending and receiving stops.

Trying to recover on PC with driver reload:
modprobe -r cc770_isa
dmesg:
[ 1820.358418] cc770: driver removed

modprobe cc770_isa irq=0xa port=0x384 indirect=1 cir=0x61 bcr=0x4A
dmesg:
[ 1826.810914] CAN device driver interface
[ 1826.812619] cc770: CAN netdevice driver
[ 1826.814126] cc770_isa: platform device 0: port=0x384, mem=0x0, irq=10
[ 1826.814158] cc770_isa cc770_isa.0: probing idx=0: port=0x384, mem=0x0, irq=10
[ 1826.814211] cc770_isa cc770_isa.0: (unregistered net_device): i82527 mode with additional functions
[ 1826.815789] cc770_isa cc770_isa.0: device registered (reg_base=0x00000384, irq=10)
[ 1826.815839] cc770_isa: driver for max. 8 devices registered

ip -d -s link show can0
6: can0: <NOARP,ECHO> mtu 16 qdisc noop state DOWN qlen 10
     link/can
     can state STOPPED (berr-counter tx 92 rx 103) restart-ms 0
     bitrate 0 sample-point 0.000
     tq 0 prop-seg 0 phase-seg1 0 phase-seg2 0 sjw 0
     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
     clock 8000000
     re-started bus-errors arbit-lost error-warn error-pass bus-off
     0          0          0          0          0          0
     RX: bytes  packets  errors  dropped overrun mcast
     0          0        0       0       0       0
     TX: bytes  packets  errors  dropped carrier collsns
     0          0        0       0       0       0

ip link set can0 up type can bitrate 500000;
dmesg:
[ 1861.776977] cc770_isa cc770_isa.0: can0: setting BTR0=0x00 BTR1=0x1c
[ 1861.777102] cc770_isa cc770_isa.0: can0: Message object 15 for RX data, RTR, SFF and EFF
[ 1861.777118] cc770_isa cc770_isa.0: can0: Message object 11 for TX data, RTR, SFF and EFF

ip -d -s link show can0
6: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN qlen 10
     link/can
     can state ERROR-ACTIVE (berr-counter tx 128 rx 128) restart-ms 0
     bitrate 500000 sample-point 0.875
     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
     clock 8000000
     re-started bus-errors arbit-lost error-warn error-pass bus-off
     0          0          0          0          0          0
     RX: bytes  packets  errors  dropped overrun mcast
     0          0        0       0       0       0
     TX: bytes  packets  errors  dropped carrier collsns
     1          0        0       0       0       0

PLC in unknown state
Unable to send and receive heartbeat
Rebooting PLC

ip -d -s link show can0
6: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN qlen 10
     link/can
     can state ERROR-ACTIVE (berr-counter tx 115 rx 0) restart-ms 0
     bitrate 500000 sample-point 0.875
     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
     clock 8000000
     re-started bus-errors arbit-lost error-warn error-pass bus-off
     0          0          0          0          0          0
     RX: bytes  packets  errors  dropped overrun mcast
     0          0        0       0       0       0
     TX: bytes  packets  errors  dropped carrier collsns
     13         13       0       0       0       0

ip -d -s link show can0
6: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN qlen 10
     link/can
     can state ERROR-ACTIVE (berr-counter tx 107 rx 0) restart-ms 0
     bitrate 500000 sample-point 0.875
     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
     clock 8000000
     re-started bus-errors arbit-lost error-warn error-pass bus-off
     0          0          0          0          0          0
     RX: bytes  packets  errors  dropped overrun mcast
     30         15       0       0       0       0
     TX: bytes  packets  errors  dropped carrier collsns
     21         21       0       0       0       0

dmesg:
[ 2102.085718] cc770_isa cc770_isa.0: can0: status interrupt (0x18)

ip -d -s link show can0
6: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN qlen 10
     link/can
     can state ERROR-ACTIVE (berr-counter tx 32 rx 0) restart-ms 0
     bitrate 500000 sample-point 0.875
     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
     clock 8000000
     re-started bus-errors arbit-lost error-warn error-pass bus-off
     0          0          0          0          0          0
     RX: bytes  packets  errors  dropped overrun mcast
     310        156      0       0       0       0
     TX: bytes  packets  errors  dropped carrier collsns
     96         96       0       0       0       0

And with counters on zero:
ip -d -s link show can0
6: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN qlen 10
     link/can
     can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0
     bitrate 500000 sample-point 0.875
     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
     clock 8000000
     re-started bus-errors arbit-lost error-warn error-pass bus-off
     0          0          0          0          0          0
     RX: bytes  packets  errors  dropped overrun mcast
     358        204      0       0       0       0
     TX: bytes  packets  errors  dropped carrier collsns
     129        129      0       0       0       0


-----------------------------------------
Disconnecting cable for around 4 seconds:

dmesg:
[ 2339.660283] cc770_isa cc770_isa.0: can0: status interrupt (0x5b)

ip -d -s link show can0
6: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN qlen 10
     link/can
     can state ERROR-WARNING (berr-counter tx 128 rx 128) restart-ms 0
     bitrate 500000 sample-point 0.875
     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
     clock 8000000
     re-started bus-errors arbit-lost error-warn error-pass bus-off
     0          0          0          1          0          0
     RX: bytes  packets  errors  dropped overrun mcast
     459        298      0       0       0       0
     TX: bytes  packets  errors  dropped carrier collsns
     193        192      0       0       0       0

Connecting again:
ip -d -s link show can0
6: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN qlen 10
     link/can
     can state ERROR-WARNING (berr-counter tx 120 rx 0) restart-ms 0
     bitrate 500000 sample-point 0.875
     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
     clock 8000000
     re-started bus-errors arbit-lost error-warn error-pass bus-off
     0          0          0          1          0          0
     RX: bytes  packets  errors  dropped overrun mcast
     473        311      0       0       0       0
     TX: bytes  packets  errors  dropped carrier collsns
     200        200      0       0       0       0

After some time (around 125 seconds):
dmesg:
[ 2387.172008] cc770_isa cc770_isa.0: can0: status interrupt (0x18)
ip -d -s link show can0
6: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN qlen 10
     link/can
     can state ERROR-ACTIVE (berr-counter tx 29 rx 0) restart-ms 0
     bitrate 500000 sample-point 0.875
     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
     clock 8000000
     re-started bus-errors arbit-lost error-warn error-pass bus-off
     0          0          0          1          0          0
     RX: bytes  packets  errors  dropped overrun mcast
     616        447      0       0       0       0
     TX: bytes  packets  errors  dropped carrier collsns
     291        291      0       0       0       0



-----------------------------------------
Disconnecting cable for around 55 seconds:

dmesg:
[ 2658.896959] cc770_isa cc770_isa.0: can0: status interrupt (0x5b)

ip -d -s link show can0
6: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN qlen 10
     link/can
     can state ERROR-WARNING (berr-counter tx 128 rx 128) restart-ms 0
     bitrate 500000 sample-point 0.875
     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
     clock 8000000
     re-started bus-errors arbit-lost error-warn error-pass bus-off
     0          0          0          2          0          0
     RX: bytes  packets  errors  dropped overrun mcast
     797        621      0       0       0       0
     TX: bytes  packets  errors  dropped carrier collsns
     408        407      0       0       0       0




ip -d -s link show can0
6: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN qlen 10
     link/can
     can state ERROR-WARNING (berr-counter tx 112 rx 0) restart-ms 0
     bitrate 500000 sample-point 0.875
     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
     clock 8000000
     re-started bus-errors arbit-lost error-warn error-pass bus-off
     0          0          0          2          0          0
     RX: bytes  packets  errors  dropped overrun mcast
     837        661      0       0       0       0
     TX: bytes  packets  errors  dropped carrier collsns
     423        423      0       0       0       0


dmesg:
[ 2765.805486] cc770_isa cc770_isa.0: can0: status interrupt (0x18)

ip -d -s link show can0
6: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN qlen 10
     link/can
     can state ERROR-ACTIVE (berr-counter tx 94 rx 0) restart-ms 0
     bitrate 500000 sample-point 0.875
     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
     clock 8000000
     re-started bus-errors arbit-lost error-warn error-pass bus-off
     0          0          0          2          0          0
     RX: bytes  packets  errors  dropped overrun mcast
     872        689      0       0       0       0
     TX: bytes  packets  errors  dropped carrier collsns
     441        441      0       0       0       0




Thanks a lot.


Wolfgang

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
       [not found]                                       ` <4EE4F76E.3000506-PyqsHJVlJN8AvxtiuMwx3w@public.gmane.org>
@ 2011-12-12  9:23                                         ` Wolfgang Grandegger
       [not found]                                           ` <4EE5C824.2050704-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
  0 siblings, 1 reply; 66+ messages in thread
From: Wolfgang Grandegger @ 2011-12-12  9:23 UTC (permalink / raw)
  To: info-PyqsHJVlJN8AvxtiuMwx3w
  Cc: Oliver Hartkopp, linux-can-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	socketcan-users-0fE9KPoRgkgATYTw5x5z8w

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

Hi Wolfgang,

On 12/11/2011 07:33 PM, Wolfgang Zarre wrote:
> Hello Wolfgang,
>> On 12/07/2011 02:42 PM, Wolfgang Grandegger wrote:
>>> Hi Wolfgang,
>>>
>>> On 12/06/2011 10:08 PM, Wolfgang Zarre wrote:
...
>>>> Let me know if You need more or some other tests.
>>>
>>> You could provoke some state changes or bus-off conditions to see if the
>>> berr-counter shows reasonable results. I'm currently consolidating and
>>> unifying error state and bus-off handling. Would be nice if you could do
>>> some further tests when I have the patches ready...
>>
>> I just pushed the mentioned modifications to the "devel" branch of my
>> "wg-linux-can-next" [1] repository. You can get it as shown below:
>>
>>    $ git clone --reference=<some-recent-net-next-tree>  \
>>        git://gitorious.org/~wgrandegger/linux-can/wg-linux-can-next.git
>>    $ git checkout -b devel devel
>>
>> [1] https://gitorious.org/~wgrandegger/linux-can/wg-linux-can-next
>>
>> Wolfgang.
> 
> OK, I was trying so far and You will find below the results.
> Just FYI the states on the PLC side couldn't be verified because the
> function
> provided by the manufacturer is not working at all and CAN analyser was not
> available.
> 
> We are running CANopen and therefore the PLC will send automatically a
> heartbeat.
> 
> I produced the bus-off state through a short circuit between L/H which was
> working as expected.
> 
> A bit odd was that on the second try I had to reload the module
> because a ip down/up was not enough.

Oops, not good.

> Let me know if You would need further tests or different procedure.

The state changes are reported via error messages, which you can list
with "candump -td -e any,0:0,#FFFFFFFF" with the attached patch.

> Producing L/H short circuit for 2 seconds
> dmesg:
> [  885.409058] cc770_isa cc770_isa.0: can0: status interrupt (0x5b)
> [  885.420475] cc770_isa cc770_isa.0: can0: status interrupt (0xc5)
> [  885.420496] cc770_isa cc770_isa.0: can0: bus-off
> 
> ip -d -s link show can0
> 4: can0: <NO-CARRIER,NOARP,UP,ECHO> mtu 16 qdisc pfifo_fast state DOWN
> qlen 10
>     link/can
>     can state BUS-OFF (berr-counter tx 92 rx 103) restart-ms 0
>     bitrate 500000 sample-point 0.875
>     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
>     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
>     clock 8000000
>     re-started bus-errors arbit-lost error-warn error-pass bus-off
>     0          0          0          1          0          1
>     RX: bytes  packets  errors  dropped overrun mcast
>     544        382      0       0       0       0
>     TX: bytes  packets  errors  dropped carrier collsns
>     30         29       0       0       0       0
> 
> Sending and receiving stops.
> 
> Trying to recover on PC:
> ip link set can0 down;
> ip -d -s link show can0
> 4: can0: <NOARP,ECHO> mtu 16 qdisc pfifo_fast state DOWN qlen 10
>     link/can
>     can state STOPPED (berr-counter tx 92 rx 103) restart-ms 0
>     bitrate 500000 sample-point 0.875
>     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
>     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
>     clock 8000000
>     re-started bus-errors arbit-lost error-warn error-pass bus-off
>     0          0          0          1          0          1
>     RX: bytes  packets  errors  dropped overrun mcast
>     544        382      0       0       0       0
>     TX: bytes  packets  errors  dropped carrier collsns
>     30         29       0       1       0       0
> 
> ip link set can0 up type can bitrate 500000;
> dmesg:
> [ 1090.937778] cc770_isa cc770_isa.0: can0: setting BTR0=0x00 BTR1=0x1c
> [ 1090.937869] cc770_isa cc770_isa.0: can0: Message object 15 for RX
> data, RTR, SFF and EFF
> [ 1090.937885] cc770_isa cc770_isa.0: can0: Message object 11 for TX
> data, RTR, SFF and EFF
> [ 1090.938050] ADDRCONF(NETDEV_CHANGE): can0: link becomes ready
> [ 1090.940769] cc770_isa cc770_isa.0: can0: status interrupt (0x5)
> 
> ip -d -s link show can0
> 4: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP qlen 10
>     link/can
>     can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0
>     bitrate 500000 sample-point 0.875
>     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
>     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
>     clock 8000000
>     re-started bus-errors arbit-lost error-warn error-pass bus-off
>     0          0          0          1          0          1
>     RX: bytes  packets  errors  dropped overrun mcast
>     552        383      0       0       0       0
>     TX: bytes  packets  errors  dropped carrier collsns
>     30         29       0       1       0       0
> 
> PLC in unknown state but not sending heartbeat,
> Rebooting PLC

Hm, does it work if you do the bus-off recovery manually with?

  # ip link set can0 up type can restart

... or automatically with?

  # ip link set can0 up type can restart-ms 5000

Anyway, rebooting/reloading should never be necessary. I will check on
my i82572.

> -----------------------------------------
> Disconnecting cable for around 4 seconds:
> 
> dmesg:
> [ 2339.660283] cc770_isa cc770_isa.0: can0: status interrupt (0x5b)
> 
> ip -d -s link show can0
> 6: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN
> qlen 10
>     link/can
>     can state ERROR-WARNING (berr-counter tx 128 rx 128) restart-ms 0
>     bitrate 500000 sample-point 0.875
>     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
>     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
>     clock 8000000
>     re-started bus-errors arbit-lost error-warn error-pass bus-off
>     0          0          0          1          0          0
>     RX: bytes  packets  errors  dropped overrun mcast
>     459        298      0       0       0       0
>     TX: bytes  packets  errors  dropped carrier collsns
>     193        192      0       0       0       0

TX and RX berr-counter are >= 128. I wonder why error passive was not
reached.

> Connecting again:
> ip -d -s link show can0
> 6: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN
> qlen 10
>     link/can
>     can state ERROR-WARNING (berr-counter tx 120 rx 0) restart-ms 0
>     bitrate 500000 sample-point 0.875
>     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
>     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
>     clock 8000000
>     re-started bus-errors arbit-lost error-warn error-pass bus-off
>     0          0          0          1          0          0
>     RX: bytes  packets  errors  dropped overrun mcast
>     473        311      0       0       0       0
>     TX: bytes  packets  errors  dropped carrier collsns
>     200        200      0       0       0       0
> 
> After some time (around 125 seconds):
> dmesg:
> [ 2387.172008] cc770_isa cc770_isa.0: can0: status interrupt (0x18)
> ip -d -s link show can0
> 6: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN
> qlen 10
>     link/can
>     can state ERROR-ACTIVE (berr-counter tx 29 rx 0) restart-ms 0
>     bitrate 500000 sample-point 0.875
>     tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
>     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
>     clock 8000000
>     re-started bus-errors arbit-lost error-warn error-pass bus-off
>     0          0          0          1          0          0
>     RX: bytes  packets  errors  dropped overrun mcast
>     616        447      0       0       0       0
>     TX: bytes  packets  errors  dropped carrier collsns
>     291        291      0       0       0       0

OK, the state is back to error active (counter < 96).

Thanks for testing...

Wolfgang.




[-- Attachment #2: 0001-candump-add-support-for-error-states-going-backward.patch --]
[-- Type: text/x-diff, Size: 1299 bytes --]

>From e7b36500c9491ab026bd3c16dfca2ca4338524ac Mon Sep 17 00:00:00 2001
From: Wolfgang Grandegger <wg-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
Date: Mon, 12 Dec 2011 10:09:22 +0100
Subject: [PATCH] candump: add support for error states going backward

Signed-off-by: Wolfgang Grandegger <wg-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
---
 lib.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/lib.c b/lib.c
index a8ed2fe..7f810b9 100644
--- a/lib.c
+++ b/lib.c
@@ -318,6 +318,7 @@ static const char *error_classes[] = {
 	"bus-off",
 	"bus-error",
 	"restarted-after-bus-off",
+	"state-change",
 };
 
 static const char *controller_problems[] = {
@@ -327,6 +328,7 @@ static const char *controller_problems[] = {
 	"tx-error-warning",
 	"rx-error-passive",
 	"tx-error-passive",
+	"back-to-error-active",
 };
 
 static const char *protocol_violation_types[] = {
@@ -471,6 +473,8 @@ void snprintf_can_error_frame(char *buf, size_t len, struct can_frame *cf,
 			if (mask == CAN_ERR_LOSTARB)
 				n += snprintf_error_lostarb(buf + n, len - n,
 							   cf);
+			if (mask == CAN_ERR_STATE_CHANGE)
+				n += snprintf_error_ctrl(buf + n, len - n, cf);
 			if (mask == CAN_ERR_CRTL)
 				n += snprintf_error_ctrl(buf + n, len - n, cf);
 			if (mask == CAN_ERR_PROT)
-- 
1.7.4.1


[-- Attachment #3: Type: text/plain, Size: 191 bytes --]

_______________________________________________
Socketcan-users mailing list
Socketcan-users-0fE9KPoRgkgATYTw5x5z8w@public.gmane.org
https://lists.berlios.de/mailman/listinfo/socketcan-users

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
       [not found]                                           ` <4EE5C824.2050704-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
@ 2011-12-12 11:18                                             ` Wolfgang Zarre
  2011-12-12 11:55                                               ` Wolfgang Grandegger
  0 siblings, 1 reply; 66+ messages in thread
From: Wolfgang Zarre @ 2011-12-12 11:18 UTC (permalink / raw)
  To: Wolfgang Grandegger
  Cc: Oliver Hartkopp, linux-can-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	socketcan-users-0fE9KPoRgkgATYTw5x5z8w

Hello Wolfgang,
> Hi Wolfgang,
>
> On 12/11/2011 07:33 PM, Wolfgang Zarre wrote:
>> Hello Wolfgang,
>>> On 12/07/2011 02:42 PM, Wolfgang Grandegger wrote:
>>>> Hi Wolfgang,
>>>>
>>>> On 12/06/2011 10:08 PM, Wolfgang Zarre wrote:
> ...
>>>>> Let me know if You need more or some other tests.
>>>>
>>>> You could provoke some state changes or bus-off conditions to see if the
>>>> berr-counter shows reasonable results. I'm currently consolidating and
>>>> unifying error state and bus-off handling. Would be nice if you could do
>>>> some further tests when I have the patches ready...
>>>
>>> I just pushed the mentioned modifications to the "devel" branch of my
>>> "wg-linux-can-next" [1] repository. You can get it as shown below:
>>>
>>>     $ git clone --reference=<some-recent-net-next-tree>   \
>>>         git://gitorious.org/~wgrandegger/linux-can/wg-linux-can-next.git
>>>     $ git checkout -b devel devel
>>>
>>> [1] https://gitorious.org/~wgrandegger/linux-can/wg-linux-can-next
>>>
>>> Wolfgang.
>>
>> OK, I was trying so far and You will find below the results.
>> Just FYI the states on the PLC side couldn't be verified because the
>> function
>> provided by the manufacturer is not working at all and CAN analyser was not
>> available.
>>
>> We are running CANopen and therefore the PLC will send automatically a
>> heartbeat.
>>
>> I produced the bus-off state through a short circuit between L/H which was
>> working as expected.
>>
>> A bit odd was that on the second try I had to reload the module
>> because a ip down/up was not enough.
>
> Oops, not good.
>

But might be in connection with the strange behaviour of the PLC.

>> Let me know if You would need further tests or different procedure.
>
> The state changes are reported via error messages, which you can list
> with "candump -td -e any,0:0,#FFFFFFFF" with the attached patch.
>

Thanks, I'll try this with the next series of tests.

>> Producing L/H short circuit for 2 seconds
>> dmesg:
>> [  885.409058] cc770_isa cc770_isa.0: can0: status interrupt (0x5b)
>> [  885.420475] cc770_isa cc770_isa.0: can0: status interrupt (0xc5)
>> [  885.420496] cc770_isa cc770_isa.0: can0: bus-off
>>
>> ip -d -s link show can0
>> 4: can0:<NO-CARRIER,NOARP,UP,ECHO>  mtu 16 qdisc pfifo_fast state DOWN
>> qlen 10
>>      link/can
>>      can state BUS-OFF (berr-counter tx 92 rx 103) restart-ms 0
>>      bitrate 500000 sample-point 0.875
>>      tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
>>      cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
>>      clock 8000000
>>      re-started bus-errors arbit-lost error-warn error-pass bus-off
>>      0          0          0          1          0          1
>>      RX: bytes  packets  errors  dropped overrun mcast
>>      544        382      0       0       0       0
>>      TX: bytes  packets  errors  dropped carrier collsns
>>      30         29       0       0       0       0
>>
>> Sending and receiving stops.
>>
>> Trying to recover on PC:
>> ip link set can0 down;
>> ip -d -s link show can0
>> 4: can0:<NOARP,ECHO>  mtu 16 qdisc pfifo_fast state DOWN qlen 10
>>      link/can
>>      can state STOPPED (berr-counter tx 92 rx 103) restart-ms 0
>>      bitrate 500000 sample-point 0.875
>>      tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
>>      cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
>>      clock 8000000
>>      re-started bus-errors arbit-lost error-warn error-pass bus-off
>>      0          0          0          1          0          1
>>      RX: bytes  packets  errors  dropped overrun mcast
>>      544        382      0       0       0       0
>>      TX: bytes  packets  errors  dropped carrier collsns
>>      30         29       0       1       0       0
>>
>> ip link set can0 up type can bitrate 500000;
>> dmesg:
>> [ 1090.937778] cc770_isa cc770_isa.0: can0: setting BTR0=0x00 BTR1=0x1c
>> [ 1090.937869] cc770_isa cc770_isa.0: can0: Message object 15 for RX
>> data, RTR, SFF and EFF
>> [ 1090.937885] cc770_isa cc770_isa.0: can0: Message object 11 for TX
>> data, RTR, SFF and EFF
>> [ 1090.938050] ADDRCONF(NETDEV_CHANGE): can0: link becomes ready
>> [ 1090.940769] cc770_isa cc770_isa.0: can0: status interrupt (0x5)
>>
>> ip -d -s link show can0
>> 4: can0:<NOARP,UP,LOWER_UP,ECHO>  mtu 16 qdisc pfifo_fast state UP qlen 10
>>      link/can
>>      can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0
>>      bitrate 500000 sample-point 0.875
>>      tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
>>      cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
>>      clock 8000000
>>      re-started bus-errors arbit-lost error-warn error-pass bus-off
>>      0          0          0          1          0          1
>>      RX: bytes  packets  errors  dropped overrun mcast
>>      552        383      0       0       0       0
>>      TX: bytes  packets  errors  dropped carrier collsns
>>      30         29       0       1       0       0
>>
>> PLC in unknown state but not sending heartbeat,
>> Rebooting PLC
>
> Hm, does it work if you do the bus-off recovery manually with?
>
>    # ip link set can0 up type can restart
>
> ... or automatically with?
>
>    # ip link set can0 up type can restart-ms 5000

Ah, ok, good point, will try out as well with the next series of tests

>
> Anyway, rebooting/reloading should never be necessary. I will check on
> my i82572.
>
>> -----------------------------------------
>> Disconnecting cable for around 4 seconds:
>>
>> dmesg:
>> [ 2339.660283] cc770_isa cc770_isa.0: can0: status interrupt (0x5b)
>>
>> ip -d -s link show can0
>> 6: can0:<NOARP,UP,LOWER_UP,ECHO>  mtu 16 qdisc pfifo_fast state UNKNOWN
>> qlen 10
>>      link/can
>>      can state ERROR-WARNING (berr-counter tx 128 rx 128) restart-ms 0
>>      bitrate 500000 sample-point 0.875
>>      tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
>>      cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
>>      clock 8000000
>>      re-started bus-errors arbit-lost error-warn error-pass bus-off
>>      0          0          0          1          0          0
>>      RX: bytes  packets  errors  dropped overrun mcast
>>      459        298      0       0       0       0
>>      TX: bytes  packets  errors  dropped carrier collsns
>>      193        192      0       0       0       0
>
> TX and RX berr-counter are>= 128. I wonder why error passive was not
> reached.

Hmmm, that is a good question and You are right > 127 should be error-passive,
anyway, just realised now, what means then 'error-warning' because I just
know error-active, error-passive and bus-off.

>
>> Connecting again:
>> ip -d -s link show can0
>> 6: can0:<NOARP,UP,LOWER_UP,ECHO>  mtu 16 qdisc pfifo_fast state UNKNOWN
>> qlen 10
>>      link/can
>>      can state ERROR-WARNING (berr-counter tx 120 rx 0) restart-ms 0
>>      bitrate 500000 sample-point 0.875
>>      tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
>>      cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
>>      clock 8000000
>>      re-started bus-errors arbit-lost error-warn error-pass bus-off
>>      0          0          0          1          0          0
>>      RX: bytes  packets  errors  dropped overrun mcast
>>      473        311      0       0       0       0
>>      TX: bytes  packets  errors  dropped carrier collsns
>>      200        200      0       0       0       0
>>
>> After some time (around 125 seconds):
>> dmesg:
>> [ 2387.172008] cc770_isa cc770_isa.0: can0: status interrupt (0x18)
>> ip -d -s link show can0
>> 6: can0:<NOARP,UP,LOWER_UP,ECHO>  mtu 16 qdisc pfifo_fast state UNKNOWN
>> qlen 10
>>      link/can
>>      can state ERROR-ACTIVE (berr-counter tx 29 rx 0) restart-ms 0
>>      bitrate 500000 sample-point 0.875
>>      tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
>>      cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
>>      clock 8000000
>>      re-started bus-errors arbit-lost error-warn error-pass bus-off
>>      0          0          0          1          0          0
>>      RX: bytes  packets  errors  dropped overrun mcast
>>      616        447      0       0       0       0
>>      TX: bytes  packets  errors  dropped carrier collsns
>>      291        291      0       0       0       0
>
> OK, the state is back to error active (counter<  96).
>
> Thanks for testing...

You are welcome, however, I have to thank You for Your work done.

So, I'll try as soon as I can another series of tests and may be
You let me know if You have patches I should include as well.

>
> Wolfgang.
>
>
>

Thanks

Wolfgang

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2011-12-12 11:18                                             ` Wolfgang Zarre
@ 2011-12-12 11:55                                               ` Wolfgang Grandegger
       [not found]                                                 ` <4EE5EBBF.6080007-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
  0 siblings, 1 reply; 66+ messages in thread
From: Wolfgang Grandegger @ 2011-12-12 11:55 UTC (permalink / raw)
  To: info
  Cc: Oliver Hartkopp, netdev, linux-can, socketcan-users, IreneV,
	Stanislav Yelenskiy

On 12/12/2011 12:18 PM, Wolfgang Zarre wrote:
> Hello Wolfgang,
>> Hi Wolfgang,
>>
>> On 12/11/2011 07:33 PM, Wolfgang Zarre wrote:
>>> Hello Wolfgang,
>>>> On 12/07/2011 02:42 PM, Wolfgang Grandegger wrote:
>>>>> Hi Wolfgang,
>>>>>
>>>>> On 12/06/2011 10:08 PM, Wolfgang Zarre wrote:
>> ...
>>>>>> Let me know if You need more or some other tests.
>>>>>
>>>>> You could provoke some state changes or bus-off conditions to see
>>>>> if the
>>>>> berr-counter shows reasonable results. I'm currently consolidating and
>>>>> unifying error state and bus-off handling. Would be nice if you
>>>>> could do
>>>>> some further tests when I have the patches ready...
>>>>
>>>> I just pushed the mentioned modifications to the "devel" branch of my
>>>> "wg-linux-can-next" [1] repository. You can get it as shown below:
>>>>
>>>>     $ git clone --reference=<some-recent-net-next-tree>   \
>>>>        
>>>> git://gitorious.org/~wgrandegger/linux-can/wg-linux-can-next.git
>>>>     $ git checkout -b devel devel
>>>>
>>>> [1] https://gitorious.org/~wgrandegger/linux-can/wg-linux-can-next
>>>>
>>>> Wolfgang.
>>>
>>> OK, I was trying so far and You will find below the results.
>>> Just FYI the states on the PLC side couldn't be verified because the
>>> function
>>> provided by the manufacturer is not working at all and CAN analyser
>>> was not
>>> available.
>>>
>>> We are running CANopen and therefore the PLC will send automatically a
>>> heartbeat.
>>>
>>> I produced the bus-off state through a short circuit between L/H
>>> which was
>>> working as expected.
>>>
>>> A bit odd was that on the second try I had to reload the module
>>> because a ip down/up was not enough.
>>
>> Oops, not good.
>>
> 
> But might be in connection with the strange behaviour of the PLC.

It's a bug! netif_start_queue is missing at the end of the open
function. Got lost some how. I have just updated (rebased!) my
wg-linux-can-next repository.

Wolfgang.

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
       [not found]                                                 ` <4EE5EBBF.6080007-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
@ 2011-12-21 18:32                                                   ` Wolfgang Zarre
  2011-12-22  9:37                                                     ` Wolfgang Grandegger
  0 siblings, 1 reply; 66+ messages in thread
From: Wolfgang Zarre @ 2011-12-21 18:32 UTC (permalink / raw)
  To: Wolfgang Grandegger
  Cc: Oliver Hartkopp, linux-can-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	socketcan-users-0fE9KPoRgkgATYTw5x5z8w

Hello Wolfgang,

> On 12/12/2011 12:18 PM, Wolfgang Zarre wrote:
>> Hello Wolfgang,
>>> Hi Wolfgang,
>>>
>>> On 12/11/2011 07:33 PM, Wolfgang Zarre wrote:
>>>> Hello Wolfgang,
>>>>> On 12/07/2011 02:42 PM, Wolfgang Grandegger wrote:
>>>>>> Hi Wolfgang,
>>>>>>
>>>>>> On 12/06/2011 10:08 PM, Wolfgang Zarre wrote:
>>> ...
>>>>>>> Let me know if You need more or some other tests.
>>>>>>
>>>>>> You could provoke some state changes or bus-off conditions to see
>>>>>> if the
>>>>>> berr-counter shows reasonable results. I'm currently consolidating and
>>>>>> unifying error state and bus-off handling. Would be nice if you
>>>>>> could do
>>>>>> some further tests when I have the patches ready...
>>>>>
>>>>> I just pushed the mentioned modifications to the "devel" branch of my
>>>>> "wg-linux-can-next" [1] repository. You can get it as shown below:
>>>>>
>>>>>      $ git clone --reference=<some-recent-net-next-tree>    \
>>>>>
>>>>> git://gitorious.org/~wgrandegger/linux-can/wg-linux-can-next.git
>>>>>      $ git checkout -b devel devel
>>>>>
>>>>> [1] https://gitorious.org/~wgrandegger/linux-can/wg-linux-can-next
>>>>>
>>>>> Wolfgang.
>>>>
>>>> OK, I was trying so far and You will find below the results.
>>>> Just FYI the states on the PLC side couldn't be verified because the
>>>> function
>>>> provided by the manufacturer is not working at all and CAN analyser
>>>> was not
>>>> available.
>>>>
>>>> We are running CANopen and therefore the PLC will send automatically a
>>>> heartbeat.
>>>>
>>>> I produced the bus-off state through a short circuit between L/H
>>>> which was
>>>> working as expected.
>>>>
>>>> A bit odd was that on the second try I had to reload the module
>>>> because a ip down/up was not enough.
>>>
>>> Oops, not good.
>>>
>>
>> But might be in connection with the strange behaviour of the PLC.
>
> It's a bug! netif_start_queue is missing at the end of the open
> function. Got lost some how. I have just updated (rebased!) my
> wg-linux-can-next repository.

Ok, I was checking out last week and since I'm running one test series
after the other.

There are several odd issues I could found and I'm trying to trace them
down beside some other work.

Even with an assumed correct configuration like I was using with the lincan
driver I'm loosing telegrams so around 1 till 2 in 500000 but might be a
different sample-point at the PLC which is opaque due the predefined setting.
For the next test I'll set the BTR's directly.
Further sometimes I can find one in dropped but mostly not.

But more odd is that after an undefined time the transmission gets
stuck followed by a buffer overrun but can receive.
No error messages nor changes in ip -d -s link show can0.

Additional it seems that neither the automatic restart nor
the manual one works.

ip link set can0 up type can restart gives me 'RTNETLINK answers: Invalid
argument' and ip link set can0 up type can bitrate 500000 restart a
RTNETLINK answers: Device or resource busy but nothing connected to can0.

So I have to perform per example  ip link set can0 down;ip link set can0 up
type can bitrate 500000 restart-ms 2000 sample-point 0.75
but this is emptying the buffer and these telegrams are lost then as well.

I was comparing with my lincan driver which was running so far ok also
to confirm a proper working PLC.

First I assumed that maybe the set_reset_mode procedure is responsible for
that misbehaviour because according to the cc770 manual we should wait for
a zero of bit 7 RstST of the CPU interface register but when the transmission
gets stuck there was no call for set_reset_mode.

Maybe it's ending up somehow recessive.

Anyway, I might compare the registers of both drivers just to figure out
what's going on but maybe You have an idea as well.

Problem is just it runs always quite some time until the issues happen
otherwise it would be more easy.



>
> Wolfgang.


Wolfgang

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2011-12-21 18:32                                                   ` Wolfgang Zarre
@ 2011-12-22  9:37                                                     ` Wolfgang Grandegger
       [not found]                                                       ` <4EF2FA3F.3010308-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
  0 siblings, 1 reply; 66+ messages in thread
From: Wolfgang Grandegger @ 2011-12-22  9:37 UTC (permalink / raw)
  To: info
  Cc: Oliver Hartkopp, netdev, linux-can, socketcan-users, IreneV,
	Stanislav Yelenskiy

Hi Wolfgang,

On 12/21/2011 07:32 PM, Wolfgang Zarre wrote:
> Hello Wolfgang,
...

>> It's a bug! netif_start_queue is missing at the end of the open
>> function. Got lost some how. I have just updated (rebased!) my
>> wg-linux-can-next repository.
> 
> Ok, I was checking out last week and since I'm running one test series
> after the other.
> 
> There are several odd issues I could found and I'm trying to trace them
> down beside some other work.
> 
> Even with an assumed correct configuration like I was using with the lincan
> driver I'm loosing telegrams so around 1 till 2 in 500000 but might be a
> different sample-point at the PLC which is opaque due the predefined
> setting.

In principle, messages can be lost because the cc770 does buffer only up
to two messages in hardware. If they are not read out quickly enough,
message loss will happen. The CAN statistics should list such overruns,
though.

> For the next test I'll set the BTR's directly.

OK, if you do not see bus errors, everything should be fine.

> Further sometimes I can find one in dropped but mostly not.
> 
> But more odd is that after an undefined time the transmission gets
> stuck followed by a buffer overrun but can receive.

I recently found a bug. Please try this fix:

http://marc.info/?l=linux-can&m=132370253713701&w=4

Did you realize related error messages in the dmesg output?

> No error messages nor changes in ip -d -s link show can0.
> 
> Additional it seems that neither the automatic restart nor
> the manual one works.

What version are you using. I think this problem has been fixed by
adding the missing netif_start_queue() at the end of the open
function, as mentioned above. Do you have that in your driver?

> ip link set can0 up type can restart gives me 'RTNETLINK answers: Invalid
> argument' and ip link set can0 up type can bitrate 500000 restart a
> RTNETLINK answers: Device or resource busy but nothing connected to can0.

The error message is shown because you try to set bitrate when the
device is up. For the restart after bus-off just type:

  # ip link set can0 type can restart

Anyway, if you run into a bus-off, then it's likely that you have
electrical problems on the CAN bus, e.g. termination, mismatching
bit-timing parameters.

> So I have to perform per example  ip link set can0 down;ip link set can0 up
> type can bitrate 500000 restart-ms 2000 sample-point 0.75
> but this is emptying the buffer and these telegrams are lost then as well.
> 
> I was comparing with my lincan driver which was running so far ok also
> to confirm a proper working PLC.
> 
> First I assumed that maybe the set_reset_mode procedure is responsible for
> that misbehaviour because according to the cc770 manual we should wait for
> a zero of bit 7 RstST of the CPU interface register but when the
> transmission
> gets stuck there was no call for set_reset_mode.
> 
> Maybe it's ending up somehow recessive.
> 
> Anyway, I might compare the registers of both drivers just to figure out
> what's going on but maybe You have an idea as well.
> 
> Problem is just it runs always quite some time until the issues happen
> otherwise it would be more easy.

Again, please check if you have netif_start_queue() at the end of the
open function.

Wolfgang.

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
       [not found]                                                       ` <4EF2FA3F.3010308-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
@ 2011-12-22 13:20                                                         ` Wolfgang Zarre
       [not found]                                                           ` <4EF32E84.1080006-PyqsHJVlJN8AvxtiuMwx3w@public.gmane.org>
  0 siblings, 1 reply; 66+ messages in thread
From: Wolfgang Zarre @ 2011-12-22 13:20 UTC (permalink / raw)
  To: Wolfgang Grandegger
  Cc: Oliver Hartkopp, linux-can-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	socketcan-users-0fE9KPoRgkgATYTw5x5z8w

Hello Wolfgang,
> Hi Wolfgang,
>
> On 12/21/2011 07:32 PM, Wolfgang Zarre wrote:
>> Hello Wolfgang,
> ...
>
>>> It's a bug! netif_start_queue is missing at the end of the open
>>> function. Got lost some how. I have just updated (rebased!) my
>>> wg-linux-can-next repository.
>>
>> Ok, I was checking out last week and since I'm running one test series
>> after the other.
>>
>> There are several odd issues I could found and I'm trying to trace them
>> down beside some other work.
>>
>> Even with an assumed correct configuration like I was using with the lincan
>> driver I'm loosing telegrams so around 1 till 2 in 500000 but might be a
>> different sample-point at the PLC which is opaque due the predefined
>> setting.
>
> In principle, messages can be lost because the cc770 does buffer only up
> to two messages in hardware. If they are not read out quickly enough,
> message loss will happen. The CAN statistics should list such overruns,
> though.
>
Actually I loose them on transmission, not reception, but as mentioned
one time we traced with a second PC and there the telegrams are not lost
which means they are really going over the bus physically.
So maybe just a timing issue but for now secondary.

However the telegrams are sent with 5ms space parallel to the heartbeat.

>> For the next test I'll set the BTR's directly.
>
> OK, if you do not see bus errors, everything should be fine.
>

The test with BTR's set was not working out due the fact that
the software for coding the PLC doesn't allow, I'm loving it.

>> Further sometimes I can find one in dropped but mostly not.
>>
>> But more odd is that after an undefined time the transmission gets
>> stuck followed by a buffer overrun but can receive.
>
> I recently found a bug. Please try this fix:
>
> http://marc.info/?l=linux-can&m=132370253713701&w=4

The fix is already included as checked out.

>
> Did you realize related error messages in the dmesg output?

Nothing at all, as mentioned .

>
>> No error messages nor changes in ip -d -s link show can0.
>>
>> Additional it seems that neither the automatic restart nor
>> the manual one works.
>
> What version are you using. I think this problem has been fixed by
> adding the missing netif_start_queue() at the end of the open
> function, as mentioned above. Do you have that in your driver?
>

Yes, is already included as well, I'm using commit
eec921ac28fde243456078a557768808d93d94a3


>> ip link set can0 up type can restart gives me 'RTNETLINK answers: Invalid
>> argument' and ip link set can0 up type can bitrate 500000 restart a
>> RTNETLINK answers: Device or resource busy but nothing connected to can0.
>
> The error message is shown because you try to set bitrate when the
> device is up. For the restart after bus-off just type:
>
>    # ip link set can0 type can restart

Actually I tried it when it's get stuck but is anyway a hint that
the device is still up,

>
> Anyway, if you run into a bus-off, then it's likely that you have
> electrical problems on the CAN bus, e.g. termination, mismatching
> bit-timing parameters.

As said I have no indication of any kind of problem:
5: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN qlen 10
     link/can
     can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 2000
     bitrate 500000 sample-point 0.750
     tq 125 prop-seg 5 phase-seg1 6 phase-seg2 4 sjw 1
     cc770: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
     clock 16000000
     re-started bus-errors arbit-lost error-warn error-pass bus-off
     0          0          0          0          0          0
     RX: bytes  packets  errors  dropped overrun mcast
     76506      74616    0       0       0       0
     TX: bytes  packets  errors  dropped carrier collsns
     2450703    616355   0       0       0       0

>
>> So I have to perform per example  ip link set can0 down;ip link set can0 up
>> type can bitrate 500000 restart-ms 2000 sample-point 0.75
>> but this is emptying the buffer and these telegrams are lost then as well.
>>
>> I was comparing with my lincan driver which was running so far ok also
>> to confirm a proper working PLC.
>>
>> First I assumed that maybe the set_reset_mode procedure is responsible for
>> that misbehaviour because according to the cc770 manual we should wait for
>> a zero of bit 7 RstST of the CPU interface register but when the
>> transmission
>> gets stuck there was no call for set_reset_mode.
>>
>> Maybe it's ending up somehow recessive.
>>
>> Anyway, I might compare the registers of both drivers just to figure out
>> what's going on but maybe You have an idea as well.
>>
>> Problem is just it runs always quite some time until the issues happen
>> otherwise it would be more easy.
>
> Again, please check if you have netif_start_queue() at the end of the
> open function.
>

As said I'm using eec921ac28fde243456078a557768808d93d94a3

However, I'll try further to investigate that issue due the fact having it
running with my lincan without problems and therefore it should be possible
to find the problem.

> Wolfgang.

Wolfgang

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
       [not found]                                                           ` <4EF32E84.1080006-PyqsHJVlJN8AvxtiuMwx3w@public.gmane.org>
@ 2011-12-31  9:39                                                             ` Wolfgang Zarre
  2012-01-04 13:10                                                               ` Wolfgang Grandegger
  0 siblings, 1 reply; 66+ messages in thread
From: Wolfgang Zarre @ 2011-12-31  9:39 UTC (permalink / raw)
  To: Wolfgang Grandegger
  Cc: Oliver Hartkopp, linux-can-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	socketcan-users-0fE9KPoRgkgATYTw5x5z8w

Hello Wolfgang,

> Hello Wolfgang,
>> Hi Wolfgang,
>>
>> On 12/21/2011 07:32 PM, Wolfgang Zarre wrote:
>>> Hello Wolfgang,
>> ...
>>
>>
>> Again, please check if you have netif_start_queue() at the end of the
>> open function.
>>
>
> As said I'm using eec921ac28fde243456078a557768808d93d94a3
>
> However, I'll try further to investigate that issue due the fact having it
> running with my lincan without problems and therefore it should be possible
> to find the problem.
>

I found the problem which was then at the end quite simple to understand why it
get stuck due the fact not receiving an interrupt for TX and due that no
reactivation of the queue.

I think that maybe also the hacks in the TX functions are obsolete with the
fix assuming that the repeated interrupts just happen by indirect access.

Here my fix which worked for me:
--------------------------------------------------------------------------------------------------------
diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c
index 2d12f89..dad6707 100644
--- a/drivers/net/can/cc770/cc770.c
+++ b/drivers/net/can/cc770/cc770.c
@@ -460,15 +460,6 @@ static netdev_tx_t cc770_start_xmit(struct sk_buff *skb, struct net_device *dev)

  	stats->tx_bytes += dlc;

-
-	/*
-	 * HM: We had some cases of repeated IRQs so make sure the
-	 * INT is acknowledged I know it's already further up, but
-	 * doing again fixed the issue
-	 */
-	cc770_write_reg(priv, msgobj[mo].ctrl0,
-			MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);
-
  	return NETDEV_TX_OK;
  }

@@ -689,12 +680,6 @@ static void cc770_tx_interrupt(struct net_device *dev, unsigned int o)
  	/* Nothing more to send, switch off interrupts */
  	cc770_write_reg(priv, msgobj[mo].ctrl0,
  			MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES);
-	/*
-	 * We had some cases of repeated IRQ so make sure the
-	 * INT is acknowledged
-	 */
-	cc770_write_reg(priv, msgobj[mo].ctrl0,
-			MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);

  	stats->tx_packets++;
  	can_get_echo_skb(dev, 0);
diff --git a/drivers/net/can/cc770/cc770_isa.c b/drivers/net/can/cc770/cc770_isa.c
index 4be5fe2..48fc128 100644
--- a/drivers/net/can/cc770/cc770_isa.c
+++ b/drivers/net/can/cc770/cc770_isa.c
@@ -148,8 +148,7 @@ static void cc770_isa_port_write_reg_indirect(const struct cc770_priv *priv,
  {
  	unsigned long base = (unsigned long)priv->reg_base;

-	outb(reg, base);
-	outb(val, base + 1);
+	outw( reg + ( val << 8), base);
  }

  static int __devinit cc770_isa_probe(struct platform_device *pdev)

---------------------------------------------------------------------------------------------


Please let me know if this is OK for You, maybe You can do some tests as well.

Would continue then with further tests regarding error conditions, however
I realised another small issue with dropped packages at reception.

As soon as You read the first time from the socket and then You stop reading
the packages are not counted as 'dropped' any more which is IMHO not correct
because as soon as You stop reading they should be counted as dropped again.


>> Wolfgang.
>
> Wolfgang

Wolfgang

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2011-12-31  9:39                                                             ` Wolfgang Zarre
@ 2012-01-04 13:10                                                               ` Wolfgang Grandegger
  2012-01-05  3:29                                                                 ` Wolfgang Zarre
  0 siblings, 1 reply; 66+ messages in thread
From: Wolfgang Grandegger @ 2012-01-04 13:10 UTC (permalink / raw)
  To: info
  Cc: Oliver Hartkopp, netdev, linux-can, socketcan-users, IreneV,
	Stanislav Yelenskiy

Hi Wolfgang,

On 12/31/2011 10:39 AM, Wolfgang Zarre wrote:
> Hello Wolfgang,
> 
>> Hello Wolfgang,
>>> Hi Wolfgang,
>>>
>>> On 12/21/2011 07:32 PM, Wolfgang Zarre wrote:
>>>> Hello Wolfgang,
>>> ...
>>>
>>>
>>> Again, please check if you have netif_start_queue() at the end of the
>>> open function.
>>>
>>
>> As said I'm using eec921ac28fde243456078a557768808d93d94a3
>>
>> However, I'll try further to investigate that issue due the fact
>> having it
>> running with my lincan without problems and therefore it should be
>> possible
>> to find the problem.
>>
> 
> I found the problem which was then at the end quite simple to understand
> why it
> get stuck due the fact not receiving an interrupt for TX and due that no
> reactivation of the queue.
> 
> I think that maybe also the hacks in the TX functions are obsolete with the
> fix assuming that the repeated interrupts just happen by indirect access.

OK, to understand you correctly...

> Here my fix which worked for me:
> --------------------------------------------------------------------------------------------------------
> 
> diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c
> index 2d12f89..dad6707 100644
> --- a/drivers/net/can/cc770/cc770.c
> +++ b/drivers/net/can/cc770/cc770.c
> @@ -460,15 +460,6 @@ static netdev_tx_t cc770_start_xmit(struct sk_buff
> *skb, struct net_device *dev)
> 
>      stats->tx_bytes += dlc;
> 
> -
> -    /*
> -     * HM: We had some cases of repeated IRQs so make sure the
> -     * INT is acknowledged I know it's already further up, but
> -     * doing again fixed the issue
> -     */
> -    cc770_write_reg(priv, msgobj[mo].ctrl0,
> -            MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);
> -
>      return NETDEV_TX_OK;
>  }
> 
> @@ -689,12 +680,6 @@ static void cc770_tx_interrupt(struct net_device
> *dev, unsigned int o)
>      /* Nothing more to send, switch off interrupts */
>      cc770_write_reg(priv, msgobj[mo].ctrl0,
>              MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES);
> -    /*
> -     * We had some cases of repeated IRQ so make sure the
> -     * INT is acknowledged
> -     */
> -    cc770_write_reg(priv, msgobj[mo].ctrl0,
> -            MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);
> 
>      stats->tx_packets++;
>      can_get_echo_skb(dev, 0);
> diff --git a/drivers/net/can/cc770/cc770_isa.c
> b/drivers/net/can/cc770/cc770_isa.c
> index 4be5fe2..48fc128 100644
> --- a/drivers/net/can/cc770/cc770_isa.c
> +++ b/drivers/net/can/cc770/cc770_isa.c
> @@ -148,8 +148,7 @@ static void cc770_isa_port_write_reg_indirect(const
> struct cc770_priv *priv,
>  {
>      unsigned long base = (unsigned long)priv->reg_base;
> 
> -    outb(reg, base);
> -    outb(val, base + 1);
> +    outw( reg + ( val << 8), base);

That modification does fix your problem, right? The others above don't
help nor harm but we don't know if it's really realted to the same
problem. I wll dig a bit deeper.

>  }
> 
>  static int __devinit cc770_isa_probe(struct platform_device *pdev)
> 
> ---------------------------------------------------------------------------------------------
> 
> 
> 
> Please let me know if this is OK for You, maybe You can do some tests as
> well.

My board does not use indirect accesses.

> Would continue then with further tests regarding error conditions, however
> I realised another small issue with dropped packages at reception.
> 
> As soon as You read the first time from the socket and then You stop
> reading
> the packages are not counted as 'dropped' any more which is IMHO not
> correct
> because as soon as You stop reading they should be counted as dropped
> again.

Will have a closer look now...

Wolfgang.

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2012-01-04 13:10                                                               ` Wolfgang Grandegger
@ 2012-01-05  3:29                                                                 ` Wolfgang Zarre
       [not found]                                                                   ` <4F051927.8010600-PyqsHJVlJN8AvxtiuMwx3w@public.gmane.org>
  0 siblings, 1 reply; 66+ messages in thread
From: Wolfgang Zarre @ 2012-01-05  3:29 UTC (permalink / raw)
  To: Wolfgang Grandegger
  Cc: Oliver Hartkopp, netdev, linux-can, socketcan-users, IreneV,
	Stanislav Yelenskiy

Hello Wolfgang,

> Hi Wolfgang,
>
> On 12/31/2011 10:39 AM, Wolfgang Zarre wrote:
>> Hello Wolfgang,
>>
>>> Hello Wolfgang,
>>>> Hi Wolfgang,
>>>>
>>>> On 12/21/2011 07:32 PM, Wolfgang Zarre wrote:
>>>>> Hello Wolfgang,
>>>> ...
>>>>
>>>>
>>>> Again, please check if you have netif_start_queue() at the end of the
>>>> open function.
>>>>
>>>
>>> As said I'm using eec921ac28fde243456078a557768808d93d94a3
>>>
>>> However, I'll try further to investigate that issue due the fact
>>> having it
>>> running with my lincan without problems and therefore it should be
>>> possible
>>> to find the problem.
>>>
>>
>> I found the problem which was then at the end quite simple to understand
>> why it
>> get stuck due the fact not receiving an interrupt for TX and due that no
>> reactivation of the queue.
>>
>> I think that maybe also the hacks in the TX functions are obsolete with the
>> fix assuming that the repeated interrupts just happen by indirect access.
>
> OK, to understand you correctly...
>
>> Here my fix which worked for me:
>> --------------------------------------------------------------------------------------------------------
>>
>> diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c
>> index 2d12f89..dad6707 100644
>> --- a/drivers/net/can/cc770/cc770.c
>> +++ b/drivers/net/can/cc770/cc770.c
>> @@ -460,15 +460,6 @@ static netdev_tx_t cc770_start_xmit(struct sk_buff
>> *skb, struct net_device *dev)
>>
>>       stats->tx_bytes += dlc;
>>
>> -
>> -    /*
>> -     * HM: We had some cases of repeated IRQs so make sure the
>> -     * INT is acknowledged I know it's already further up, but
>> -     * doing again fixed the issue
>> -     */
>> -    cc770_write_reg(priv, msgobj[mo].ctrl0,
>> -            MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);
>> -
>>       return NETDEV_TX_OK;
>>   }
>>
>> @@ -689,12 +680,6 @@ static void cc770_tx_interrupt(struct net_device
>> *dev, unsigned int o)
>>       /* Nothing more to send, switch off interrupts */
>>       cc770_write_reg(priv, msgobj[mo].ctrl0,
>>               MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES);
>> -    /*
>> -     * We had some cases of repeated IRQ so make sure the
>> -     * INT is acknowledged
>> -     */
>> -    cc770_write_reg(priv, msgobj[mo].ctrl0,
>> -            MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);
>>
>>       stats->tx_packets++;
>>       can_get_echo_skb(dev, 0);
>> diff --git a/drivers/net/can/cc770/cc770_isa.c
>> b/drivers/net/can/cc770/cc770_isa.c
>> index 4be5fe2..48fc128 100644
>> --- a/drivers/net/can/cc770/cc770_isa.c
>> +++ b/drivers/net/can/cc770/cc770_isa.c
>> @@ -148,8 +148,7 @@ static void cc770_isa_port_write_reg_indirect(const
>> struct cc770_priv *priv,
>>   {
>>       unsigned long base = (unsigned long)priv->reg_base;
>>
>> -    outb(reg, base);
>> -    outb(val, base + 1);
>> +    outw( reg + ( val<<  8), base);
>
> That modification does fix your problem, right? The others above don't
> help nor harm but we don't know if it's really realted to the same
> problem. I wll dig a bit deeper.

Exactly. The others above I removed because facing the opposite, even
missing interrupts but then just to avoid other possible side effects
and then assuming that they might be related.


>
>>   }
>>
>>   static int __devinit cc770_isa_probe(struct platform_device *pdev)
>>
>> ---------------------------------------------------------------------------------------------
>>
>>
>>
>> Please let me know if this is OK for You, maybe You can do some tests as
>> well.
>
> My board does not use indirect accesses.
>

Ah Ok, I see, but let me know if I may help with additional tests You would
like to have beside the other mentioned tests as long as I have the hardware.

>> Would continue then with further tests regarding error conditions, however
>> I realised another small issue with dropped packages at reception.
>>
>> As soon as You read the first time from the socket and then You stop
>> reading
>> the packages are not counted as 'dropped' any more which is IMHO not
>> correct
>> because as soon as You stop reading they should be counted as dropped
>> again.
>
> Will have a closer look now...

Thanks a lot.
Also I'll inform You as soon as I can continue with some further tests
regarding bus states and error counters and maybe also with patches in
case I have.

>
> Wolfgang.

Wolfgang

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
       [not found]                                                                   ` <4F051927.8010600-PyqsHJVlJN8AvxtiuMwx3w@public.gmane.org>
@ 2012-01-05 11:51                                                                     ` Wolfgang Grandegger
  2012-01-05 12:00                                                                       ` David Laight
  0 siblings, 1 reply; 66+ messages in thread
From: Wolfgang Grandegger @ 2012-01-05 11:51 UTC (permalink / raw)
  To: info-PyqsHJVlJN8AvxtiuMwx3w
  Cc: Oliver Hartkopp, linux-can-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	socketcan-users-0fE9KPoRgkgATYTw5x5z8w

Hi Wolfgang,

On 01/05/2012 04:29 AM, Wolfgang Zarre wrote:
> Hello Wolfgang,
> 
>> Hi Wolfgang,
...
>>> diff --git a/drivers/net/can/cc770/cc770_isa.c
>>> b/drivers/net/can/cc770/cc770_isa.c
>>> index 4be5fe2..48fc128 100644
>>> --- a/drivers/net/can/cc770/cc770_isa.c
>>> +++ b/drivers/net/can/cc770/cc770_isa.c
>>> @@ -148,8 +148,7 @@ static void cc770_isa_port_write_reg_indirect(const
>>> struct cc770_priv *priv,
>>>   {
>>>       unsigned long base = (unsigned long)priv->reg_base;
>>>
>>> -    outb(reg, base);
>>> -    outb(val, base + 1);
>>> +    outw( reg + ( val<<  8), base);
>>
>> That modification does fix your problem, right? The others above don't
>> help nor harm but we don't know if it's really realted to the same
>> problem. I wll dig a bit deeper.
> 
> Exactly. The others above I removed because facing the opposite, even
> missing interrupts but then just to avoid other possible side effects
> and then assuming that they might be related.

OK. My concern: Can we be sure that 16bit accesses are always supported
by the hardware? Does a spinlock_irqsave/spinlock_irqrestore around the
8bit accesses already help?

About the "HM:" fixes, I did not find any info in the svn log. Maybe
Oliver knows why they have been added.

>>
>>>   }
>>>
>>>   static int __devinit cc770_isa_probe(struct platform_device *pdev)
>>>
>>> ---------------------------------------------------------------------------------------------
>>>
>>>
>>>
>>>
>>> Please let me know if this is OK for You, maybe You can do some tests as
>>> well.
>>
>> My board does not use indirect accesses.
>>
> 
> Ah Ok, I see, but let me know if I may help with additional tests You would
> like to have beside the other mentioned tests as long as I have the
> hardware.

I will do some test anyway.

>>> Would continue then with further tests regarding error conditions,
>>> however
>>> I realised another small issue with dropped packages at reception.
>>>
>>> As soon as You read the first time from the socket and then You stop
>>> reading
>>> the packages are not counted as 'dropped' any more which is IMHO not
>>> correct
>>> because as soon as You stop reading they should be counted as dropped
>>> again.
>>
>> Will have a closer look now...
> 
> Thanks a lot.
> Also I'll inform You as soon as I can continue with some further tests
> regarding bus states and error counters and maybe also with patches in
> case I have.

No hurry... I'm first awaiting some patches to go mainline.

Wolfgang.

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

* RE: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2012-01-05 11:51                                                                     ` Wolfgang Grandegger
@ 2012-01-05 12:00                                                                       ` David Laight
  2012-01-09 21:47                                                                         ` Wolfgang Zarre
  0 siblings, 1 reply; 66+ messages in thread
From: David Laight @ 2012-01-05 12:00 UTC (permalink / raw)
  To: Wolfgang Grandegger, info
  Cc: Oliver Hartkopp, netdev, linux-can, socketcan-users, IreneV,
	Stanislav Yelenskiy

> >>> -    outb(reg, base);
> >>> -    outb(val, base + 1);
> >>> +    outw( reg + ( val<<  8), base);
> >>
> >> That modification does fix your problem, right? The others above
don't
> >> help nor harm but we don't know if it's really realted to the same
> >> problem. I wll dig a bit deeper.
> > 
> > Exactly. The others above I removed because facing the opposite,
even
> > missing interrupts but then just to avoid other possible side
effects
> > and then assuming that they might be related.
> 
> OK. My concern: Can we be sure that 16bit accesses are always
supported
> by the hardware? Does a spinlock_irqsave/spinlock_irqrestore around
the
> 8bit accesses already help?

Hmmm... are there any register reads that need the
same 'double cycle' sequence ??
If so you need to stop reads being interleaved (with
themselves and writes) so requesting a 16bit access
doesn't help.

Which means you need a spinlock...

	David



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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2012-01-05 12:00                                                                       ` David Laight
@ 2012-01-09 21:47                                                                         ` Wolfgang Zarre
  2012-01-09 23:11                                                                           ` Marc Kleine-Budde
                                                                                             ` (2 more replies)
  0 siblings, 3 replies; 66+ messages in thread
From: Wolfgang Zarre @ 2012-01-09 21:47 UTC (permalink / raw)
  To: David Laight, Wolfgang Grandegger, Oliver Hartkopp, henrik
  Cc: netdev, linux-can, socketcan-users, IreneV, Stanislav Yelenskiy,
	oe, henrik

Hello guys,

>>>>> -    outb(reg, base);
>>>>> -    outb(val, base + 1);
>>>>> +    outw( reg + ( val<<   8), base);
>>>>
>>>> That modification does fix your problem, right? The others above
> don't
>>>> help nor harm but we don't know if it's really realted to the same
>>>> problem. I wll dig a bit deeper.
>>>
>>> Exactly. The others above I removed because facing the opposite,
> even
>>> missing interrupts but then just to avoid other possible side
> effects
>>> and then assuming that they might be related.
>>
>> OK. My concern: Can we be sure that 16bit accesses are always
> supported
>> by the hardware? Does a spinlock_irqsave/spinlock_irqrestore around
> the
>> 8bit accesses already help?
>
> Hmmm... are there any register reads that need the
> same 'double cycle' sequence ??
> If so you need to stop reads being interleaved (with
> themselves and writes) so requesting a 16bit access
> doesn't help.
>
> Which means you need a spinlock...
>
> 	David
>
>

@David: Thank You very much for that hint. You are right and to
implement correct we need a spinlock.

@Wolfgang: I was thinking about Your question regarding 8/16 bit and
in fact it wouldn't work at all on a clean 8 bit cards.

Further it wouldn't work on 16 bit cards where the MSB is not equal
to base port +1 and anyway, it's depending always on how the chip is
interfaced to the ISA bus and in which mode the chip is configured.


And therefore I was giving David's hint a try in using a spinlock in
function cc770_isa_port_write_reg_indirect() and patched as follows:

---------------------------------------------------------------------
diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c
index 2d12f89..dad6707 100644
--- a/drivers/net/can/cc770/cc770.c
+++ b/drivers/net/can/cc770/cc770.c
@@ -460,15 +460,6 @@ static netdev_tx_t cc770_start_xmit(struct sk_buff *skb, struct net_device *dev)

  	stats->tx_bytes += dlc;

-
-	/*
-	 * HM: We had some cases of repeated IRQs so make sure the
-	 * INT is acknowledged I know it's already further up, but
-	 * doing again fixed the issue
-	 */
-	cc770_write_reg(priv, msgobj[mo].ctrl0,
-			MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);
-
  	return NETDEV_TX_OK;
  }

@@ -689,12 +680,6 @@ static void cc770_tx_interrupt(struct net_device *dev, unsigned int o)
  	/* Nothing more to send, switch off interrupts */
  	cc770_write_reg(priv, msgobj[mo].ctrl0,
  			MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES);
-	/*
-	 * We had some cases of repeated IRQ so make sure the
-	 * INT is acknowledged
-	 */
-	cc770_write_reg(priv, msgobj[mo].ctrl0,
-			MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);

  	stats->tx_packets++;
  	can_get_echo_skb(dev, 0);
diff --git a/drivers/net/can/cc770/cc770_isa.c b/drivers/net/can/cc770/cc770_isa.c
index 4be5fe2..fe39eed 100644
--- a/drivers/net/can/cc770/cc770_isa.c
+++ b/drivers/net/can/cc770/cc770_isa.c
@@ -110,6 +110,9 @@ MODULE_PARM_DESC(bcr, "Bus configuration register (default=0x40 [CBY])");
  #define CC770_IOSIZE          0x20
  #define CC770_IOSIZE_INDIRECT 0x02

+/* Spinlock for cc770_isa_port_write_reg_indirect */
+static DEFINE_SPINLOCK( outb_lock);
+
  static struct platform_device *cc770_isa_devs[MAXDEV];

  static u8 cc770_isa_mem_read_reg(const struct cc770_priv *priv, int reg)
@@ -147,9 +150,12 @@ static void cc770_isa_port_write_reg_indirect(const struct cc770_priv *priv,
  						int reg, u8 val)
  {
  	unsigned long base = (unsigned long)priv->reg_base;
+	unsigned long flags;

+	spin_lock_irqsave( &outb_lock, flags);
  	outb(reg, base);
  	outb(val, base + 1);
+	spin_unlock_irqrestore( &outb_lock, flags);	
  }

  static int __devinit cc770_isa_probe(struct platform_device *pdev)
----------------------------------------------------------------------


The result is absolutely perfect. I was sending 2,000,000 telegrams
without any problem like the foregoing patch but now 8 bit compatible.




Further I have also investigated a bit the issue regarding the "HM"
patches.

I checked out the can4linux and I could find this patch in file
can_i82527funcs.c as mentioned by Oliver.
@Oliver: BTW thanks for Your investigation.

After studying the Makefile and some tests I discovered that
this file is just used for the target SBS_PC7 but funny enough not
for GENERIC_I82527.

I was seeking the declaration of CANout used in can_i82527funcs.c
to see if it's based on the same code we had and as well as in Lincan
but unfortunately the target SBS_PC7 doesn't compile with kernel
2.6.39-4 and moreover I got the message:
...can4linux/trunk/can4linux/i82527funcs.c:72:
                       error: implicit declaration of function 'CANout'

And additional not knowing if the board of SBS_PC7 is ISA or PCI based
I tried to find out and found after some research the following
thread:
http://old.nabble.com/-PATCH-v2--cc770-isa%3A-legacy-driver-for-CC770-i82725-on-the-ISA-bus-td24216347.html

According to that I assumed it's ISA based and is working with cc770_isa.

But not finding the declaration of CANout used in can_i82527funcs.c I
assumed further that it was done without spinlock which might cause
the effect of repeated or even lost interrupts as well depending on
the hardware configuration.

If this is the case then the HM patches would be obsolete and maybe
someone owning a SBS PC7 can test without these patches.

@Henrik: I would like to ask You if You can confirm this when You are
back.
Thanks a lot.


Wolfgang


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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2012-01-09 21:47                                                                         ` Wolfgang Zarre
@ 2012-01-09 23:11                                                                           ` Marc Kleine-Budde
  2012-01-10  9:30                                                                             ` Wolfgang Grandegger
  2012-01-10 10:00                                                                           ` David Laight
  2012-01-10 11:41                                                                           ` Henrik Maier
  2 siblings, 1 reply; 66+ messages in thread
From: Marc Kleine-Budde @ 2012-01-09 23:11 UTC (permalink / raw)
  To: info
  Cc: David Laight, Wolfgang Grandegger, Oliver Hartkopp, henrik,
	netdev, linux-can, socketcan-users, IreneV, Stanislav Yelenskiy,
	oe, henrik

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

On 01/09/2012 10:47 PM, Wolfgang Zarre wrote:
[...]

>>> OK. My concern: Can we be sure that 16bit accesses are always
>> supported
>>> by the hardware? Does a spinlock_irqsave/spinlock_irqrestore around
>> the
>>> 8bit accesses already help?
>>
>> Hmmm... are there any register reads that need the
>> same 'double cycle' sequence ??
>> If so you need to stop reads being interleaved (with
>> themselves and writes) so requesting a 16bit access
>> doesn't help.
>>
>> Which means you need a spinlock...
>>
>>     David
>>
>>
> 
> @David: Thank You very much for that hint. You are right and to
> implement correct we need a spinlock.
> 
> @Wolfgang: I was thinking about Your question regarding 8/16 bit and
> in fact it wouldn't work at all on a clean 8 bit cards.
> 
> Further it wouldn't work on 16 bit cards where the MSB is not equal
> to base port +1 and anyway, it's depending always on how the chip is
> interfaced to the ISA bus and in which mode the chip is configured.
> 
> 
> And therefore I was giving David's hint a try in using a spinlock in
> function cc770_isa_port_write_reg_indirect() and patched as follows:
> 
> ---------------------------------------------------------------------
> diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c
> index 2d12f89..dad6707 100644
> --- a/drivers/net/can/cc770/cc770.c
> +++ b/drivers/net/can/cc770/cc770.c
> @@ -460,15 +460,6 @@ static netdev_tx_t cc770_start_xmit(struct sk_buff
> *skb, struct net_device *dev)
> 
>      stats->tx_bytes += dlc;
> 
> -
> -    /*
> -     * HM: We had some cases of repeated IRQs so make sure the
> -     * INT is acknowledged I know it's already further up, but
> -     * doing again fixed the issue
> -     */
> -    cc770_write_reg(priv, msgobj[mo].ctrl0,
> -            MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);
> -
>      return NETDEV_TX_OK;
>  }
> 
> @@ -689,12 +680,6 @@ static void cc770_tx_interrupt(struct net_device
> *dev, unsigned int o)
>      /* Nothing more to send, switch off interrupts */
>      cc770_write_reg(priv, msgobj[mo].ctrl0,
>              MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES);
> -    /*
> -     * We had some cases of repeated IRQ so make sure the
> -     * INT is acknowledged
> -     */
> -    cc770_write_reg(priv, msgobj[mo].ctrl0,
> -            MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);
> 
>      stats->tx_packets++;
>      can_get_echo_skb(dev, 0);
> diff --git a/drivers/net/can/cc770/cc770_isa.c
> b/drivers/net/can/cc770/cc770_isa.c
> index 4be5fe2..fe39eed 100644
> --- a/drivers/net/can/cc770/cc770_isa.c
> +++ b/drivers/net/can/cc770/cc770_isa.c
> @@ -110,6 +110,9 @@ MODULE_PARM_DESC(bcr, "Bus configuration register
> (default=0x40 [CBY])");
>  #define CC770_IOSIZE          0x20
>  #define CC770_IOSIZE_INDIRECT 0x02
> 
> +/* Spinlock for cc770_isa_port_write_reg_indirect */
> +static DEFINE_SPINLOCK( outb_lock);
> +

Do we need a global or a per device spin lock? If this should be a per
device one, please introduce a cc770_isa_priv and put the spinlock
there. Don't forget to initialize the spinlock.

>  static struct platform_device *cc770_isa_devs[MAXDEV];
> 
>  static u8 cc770_isa_mem_read_reg(const struct cc770_priv *priv, int reg)
> @@ -147,9 +150,12 @@ static void cc770_isa_port_write_reg_indirect(const
> struct cc770_priv *priv,
>                          int reg, u8 val)
>  {
>      unsigned long base = (unsigned long)priv->reg_base;
> +    unsigned long flags;

please indent with tab, not space (your mailer probably converts tabs to
space)

> 
> +    spin_lock_irqsave( &outb_lock, flags);
                         ^

please remove the whitespace.

>      outb(reg, base);
>      outb(val, base + 1);
> +    spin_unlock_irqrestore( &outb_lock, flags);   
                              ^                   ^^^
please remove this and trailing whitespace.

>  }
> 
>  static int __devinit cc770_isa_probe(struct platform_device *pdev)
> ----------------------------------------------------------------------

cheers, 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: 262 bytes --]

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2012-01-09 23:11                                                                           ` Marc Kleine-Budde
@ 2012-01-10  9:30                                                                             ` Wolfgang Grandegger
  2012-01-10 12:30                                                                               ` Wolfgang Zarre
  0 siblings, 1 reply; 66+ messages in thread
From: Wolfgang Grandegger @ 2012-01-10  9:30 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: info, David Laight, Oliver Hartkopp, henrik, netdev, linux-can,
	socketcan-users, IreneV, Stanislav Yelenskiy, oe, henrik

On 01/10/2012 12:11 AM, Marc Kleine-Budde wrote:
> On 01/09/2012 10:47 PM, Wolfgang Zarre wrote:
> [...]
> 
>>>> OK. My concern: Can we be sure that 16bit accesses are always
>>> supported
>>>> by the hardware? Does a spinlock_irqsave/spinlock_irqrestore around
>>> the
>>>> 8bit accesses already help?
>>>
>>> Hmmm... are there any register reads that need the
>>> same 'double cycle' sequence ??
>>> If so you need to stop reads being interleaved (with
>>> themselves and writes) so requesting a 16bit access
>>> doesn't help.
>>>
>>> Which means you need a spinlock...
>>>
>>>     David
>>>
>>>
>>
>> @David: Thank You very much for that hint. You are right and to
>> implement correct we need a spinlock.
>>
>> @Wolfgang: I was thinking about Your question regarding 8/16 bit and
>> in fact it wouldn't work at all on a clean 8 bit cards.
>>
>> Further it wouldn't work on 16 bit cards where the MSB is not equal
>> to base port +1 and anyway, it's depending always on how the chip is
>> interfaced to the ISA bus and in which mode the chip is configured.
>>
>>
>> And therefore I was giving David's hint a try in using a spinlock in
>> function cc770_isa_port_write_reg_indirect() and patched as follows:
>>
>> ---------------------------------------------------------------------
>> diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c
>> index 2d12f89..dad6707 100644
>> --- a/drivers/net/can/cc770/cc770.c
>> +++ b/drivers/net/can/cc770/cc770.c
>> @@ -460,15 +460,6 @@ static netdev_tx_t cc770_start_xmit(struct sk_buff
>> *skb, struct net_device *dev)
>>
>>      stats->tx_bytes += dlc;
>>
>> -
>> -    /*
>> -     * HM: We had some cases of repeated IRQs so make sure the
>> -     * INT is acknowledged I know it's already further up, but
>> -     * doing again fixed the issue
>> -     */
>> -    cc770_write_reg(priv, msgobj[mo].ctrl0,
>> -            MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);
>> -
>>      return NETDEV_TX_OK;
>>  }
>>
>> @@ -689,12 +680,6 @@ static void cc770_tx_interrupt(struct net_device
>> *dev, unsigned int o)
>>      /* Nothing more to send, switch off interrupts */
>>      cc770_write_reg(priv, msgobj[mo].ctrl0,
>>              MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES);
>> -    /*
>> -     * We had some cases of repeated IRQ so make sure the
>> -     * INT is acknowledged
>> -     */
>> -    cc770_write_reg(priv, msgobj[mo].ctrl0,
>> -            MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);

Please provide an extra patch for these unrelated changes. If we really
want to remove it.

>>      stats->tx_packets++;
>>      can_get_echo_skb(dev, 0);
>> diff --git a/drivers/net/can/cc770/cc770_isa.c
>> b/drivers/net/can/cc770/cc770_isa.c
>> index 4be5fe2..fe39eed 100644
>> --- a/drivers/net/can/cc770/cc770_isa.c
>> +++ b/drivers/net/can/cc770/cc770_isa.c
>> @@ -110,6 +110,9 @@ MODULE_PARM_DESC(bcr, "Bus configuration register
>> (default=0x40 [CBY])");
>>  #define CC770_IOSIZE          0x20
>>  #define CC770_IOSIZE_INDIRECT 0x02
>>
>> +/* Spinlock for cc770_isa_port_write_reg_indirect */
>> +static DEFINE_SPINLOCK( outb_lock);
>> +
> 
> Do we need a global or a per device spin lock? If this should be a per
> device one, please introduce a cc770_isa_priv and put the spinlock
> there. Don't forget to initialize the spinlock.

Yes, that's what I was thinking as well but in the ocan driver I find:

/*
 * we need a spinlock here, as the address register looks shared between
 * two PC-ECAN devices. Moreover, we need to protect WRT interrupts
 */

Looks like wired hardware. Anyway, a global spinlock might be safer.

Wolfgang.

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

* RE: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2012-01-09 21:47                                                                         ` Wolfgang Zarre
  2012-01-09 23:11                                                                           ` Marc Kleine-Budde
@ 2012-01-10 10:00                                                                           ` David Laight
  2012-01-10 12:41                                                                             ` Wolfgang Zarre
  2012-01-10 11:41                                                                           ` Henrik Maier
  2 siblings, 1 reply; 66+ messages in thread
From: David Laight @ 2012-01-10 10:00 UTC (permalink / raw)
  To: info, Wolfgang Grandegger, Oliver Hartkopp, henrik
  Cc: netdev, linux-can, socketcan-users, IreneV, Stanislav Yelenskiy,
	oe, henrik

 
> cc770_isa_port_write_reg_indirect(const struct cc770_priv *priv,
>   						int reg, u8 val)
>   {
>   	unsigned long base = (unsigned long)priv->reg_base;
> +	unsigned long flags;
> 
> +	spin_lock_irqsave( &outb_lock, flags);
>   	outb(reg, base);
>   	outb(val, base + 1);
> +	spin_unlock_irqrestore( &outb_lock, flags);	

Is there a 'read_reg_indirect' function??
If so it also needs to use the same mutex.
I'd double check all references to the 'reg_base' field.

	David



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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2012-01-09 21:47                                                                         ` Wolfgang Zarre
  2012-01-09 23:11                                                                           ` Marc Kleine-Budde
  2012-01-10 10:00                                                                           ` David Laight
@ 2012-01-10 11:41                                                                           ` Henrik Maier
  2012-01-10 11:59                                                                             ` Wolfgang Grandegger
  2 siblings, 1 reply; 66+ messages in thread
From: Henrik Maier @ 2012-01-10 11:41 UTC (permalink / raw)
  To: info
  Cc: David Laight, Wolfgang Grandegger, Oliver Hartkopp, netdev,
	linux-can, socketcan-users, IreneV, Stanislav Yelenskiy, oe,
	henrik

Hello guys,

see comments below.

On 9/01/2012 10:47 PM, Wolfgang Zarre wrote:
> Further I have also investigated a bit the issue regarding the "HM"
> patches.
>
> I checked out the can4linux and I could find this patch in file
> can_i82527funcs.c as mentioned by Oliver.
> @Oliver: BTW thanks for Your investigation.
>
> After studying the Makefile and some tests I discovered that
> this file is just used for the target SBS_PC7 but funny enough not
> for GENERIC_I82527.
>
> I was seeking the declaration of CANout used in can_i82527funcs.c
> to see if it's based on the same code we had and as well as in Lincan
> but unfortunately the target SBS_PC7 doesn't compile with kernel
> 2.6.39-4 and moreover I got the message:
> ...can4linux/trunk/can4linux/i82527funcs.c:72:
>                       error: implicit declaration of function 'CANout'
>
> And additional not knowing if the board of SBS_PC7 is ISA or PCI based
> I tried to find out and found after some research the following
> thread:
> http://old.nabble.com/-PATCH-v2--cc770-isa%3A-legacy-driver-for-CC770-i82725-on-the-ISA-bus-td24216347.html 
>
>
> According to that I assumed it's ISA based and is working with cc770_isa.
>
> But not finding the declaration of CANout used in can_i82527funcs.c I
> assumed further that it was done without spinlock which might cause
> the effect of repeated or even lost interrupts as well depending on
> the hardware configuration.
>
> If this is the case then the HM patches would be obsolete and maybe
> someone owning a SBS PC7 can test without these patches.
>
> @Henrik: I would like to ask You if You can confirm this when You are
> back.
> Thanks a lot.
>
>
> Wolfgang

The can4linux port I made was done for a specific project and a specific 
hardware, the SBS PC7, and only ever tested on that hardware. The i82527 
code was already in the can4linux 3.x archive but not maintained for a 
while and has become non-functional over time.

Initially we used the 2.4 Linux kernel and the can4linux version 3.1 as 
basis for the re-integration of the i82527. I called our modified 
version  "3.1i" (i for Intel). This is from the changelog:

3.1i - Integration of the i82527 code into can4linux version 3.1,
       major refactoring and clean-up of the i82527 code, fixed
       interrupt lock-up issue w/ sending while receiving in heavy load,
       fixed issue w/ stopping and re-starting the bus, added
       new acceptance mask function to bring code in line with SJA1000 code
       base, new I/O model to support the SJA1000 CANin/CANout macros,
       support added to the makefile for generic i82527 cards and
       SBS PC7compact DINrail mounted industry PC
       by Henrik Maier of FOCUS Software Engineering Pty Ltd 
<www.focus-sw.com>

As time passed the requirement for kernel 2.6 support emerged and we did 
the same based on can4linux 3.3.2 and called it "3.3.2i" which later was 
merged into the official can4linux archive and became 3.3.3.

The "repeated TX IRQ" issue came up only with kernel 2.6 and was not 
required in the 2.4 version. The way I fixed it may not have been the 
best, but it solved the immediate need of finishing a project and 
getting the driver stable. I am not a kernel driver expert.

The PC7 hardware is now obsolete anyway. From my point we can do a 
"clean" start and remove the old baggage.

The PC7 CAN interface is ISA based and I don't have a hardware any more 
to test.

Some background info and our "i" versions are published here:

http://www.focus-sw.com/can/can4linux.html

I hope that helps a bit. It has been a few years since I worked with 
can4linux but it is great to see that the community is further enhancing 
CAN support for Linux.

Henrik



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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2012-01-10 11:41                                                                           ` Henrik Maier
@ 2012-01-10 11:59                                                                             ` Wolfgang Grandegger
  2012-01-10 12:43                                                                               ` Wolfgang Zarre
  0 siblings, 1 reply; 66+ messages in thread
From: Wolfgang Grandegger @ 2012-01-10 11:59 UTC (permalink / raw)
  To: Henrik Maier
  Cc: info, David Laight, Oliver Hartkopp, netdev, linux-can,
	socketcan-users, IreneV, Stanislav Yelenskiy, oe, henrik

Hi Henrik,

On 01/10/2012 12:41 PM, Henrik Maier wrote:
> Hello guys,
> 
> see comments below.
> 
> On 9/01/2012 10:47 PM, Wolfgang Zarre wrote:
>> Further I have also investigated a bit the issue regarding the "HM"
>> patches.
>>
>> I checked out the can4linux and I could find this patch in file
>> can_i82527funcs.c as mentioned by Oliver.
>> @Oliver: BTW thanks for Your investigation.
>>
>> After studying the Makefile and some tests I discovered that
>> this file is just used for the target SBS_PC7 but funny enough not
>> for GENERIC_I82527.
>>
>> I was seeking the declaration of CANout used in can_i82527funcs.c
>> to see if it's based on the same code we had and as well as in Lincan
>> but unfortunately the target SBS_PC7 doesn't compile with kernel
>> 2.6.39-4 and moreover I got the message:
>> ...can4linux/trunk/can4linux/i82527funcs.c:72:
>>                       error: implicit declaration of function 'CANout'
>>
>> And additional not knowing if the board of SBS_PC7 is ISA or PCI based
>> I tried to find out and found after some research the following
>> thread:
>> http://old.nabble.com/-PATCH-v2--cc770-isa%3A-legacy-driver-for-CC770-i82725-on-the-ISA-bus-td24216347.html
>>
>>
>> According to that I assumed it's ISA based and is working with cc770_isa.
>>
>> But not finding the declaration of CANout used in can_i82527funcs.c I
>> assumed further that it was done without spinlock which might cause
>> the effect of repeated or even lost interrupts as well depending on
>> the hardware configuration.
>>
>> If this is the case then the HM patches would be obsolete and maybe
>> someone owning a SBS PC7 can test without these patches.
>>
>> @Henrik: I would like to ask You if You can confirm this when You are
>> back.
>> Thanks a lot.
>>
>>
>> Wolfgang
> 
> The can4linux port I made was done for a specific project and a specific
> hardware, the SBS PC7, and only ever tested on that hardware. The i82527
> code was already in the can4linux 3.x archive but not maintained for a
> while and has become non-functional over time.
> 
> Initially we used the 2.4 Linux kernel and the can4linux version 3.1 as
> basis for the re-integration of the i82527. I called our modified
> version  "3.1i" (i for Intel). This is from the changelog:
> 
> 3.1i - Integration of the i82527 code into can4linux version 3.1,
>       major refactoring and clean-up of the i82527 code, fixed
>       interrupt lock-up issue w/ sending while receiving in heavy load,
>       fixed issue w/ stopping and re-starting the bus, added
>       new acceptance mask function to bring code in line with SJA1000 code
>       base, new I/O model to support the SJA1000 CANin/CANout macros,
>       support added to the makefile for generic i82527 cards and
>       SBS PC7compact DINrail mounted industry PC
>       by Henrik Maier of FOCUS Software Engineering Pty Ltd
> <www.focus-sw.com>
> 
> As time passed the requirement for kernel 2.6 support emerged and we did
> the same based on can4linux 3.3.2 and called it "3.3.2i" which later was
> merged into the official can4linux archive and became 3.3.3.
> 
> The "repeated TX IRQ" issue came up only with kernel 2.6 and was not
> required in the 2.4 version. The way I fixed it may not have been the
> best, but it solved the immediate need of finishing a project and
> getting the driver stable. I am not a kernel driver expert.

OK, then most likely it's not a hardware issue.

> The PC7 hardware is now obsolete anyway. From my point we can do a
> "clean" start and remove the old baggage.
> 
> The PC7 CAN interface is ISA based and I don't have a hardware any more
> to test.
> 
> Some background info and our "i" versions are published here:
> 
> http://www.focus-sw.com/can/can4linux.html
> 
> I hope that helps a bit. It has been a few years since I worked with
> can4linux but it is great to see that the community is further enhancing
> CAN support for Linux.

Yes, of course. Thanks for digging that out. As you suggest, we will
remove that code and wait what happens.

Wolfgang.


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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2012-01-10  9:30                                                                             ` Wolfgang Grandegger
@ 2012-01-10 12:30                                                                               ` Wolfgang Zarre
  2012-01-10 14:20                                                                                 ` Wolfgang Grandegger
  2012-01-11  9:00                                                                                 ` Wolfgang Zarre
  0 siblings, 2 replies; 66+ messages in thread
From: Wolfgang Zarre @ 2012-01-10 12:30 UTC (permalink / raw)
  To: Wolfgang Grandegger
  Cc: Marc Kleine-Budde, David Laight, Oliver Hartkopp, henrik, netdev,
	linux-can, socketcan-users, IreneV, Stanislav Yelenskiy, oe,
	henrik

Hello Wolfgang,

> On 01/10/2012 12:11 AM, Marc Kleine-Budde wrote:
>> On 01/09/2012 10:47 PM, Wolfgang Zarre wrote:
>> [...]
>>
>>>>> OK. My concern: Can we be sure that 16bit accesses are always
>>>> supported
>>>>> by the hardware? Does a spinlock_irqsave/spinlock_irqrestore around
>>>> the
>>>>> 8bit accesses already help?
>>>>
>>>> Hmmm... are there any register reads that need the
>>>> same 'double cycle' sequence ??
>>>> If so you need to stop reads being interleaved (with
>>>> themselves and writes) so requesting a 16bit access
>>>> doesn't help.
>>>>
>>>> Which means you need a spinlock...
>>>>
>>>>      David
>>>>
>>>>
>>>
>>> @David: Thank You very much for that hint. You are right and to
>>> implement correct we need a spinlock.
>>>
>>> @Wolfgang: I was thinking about Your question regarding 8/16 bit and
>>> in fact it wouldn't work at all on a clean 8 bit cards.
>>>
>>> Further it wouldn't work on 16 bit cards where the MSB is not equal
>>> to base port +1 and anyway, it's depending always on how the chip is
>>> interfaced to the ISA bus and in which mode the chip is configured.
>>>
>>>
>>> And therefore I was giving David's hint a try in using a spinlock in
>>> function cc770_isa_port_write_reg_indirect() and patched as follows:
>>>
>>> ---------------------------------------------------------------------
>>> diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c
>>> index 2d12f89..dad6707 100644
>>> --- a/drivers/net/can/cc770/cc770.c
>>> +++ b/drivers/net/can/cc770/cc770.c
>>> @@ -460,15 +460,6 @@ static netdev_tx_t cc770_start_xmit(struct sk_buff
>>> *skb, struct net_device *dev)
>>>
>>>       stats->tx_bytes += dlc;
>>>
>>> -
>>> -    /*
>>> -     * HM: We had some cases of repeated IRQs so make sure the
>>> -     * INT is acknowledged I know it's already further up, but
>>> -     * doing again fixed the issue
>>> -     */
>>> -    cc770_write_reg(priv, msgobj[mo].ctrl0,
>>> -            MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);
>>> -
>>>       return NETDEV_TX_OK;
>>>   }
>>>
>>> @@ -689,12 +680,6 @@ static void cc770_tx_interrupt(struct net_device
>>> *dev, unsigned int o)
>>>       /* Nothing more to send, switch off interrupts */
>>>       cc770_write_reg(priv, msgobj[mo].ctrl0,
>>>               MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES);
>>> -    /*
>>> -     * We had some cases of repeated IRQ so make sure the
>>> -     * INT is acknowledged
>>> -     */
>>> -    cc770_write_reg(priv, msgobj[mo].ctrl0,
>>> -            MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);
>
> Please provide an extra patch for these unrelated changes. If we really
> want to remove it.
>

Sure, this I can do.

>>>       stats->tx_packets++;
>>>       can_get_echo_skb(dev, 0);
>>> diff --git a/drivers/net/can/cc770/cc770_isa.c
>>> b/drivers/net/can/cc770/cc770_isa.c
>>> index 4be5fe2..fe39eed 100644
>>> --- a/drivers/net/can/cc770/cc770_isa.c
>>> +++ b/drivers/net/can/cc770/cc770_isa.c
>>> @@ -110,6 +110,9 @@ MODULE_PARM_DESC(bcr, "Bus configuration register
>>> (default=0x40 [CBY])");
>>>   #define CC770_IOSIZE          0x20
>>>   #define CC770_IOSIZE_INDIRECT 0x02
>>>
>>> +/* Spinlock for cc770_isa_port_write_reg_indirect */
>>> +static DEFINE_SPINLOCK( outb_lock);
>>> +
>>
>> Do we need a global or a per device spin lock? If this should be a per
>> device one, please introduce a cc770_isa_priv and put the spinlock
>> there. Don't forget to initialize the spinlock.
>
> Yes, that's what I was thinking as well but in the ocan driver I find:
>
> /*
>   * we need a spinlock here, as the address register looks shared between
>   * two PC-ECAN devices. Moreover, we need to protect WRT interrupts
>   */
>
> Looks like wired hardware. Anyway, a global spinlock might be safer.
>

Hmmm, actually I thought to place the spinlock local because of having
the problem just with the interrupt and not with mutex.

But if global wouldn't it then better to make an array[MAX_DEV] for the
lock with initialisation in _init or _start?

But if PC-ECAN works with that configuration?

> Wolfgang.

Wolfgang

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2012-01-10 10:00                                                                           ` David Laight
@ 2012-01-10 12:41                                                                             ` Wolfgang Zarre
  2012-01-10 14:43                                                                               ` Wolfgang Grandegger
  0 siblings, 1 reply; 66+ messages in thread
From: Wolfgang Zarre @ 2012-01-10 12:41 UTC (permalink / raw)
  To: David Laight
  Cc: Wolfgang Grandegger, Oliver Hartkopp, henrik, netdev, linux-can,
	socketcan-users, IreneV, Stanislav Yelenskiy, oe, henrik

Hello David,
>
>> cc770_isa_port_write_reg_indirect(const struct cc770_priv *priv,
>>    						int reg, u8 val)
>>    {
>>    	unsigned long base = (unsigned long)priv->reg_base;
>> +	unsigned long flags;
>>
>> +	spin_lock_irqsave(&outb_lock, flags);
>>    	outb(reg, base);
>>    	outb(val, base + 1);
>> +	spin_unlock_irqrestore(&outb_lock, flags);	
>
> Is there a 'read_reg_indirect' function??

Yes, there is.

> If so it also needs to use the same mutex.

Actually, I don't think that we have a problem with mutex
beside that it's using just one inb() statement but having
for sure with an interrupt between both outb() statements which
seems to be critical for the cc770.

However, if inb() or outb() can be interrupted then it would be
an issue.

> I'd double check all references to the 'reg_base' field.
>
> 	David
>
>

Wolfgang

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2012-01-10 11:59                                                                             ` Wolfgang Grandegger
@ 2012-01-10 12:43                                                                               ` Wolfgang Zarre
  0 siblings, 0 replies; 66+ messages in thread
From: Wolfgang Zarre @ 2012-01-10 12:43 UTC (permalink / raw)
  To: Wolfgang Grandegger, Henrik Maier
  Cc: David Laight, Oliver Hartkopp, netdev, linux-can,
	socketcan-users, IreneV, Stanislav Yelenskiy, oe, henrik

Hello guys,

> Hi Henrik,
>
> On 01/10/2012 12:41 PM, Henrik Maier wrote:
>> Hello guys,
>>
>> see comments below.
>>
>> On 9/01/2012 10:47 PM, Wolfgang Zarre wrote:
>>> Further I have also investigated a bit the issue regarding the "HM"
>>> patches.
>>>
>>> I checked out the can4linux and I could find this patch in file
>>> can_i82527funcs.c as mentioned by Oliver.
>>> @Oliver: BTW thanks for Your investigation.
>>>
>>> After studying the Makefile and some tests I discovered that
>>> this file is just used for the target SBS_PC7 but funny enough not
>>> for GENERIC_I82527.
>>>
>>> I was seeking the declaration of CANout used in can_i82527funcs.c
>>> to see if it's based on the same code we had and as well as in Lincan
>>> but unfortunately the target SBS_PC7 doesn't compile with kernel
>>> 2.6.39-4 and moreover I got the message:
>>> ...can4linux/trunk/can4linux/i82527funcs.c:72:
>>>                        error: implicit declaration of function 'CANout'
>>>
>>> And additional not knowing if the board of SBS_PC7 is ISA or PCI based
>>> I tried to find out and found after some research the following
>>> thread:
>>> http://old.nabble.com/-PATCH-v2--cc770-isa%3A-legacy-driver-for-CC770-i82725-on-the-ISA-bus-td24216347.html
>>>
>>>
>>> According to that I assumed it's ISA based and is working with cc770_isa.
>>>
>>> But not finding the declaration of CANout used in can_i82527funcs.c I
>>> assumed further that it was done without spinlock which might cause
>>> the effect of repeated or even lost interrupts as well depending on
>>> the hardware configuration.
>>>
>>> If this is the case then the HM patches would be obsolete and maybe
>>> someone owning a SBS PC7 can test without these patches.
>>>
>>> @Henrik: I would like to ask You if You can confirm this when You are
>>> back.
>>> Thanks a lot.
>>>
>>>
>>> Wolfgang
>>
>> The can4linux port I made was done for a specific project and a specific
>> hardware, the SBS PC7, and only ever tested on that hardware. The i82527
>> code was already in the can4linux 3.x archive but not maintained for a
>> while and has become non-functional over time.
>>
>> Initially we used the 2.4 Linux kernel and the can4linux version 3.1 as
>> basis for the re-integration of the i82527. I called our modified
>> version  "3.1i" (i for Intel). This is from the changelog:
>>
>> 3.1i - Integration of the i82527 code into can4linux version 3.1,
>>        major refactoring and clean-up of the i82527 code, fixed
>>        interrupt lock-up issue w/ sending while receiving in heavy load,
>>        fixed issue w/ stopping and re-starting the bus, added
>>        new acceptance mask function to bring code in line with SJA1000 code
>>        base, new I/O model to support the SJA1000 CANin/CANout macros,
>>        support added to the makefile for generic i82527 cards and
>>        SBS PC7compact DINrail mounted industry PC
>>        by Henrik Maier of FOCUS Software Engineering Pty Ltd
>> <www.focus-sw.com>
>>
>> As time passed the requirement for kernel 2.6 support emerged and we did
>> the same based on can4linux 3.3.2 and called it "3.3.2i" which later was
>> merged into the official can4linux archive and became 3.3.3.
>>
>> The "repeated TX IRQ" issue came up only with kernel 2.6 and was not
>> required in the 2.4 version. The way I fixed it may not have been the
>> best, but it solved the immediate need of finishing a project and
>> getting the driver stable. I am not a kernel driver expert.
>
> OK, then most likely it's not a hardware issue.
>
>> The PC7 hardware is now obsolete anyway. From my point we can do a
>> "clean" start and remove the old baggage.
>>
>> The PC7 CAN interface is ISA based and I don't have a hardware any more
>> to test.
>>
>> Some background info and our "i" versions are published here:
>>
>> http://www.focus-sw.com/can/can4linux.html
>>
>> I hope that helps a bit. It has been a few years since I worked with
>> can4linux but it is great to see that the community is further enhancing
>> CAN support for Linux.
>
> Yes, of course. Thanks for digging that out. As you suggest, we will
> remove that code and wait what happens.
>

Ok, I'll prepare this patch separately as said.

> Wolfgang.
>

Wolfgang

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2012-01-10 12:30                                                                               ` Wolfgang Zarre
@ 2012-01-10 14:20                                                                                 ` Wolfgang Grandegger
  2012-01-10 14:25                                                                                   ` Wolfgang Grandegger
  2012-01-11  9:00                                                                                 ` Wolfgang Zarre
  1 sibling, 1 reply; 66+ messages in thread
From: Wolfgang Grandegger @ 2012-01-10 14:20 UTC (permalink / raw)
  To: info
  Cc: Marc Kleine-Budde, David Laight, Oliver Hartkopp, henrik, netdev,
	linux-can, socketcan-users, IreneV, Stanislav Yelenskiy, oe,
	henrik

On 01/10/2012 01:30 PM, Wolfgang Zarre wrote:
> Hello Wolfgang,
> 
>> On 01/10/2012 12:11 AM, Marc Kleine-Budde wrote:
>>> On 01/09/2012 10:47 PM, Wolfgang Zarre wrote:
>>> [...]
>>>
>>>>>> OK. My concern: Can we be sure that 16bit accesses are always
>>>>> supported
>>>>>> by the hardware? Does a spinlock_irqsave/spinlock_irqrestore around
>>>>> the
>>>>>> 8bit accesses already help?
>>>>>
>>>>> Hmmm... are there any register reads that need the
>>>>> same 'double cycle' sequence ??
>>>>> If so you need to stop reads being interleaved (with
>>>>> themselves and writes) so requesting a 16bit access
>>>>> doesn't help.
>>>>>
>>>>> Which means you need a spinlock...
>>>>>
>>>>>      David
>>>>>
>>>>>
>>>>
>>>> @David: Thank You very much for that hint. You are right and to
>>>> implement correct we need a spinlock.
>>>>
>>>> @Wolfgang: I was thinking about Your question regarding 8/16 bit and
>>>> in fact it wouldn't work at all on a clean 8 bit cards.
>>>>
>>>> Further it wouldn't work on 16 bit cards where the MSB is not equal
>>>> to base port +1 and anyway, it's depending always on how the chip is
>>>> interfaced to the ISA bus and in which mode the chip is configured.
>>>>
>>>>
>>>> And therefore I was giving David's hint a try in using a spinlock in
>>>> function cc770_isa_port_write_reg_indirect() and patched as follows:
>>>>
>>>> ---------------------------------------------------------------------
>>>> diff --git a/drivers/net/can/cc770/cc770.c
>>>> b/drivers/net/can/cc770/cc770.c
>>>> index 2d12f89..dad6707 100644
>>>> --- a/drivers/net/can/cc770/cc770.c
>>>> +++ b/drivers/net/can/cc770/cc770.c
>>>> @@ -460,15 +460,6 @@ static netdev_tx_t cc770_start_xmit(struct sk_buff
>>>> *skb, struct net_device *dev)
>>>>
>>>>       stats->tx_bytes += dlc;
>>>>
>>>> -
>>>> -    /*
>>>> -     * HM: We had some cases of repeated IRQs so make sure the
>>>> -     * INT is acknowledged I know it's already further up, but
>>>> -     * doing again fixed the issue
>>>> -     */
>>>> -    cc770_write_reg(priv, msgobj[mo].ctrl0,
>>>> -            MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);
>>>> -
>>>>       return NETDEV_TX_OK;
>>>>   }
>>>>
>>>> @@ -689,12 +680,6 @@ static void cc770_tx_interrupt(struct net_device
>>>> *dev, unsigned int o)
>>>>       /* Nothing more to send, switch off interrupts */
>>>>       cc770_write_reg(priv, msgobj[mo].ctrl0,
>>>>               MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES);
>>>> -    /*
>>>> -     * We had some cases of repeated IRQ so make sure the
>>>> -     * INT is acknowledged
>>>> -     */
>>>> -    cc770_write_reg(priv, msgobj[mo].ctrl0,
>>>> -            MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);
>>
>> Please provide an extra patch for these unrelated changes. If we really
>> want to remove it.
>>
> 
> Sure, this I can do.
> 
>>>>       stats->tx_packets++;
>>>>       can_get_echo_skb(dev, 0);
>>>> diff --git a/drivers/net/can/cc770/cc770_isa.c
>>>> b/drivers/net/can/cc770/cc770_isa.c
>>>> index 4be5fe2..fe39eed 100644
>>>> --- a/drivers/net/can/cc770/cc770_isa.c
>>>> +++ b/drivers/net/can/cc770/cc770_isa.c
>>>> @@ -110,6 +110,9 @@ MODULE_PARM_DESC(bcr, "Bus configuration register
>>>> (default=0x40 [CBY])");
>>>>   #define CC770_IOSIZE          0x20
>>>>   #define CC770_IOSIZE_INDIRECT 0x02
>>>>
>>>> +/* Spinlock for cc770_isa_port_write_reg_indirect */
>>>> +static DEFINE_SPINLOCK( outb_lock);

Please use a more specific name, e.g.: cc770_isa_port_lock

>>>> +
>>>
>>> Do we need a global or a per device spin lock? If this should be a per
>>> device one, please introduce a cc770_isa_priv and put the spinlock
>>> there. Don't forget to initialize the spinlock.
>>
>> Yes, that's what I was thinking as well but in the ocan driver I find:
>>
>> /*
>>   * we need a spinlock here, as the address register looks shared between
>>   * two PC-ECAN devices. Moreover, we need to protect WRT interrupts
>>   */
>>
>> Looks like wired hardware. Anyway, a global spinlock might be safer.
>>
> 
> Hmmm, actually I thought to place the spinlock local because of having
> the problem just with the interrupt and not with mutex.
> 
> But if global wouldn't it then better to make an array[MAX_DEV] for the
> lock with initialisation in _init or _start?

Global means *one* spin-irq-lock for the indirect register access of all
devices. That might be the most efficient solution but we are sure that
it works, also with wired i82527 hardware, which seem to exist. That's
also what the related lincan and ocan drivers used.

Wolfgang.

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2012-01-10 14:20                                                                                 ` Wolfgang Grandegger
@ 2012-01-10 14:25                                                                                   ` Wolfgang Grandegger
  0 siblings, 0 replies; 66+ messages in thread
From: Wolfgang Grandegger @ 2012-01-10 14:25 UTC (permalink / raw)
  To: info
  Cc: Marc Kleine-Budde, David Laight, Oliver Hartkopp, henrik, netdev,
	linux-can, socketcan-users, IreneV, Stanislav Yelenskiy, oe,
	henrik

On 01/10/2012 03:20 PM, Wolfgang Grandegger wrote:
> On 01/10/2012 01:30 PM, Wolfgang Zarre wrote:
>> Hello Wolfgang,
>>
>>> On 01/10/2012 12:11 AM, Marc Kleine-Budde wrote:
>>>> On 01/09/2012 10:47 PM, Wolfgang Zarre wrote:
>>>> [...]
>>>>
>>>>>>> OK. My concern: Can we be sure that 16bit accesses are always
>>>>>> supported
>>>>>>> by the hardware? Does a spinlock_irqsave/spinlock_irqrestore around
>>>>>> the
>>>>>>> 8bit accesses already help?
>>>>>>
>>>>>> Hmmm... are there any register reads that need the
>>>>>> same 'double cycle' sequence ??
>>>>>> If so you need to stop reads being interleaved (with
>>>>>> themselves and writes) so requesting a 16bit access
>>>>>> doesn't help.
>>>>>>
>>>>>> Which means you need a spinlock...
>>>>>>
>>>>>>      David
>>>>>>
>>>>>>
>>>>>
>>>>> @David: Thank You very much for that hint. You are right and to
>>>>> implement correct we need a spinlock.
>>>>>
>>>>> @Wolfgang: I was thinking about Your question regarding 8/16 bit and
>>>>> in fact it wouldn't work at all on a clean 8 bit cards.
>>>>>
>>>>> Further it wouldn't work on 16 bit cards where the MSB is not equal
>>>>> to base port +1 and anyway, it's depending always on how the chip is
>>>>> interfaced to the ISA bus and in which mode the chip is configured.
>>>>>
>>>>>
>>>>> And therefore I was giving David's hint a try in using a spinlock in
>>>>> function cc770_isa_port_write_reg_indirect() and patched as follows:
>>>>>
>>>>> ---------------------------------------------------------------------
>>>>> diff --git a/drivers/net/can/cc770/cc770.c
>>>>> b/drivers/net/can/cc770/cc770.c
>>>>> index 2d12f89..dad6707 100644
>>>>> --- a/drivers/net/can/cc770/cc770.c
>>>>> +++ b/drivers/net/can/cc770/cc770.c
>>>>> @@ -460,15 +460,6 @@ static netdev_tx_t cc770_start_xmit(struct sk_buff
>>>>> *skb, struct net_device *dev)
>>>>>
>>>>>       stats->tx_bytes += dlc;
>>>>>
>>>>> -
>>>>> -    /*
>>>>> -     * HM: We had some cases of repeated IRQs so make sure the
>>>>> -     * INT is acknowledged I know it's already further up, but
>>>>> -     * doing again fixed the issue
>>>>> -     */
>>>>> -    cc770_write_reg(priv, msgobj[mo].ctrl0,
>>>>> -            MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);
>>>>> -
>>>>>       return NETDEV_TX_OK;
>>>>>   }
>>>>>
>>>>> @@ -689,12 +680,6 @@ static void cc770_tx_interrupt(struct net_device
>>>>> *dev, unsigned int o)
>>>>>       /* Nothing more to send, switch off interrupts */
>>>>>       cc770_write_reg(priv, msgobj[mo].ctrl0,
>>>>>               MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES);
>>>>> -    /*
>>>>> -     * We had some cases of repeated IRQ so make sure the
>>>>> -     * INT is acknowledged
>>>>> -     */
>>>>> -    cc770_write_reg(priv, msgobj[mo].ctrl0,
>>>>> -            MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);
>>>
>>> Please provide an extra patch for these unrelated changes. If we really
>>> want to remove it.
>>>
>>
>> Sure, this I can do.
>>
>>>>>       stats->tx_packets++;
>>>>>       can_get_echo_skb(dev, 0);
>>>>> diff --git a/drivers/net/can/cc770/cc770_isa.c
>>>>> b/drivers/net/can/cc770/cc770_isa.c
>>>>> index 4be5fe2..fe39eed 100644
>>>>> --- a/drivers/net/can/cc770/cc770_isa.c
>>>>> +++ b/drivers/net/can/cc770/cc770_isa.c
>>>>> @@ -110,6 +110,9 @@ MODULE_PARM_DESC(bcr, "Bus configuration register
>>>>> (default=0x40 [CBY])");
>>>>>   #define CC770_IOSIZE          0x20
>>>>>   #define CC770_IOSIZE_INDIRECT 0x02
>>>>>
>>>>> +/* Spinlock for cc770_isa_port_write_reg_indirect */
>>>>> +static DEFINE_SPINLOCK( outb_lock);
> 
> Please use a more specific name, e.g.: cc770_isa_port_lock
> 
>>>>> +
>>>>
>>>> Do we need a global or a per device spin lock? If this should be a per
>>>> device one, please introduce a cc770_isa_priv and put the spinlock
>>>> there. Don't forget to initialize the spinlock.
>>>
>>> Yes, that's what I was thinking as well but in the ocan driver I find:
>>>
>>> /*
>>>   * we need a spinlock here, as the address register looks shared between
>>>   * two PC-ECAN devices. Moreover, we need to protect WRT interrupts
>>>   */
>>>
>>> Looks like wired hardware. Anyway, a global spinlock might be safer.
>>>
>>
>> Hmmm, actually I thought to place the spinlock local because of having
>> the problem just with the interrupt and not with mutex.
>>
>> But if global wouldn't it then better to make an array[MAX_DEV] for the
>> lock with initialisation in _init or _start?
> 
> Global means *one* spin-irq-lock for the indirect register access of all
> devices. That might be the most efficient solution but we are sure that

s/might/might not/

> it works, also with wired i82527 hardware, which seem to exist. That's
> also what the related lincan and ocan drivers used.

Wolfgang.

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2012-01-10 12:41                                                                             ` Wolfgang Zarre
@ 2012-01-10 14:43                                                                               ` Wolfgang Grandegger
  2012-01-10 14:50                                                                                 ` Oliver Hartkopp
  2012-01-10 16:13                                                                                 ` Wolfgang Zarre
  0 siblings, 2 replies; 66+ messages in thread
From: Wolfgang Grandegger @ 2012-01-10 14:43 UTC (permalink / raw)
  To: info
  Cc: David Laight, Oliver Hartkopp, henrik, netdev, linux-can,
	socketcan-users, IreneV, Stanislav Yelenskiy, oe, henrik

On 01/10/2012 01:41 PM, Wolfgang Zarre wrote:
> Hello David,
>>
>>> cc770_isa_port_write_reg_indirect(const struct cc770_priv *priv,
>>>                            int reg, u8 val)
>>>    {
>>>        unsigned long base = (unsigned long)priv->reg_base;
>>> +    unsigned long flags;
>>>
>>> +    spin_lock_irqsave(&outb_lock, flags);
>>>        outb(reg, base);
>>>        outb(val, base + 1);
>>> +    spin_unlock_irqrestore(&outb_lock, flags);   
>>
>> Is there a 'read_reg_indirect' function??
> 
> Yes, there is.
> 
>> If so it also needs to use the same mutex.
> 
> Actually, I don't think that we have a problem with mutex
> beside that it's using just one inb() statement but having
> for sure with an interrupt between both outb() statements which
> seems to be critical for the cc770.

But the indirect read function also sets the address register before
reading the data using inb(). This sequence should also not be
interrupted and therefore we need to synchronize. For the indirect
access of the SJA1000 we also need to add spinlocks. Wonder why nobody
complained so far.

Wolfgang.

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2012-01-10 14:43                                                                               ` Wolfgang Grandegger
@ 2012-01-10 14:50                                                                                 ` Oliver Hartkopp
  2012-01-10 16:13                                                                                 ` Wolfgang Zarre
  1 sibling, 0 replies; 66+ messages in thread
From: Oliver Hartkopp @ 2012-01-10 14:50 UTC (permalink / raw)
  To: Wolfgang Grandegger
  Cc: info, David Laight, henrik, netdev, linux-can, socketcan-users,
	IreneV, Stanislav Yelenskiy, oe, henrik

On 10.01.2012 15:43, Wolfgang Grandegger wrote:

> On 01/10/2012 01:41 PM, Wolfgang Zarre wrote:
>> Hello David,
>>>
>>>> cc770_isa_port_write_reg_indirect(const struct cc770_priv *priv,
>>>>                            int reg, u8 val)
>>>>    {
>>>>        unsigned long base = (unsigned long)priv->reg_base;
>>>> +    unsigned long flags;
>>>>
>>>> +    spin_lock_irqsave(&outb_lock, flags);
>>>>        outb(reg, base);
>>>>        outb(val, base + 1);
>>>> +    spin_unlock_irqrestore(&outb_lock, flags);   
>>>
>>> Is there a 'read_reg_indirect' function??
>>
>> Yes, there is.
>>
>>> If so it also needs to use the same mutex.
>>
>> Actually, I don't think that we have a problem with mutex
>> beside that it's using just one inb() statement but having
>> for sure with an interrupt between both outb() statements which
>> seems to be critical for the cc770.
> 
> But the indirect read function also sets the address register before
> reading the data using inb(). This sequence should also not be
> interrupted and therefore we need to synchronize. For the indirect
> access of the SJA1000 we also need to add spinlocks. Wonder why nobody
> complained so far.


Maybe due to old single core hardware that has SJA1000 hw with indirect
addressing? Or this old hardware has not been 'kernel-upgraded' so far ...

In any case you are right with the missing spinlocks.

Regards,
Oliver

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2012-01-10 14:43                                                                               ` Wolfgang Grandegger
  2012-01-10 14:50                                                                                 ` Oliver Hartkopp
@ 2012-01-10 16:13                                                                                 ` Wolfgang Zarre
  2012-01-10 16:20                                                                                   ` Marc Kleine-Budde
  2012-01-10 16:23                                                                                   ` Wolfgang Grandegger
  1 sibling, 2 replies; 66+ messages in thread
From: Wolfgang Zarre @ 2012-01-10 16:13 UTC (permalink / raw)
  To: Wolfgang Grandegger
  Cc: David Laight, Oliver Hartkopp, henrik, netdev, linux-can,
	socketcan-users, IreneV, Stanislav Yelenskiy, oe, henrik

Hello Wolfgang,

> On 01/10/2012 01:41 PM, Wolfgang Zarre wrote:
>> Hello David,
>>>
>>>> cc770_isa_port_write_reg_indirect(const struct cc770_priv *priv,
>>>>                             int reg, u8 val)
>>>>     {
>>>>         unsigned long base = (unsigned long)priv->reg_base;
>>>> +    unsigned long flags;
>>>>
>>>> +    spin_lock_irqsave(&outb_lock, flags);
>>>>         outb(reg, base);
>>>>         outb(val, base + 1);
>>>> +    spin_unlock_irqrestore(&outb_lock, flags);
>>>
>>> Is there a 'read_reg_indirect' function??
>>
>> Yes, there is.
>>
>>> If so it also needs to use the same mutex.
>>
>> Actually, I don't think that we have a problem with mutex
>> beside that it's using just one inb() statement but having
>> for sure with an interrupt between both outb() statements which
>> seems to be critical for the cc770.
>
> But the indirect read function also sets the address register before
> reading the data using inb(). This sequence should also not be
> interrupted and therefore we need to synchronize. For the indirect
> access of the SJA1000 we also need to add spinlocks. Wonder why nobody
> complained so far.

So, if I understand correct that means that inb() can be interrupted between
setting the address and reading. If this is the case then yes, we need
spinlock if this is not the case then IMHO we wouldn't need or am I wrong?



>
> Wolfgang.
>

Wolfgang

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2012-01-10 16:13                                                                                 ` Wolfgang Zarre
@ 2012-01-10 16:20                                                                                   ` Marc Kleine-Budde
  2012-01-10 16:23                                                                                   ` Wolfgang Grandegger
  1 sibling, 0 replies; 66+ messages in thread
From: Marc Kleine-Budde @ 2012-01-10 16:20 UTC (permalink / raw)
  To: info
  Cc: Wolfgang Grandegger, David Laight, Oliver Hartkopp, henrik,
	netdev, linux-can, socketcan-users, IreneV, Stanislav Yelenskiy,
	oe, henrik

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

On 01/10/2012 05:13 PM, Wolfgang Zarre wrote:
> Hello Wolfgang,
> 
>> On 01/10/2012 01:41 PM, Wolfgang Zarre wrote:
>>> Hello David,
>>>>
>>>>> cc770_isa_port_write_reg_indirect(const struct cc770_priv *priv,
>>>>>                             int reg, u8 val)
>>>>>     {
>>>>>         unsigned long base = (unsigned long)priv->reg_base;
>>>>> +    unsigned long flags;
>>>>>
>>>>> +    spin_lock_irqsave(&outb_lock, flags);
>>>>>         outb(reg, base);
>>>>>         outb(val, base + 1);
>>>>> +    spin_unlock_irqrestore(&outb_lock, flags);
>>>>
>>>> Is there a 'read_reg_indirect' function??
>>>
>>> Yes, there is.
>>>
>>>> If so it also needs to use the same mutex.
>>>
>>> Actually, I don't think that we have a problem with mutex
>>> beside that it's using just one inb() statement but having
>>> for sure with an interrupt between both outb() statements which
>>> seems to be critical for the cc770.
>>
>> But the indirect read function also sets the address register before
>> reading the data using inb(). This sequence should also not be
>> interrupted and therefore we need to synchronize. For the indirect
>> access of the SJA1000 we also need to add spinlocks. Wonder why nobody
>> complained so far.
> 
> So, if I understand correct that means that inb() can be interrupted
> between
> setting the address and reading. If this is the case then yes, we need
> spinlock if this is not the case then IMHO we wouldn't need or am I wrong?

If I understand correct, this function is the problem:

> static u8 cc770_isa_port_read_reg_indirect(const struct cc770_priv *priv,
>                                              int reg)
> {
>         unsigned long base = (unsigned long)priv->reg_base;
> 
>         outb(reg, base);

an interrupt can happen here, which does another indirect read or write
access, leaving "reg" pointing to the wrong register.

>         return inb(base + 1);
> }

Mar
c
-- 
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: 262 bytes --]

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2012-01-10 16:13                                                                                 ` Wolfgang Zarre
  2012-01-10 16:20                                                                                   ` Marc Kleine-Budde
@ 2012-01-10 16:23                                                                                   ` Wolfgang Grandegger
  2012-01-10 19:02                                                                                     ` Wolfgang Zarre
  1 sibling, 1 reply; 66+ messages in thread
From: Wolfgang Grandegger @ 2012-01-10 16:23 UTC (permalink / raw)
  To: info
  Cc: David Laight, Oliver Hartkopp, henrik, netdev, linux-can,
	socketcan-users, IreneV, Stanislav Yelenskiy, oe, henrik

Hi Wolfgang,

On 01/10/2012 05:13 PM, Wolfgang Zarre wrote:
> Hello Wolfgang,
> 
>> On 01/10/2012 01:41 PM, Wolfgang Zarre wrote:
>>> Hello David,
>>>>
>>>>> cc770_isa_port_write_reg_indirect(const struct cc770_priv *priv,
>>>>>                             int reg, u8 val)
>>>>>     {
>>>>>         unsigned long base = (unsigned long)priv->reg_base;
>>>>> +    unsigned long flags;
>>>>>
>>>>> +    spin_lock_irqsave(&outb_lock, flags);
>>>>>         outb(reg, base);
>>>>>         outb(val, base + 1);
>>>>> +    spin_unlock_irqrestore(&outb_lock, flags);
>>>>
>>>> Is there a 'read_reg_indirect' function??
>>>
>>> Yes, there is.
>>>
>>>> If so it also needs to use the same mutex.
>>>
>>> Actually, I don't think that we have a problem with mutex
>>> beside that it's using just one inb() statement but having
>>> for sure with an interrupt between both outb() statements which
>>> seems to be critical for the cc770.
>>
>> But the indirect read function also sets the address register before
>> reading the data using inb(). This sequence should also not be
>> interrupted and therefore we need to synchronize. For the indirect
>> access of the SJA1000 we also need to add spinlocks. Wonder why nobody
>> complained so far.
> 
> So, if I understand correct that means that inb() can be interrupted
> between
> setting the address and reading. If this is the case then yes, we need
> spinlock if this is not the case then IMHO we wouldn't need or am I wrong?

I think we speak about different things. inb() cannot be interrupted but
outb() followed by inb(). For indirect accesses we need something like:

/* Spinlock for cc770_isa_port_write_reg_indirect */
static DEFINE_SPINLOCK(cc770_isa_port_lock);

static u8 cc770_isa_port_read_reg_indirect(const struct cc770_priv *priv,
                                             int reg)
{
        unsigned long base = (unsigned long)priv->reg_base;
	unsigned long flags;
	u8 val;

	spin_lock_irqsave(&cc770_isa_port_lock, flags);
        outb(reg, base);
        val = inb(base + 1);
	spin_unlock_irqrestore(&cc770_isa_port_lock, flags);    

	return val;
}

static void cc770_isa_port_write_reg_indirect(const struct cc770_priv *priv,
                                                int reg, u8 val)
{
        unsigned long base = (unsigned long)priv->reg_base;
	unsigned long flags;

	spin_lock_irqsave(&cc770_isa_port_lock, flags);
        outb(reg, base);
        outb(val, base + 1);
	spin_unlock_irqrestore(&cc770_isa_port_lock, flags);    
}

Hope we are in synch now.

Wolfgang.


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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2012-01-10 16:23                                                                                   ` Wolfgang Grandegger
@ 2012-01-10 19:02                                                                                     ` Wolfgang Zarre
  2012-01-11  9:05                                                                                       ` Wolfgang Zarre
  0 siblings, 1 reply; 66+ messages in thread
From: Wolfgang Zarre @ 2012-01-10 19:02 UTC (permalink / raw)
  To: Wolfgang Grandegger, David Laight
  Cc: Oliver Hartkopp, henrik, netdev, linux-can, socketcan-users,
	IreneV, Stanislav Yelenskiy, oe, henrik

Hello Wolfgang,

-------- Original Message  --------
Subject: Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
From: Wolfgang Grandegger <wg@grandegger.com>
To: info@essax.com
Cc: David Laight <David.Laight@ACULAB.COM>, Oliver Hartkopp <socketcan@hartkopp.net>, henrik@proconx.com, netdev@vger.kernel.org, linux-can@vger.kernel.org, 
socketcan-users@lists.berlios.de, IreneV <boir1@yandex.ru>, Stanislav Yelenskiy <stanislavelensky@yahoo.com>, oe@port.de, henrik@focus-sw.com
Date: Tue Jan 10 2012 17:23:59 GMT+0100 (CET)

> Hi Wolfgang,
>
> On 01/10/2012 05:13 PM, Wolfgang Zarre wrote:
>> Hello Wolfgang,
>>
>>> On 01/10/2012 01:41 PM, Wolfgang Zarre wrote:
>>>> Hello David,
>>>>>
>>>>>> cc770_isa_port_write_reg_indirect(const struct cc770_priv *priv,
>>>>>>                              int reg, u8 val)
>>>>>>      {
>>>>>>          unsigned long base = (unsigned long)priv->reg_base;
>>>>>> +    unsigned long flags;
>>>>>>
>>>>>> +    spin_lock_irqsave(&outb_lock, flags);
>>>>>>          outb(reg, base);
>>>>>>          outb(val, base + 1);
>>>>>> +    spin_unlock_irqrestore(&outb_lock, flags);
>>>>>
>>>>> Is there a 'read_reg_indirect' function??
>>>>
>>>> Yes, there is.
>>>>
>>>>> If so it also needs to use the same mutex.
>>>>
>>>> Actually, I don't think that we have a problem with mutex
>>>> beside that it's using just one inb() statement but having
>>>> for sure with an interrupt between both outb() statements which
>>>> seems to be critical for the cc770.
>>>
>>> But the indirect read function also sets the address register before
>>> reading the data using inb(). This sequence should also not be
>>> interrupted and therefore we need to synchronize. For the indirect
>>> access of the SJA1000 we also need to add spinlocks. Wonder why nobody
>>> complained so far.
>>
>> So, if I understand correct that means that inb() can be interrupted
>> between
>> setting the address and reading. If this is the case then yes, we need
>> spinlock if this is not the case then IMHO we wouldn't need or am I wrong?
>
> I think we speak about different things. inb() cannot be interrupted but
> outb() followed by inb(). For indirect accesses we need something like:
>
> /* Spinlock for cc770_isa_port_write_reg_indirect */
> static DEFINE_SPINLOCK(cc770_isa_port_lock);
>
> static u8 cc770_isa_port_read_reg_indirect(const struct cc770_priv *priv,
>                                               int reg)
> {
>          unsigned long base = (unsigned long)priv->reg_base;
> 	unsigned long flags;
> 	u8 val;
>
> 	spin_lock_irqsave(&cc770_isa_port_lock, flags);
>          outb(reg, base);
>          val = inb(base + 1);
> 	spin_unlock_irqrestore(&cc770_isa_port_lock, flags);
>
> 	return val;
> }
>
> static void cc770_isa_port_write_reg_indirect(const struct cc770_priv *priv,
>                                                  int reg, u8 val)
> {
>          unsigned long base = (unsigned long)priv->reg_base;
> 	unsigned long flags;
>
> 	spin_lock_irqsave(&cc770_isa_port_lock, flags);
>          outb(reg, base);
>          outb(val, base + 1);
> 	spin_unlock_irqrestore(&cc770_isa_port_lock, flags);
> }
>
> Hope we are in synch now.
>

Thanks a lot. Yes, now phase locked and in synch and sorry, by mistake
I looked at the wrong function (cc770_isa_port_read_reg) in the heat of
the moment.

Absolutely clear, there we need a spinlock definitely. I'll start another test run
just to confirm.


> Wolfgang.
>

Wolfgang

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2012-01-10 12:30                                                                               ` Wolfgang Zarre
  2012-01-10 14:20                                                                                 ` Wolfgang Grandegger
@ 2012-01-11  9:00                                                                                 ` Wolfgang Zarre
  2012-01-11  9:37                                                                                   ` David Laight
  2012-01-11  9:38                                                                                   ` Marc Kleine-Budde
  1 sibling, 2 replies; 66+ messages in thread
From: Wolfgang Zarre @ 2012-01-11  9:00 UTC (permalink / raw)
  To: Wolfgang Grandegger
  Cc: Marc Kleine-Budde, David Laight, Oliver Hartkopp, henrik, netdev,
	linux-can, socketcan-users, IreneV, Stanislav Yelenskiy, oe,
	henrik

Hello Wolfgang,

> Hello Wolfgang,
>
>> On 01/10/2012 12:11 AM, Marc Kleine-Budde wrote:
>>> On 01/09/2012 10:47 PM, Wolfgang Zarre wrote:
>>> [...]
>>>
>>>>>> OK. My concern: Can we be sure that 16bit accesses are always
>>>>> supported
>>>>>> by the hardware? Does a spinlock_irqsave/spinlock_irqrestore around
>>>>> the
>>>>>> 8bit accesses already help?
>>>>>
>>>>> Hmmm... are there any register reads that need the
>>>>> same 'double cycle' sequence ??
>>>>> If so you need to stop reads being interleaved (with
>>>>> themselves and writes) so requesting a 16bit access
>>>>> doesn't help.
>>>>>
>>>>> Which means you need a spinlock...
>>>>>
>>>>> David
>>>>>
>>>>>
>>>>
>>>> @David: Thank You very much for that hint. You are right and to
>>>> implement correct we need a spinlock.
>>>>
>>>> @Wolfgang: I was thinking about Your question regarding 8/16 bit and
>>>> in fact it wouldn't work at all on a clean 8 bit cards.
>>>>
>>>> Further it wouldn't work on 16 bit cards where the MSB is not equal
>>>> to base port +1 and anyway, it's depending always on how the chip is
>>>> interfaced to the ISA bus and in which mode the chip is configured.
>>>>
>>>>
>>>> And therefore I was giving David's hint a try in using a spinlock in
>>>> function cc770_isa_port_write_reg_indirect() and patched as follows:
>>>>
>>>> ---------------------------------------------------------------------
>>>> diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c
>>>> index 2d12f89..dad6707 100644
>>>> --- a/drivers/net/can/cc770/cc770.c
>>>> +++ b/drivers/net/can/cc770/cc770.c
>>>> @@ -460,15 +460,6 @@ static netdev_tx_t cc770_start_xmit(struct sk_buff
>>>> *skb, struct net_device *dev)
>>>>
>>>> stats->tx_bytes += dlc;
>>>>
>>>> -
>>>> - /*
>>>> - * HM: We had some cases of repeated IRQs so make sure the
>>>> - * INT is acknowledged I know it's already further up, but
>>>> - * doing again fixed the issue
>>>> - */
>>>> - cc770_write_reg(priv, msgobj[mo].ctrl0,
>>>> - MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);
>>>> -
>>>> return NETDEV_TX_OK;
>>>> }
>>>>
>>>> @@ -689,12 +680,6 @@ static void cc770_tx_interrupt(struct net_device
>>>> *dev, unsigned int o)
>>>> /* Nothing more to send, switch off interrupts */
>>>> cc770_write_reg(priv, msgobj[mo].ctrl0,
>>>> MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES);
>>>> - /*
>>>> - * We had some cases of repeated IRQ so make sure the
>>>> - * INT is acknowledged
>>>> - */
>>>> - cc770_write_reg(priv, msgobj[mo].ctrl0,
>>>> - MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);
>>
>> Please provide an extra patch for these unrelated changes. If we really
>> want to remove it.
>>
>
> Sure, this I can do.
>

Ok, here the patch to remove:
--------------------------------------------------------
diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c
index 2d12f89..dad6707 100644
--- a/drivers/net/can/cc770/cc770.c
+++ b/drivers/net/can/cc770/cc770.c
@@ -460,15 +460,6 @@ static netdev_tx_t cc770_start_xmit(struct sk_buff *skb, struct net_device *dev)

  	stats->tx_bytes += dlc;

-
-	/*
-	 * HM: We had some cases of repeated IRQs so make sure the
-	 * INT is acknowledged I know it's already further up, but
-	 * doing again fixed the issue
-	 */
-	cc770_write_reg(priv, msgobj[mo].ctrl0,
-			MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);
-
  	return NETDEV_TX_OK;
  }

@@ -689,12 +680,6 @@ static void cc770_tx_interrupt(struct net_device *dev, unsigned int o)
  	/* Nothing more to send, switch off interrupts */
  	cc770_write_reg(priv, msgobj[mo].ctrl0,
  			MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES);
-	/*
-	 * We had some cases of repeated IRQ so make sure the
-	 * INT is acknowledged
-	 */
-	cc770_write_reg(priv, msgobj[mo].ctrl0,
-			MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);

  	stats->tx_packets++;
  	can_get_echo_skb(dev, 0);
----------------------------------------------------------


>>>> stats->tx_packets++;
>>>> can_get_echo_skb(dev, 0);
>>>> diff --git a/drivers/net/can/cc770/cc770_isa.c
>>>> b/drivers/net/can/cc770/cc770_isa.c
>>>> index 4be5fe2..fe39eed 100644
>>>> --- a/drivers/net/can/cc770/cc770_isa.c
>>>> +++ b/drivers/net/can/cc770/cc770_isa.c
>>>> @@ -110,6 +110,9 @@ MODULE_PARM_DESC(bcr, "Bus configuration register
>>>> (default=0x40 [CBY])");
>>>> #define CC770_IOSIZE 0x20
>>>> #define CC770_IOSIZE_INDIRECT 0x02
>>>>
>>>> +/* Spinlock for cc770_isa_port_write_reg_indirect */
>>>> +static DEFINE_SPINLOCK( outb_lock);
>>>> +
>>>
>>> Do we need a global or a per device spin lock? If this should be a per
>>> device one, please introduce a cc770_isa_priv and put the spinlock
>>> there. Don't forget to initialize the spinlock.
>>
>> Yes, that's what I was thinking as well but in the ocan driver I find:
>>
>> /*
>> * we need a spinlock here, as the address register looks shared between
>> * two PC-ECAN devices. Moreover, we need to protect WRT interrupts
>> */
>>
>> Looks like wired hardware. Anyway, a global spinlock might be safer.
>>
>
> Hmmm, actually I thought to place the spinlock local because of having
> the problem just with the interrupt and not with mutex.
>
> But if global wouldn't it then better to make an array[MAX_DEV] for the
> lock with initialisation in _init or _start?
>
> But if PC-ECAN works with that configuration?
>
>> Wolfgang.
>
> Wolfgang

Wolfgang

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2012-01-10 19:02                                                                                     ` Wolfgang Zarre
@ 2012-01-11  9:05                                                                                       ` Wolfgang Zarre
  2012-01-11  9:31                                                                                         ` Marc Kleine-Budde
  0 siblings, 1 reply; 66+ messages in thread
From: Wolfgang Zarre @ 2012-01-11  9:05 UTC (permalink / raw)
  To: Wolfgang Grandegger
  Cc: David Laight, Oliver Hartkopp, henrik, netdev, linux-can,
	socketcan-users, IreneV, Stanislav Yelenskiy, oe, henrik

Hello Wolfgang,

> Hello Wolfgang,
>
> -------- Original Message --------
> Subject: Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
> From: Wolfgang Grandegger <wg@grandegger.com>
> To: info@essax.com
> Cc: David Laight <David.Laight@ACULAB.COM>, Oliver Hartkopp <socketcan@hartkopp.net>, henrik@proconx.com, netdev@vger.kernel.org, linux-can@vger.kernel.org,
> socketcan-users@lists.berlios.de, IreneV <boir1@yandex.ru>, Stanislav Yelenskiy <stanislavelensky@yahoo.com>, oe@port.de, henrik@focus-sw.com
> Date: Tue Jan 10 2012 17:23:59 GMT+0100 (CET)
>
>> Hi Wolfgang,
>>
>> On 01/10/2012 05:13 PM, Wolfgang Zarre wrote:
>>> Hello Wolfgang,
>>>
>>>> On 01/10/2012 01:41 PM, Wolfgang Zarre wrote:
>>>>> Hello David,
>>>>>>
>>>>>>> cc770_isa_port_write_reg_indirect(const struct cc770_priv *priv,
>>>>>>> int reg, u8 val)
>>>>>>> {
>>>>>>> unsigned long base = (unsigned long)priv->reg_base;
>>>>>>> + unsigned long flags;
>>>>>>>
>>>>>>> + spin_lock_irqsave(&outb_lock, flags);
>>>>>>> outb(reg, base);
>>>>>>> outb(val, base + 1);
>>>>>>> + spin_unlock_irqrestore(&outb_lock, flags);
>>>>>>
>>>>>> Is there a 'read_reg_indirect' function??
>>>>>
>>>>> Yes, there is.
>>>>>
>>>>>> If so it also needs to use the same mutex.
>>>>>
>>>>> Actually, I don't think that we have a problem with mutex
>>>>> beside that it's using just one inb() statement but having
>>>>> for sure with an interrupt between both outb() statements which
>>>>> seems to be critical for the cc770.
>>>>
>>>> But the indirect read function also sets the address register before
>>>> reading the data using inb(). This sequence should also not be
>>>> interrupted and therefore we need to synchronize. For the indirect
>>>> access of the SJA1000 we also need to add spinlocks. Wonder why nobody
>>>> complained so far.
>>>
>>> So, if I understand correct that means that inb() can be interrupted
>>> between
>>> setting the address and reading. If this is the case then yes, we need
>>> spinlock if this is not the case then IMHO we wouldn't need or am I wrong?
>>
>> I think we speak about different things. inb() cannot be interrupted but
>> outb() followed by inb(). For indirect accesses we need something like:
>>
>> /* Spinlock for cc770_isa_port_write_reg_indirect */
>> static DEFINE_SPINLOCK(cc770_isa_port_lock);
>>
>> static u8 cc770_isa_port_read_reg_indirect(const struct cc770_priv *priv,
>> int reg)
>> {
>> unsigned long base = (unsigned long)priv->reg_base;
>> unsigned long flags;
>> u8 val;
>>
>> spin_lock_irqsave(&cc770_isa_port_lock, flags);
>> outb(reg, base);
>> val = inb(base + 1);
>> spin_unlock_irqrestore(&cc770_isa_port_lock, flags);
>>
>> return val;
>> }
>>
>> static void cc770_isa_port_write_reg_indirect(const struct cc770_priv *priv,
>> int reg, u8 val)
>> {
>> unsigned long base = (unsigned long)priv->reg_base;
>> unsigned long flags;
>>
>> spin_lock_irqsave(&cc770_isa_port_lock, flags);
>> outb(reg, base);
>> outb(val, base + 1);
>> spin_unlock_irqrestore(&cc770_isa_port_lock, flags);
>> }
>>
>> Hope we are in synch now.
>>
>
> Thanks a lot. Yes, now phase locked and in synch and sorry, by mistake
> I looked at the wrong function (cc770_isa_port_read_reg) in the heat of
> the moment.
>
> Absolutely clear, there we need a spinlock definitely. I'll start another test run
> just to confirm.
>
>


Test was successful, 2.000.000 telegrams again without problems.
Here so far the patch as You suggested:

-------------------------------------------------------------------
  diff --git a/drivers/net/can/cc770/cc770_isa.c b/drivers/net/can/cc770/cc770_isa.c
index 4be5fe2..adf3e45 100644
--- a/drivers/net/can/cc770/cc770_isa.c
+++ b/drivers/net/can/cc770/cc770_isa.c
@@ -110,6 +110,10 @@ MODULE_PARM_DESC(bcr, "Bus configuration register (default=0x40 [CBY])");
  #define CC770_IOSIZE          0x20
  #define CC770_IOSIZE_INDIRECT 0x02

+/* Spinlock for cc770_isa_port_write_reg_indirect */
+static DEFINE_SPINLOCK(cc770_isa_port_lock);
+
+
  static struct platform_device *cc770_isa_devs[MAXDEV];

  static u8 cc770_isa_mem_read_reg(const struct cc770_priv *priv, int reg)
@@ -138,18 +142,26 @@ static u8 cc770_isa_port_read_reg_indirect(const struct cc770_priv *priv,
  					     int reg)
  {
  	unsigned long base = (unsigned long)priv->reg_base;
+	unsigned long flags;
+	u8 val;

+	spin_lock_irqsave(&cc770_isa_port_lock, flags);
  	outb(reg, base);
-	return inb(base + 1);
+	val = inb(base + 1);
+	spin_unlock_irqrestore(&cc770_isa_port_lock, flags);
+	return val;
  }

  static void cc770_isa_port_write_reg_indirect(const struct cc770_priv *priv,
  						int reg, u8 val)
  {
  	unsigned long base = (unsigned long)priv->reg_base;
+	unsigned long flags;

+	spin_lock_irqsave(&cc770_isa_port_lock, flags);
  	outb(reg, base);
  	outb(val, base + 1);
+	spin_unlock_irqrestore(&cc770_isa_port_lock, flags); 	
  }

  static int __devinit cc770_isa_probe(struct platform_device *pdev)
-------------------------------------------------------


>> Wolfgang.
>>
>
> Wolfgang

Wolfgang

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2012-01-11  9:05                                                                                       ` Wolfgang Zarre
@ 2012-01-11  9:31                                                                                         ` Marc Kleine-Budde
  0 siblings, 0 replies; 66+ messages in thread
From: Marc Kleine-Budde @ 2012-01-11  9:31 UTC (permalink / raw)
  To: info
  Cc: Wolfgang Grandegger, David Laight, Oliver Hartkopp, henrik,
	netdev, linux-can, socketcan-users, IreneV, Stanislav Yelenskiy,
	oe, henrik

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

On 01/11/2012 10:05 AM, Wolfgang Zarre wrote:
[...]

The patch looks good, it has some style issues though, see comments
inline. Please fix them, add a description to the patch, don't forget
your S-o-b, same applies to the other patch which removes the extra IRQ
ack. Please create a series of two patches, first this (the spinlock
patch), the second the rermoval of the extra IRQ ack. Send this patches
to this list. See [1] for more information about patch submitting.

Marc

[1] http://lxr.linux.no/linux+v3.2/Documentation/SubmittingPatches#L86

> Test was successful, 2.000.000 telegrams again without problems.
> Here so far the patch as You suggested:
> 
> -------------------------------------------------------------------
>  diff --git a/drivers/net/can/cc770/cc770_isa.c
> b/drivers/net/can/cc770/cc770_isa.c
> index 4be5fe2..adf3e45 100644
> --- a/drivers/net/can/cc770/cc770_isa.c
> +++ b/drivers/net/can/cc770/cc770_isa.c
> @@ -110,6 +110,10 @@ MODULE_PARM_DESC(bcr, "Bus configuration register
> (default=0x40 [CBY])");
>  #define CC770_IOSIZE          0x20
>  #define CC770_IOSIZE_INDIRECT 0x02
> 
> +/* Spinlock for cc770_isa_port_write_reg_indirect */

The spinlock is used in read_reg_indirect, too

> +static DEFINE_SPINLOCK(cc770_isa_port_lock);
> +
> +

Just one new blank line please.

>  static struct platform_device *cc770_isa_devs[MAXDEV];
> 
>  static u8 cc770_isa_mem_read_reg(const struct cc770_priv *priv, int reg)
> @@ -138,18 +142,26 @@ static u8 cc770_isa_port_read_reg_indirect(const
> struct cc770_priv *priv,
>                           int reg)
>  {
>      unsigned long base = (unsigned long)priv->reg_base;
> +    unsigned long flags;
> +    u8 val;
> 
> +    spin_lock_irqsave(&cc770_isa_port_lock, flags);
>      outb(reg, base);
> -    return inb(base + 1);
> +    val = inb(base + 1);
> +    spin_unlock_irqrestore(&cc770_isa_port_lock, flags);

Please insert a newline before return.

> +    return val;
>  }
> 
>  static void cc770_isa_port_write_reg_indirect(const struct cc770_priv
> *priv,
>                          int reg, u8 val)
>  {
>      unsigned long base = (unsigned long)priv->reg_base;
> +    unsigned long flags;
> 
> +    spin_lock_irqsave(&cc770_isa_port_lock, flags);
>      outb(reg, base);
>      outb(val, base + 1);
> +    spin_unlock_irqrestore(&cc770_isa_port_lock, flags);    
>  }
> 
>  static int __devinit cc770_isa_probe(struct platform_device *pdev)
> -------------------------------------------------------


-- 
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: 262 bytes --]

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

* RE: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2012-01-11  9:00                                                                                 ` Wolfgang Zarre
@ 2012-01-11  9:37                                                                                   ` David Laight
  2012-01-11 14:37                                                                                     ` Wolfgang Zarre
  2012-01-11  9:38                                                                                   ` Marc Kleine-Budde
  1 sibling, 1 reply; 66+ messages in thread
From: David Laight @ 2012-01-11  9:37 UTC (permalink / raw)
  To: info, Wolfgang Grandegger
  Cc: Marc Kleine-Budde, Oliver Hartkopp, henrik, netdev, linux-can,
	socketcan-users, IreneV, Stanislav Yelenskiy, oe, henrik

 
> @@ -689,12 +680,6 @@ static void cc770_tx_interrupt(struct 
> net_device *dev, unsigned int o)
>   	/* Nothing more to send, switch off interrupts */
>   	cc770_write_reg(priv, msgobj[mo].ctrl0,
>   			MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES);
> -	/*
> -	 * We had some cases of repeated IRQ so make sure the
> -	 * INT is acknowledged
> -	 */
> -	cc770_write_reg(priv, msgobj[mo].ctrl0,
> -			MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);

A wild guess is that this is needed to clear an interrupt
that was asserted during the ISR processing.
So you need to ack the IRQ as well as mask it.

Not sure if the difference between the xxx_UNC and xxx_RES
bits though.

	David



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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2012-01-11  9:00                                                                                 ` Wolfgang Zarre
  2012-01-11  9:37                                                                                   ` David Laight
@ 2012-01-11  9:38                                                                                   ` Marc Kleine-Budde
  2012-01-11 14:42                                                                                     ` Wolfgang Zarre
  1 sibling, 1 reply; 66+ messages in thread
From: Marc Kleine-Budde @ 2012-01-11  9:38 UTC (permalink / raw)
  To: info
  Cc: Wolfgang Grandegger, David Laight, Oliver Hartkopp, henrik,
	netdev, linux-can, socketcan-users, IreneV, Stanislav Yelenskiy,
	oe, henrik

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

Hello,

On 01/11/2012 10:00 AM, Wolfgang Zarre wrote:
>>> Please provide an extra patch for these unrelated changes. If we really
>>> want to remove it.
>>>
>>
>> Sure, this I can do.
>>
> 
> Ok, here the patch to remove:

Looks good, please add a patch description and put in a patch series
together with the spinlock patch (see other mail).

Marc

> --------------------------------------------------------
> diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c
> index 2d12f89..dad6707 100644
> --- a/drivers/net/can/cc770/cc770.c
> +++ b/drivers/net/can/cc770/cc770.c
> @@ -460,15 +460,6 @@ static netdev_tx_t cc770_start_xmit(struct sk_buff
> *skb, struct net_device *dev)
> 
>      stats->tx_bytes += dlc;
> 
> -
> -    /*
> -     * HM: We had some cases of repeated IRQs so make sure the
> -     * INT is acknowledged I know it's already further up, but
> -     * doing again fixed the issue
> -     */
> -    cc770_write_reg(priv, msgobj[mo].ctrl0,
> -            MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);
> -
>      return NETDEV_TX_OK;
>  }
> 
> @@ -689,12 +680,6 @@ static void cc770_tx_interrupt(struct net_device
> *dev, unsigned int o)
>      /* Nothing more to send, switch off interrupts */
>      cc770_write_reg(priv, msgobj[mo].ctrl0,
>              MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES);
> -    /*
> -     * We had some cases of repeated IRQ so make sure the
> -     * INT is acknowledged
> -     */
> -    cc770_write_reg(priv, msgobj[mo].ctrl0,
> -            MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);
> 
>      stats->tx_packets++;
>      can_get_echo_skb(dev, 0);
> ----------------------------------------------------------

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: 262 bytes --]

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2012-01-11  9:37                                                                                   ` David Laight
@ 2012-01-11 14:37                                                                                     ` Wolfgang Zarre
  0 siblings, 0 replies; 66+ messages in thread
From: Wolfgang Zarre @ 2012-01-11 14:37 UTC (permalink / raw)
  To: David Laight, Wolfgang Grandegger
  Cc: Marc Kleine-Budde, Oliver Hartkopp, henrik, netdev, linux-can,
	socketcan-users, IreneV, Stanislav Yelenskiy, oe, henrik

Hello David,

>
>> @@ -689,12 +680,6 @@ static void cc770_tx_interrupt(struct
>> net_device *dev, unsigned int o)
>>    	/* Nothing more to send, switch off interrupts */
>>    	cc770_write_reg(priv, msgobj[mo].ctrl0,
>>    			MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES);
>> -	/*
>> -	 * We had some cases of repeated IRQ so make sure the
>> -	 * INT is acknowledged
>> -	 */
>> -	cc770_write_reg(priv, msgobj[mo].ctrl0,
>> -			MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);
>
> A wild guess is that this is needed to clear an interrupt
> that was asserted during the ISR processing.
> So you need to ack the IRQ as well as mask it.

I was digging a bit and as far as I understood by studying both
manuals of i82527 and cc770 the procedure is in any case most
probably not completely clean.

 From my point of view there would be no need to set and reset
TXIE/RXIE after every request because according to the description
as below (e.g for TXIE):


       MSB LSB    Meaning
Write  0   0  Not allowed
               (indeterminate)
        0   1  reset
        1   0  set
        1   1  unchanged



TXIE Transmit Interrupt Enable
  one  An interrupt will be generated after a successful
       transmission of a frame
  zero No interrupt will be generated after a successful
       transmission of a frame
       The Transmit Interrupt Enable bit enables the
       82527 to initiate an interrupt after the successful
       transmission by the corresponding message
       object This bit is written by the CPU

In fact with that we are telling the chip if we want to have
interrupts or not for a transmission and therefore it would
be enough, so far I understood, to set it at _init and switch
it of at _deinit and between just using 'unchanged'.

Actually to ack the IRQ we would have to set TXOK of the
status register to zero after reading a one for a successful
transmission but is in fact the chip doesn't care if we
reset TXOK or not.

However, if time permits I'll try to dig deeper and doing some
tests because it would need some changes more.


Anyway, I might be wrong as well because sometimes I'm checking
under heavy workload the wrong bit's as You know already ;-)


More or less the reason for the request of removal was just because
assuming that the repeated interrupts were caused as well not having
spinlock's and on the other hand if obsolete to save I/O resources
which affects mostly smaller systems with heavy load.

However, maybe Wolfgang can give an advice.


>
> Not sure if the difference between the xxx_UNC and xxx_RES
> bits though.
>
> 	David
>
>
Wolfgang

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2012-01-11  9:38                                                                                   ` Marc Kleine-Budde
@ 2012-01-11 14:42                                                                                     ` Wolfgang Zarre
  2012-01-11 15:02                                                                                       ` Marc Kleine-Budde
  0 siblings, 1 reply; 66+ messages in thread
From: Wolfgang Zarre @ 2012-01-11 14:42 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: Wolfgang Grandegger, David Laight, Oliver Hartkopp, henrik,
	netdev, linux-can, socketcan-users, IreneV, Stanislav Yelenskiy,
	oe, henrik

Hello Marc,

> Hello,
>
> On 01/11/2012 10:00 AM, Wolfgang Zarre wrote:
>>>> Please provide an extra patch for these unrelated changes. If we really
>>>> want to remove it.
>>>>
>>>
>>> Sure, this I can do.
>>>
>>
>> Ok, here the patch to remove:
>
> Looks good, please add a patch description and put in a patch series
> together with the spinlock patch (see other mail).

Thanks, also for the additional hints.

It might be that I let this patch for now until clarified if we
should remove or not.

>
> Marc
>
>> --------------------------------------------------------
>> diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c
>> index 2d12f89..dad6707 100644
>> --- a/drivers/net/can/cc770/cc770.c
>> +++ b/drivers/net/can/cc770/cc770.c
>> @@ -460,15 +460,6 @@ static netdev_tx_t cc770_start_xmit(struct sk_buff
>> *skb, struct net_device *dev)
>>
>>       stats->tx_bytes += dlc;
>>
>> -
>> -    /*
>> -     * HM: We had some cases of repeated IRQs so make sure the
>> -     * INT is acknowledged I know it's already further up, but
>> -     * doing again fixed the issue
>> -     */
>> -    cc770_write_reg(priv, msgobj[mo].ctrl0,
>> -            MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);
>> -
>>       return NETDEV_TX_OK;
>>   }
>>
>> @@ -689,12 +680,6 @@ static void cc770_tx_interrupt(struct net_device
>> *dev, unsigned int o)
>>       /* Nothing more to send, switch off interrupts */
>>       cc770_write_reg(priv, msgobj[mo].ctrl0,
>>               MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES);
>> -    /*
>> -     * We had some cases of repeated IRQ so make sure the
>> -     * INT is acknowledged
>> -     */
>> -    cc770_write_reg(priv, msgobj[mo].ctrl0,
>> -            MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);
>>
>>       stats->tx_packets++;
>>       can_get_echo_skb(dev, 0);
>> ----------------------------------------------------------
>
> Marc
>

Wolfgang

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

* Re: [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527
  2012-01-11 14:42                                                                                     ` Wolfgang Zarre
@ 2012-01-11 15:02                                                                                       ` Marc Kleine-Budde
  0 siblings, 0 replies; 66+ messages in thread
From: Marc Kleine-Budde @ 2012-01-11 15:02 UTC (permalink / raw)
  To: info
  Cc: Wolfgang Grandegger, David Laight, Oliver Hartkopp, henrik,
	netdev, linux-can, socketcan-users, IreneV, Stanislav Yelenskiy,
	oe, henrik

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

On 01/11/2012 03:42 PM, Wolfgang Zarre wrote:
> Thanks, also for the additional hints.

You're welcome.

> It might be that I let this patch for now until clarified if we
> should remove or not.

Yes, the just prepare the spinlock patch.

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: 262 bytes --]

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

end of thread, other threads:[~2012-01-11 15:02 UTC | newest]

Thread overview: 66+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-11-25  9:43 [PATCH net-next v2 0/4] can: cc770: add support for the Bosch CC770 and Intel AN82527 Wolfgang Grandegger
2011-11-25  9:43 ` [PATCH net-next v2 1/4] can: cc770: add driver core " Wolfgang Grandegger
     [not found]   ` <1322214204-1121-2-git-send-email-wg-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
2011-11-26 15:11     ` Oliver Hartkopp
2011-11-28 11:28   ` [Socketcan-users] " Marc Kleine-Budde
2011-11-28 13:52     ` Wolfgang Grandegger
     [not found]       ` <4ED3922A.50704-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
2011-11-28 14:01         ` Marc Kleine-Budde
2011-11-28 14:01           ` [Socketcan-users] " David Laight
     [not found]           ` <4ED3941D.3070302-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
2011-11-28 14:10             ` Wolfgang Grandegger
     [not found]               ` <4ED3966E.7080609-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
2011-11-28 14:18                 ` Marc Kleine-Budde
     [not found]     ` <4ED3704D.5020903-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
2011-11-29  9:20       ` Wolfgang Grandegger
2011-11-25  9:43 ` [PATCH net-next v2 2/4] can: cc770: add legacy ISA bus driver for the CC770 and AN82527 Wolfgang Grandegger
     [not found]   ` <1322214204-1121-3-git-send-email-wg-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
2011-11-26 14:59     ` Oliver Hartkopp
2011-11-28  8:56       ` Wolfgang Zarre
2011-11-28  9:17         ` Wolfgang Grandegger
2011-11-28 12:03           ` Wolfgang Zarre
     [not found]             ` <4ED37885.8080909-PyqsHJVlJN8AvxtiuMwx3w@public.gmane.org>
2011-11-28 16:06               ` Oliver Hartkopp
     [not found]                 ` <4ED3B198.2040308-fJ+pQTUTwRTk1uMJSBkQmQ@public.gmane.org>
2011-11-29  9:16                   ` Wolfgang Grandegger
     [not found]                     ` <4ED4A2EC.40103-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
2011-12-04 18:47                       ` Wolfgang Zarre
2011-12-04 18:56                         ` Wolfgang Grandegger
     [not found]                           ` <4EDBC25D.50405-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
2011-12-06 21:08                             ` Wolfgang Zarre
     [not found]                               ` <4EDE8435.5080100-PyqsHJVlJN8AvxtiuMwx3w@public.gmane.org>
2011-12-07 13:42                                 ` Wolfgang Grandegger
2011-12-09 10:26                                   ` Wolfgang Grandegger
2011-12-11 18:33                                     ` Wolfgang Zarre
     [not found]                                       ` <4EE4F76E.3000506-PyqsHJVlJN8AvxtiuMwx3w@public.gmane.org>
2011-12-12  9:23                                         ` Wolfgang Grandegger
     [not found]                                           ` <4EE5C824.2050704-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
2011-12-12 11:18                                             ` Wolfgang Zarre
2011-12-12 11:55                                               ` Wolfgang Grandegger
     [not found]                                                 ` <4EE5EBBF.6080007-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
2011-12-21 18:32                                                   ` Wolfgang Zarre
2011-12-22  9:37                                                     ` Wolfgang Grandegger
     [not found]                                                       ` <4EF2FA3F.3010308-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
2011-12-22 13:20                                                         ` Wolfgang Zarre
     [not found]                                                           ` <4EF32E84.1080006-PyqsHJVlJN8AvxtiuMwx3w@public.gmane.org>
2011-12-31  9:39                                                             ` Wolfgang Zarre
2012-01-04 13:10                                                               ` Wolfgang Grandegger
2012-01-05  3:29                                                                 ` Wolfgang Zarre
     [not found]                                                                   ` <4F051927.8010600-PyqsHJVlJN8AvxtiuMwx3w@public.gmane.org>
2012-01-05 11:51                                                                     ` Wolfgang Grandegger
2012-01-05 12:00                                                                       ` David Laight
2012-01-09 21:47                                                                         ` Wolfgang Zarre
2012-01-09 23:11                                                                           ` Marc Kleine-Budde
2012-01-10  9:30                                                                             ` Wolfgang Grandegger
2012-01-10 12:30                                                                               ` Wolfgang Zarre
2012-01-10 14:20                                                                                 ` Wolfgang Grandegger
2012-01-10 14:25                                                                                   ` Wolfgang Grandegger
2012-01-11  9:00                                                                                 ` Wolfgang Zarre
2012-01-11  9:37                                                                                   ` David Laight
2012-01-11 14:37                                                                                     ` Wolfgang Zarre
2012-01-11  9:38                                                                                   ` Marc Kleine-Budde
2012-01-11 14:42                                                                                     ` Wolfgang Zarre
2012-01-11 15:02                                                                                       ` Marc Kleine-Budde
2012-01-10 10:00                                                                           ` David Laight
2012-01-10 12:41                                                                             ` Wolfgang Zarre
2012-01-10 14:43                                                                               ` Wolfgang Grandegger
2012-01-10 14:50                                                                                 ` Oliver Hartkopp
2012-01-10 16:13                                                                                 ` Wolfgang Zarre
2012-01-10 16:20                                                                                   ` Marc Kleine-Budde
2012-01-10 16:23                                                                                   ` Wolfgang Grandegger
2012-01-10 19:02                                                                                     ` Wolfgang Zarre
2012-01-11  9:05                                                                                       ` Wolfgang Zarre
2012-01-11  9:31                                                                                         ` Marc Kleine-Budde
2012-01-10 11:41                                                                           ` Henrik Maier
2012-01-10 11:59                                                                             ` Wolfgang Grandegger
2012-01-10 12:43                                                                               ` Wolfgang Zarre
2011-11-28 12:09   ` Marc Kleine-Budde
     [not found]     ` <4ED379F3.1070206-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
2011-11-28 13:59       ` Wolfgang Grandegger
2011-11-28 14:03         ` David Laight
     [not found]           ` <AE90C24D6B3A694183C094C60CF0A2F6D8AEE9-CgBM+Bx2aUAnGFn1LkZF6NBPR1lH4CV8@public.gmane.org>
2011-11-28 14:09             ` Marc Kleine-Budde
     [not found]               ` <4ED3960F.4040508-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
2011-11-28 15:10                 ` Wolfgang Grandegger
2011-11-25  9:43 ` [PATCH net-next v2 3/4] can: cc770: add platform " Wolfgang Grandegger
2011-11-25  9:43 ` [PATCH net-next v2 4/4] powerpc: tqm8548/tqm8xx: add and update CAN device nodes Wolfgang Grandegger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).