}
 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)
 {
 
 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);