Commit 215db185 authored by Andri Yngvason's avatar Andri Yngvason Committed by Marc Kleine-Budde

can: sja1000: Consolidate and unify state change handling

Replacing error state change handling with the new mechanism.
Signed-off-by: default avatarAndri Yngvason <andri.yngvason@marel.com>
Acked-by: default avatarWolfgang Grandegger <wg@grandegger.com>
Signed-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parent bac78aab
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment