Kurt Van Dijck wrote: > On Fri, Feb 05, 2010 at 11:44:42AM +0100, Wolfgang Grandegger wrote: >> Oliver Hartkopp wrote: >>> christian pellegrin wrote: >>>> On Fri, Feb 5, 2010 at 10:05 AM, Kurt Van Dijck <[email protected]> >>>> wrote: >>>> >>>>> I never enabled the bus-error interrupts anywhere embedded. >>>>> To research odd behaviour, the error counters were helpfull, >>>> I like this idea much. I speak from a point of view of meanness ;-) : >>>> we have paid the chip manufacturer for the REC and TEC counters that >>>> are cleverly incremented and decremented (AFAIK it's more likely they >>>> are incremented that decremented, so there is always a window in which >>>> the user space application can catch an increase in them even if not >>>> polling at an excessive rate) by the controller itself so they could >>>> be easily exported to user space. Perhaps all we need is a function >>>> for this in can_priv such do_get_err_counters. Even better if these >>>> counters are exported via sysfs so the function above is guaranteed to >>>> be called in non-atomic context. >>>> >>> Trying to summarize these points, what about this: >>> >>> 1. We disable bus-error interrupts by default >> Fine for me, even if that changes the current behavior. > Ack >>> 2. They can be enabled via netlink >> Yep. > Ack >>> 3. Once they are enabled we send the (unified) rx/tx error counters inside >>> the >>> currently reserved bytes of the CAN error frame to the userspace. >> The problem is that some CAN controllers do not allow to read these >> counters while it's active. But in general we could add the rx/txerr to >> any error message, if possible. The information in the error message is >> hardware dependent anyway. > Ack >>> Would this meet the requirements in production-use and development-use ?? > Yes, for me, this would meet the requirements.
OK, the preliminary patch for SVN below implements this solution and shows what we are speaking about. As a nice side effect, it also allows to check if the device supports bus-error reporting. Marc, could you please check the at91_can modifications? Wolfgang. [PATCH/RFC] make bus-error generation configurable via netlink interface By default, bus-error generation is *disabled* and it can be enabled with: "ip link set can0 up type can bitrate 500000 bus-error 1". Signed-off-by: Wolfgang Grandegger <[email protected]> --- drivers/net/can/at91_can.c | 5 ++++- drivers/net/can/sja1000/sja1000.c | 11 ++++++++--- include/socketcan/can/netlink.h | 9 +++++---- 3 files changed, 17 insertions(+), 8 deletions(-) Index: 2.6/include/socketcan/can/netlink.h =================================================================== --- 2.6.orig/include/socketcan/can/netlink.h +++ 2.6/include/socketcan/can/netlink.h @@ -79,10 +79,11 @@ struct can_ctrlmode { __u32 flags; }; -#define CAN_CTRLMODE_LOOPBACK 0x1 /* Loopback mode */ -#define CAN_CTRLMODE_LISTENONLY 0x2 /* Listen-only mode */ -#define CAN_CTRLMODE_3_SAMPLES 0x4 /* Triple sampling mode */ -#define CAN_CTRLMODE_ONE_SHOT 0x8 /* One-Shot mode */ +#define CAN_CTRLMODE_LOOPBACK 0x01 /* Loopback mode */ +#define CAN_CTRLMODE_LISTENONLY 0x02 /* Listen-only mode */ +#define CAN_CTRLMODE_3_SAMPLES 0x04 /* Triple sampling mode */ +#define CAN_CTRLMODE_ONE_SHOT 0x08 /* One-Shot mode */ +#define CAN_CTRLMODE_BUS_ERROR 0x10 /* Bus-error support mode */ /* * CAN device statistics Index: 2.6/drivers/net/can/at91_can.c =================================================================== --- 2.6.orig/drivers/net/can/at91_can.c +++ 2.6/drivers/net/can/at91_can.c @@ -292,6 +292,8 @@ static void at91_chip_start(struct net_d /* Enable interrupts */ reg_ier = AT91_IRQ_MB_RX | AT91_IRQ_ERRP | AT91_IRQ_ERR_FRAME; + if (!(priv->can.ctrlmode & CAN_CTRLMODE_BUS_ERROR)) + reg_ier &= ~AT91_IRQ_BERR; at91_write(priv, AT91_IDR, AT91_IRQ_ALL); at91_write(priv, AT91_IER, reg_ier); } @@ -1094,7 +1096,8 @@ static int __init at91_can_probe(struct priv->can.bittiming_const = &at91_bittiming_const; priv->can.do_set_bittiming = at91_set_bittiming; priv->can.do_set_mode = at91_set_mode; - priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; + priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES | + CAN_CTRLMODE_BUS_ERROR; priv->reg_base = addr; priv->dev = dev; priv->clk = clk; Index: 2.6/drivers/net/can/sja1000/sja1000.c =================================================================== --- 2.6.orig/drivers/net/can/sja1000/sja1000.c +++ 2.6/drivers/net/can/sja1000/sja1000.c @@ -133,9 +133,13 @@ static void set_normal_mode(struct net_d for (i = 0; i < 100; i++) { /* check reset bit */ if ((status & MOD_RM) == 0) { + u8 reg_ier = IRQ_ALL; + + if (!(priv->can.ctrlmode & CAN_CTRLMODE_BUS_ERROR)) + reg_ier &= ~IRQ_BEI; priv->can.state = CAN_STATE_ERROR_ACTIVE; - /* enable all interrupts */ - priv->write_reg(priv, REG_IER, IRQ_ALL); + /* enable interrupts */ + priv->write_reg(priv, REG_IER, reg_ier); return; } @@ -602,7 +606,8 @@ struct net_device *alloc_sja1000dev(int priv->can.bittiming_const = &sja1000_bittiming_const; priv->can.do_set_bittiming = sja1000_set_bittiming; priv->can.do_set_mode = sja1000_set_mode; - priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; + priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES | + CAN_CTRLMODE_BUS_ERROR; if (sizeof_priv) priv->priv = (void *)priv + sizeof(struct sja1000_priv); _______________________________________________ Socketcan-users mailing list [email protected] https://lists.berlios.de/mailman/listinfo/socketcan-users
