Commit bf176313 authored by Marc Kleine-Budde's avatar Marc Kleine-Budde

Merge patch series "can: at91: add can_state_get_by_berr_counter() helper,...

Merge patch series "can: at91: add can_state_get_by_berr_counter() helper, cleanup and convert to rx_offload"

Marc Kleine-Budde <mkl@pengutronix.de> says:

This series first introduces the can_state_get_by_berr_counter()
helper function. It returns the current TX and RX state depending on
the provided CAN bit error counters. It will be later used by the
at91_can driver.

The remaining patches of this series first clean up the at91_can
driver, clean up the bus- and line error (including bus-off) handling,
and then convert it use the rx_offload helper. The driver works better
under high system load and the order of received CAN frames is better
maintained.

Due to a hardware limitation the converted driver could trigger a race
condition in the can_restart() CAN bus-off handler. The patch series
[1] fixes the issue.

[1] https://lore.kernel.org/all/20231005-can-dev-fix-can-restart-v2-0-91b5c1fd922c@pengutronix.de

Changes in v2:
- 1/27: can_state_err_to_state(): use symbolic error values instead of
  plain numbers (Thanks Vincent)
- 27/27: fix patch description and typos (Thanks Vincent)
- Link to v1: https://lore.kernel.org/all/20231004-at91_can-rx_offload-v1-0-c32bf99097db@pengutronix.de

Link: https://lore.kernel.org/all/20231005-at91_can-rx_offload-v2-0-9987d53600e0@pengutronix.deSigned-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parents 2f0382a7 137f59d5
......@@ -89,6 +89,7 @@ config CAN_RX_OFFLOAD
config CAN_AT91
tristate "Atmel AT91 onchip CAN controller"
depends on (ARCH_AT91 || COMPILE_TEST) && HAS_IOMEM
select CAN_RX_OFFLOAD
help
This is a driver for the SoC CAN controller in Atmel's AT91SAM9263
and AT91SAM9X5 processors.
......
This diff is collapsed.
......@@ -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)
{
......
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment