summaryrefslogtreecommitdiffstats
path: root/drivers/net/can/dev
diff options
context:
space:
mode:
authorMarc Kleine-Budde <mkl@pengutronix.de>2023-09-28 09:24:28 +0200
committerMarc Kleine-Budde <mkl@pengutronix.de>2023-10-05 21:44:48 +0200
commit9beebc2b5d0038a65977a7a14909598c64ce070f (patch)
treebf196909d99bd5bfc45327af664101263046a7ac /drivers/net/can/dev
parent2f0382a7590ed65ef6a4336aace0f30814e24dc1 (diff)
downloadlinux-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.c22
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)
{