diff options
author | Marc Kleine-Budde <mkl@pengutronix.de> | 2023-09-28 09:24:28 +0200 |
---|---|---|
committer | Marc Kleine-Budde <mkl@pengutronix.de> | 2023-10-05 21:44:48 +0200 |
commit | 9beebc2b5d0038a65977a7a14909598c64ce070f (patch) | |
tree | bf196909d99bd5bfc45327af664101263046a7ac /drivers/net/can/dev | |
parent | 2f0382a7590ed65ef6a4336aace0f30814e24dc1 (diff) | |
download | linux-9beebc2b5d0038a65977a7a14909598c64ce070f.tar.gz linux-9beebc2b5d0038a65977a7a14909598c64ce070f.tar.bz2 linux-9beebc2b5d0038a65977a7a14909598c64ce070f.zip |
can: dev: add can_state_get_by_berr_counter() to return the CAN state based on the current error counters
Some CAN controllers do not have a register that contains the current
CAN state, but only a register that contains the error counters.
Introduce a new function can_state_get_by_berr_counter() that returns
the current TX and RX state depending on the provided CAN bit error
counters.
Link: https://lore.kernel.org/all/20231005-at91_can-rx_offload-v2-1-9987d53600e0@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Diffstat (limited to 'drivers/net/can/dev')
-rw-r--r-- | drivers/net/can/dev/dev.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c index 82b12902fc35..3a3be5cdfc1f 100644 --- a/drivers/net/can/dev/dev.c +++ b/drivers/net/can/dev/dev.c @@ -90,6 +90,28 @@ const char *can_get_state_str(const enum can_state state) } EXPORT_SYMBOL_GPL(can_get_state_str); +static enum can_state can_state_err_to_state(u16 err) +{ + if (err < CAN_ERROR_WARNING_THRESHOLD) + return CAN_STATE_ERROR_ACTIVE; + if (err < CAN_ERROR_PASSIVE_THRESHOLD) + return CAN_STATE_ERROR_WARNING; + if (err < CAN_BUS_OFF_THRESHOLD) + return CAN_STATE_ERROR_PASSIVE; + + return CAN_STATE_BUS_OFF; +} + +void can_state_get_by_berr_counter(const struct net_device *dev, + const struct can_berr_counter *bec, + enum can_state *tx_state, + enum can_state *rx_state) +{ + *tx_state = can_state_err_to_state(bec->txerr); + *rx_state = can_state_err_to_state(bec->rxerr); +} +EXPORT_SYMBOL_GPL(can_state_get_by_berr_counter); + void can_change_state(struct net_device *dev, struct can_frame *cf, enum can_state tx_state, enum can_state rx_state) { |