aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/can
diff options
context:
space:
mode:
authorAnssi Hannula <anssi.hannula@bitwise.fi>2018-01-29 17:28:24 +0200
committerMarc Kleine-Budde <mkl@pengutronix.de>2018-07-27 10:40:17 +0200
commit6181dbc02b6c73fd2e07d06bb8766867bb96ebbe (patch)
tree4f70f5427bcd94b196f93ae9d6de9dd1ace48777 /drivers/net/can
parentcan: xilinx_can: only report warning and passive states on state changes (diff)
downloadlinux-dev-6181dbc02b6c73fd2e07d06bb8766867bb96ebbe.tar.xz
linux-dev-6181dbc02b6c73fd2e07d06bb8766867bb96ebbe.zip
can: xilinx_can: use can_change_state()
Replace some custom code with a call to can_change_state(). This subtly changes the error reporting behavior when both RX and TX error counters indicate the same state. Previously, if both RX and TX counters indicated the same state: - if overall state is PASSIVE, report CAN_ERR_CRTL_RX_PASSIVE - if overall state is WARNING, report CAN_ERR_CRTL_TX_WARNING or CAN_ERR_CRTL_RX_WARNING depending on which counter is higher, or CAN_ERR_CRTL_RX_WARNING if the counters have the same value. After this commit: - report RX_* or TX_* depending on which counter is higher, or both if the counters have exactly the same value. This behavior is consistent with many other CAN drivers that use this same code pattern. Tested with the integrated CAN on Zynq-7000 SoC. v2: Simplify resolving states as suggested by Andri Yngvason. Signed-off-by: Anssi Hannula <anssi.hannula@bitwise.fi> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Diffstat (limited to 'drivers/net/can')
-rw-r--r--drivers/net/can/xilinx_can.c34
1 files changed, 7 insertions, 27 deletions
diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c
index 32e49acd4ebd..c7e5373a8f3c 100644
--- a/drivers/net/can/xilinx_can.c
+++ b/drivers/net/can/xilinx_can.c
@@ -594,39 +594,19 @@ static void xcan_set_error_state(struct net_device *ndev,
u32 ecr = priv->read_reg(priv, XCAN_ECR_OFFSET);
u32 txerr = ecr & XCAN_ECR_TEC_MASK;
u32 rxerr = (ecr & XCAN_ECR_REC_MASK) >> XCAN_ESR_REC_SHIFT;
+ enum can_state tx_state = txerr >= rxerr ? new_state : 0;
+ enum can_state rx_state = txerr <= rxerr ? new_state : 0;
- priv->can.state = new_state;
+ /* non-ERROR states are handled elsewhere */
+ if (WARN_ON(new_state > CAN_STATE_ERROR_PASSIVE))
+ return;
+
+ can_change_state(ndev, cf, tx_state, rx_state);
if (cf) {
- cf->can_id |= CAN_ERR_CRTL;
cf->data[6] = txerr;
cf->data[7] = rxerr;
}
-
- switch (new_state) {
- case CAN_STATE_ERROR_PASSIVE:
- priv->can.can_stats.error_passive++;
- if (cf)
- cf->data[1] = (rxerr > 127) ?
- CAN_ERR_CRTL_RX_PASSIVE :
- CAN_ERR_CRTL_TX_PASSIVE;
- break;
- case CAN_STATE_ERROR_WARNING:
- priv->can.can_stats.error_warning++;
- if (cf)
- cf->data[1] |= (txerr > rxerr) ?
- CAN_ERR_CRTL_TX_WARNING :
- CAN_ERR_CRTL_RX_WARNING;
- break;
- case CAN_STATE_ERROR_ACTIVE:
- if (cf)
- cf->data[1] |= CAN_ERR_CRTL_ACTIVE;
- break;
- default:
- /* non-ERROR states are handled elsewhere */
- WARN_ON(1);
- break;
- }
}
/**