This is an automated email from the ASF dual-hosted git repository.

jerpelea pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 53b44a66cbcc32934d521a5b7c9e70ed2886bc44
Author: p-szafonimateusz <[email protected]>
AuthorDate: Tue Jun 9 12:32:20 2026 +0200

    drivers/can/kvaser_pci.c: fix RX getting stuck under load.
    
    RX frames are handled in a deferred poll, but the SJA1000 RX interrupt
    stays asserted while the FIFO has data. So the interrupt kept firing and
    starved the poll thread, the FIFO overran, and the driver never cleared
    the overrun.
    
    Mask the RX interrupt in the handler and re-enable it from the poll once
    the FIFO is empty, and clear the overrun there so RX recovers.
    
    Signed-off-by: p-szafonimateusz <[email protected]>
---
 drivers/can/kvaser_pci.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/can/kvaser_pci.c b/drivers/can/kvaser_pci.c
index 2a4fca40e70..e5177bfe2bc 100644
--- a/drivers/can/kvaser_pci.c
+++ b/drivers/can/kvaser_pci.c
@@ -1215,6 +1215,14 @@ static FAR netpkt_t *kvaser_sock_recv(FAR struct 
netdev_lowerhalf_s *dev)
   st = kvaser_getreg_sja(priv, SJA1000_STATUS_REG);
   if ((st & SJA1000_RX_BUF_ST) == 0)
     {
+      /* RX FIFO drained. Clear any data overrun, otherwise the SJA1000
+       * drops every further received frame until it is cleared. Also
+       * re-enable the RX interrupt that the ISR masked.
+       */
+
+      kvaser_putreg_sja(priv, SJA1000_CMD_REG, SJA1000_CLR_OVERRUN);
+      kvaser_rxint(priv, true);
+
 #ifdef CONFIG_NET_CAN_ERRORS
       /* Check for errors */
 
@@ -1426,10 +1434,16 @@ static void kvaser_sock_interrupt(FAR struct 
kvaser_driver_s *priv)
               continue;
             }
 
-          /* RX ready */
+          /* RX ready. The SJA1000 RX interrupt is level triggered (it stays
+           * asserted while the RX FIFO is non-empty), and we process RX in a
+           * deferred poll, so leaving it enabled here makes the ISR re-fire
+           * continuously and starve the poll thread until the FIFO overruns.
+           * Mask it; kvaser_sock_recv() re-enables it once the FIFO drains.
+           */
 
           if (st & KVASER_SOCK_RXINT)
             {
+              kvaser_rxint(&priv->sja[i], false);
               netdev_lower_rxready(&priv->sja[i].dev);
             }
 

Reply via email to