]> git.itanic.dy.fi Git - linux-stable/commitdiff
can: dev: add can_state_get_by_berr_counter() to return the CAN state based on the...
authorMarc Kleine-Budde <mkl@pengutronix.de>
Thu, 28 Sep 2023 07:24:28 +0000 (09:24 +0200)
committerMarc Kleine-Budde <mkl@pengutronix.de>
Thu, 5 Oct 2023 19:44:48 +0000 (21:44 +0200)
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>
drivers/net/can/dev/dev.c
include/linux/can/dev.h

index 82b12902fc355c67df2dab303a322232fde3fa73..3a3be5cdfc1f8da5c98017e1e5dd92f4591d85f9 100644 (file)
@@ -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)
 {
index 982ba245eb41ce701f529a4fa0fd95ec85da914a..1b92aed4936325121d6c1ee2836572d9cfc06685 100644 (file)
@@ -195,6 +195,10 @@ int can_restart_now(struct net_device *dev);
 void can_bus_off(struct net_device *dev);
 
 const char *can_get_state_str(const enum can_state state);
+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);
 void can_change_state(struct net_device *dev, struct can_frame *cf,
                      enum can_state tx_state, enum can_state rx_state);