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

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.de


Signed-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parents 2f0382a7 137f59d5
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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.
+398 −586

File changed.

Preview size limit exceeded, changes collapsed.

+22 −0
Original line number Diff line number Diff line
@@ -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)
{
+4 −0
Original line number Diff line number Diff line
@@ -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);