From: Fedor Ross <fedor.ross@xxxxxxx> Make `MCP251XFD_POLL_TIMEOUT_US` timeout calculation dynamic. Use maximum of 1ms and bit time of one full 72 bytes CANFD frame at the current bitrate. This seems to be necessary when configuring low bit rates like 10 Kbit/s for example. Otherwise during polling for the CAN controller to enter 'Normal CAN 2.0 mode' the timeout limit is exceeded and the configuration fails with: $ ip link set dev can1 up type can bitrate 10000 [ 731.911072] mcp251xfd spi2.1 can1: Controller failed to enter mode CAN 2.0 Mode (6) and stays in Configuration Mode (4) (con=0x068b0760, osc=0x00000468). [ 731.927192] mcp251xfd spi2.1 can1: CRC read error at address 0x0e0c (length=4, data=00 00 00 00, CRC=0x0000) retrying. [ 731.938101] A link change request failed with some changes committed already. Interface can1 may have been left with an inconsistent configuration, please check. RTNETLINK answers: Connection timed out Fixes: 55e5b97f003e8 ("can: mcp25xxfd: add driver for Microchip MCP25xxFD SPI CAN") Signed-off-by: Fedor Ross <fedor.ross@xxxxxxx> Signed-off-by: Marek Vasut <marex@xxxxxxx> --- Cc: "David S. Miller" <davem@xxxxxxxxxxxxx> Cc: Eric Dumazet <edumazet@xxxxxxxxxx> Cc: Jakub Kicinski <kuba@xxxxxxxxxx> Cc: Liam Girdwood <lgirdwood@xxxxxxxxx> Cc: Manivannan Sadhasivam <mani@xxxxxxxxxx> Cc: Marc Kleine-Budde <mkl@xxxxxxxxxxxxxx> Cc: Marek Vasut <marex@xxxxxxx> Cc: Mark Brown <broonie@xxxxxxxxxx> Cc: Paolo Abeni <pabeni@xxxxxxxxxx> Cc: Thomas Kopp <thomas.kopp@xxxxxxxxxxxxx> Cc: Wolfgang Grandegger <wg@xxxxxxxxxxxxxx> Cc: linux-can@xxxxxxxxxxxxxxx --- drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c index 68df6d4641b5c..9908843798cef 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c @@ -227,6 +227,7 @@ static int __mcp251xfd_chip_set_mode(const struct mcp251xfd_priv *priv, const u8 mode_req, bool nowait) { + const struct can_bittiming *bt = &priv->can.bittiming; u32 con = 0, con_reqop, osc = 0; u8 mode; int err; @@ -251,7 +252,8 @@ __mcp251xfd_chip_set_mode(const struct mcp251xfd_priv *priv, FIELD_GET(MCP251XFD_REG_CON_OPMOD_MASK, con) == mode_req, MCP251XFD_POLL_SLEEP_US, - MCP251XFD_POLL_TIMEOUT_US); + max(MCP251XFD_POLL_TIMEOUT_US, + 576 * USEC_PER_SEC / bt->bitrate)); if (err != -ETIMEDOUT && err != -EBADMSG) return err; -- 2.39.2