Allow state to decrease bus-off->passive->warning->active.
Use the common function can_chage_state().

Here is an example output of "candump -candump -td -e any,0:0,#FFFFFFFF"
for a recovery from error passive state due to no ack/cable (reconnect
after 5s) for an Intel 82527 on a TQM855L board:

 (000.200637)  can0   58  [4] 51 C0 12 C4
 (000.202869)  can0  20000224  [8] 00 0C 00 00 00 00 00 00   ERRORFRAME
        controller-problem{rx-error-warning,tx-error-warning}
        no-acknowledgement-on-tx
        state-change{rx-error-warning,tx-error-warning}
 (004.928599)  can0   59  [8] 50 69 F9 1F 6A 88 4B 3A
 (000.000429)  can0   5A  [8] 29 1C 44 49 06 8C F8 07
 ...
 (000.200789)  can0   8A  [8] 38 6B F1 09 0B A2 6D 80
 (000.200831)  can0  20000200  [8] 00 40 00 00 00 00 00 00   ERRORFRAME
        state-change{back-to-error-active}
 (000.000021)  can0   8B  [7] 4B 9A 8A E7 5B C5 CD

The Intel 82527 does not report state changes to error passive.

Signed-off-by: Wolfgang Grandegger <[email protected]>
---
 drivers/net/can/cc770/cc770.c |   37 ++++++++++++-------------------------
 1 files changed, 12 insertions(+), 25 deletions(-)

diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c
index 7668967..905a3ca 100644
--- a/drivers/net/can/cc770/cc770.c
+++ b/drivers/net/can/cc770/cc770.c
@@ -349,8 +349,8 @@ static int cc770_set_mode(struct net_device *dev, enum 
can_mode mode)
 {
        switch (mode) {
        case CAN_MODE_START:
-               cc770_start(dev);
                netif_wake_queue(dev);
+               cc770_start(dev);
                break;
 
        default:
@@ -513,6 +513,7 @@ static int cc770_err(struct net_device *dev, u8 status)
 {
        struct cc770_priv *priv = netdev_priv(dev);
        struct net_device_stats *stats = &dev->stats;
+       enum can_state new_state;
        struct can_frame *cf;
        struct sk_buff *skb;
        u8 lec;
@@ -523,38 +524,25 @@ static int cc770_err(struct net_device *dev, u8 status)
        if (!skb)
                return -ENOMEM;
 
-       /* Use extended functions of the CC770 */
-       if (priv->control_normal_mode & CTRL_EAF) {
-               cf->data[6] = cc770_read_reg(priv, tx_error_counter);
-               cf->data[7] = cc770_read_reg(priv, rx_error_counter);
-       }
-
+       /* Handle state changes */
        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;
+               new_state = CAN_STATE_BUS_OFF;
                can_bus_off(dev);
        } else if (status & STAT_WARN) {
-               cf->can_id |= CAN_ERR_CRTL;
                /* Only the CC770 does show error passive */
-               if (cf->data[7] > 127) {
-                       cf->data[1] = CAN_ERR_CRTL_RX_PASSIVE |
-                               CAN_ERR_CRTL_TX_PASSIVE;
-                       priv->can.state = CAN_STATE_ERROR_PASSIVE;
-                       priv->can.can_stats.error_passive++;
-               } else {
-                       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++;
-               }
+               if (priv->control_normal_mode & CTRL_EAF &&
+                   cc770_read_reg(priv, rx_error_counter) > 127)
+                       new_state = CAN_STATE_ERROR_PASSIVE;
+               else
+                       new_state = CAN_STATE_ERROR_WARNING;
        } else {
                /* Back to error avtive */
-               cf->can_id |= CAN_ERR_PROT;
-               cf->data[2] = CAN_ERR_PROT_ACTIVE;
-               priv->can.state = CAN_STATE_ERROR_ACTIVE;
+               new_state = CAN_STATE_ERROR_ACTIVE;
        }
+       if (new_state != priv->can.state)
+               can_change_state(dev, cf, new_state, CAN_ERR_DIR_UNKNOWN);
 
        lec = status & STAT_LEC_MASK;
        if (lec < 7 && lec > 0) {
@@ -770,7 +758,6 @@ static int cc770_open(struct net_device *dev)
        cc770_start(dev);
 
        netif_start_queue(dev);
-
        return 0;
 }
 
-- 
1.7.4.1

_______________________________________________
Socketcan-users mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/socketcan-users

Reply via email to