In peripherals, m_can_rx_handler is called with quota = 1 from an ISR context. If the M_CAN reports a high volume of errors, such as message loss due to heavy bus traffic, then error handling, which is prioritised in m_can_rx_handler, fills the quota immediately, and RX does not occur. This has been observed to cause an indefinite blocking of RX. The patch fixes this by ensuring that in peripherals, m_can_do_rx_poll is always called with a quota of at least 1, regardless of any errors handled. This has been tested with the TCAN4550 under heavy bus traffic; message loss is still detected correctly. Signed-off-by: Torin Cooper-Bennun <torin@xxxxxxxxxxxxxxxxxx> --- drivers/net/can/m_can/m_can.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 3752520a7d4b..3ec42e613ca1 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -866,8 +866,14 @@ static int m_can_rx_handler(struct net_device *dev, int quota) if (irqstatus & IR_ERR_BUS_30X) work_done += m_can_handle_bus_errors(dev, irqstatus, psr); - if (irqstatus & IR_RF0N) - work_done += m_can_do_rx_poll(dev, (quota - work_done)); + if (irqstatus & IR_RF0N) { + int rx_quota = quota - work_done; + + if (cdev->is_peripheral && (rx_quota <= 0)) + rx_quota = 1; + + work_done += m_can_do_rx_poll(dev, rx_quota); + } end: return work_done; } -- 2.30.1