Commit 6f12001a authored by Jeroen Hofstee's avatar Jeroen Hofstee Committed by Marc Kleine-Budde

can: c_can: C_CAN: add bus recovery events

While the state is updated when the error counters increase and
decrease, there is no event when the bus recovers and the error counters
decrease again. So add that event as well.

Change the state going downward to be ERROR_PASSIVE -> ERROR_WARNING ->
ERROR_ACTIVE instead of directly to ERROR_ACTIVE again.
Signed-off-by: default avatarJeroen Hofstee <jhofstee@victronenergy.com>
Acked-by: default avatarKurt Van Dijck <dev.kurt@vandijck-laurijssen.be>
Tested-by: default avatarKurt Van Dijck <dev.kurt@vandijck-laurijssen.be>
Signed-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parent 23c5a948
...@@ -915,6 +915,9 @@ static int c_can_handle_state_change(struct net_device *dev, ...@@ -915,6 +915,9 @@ static int c_can_handle_state_change(struct net_device *dev,
struct can_berr_counter bec; struct can_berr_counter bec;
switch (error_type) { switch (error_type) {
case C_CAN_NO_ERROR:
priv->can.state = CAN_STATE_ERROR_ACTIVE;
break;
case C_CAN_ERROR_WARNING: case C_CAN_ERROR_WARNING:
/* error warning state */ /* error warning state */
priv->can.can_stats.error_warning++; priv->can.can_stats.error_warning++;
...@@ -945,6 +948,13 @@ static int c_can_handle_state_change(struct net_device *dev, ...@@ -945,6 +948,13 @@ static int c_can_handle_state_change(struct net_device *dev,
ERR_CNT_RP_SHIFT; ERR_CNT_RP_SHIFT;
switch (error_type) { switch (error_type) {
case C_CAN_NO_ERROR:
/* error warning state */
cf->can_id |= CAN_ERR_CRTL;
cf->data[1] = CAN_ERR_CRTL_ACTIVE;
cf->data[6] = bec.txerr;
cf->data[7] = bec.rxerr;
break;
case C_CAN_ERROR_WARNING: case C_CAN_ERROR_WARNING:
/* error warning state */ /* error warning state */
cf->can_id |= CAN_ERR_CRTL; cf->can_id |= CAN_ERR_CRTL;
...@@ -1089,11 +1099,17 @@ static int c_can_poll(struct napi_struct *napi, int quota) ...@@ -1089,11 +1099,17 @@ static int c_can_poll(struct napi_struct *napi, int quota)
/* handle bus recovery events */ /* handle bus recovery events */
if ((!(curr & STATUS_BOFF)) && (last & STATUS_BOFF)) { if ((!(curr & STATUS_BOFF)) && (last & STATUS_BOFF)) {
netdev_dbg(dev, "left bus off state\n"); netdev_dbg(dev, "left bus off state\n");
priv->can.state = CAN_STATE_ERROR_ACTIVE; work_done += c_can_handle_state_change(dev, C_CAN_ERROR_PASSIVE);
} }
if ((!(curr & STATUS_EPASS)) && (last & STATUS_EPASS)) { if ((!(curr & STATUS_EPASS)) && (last & STATUS_EPASS)) {
netdev_dbg(dev, "left error passive state\n"); netdev_dbg(dev, "left error passive state\n");
priv->can.state = CAN_STATE_ERROR_ACTIVE; work_done += c_can_handle_state_change(dev, C_CAN_ERROR_WARNING);
}
if ((!(curr & STATUS_EWARN)) && (last & STATUS_EWARN)) {
netdev_dbg(dev, "left error warning state\n");
work_done += c_can_handle_state_change(dev, C_CAN_NO_ERROR);
} }
/* handle lec errors on the bus */ /* handle lec errors on the bus */
......
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