can: sja1000: Consolidate and unify state change handling
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>
This commit is contained in:
parent
bac78aabcf
commit
215db1856e
|
@ -392,12 +392,20 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
|
||||||
struct can_frame *cf;
|
struct can_frame *cf;
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
enum can_state state = priv->can.state;
|
enum can_state state = priv->can.state;
|
||||||
|
enum can_state rx_state, tx_state;
|
||||||
|
unsigned int rxerr, txerr;
|
||||||
uint8_t ecc, alc;
|
uint8_t ecc, alc;
|
||||||
|
|
||||||
skb = alloc_can_err_skb(dev, &cf);
|
skb = alloc_can_err_skb(dev, &cf);
|
||||||
if (skb == NULL)
|
if (skb == NULL)
|
||||||
return -ENOMEM;
|
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) {
|
if (isrc & IRQ_DOI) {
|
||||||
/* data overrun interrupt */
|
/* data overrun interrupt */
|
||||||
netdev_dbg(dev, "data overrun interrupt\n");
|
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 */
|
/* error warning interrupt */
|
||||||
netdev_dbg(dev, "error warning interrupt\n");
|
netdev_dbg(dev, "error warning interrupt\n");
|
||||||
|
|
||||||
if (status & SR_BS) {
|
if (status & SR_BS)
|
||||||
state = CAN_STATE_BUS_OFF;
|
state = CAN_STATE_BUS_OFF;
|
||||||
cf->can_id |= CAN_ERR_BUSOFF;
|
else if (status & SR_ES)
|
||||||
can_bus_off(dev);
|
|
||||||
} else if (status & SR_ES) {
|
|
||||||
state = CAN_STATE_ERROR_WARNING;
|
state = CAN_STATE_ERROR_WARNING;
|
||||||
} else
|
else
|
||||||
state = CAN_STATE_ERROR_ACTIVE;
|
state = CAN_STATE_ERROR_ACTIVE;
|
||||||
}
|
}
|
||||||
if (isrc & IRQ_BEI) {
|
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) {
|
if (isrc & IRQ_EPI) {
|
||||||
/* error passive interrupt */
|
/* error passive interrupt */
|
||||||
netdev_dbg(dev, "error passive interrupt\n");
|
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
|
else
|
||||||
state = CAN_STATE_ERROR_ACTIVE;
|
state = CAN_STATE_ERROR_PASSIVE;
|
||||||
}
|
}
|
||||||
if (isrc & IRQ_ALI) {
|
if (isrc & IRQ_ALI) {
|
||||||
/* arbitration lost interrupt */
|
/* 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;
|
cf->data[0] = alc & 0x1f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state != priv->can.state && (state == CAN_STATE_ERROR_WARNING ||
|
if (state != priv->can.state) {
|
||||||
state == CAN_STATE_ERROR_PASSIVE)) {
|
tx_state = txerr >= rxerr ? state : 0;
|
||||||
uint8_t rxerr = priv->read_reg(priv, SJA1000_RXERR);
|
rx_state = txerr <= rxerr ? state : 0;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
netif_rx(skb);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue