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

Reply via email to