diff options
author | Dario Binacchi <dariobin@libero.it> | 2021-08-07 15:07:59 +0200 |
---|---|---|
committer | Marc Kleine-Budde <mkl@pengutronix.de> | 2021-08-19 15:07:05 +0200 |
commit | 28e86e9ab522e65b08545e5008d0f1ac5b19dad1 (patch) | |
tree | 2846dda37f04f68157b691cb0323536f3ce6935c /drivers/net/can/c_can/c_can.h | |
parent | a54cdbba9deee77ca48b5eec0c26fcc72538538c (diff) |
can: c_can: support tx ring algorithm
The algorithm is already used successfully by other CAN drivers
(e.g. mcp251xfd). Its implementation was kindly suggested to me by
Marc Kleine-Budde following a patch I had previously submitted. You can
find every detail at https://lore.kernel.org/patchwork/patch/1422929/.
The idea is that after this patch, it will be easier to patch the driver
to use the message object memory as a true FIFO.
Link: https://lore.kernel.org/r/20210807130800.5246-4-dariobin@libero.it
Suggested-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Dario Binacchi <dariobin@libero.it>
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 | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h index 8f23e9c83c84..9b4e54c950a6 100644 --- a/drivers/net/can/c_can/c_can.h +++ b/drivers/net/can/c_can/c_can.h @@ -176,6 +176,13 @@ struct c_can_raminit { bool needs_pulse; }; +/* c_can tx ring structure */ +struct c_can_tx_ring { + unsigned int head; + unsigned int tail; + unsigned int obj_num; +}; + /* c_can private data structure */ struct c_can_priv { struct can_priv can; /* must be the first member */ @@ -190,10 +197,10 @@ struct c_can_priv { unsigned int msg_obj_tx_first; unsigned int msg_obj_tx_last; u32 msg_obj_rx_mask; - atomic_t tx_active; atomic_t sie_pending; unsigned long tx_dir; int last_status; + struct c_can_tx_ring tx; u16 (*read_reg)(const struct c_can_priv *priv, enum reg index); void (*write_reg)(const struct c_can_priv *priv, enum reg index, u16 val); u32 (*read_reg32)(const struct c_can_priv *priv, enum reg index); @@ -219,4 +226,28 @@ int c_can_power_down(struct net_device *dev); void c_can_set_ethtool_ops(struct net_device *dev); +static inline u8 c_can_get_tx_head(const struct c_can_tx_ring *ring) +{ + return ring->head & (ring->obj_num - 1); +} + +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) +{ + u8 head = c_can_get_tx_head(ring); + u8 tail = c_can_get_tx_tail(ring); + + /* 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 */ |