can: sja1000: Consolidate and unify state change handling
authorAndri Yngvason <andri.yngvason@marel.com>
Wed, 3 Dec 2014 17:54:13 +0000 (17:54 +0000)
committerMarc Kleine-Budde <mkl@pengutronix.de>
Sun, 7 Dec 2014 20:22:09 +0000 (21:22 +0100)
Replacing error state change handling with the new mechanism.

Signed-off-by: Andri Yngvason <andri.yngvason@marel.com>
Acked-by: Wolfgang Grandegger <wg@grandegger.com>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
drivers/net/can/sja1000/sja1000.c

index b27ac60..32bd7f4 100644 (file)
@@ -392,12 +392,20 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
        struct can_frame *cf;
        struct sk_buff *skb;
        enum can_state state = priv->can.state;
+       enum can_state rx_state, tx_state;
+       unsigned int rxerr, txerr;
        uint8_t ecc, alc;
 
        skb = alloc_can_err_skb(dev, &cf);
        if (skb == NULL)
                return -ENOMEM;
 
+       txerr = priv->read_reg(priv, SJA1000_TXERR);
+       rxerr = priv->read_reg(priv, SJA1000_RXERR);
+
+       cf->data[6] = txerr;
+       cf->data[7] = rxerr;
+
        if (isrc & IRQ_DOI) {
                /* data overrun interrupt */
                netdev_dbg(dev, "data overrun interrupt\n");
@@ -412,13 +420,11 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
                /* error warning interrupt */
                netdev_dbg(dev, "error warning interrupt\n");
 
-               if (status & SR_BS) {
+               if (status & SR_BS)
                        state = CAN_STATE_BUS_OFF;
-                       cf->can_id |= CAN_ERR_BUSOFF;
-                       can_bus_off(dev);
-               } else if (status & SR_ES) {
+               else if (status & SR_ES)
                        state = CAN_STATE_ERROR_WARNING;
-               else
+               else
                        state = CAN_STATE_ERROR_ACTIVE;
        }
        if (isrc & IRQ_BEI) {
@@ -452,10 +458,11 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
        if (isrc & IRQ_EPI) {
                /* error passive interrupt */
                netdev_dbg(dev, "error passive interrupt\n");
-               if (status & SR_ES)
-                       state = CAN_STATE_ERROR_PASSIVE;
+
+               if (state == CAN_STATE_ERROR_PASSIVE)
+                       state = CAN_STATE_ERROR_WARNING;
                else
-                       state = CAN_STATE_ERROR_ACTIVE;
+                       state = CAN_STATE_ERROR_PASSIVE;
        }
        if (isrc & IRQ_ALI) {
                /* arbitration lost interrupt */
@@ -467,27 +474,15 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
                cf->data[0] = alc & 0x1f;
        }
 
-       if (state != priv->can.state && (state == CAN_STATE_ERROR_WARNING ||
-                                        state == CAN_STATE_ERROR_PASSIVE)) {
-               uint8_t rxerr = priv->read_reg(priv, SJA1000_RXERR);
-               uint8_t txerr = priv->read_reg(priv, SJA1000_TXERR);
-               cf->can_id |= CAN_ERR_CRTL;
-               if (state == CAN_STATE_ERROR_WARNING) {
-                       priv->can.can_stats.error_warning++;
-                       cf->data[1] = (txerr > rxerr) ?
-                               CAN_ERR_CRTL_TX_WARNING :
-                               CAN_ERR_CRTL_RX_WARNING;
-               } else {
-                       priv->can.can_stats.error_passive++;
-                       cf->data[1] = (txerr > rxerr) ?
-                               CAN_ERR_CRTL_TX_PASSIVE :
-                               CAN_ERR_CRTL_RX_PASSIVE;
-               }
-               cf->data[6] = txerr;
-               cf->data[7] = rxerr;
-       }
+       if (state != priv->can.state) {
+               tx_state = txerr >= rxerr ? state : 0;
+               rx_state = txerr <= rxerr ? state : 0;
 
-       priv->can.state = state;
+               can_change_state(dev, cf, tx_state, rx_state);
+
+               if(state == CAN_STATE_BUS_OFF)
+                       can_bus_off(dev);
+       }
 
        netif_rx(skb);