[PATCH] can: m_can: m_can_rx_handler(): fix RX in periphs being blocked by error handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Automotive Discussions]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]     [CAN Bus]

  Powered by Linux