Message ID | 20241104-mcp251xfd-fix-length-calculation-v3-1-608b6e7e2197@pengutronix.de (mailing list archive) |
---|---|
State | Awaiting Upstream |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | [can,v3] can: mcp251xfd: mcp251xfd_get_tef_len(): fix length calculation | expand |
Context | Check | Description |
---|---|---|
netdev/tree_selection | success | Series ignored based on subject |
On Mon, Nov 04, 2024 at 05:42:40PM +0100, Marc Kleine-Budde wrote: > Commit b8e0ddd36ce9 ("can: mcp251xfd: tef: prepare to workaround > broken TEF FIFO tail index erratum") introduced > mcp251xfd_get_tef_len() to get the number of unhandled transmit events > from the Transmit Event FIFO (TEF). > > As the TEF has no head pointer, the driver uses the TX FIFO's tail > pointer instead, assuming that send frames are completed. However the > check for the TEF being full was not correct. This leads to the driver > stop working if the TEF is full. > > Fix the TEF full check by assuming that if, from the driver's point of > view, there are no free TX buffers in the chip and the TX FIFO is > empty, all messages must have been sent and the TEF must therefore be > full. > > Reported-by: Sven Schuchmann <schuchmann@schleissheimer.de> > Closes: https://patch.msgid.link/FR3P281MB155216711EFF900AD9791B7ED9692@FR3P281MB1552.DEUP281.PROD.OUTLOOK.COM > Fixes: b8e0ddd36ce9 ("can: mcp251xfd: tef: prepare to workaround broken TEF FIFO tail index erratum") > Tested-by: Sven Schuchmann <schuchmann@schleissheimer.de> > Cc: stable@vger.kernel.org > Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> Reviewed-by: Simon Horman <horms@kernel.org> ...
diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c index f732556d233a7be3b43f6f08e0b8f25732190104..d3ac865933fdf6c4ecdd80ad4d7accbff51eb0f8 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c @@ -16,9 +16,9 @@ #include "mcp251xfd.h" -static inline bool mcp251xfd_tx_fifo_sta_full(u32 fifo_sta) +static inline bool mcp251xfd_tx_fifo_sta_empty(u32 fifo_sta) { - return !(fifo_sta & MCP251XFD_REG_FIFOSTA_TFNRFNIF); + return fifo_sta & MCP251XFD_REG_FIFOSTA_TFERFFIF; } static inline int @@ -122,7 +122,11 @@ mcp251xfd_get_tef_len(struct mcp251xfd_priv *priv, u8 *len_p) if (err) return err; - if (mcp251xfd_tx_fifo_sta_full(fifo_sta)) { + /* If the chip says the TX-FIFO is empty, but there are no TX + * buffers free in the ring, we assume all have been sent. + */ + if (mcp251xfd_tx_fifo_sta_empty(fifo_sta) && + mcp251xfd_get_tx_free(tx_ring) == 0) { *len_p = tx_ring->obj_num; return 0; }