diff options
author | Marc Kleine-Budde <mkl@pengutronix.de> | 2022-09-23 14:42:23 +0300 |
---|---|---|
committer | Marc Kleine-Budde <mkl@pengutronix.de> | 2022-09-28 11:34:04 +0300 |
commit | 81d192c2ce74157e717e1fc4b68791f82f7499d4 (patch) | |
tree | 2d0b8ff8cbd043fc2db81c6a64576bdb6b72e153 /drivers/net/can/c_can/c_can.h | |
parent | 44d70bb561dac9363f45787aa93dfca36877ee01 (diff) | |
download | linux-81d192c2ce74157e717e1fc4b68791f82f7499d4.tar.xz |
can: c_can: don't cache TX messages for C_CAN cores
As Jacob noticed, the optimization introduced in 387da6bc7a82 ("can:
c_can: cache frames to operate as a true FIFO") doesn't properly work
on C_CAN, but on D_CAN IP cores. The exact reasons are still unknown.
For now disable caching if CAN frames in the TX path for C_CAN cores.
Fixes: 387da6bc7a82 ("can: c_can: cache frames to operate as a true FIFO")
Link: https://lore.kernel.org/all/20220928083354.1062321-1-mkl@pengutronix.de
Link: https://lore.kernel.org/all/15a8084b-9617-2da1-6704-d7e39d60643b@gmail.com
Reported-by: Jacob Kroon <jacob.kroon@gmail.com>
Tested-by: Jacob Kroon <jacob.kroon@gmail.com>
Cc: stable@vger.kernel.org # v5.15
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Diffstat (limited to 'drivers/net/can/c_can/c_can.h')
-rw-r--r-- | drivers/net/can/c_can/c_can.h | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h index f23a03300a81..029cd8194ed5 100644 --- a/drivers/net/can/c_can/c_can.h +++ b/drivers/net/can/c_can/c_can.h @@ -235,9 +235,22 @@ static inline u8 c_can_get_tx_tail(const struct c_can_tx_ring *ring) return ring->tail & (ring->obj_num - 1); } -static inline u8 c_can_get_tx_free(const struct c_can_tx_ring *ring) +static inline u8 c_can_get_tx_free(const struct c_can_priv *priv, + const struct c_can_tx_ring *ring) { - return ring->obj_num - (ring->head - ring->tail); + u8 head = c_can_get_tx_head(ring); + u8 tail = c_can_get_tx_tail(ring); + + if (priv->type == BOSCH_D_CAN) + return ring->obj_num - (ring->head - ring->tail); + + /* This is not a FIFO. C/D_CAN sends out the buffers + * prioritized. The lowest buffer number wins. + */ + if (head < tail) + return 0; + + return ring->obj_num - head; } #endif /* C_CAN_H */ |