drivers/can/kvaser_pci.c: configure number of passes in interrupt handler

Configure number of passes in interrupt handler logic to avoid losing RX frames
in QEMU environment.

Signed-off-by: p-szafonimateusz <p-szafonimateusz@xiaomi.com>
This commit is contained in:
p-szafonimateusz
2025-06-19 14:34:13 +02:00
committed by Donny(董九柱)
parent e2cdb7ef34
commit 4ed174a7e0
2 changed files with 51 additions and 39 deletions
+10
View File
@@ -273,6 +273,16 @@ config CAN_KVASER
if CAN_KVASER if CAN_KVASER
config CAN_KVASER_IRQ_PASSES
int "Kvaser PCI interrupt passes"
default 16
range 1 512
---help---
This option sets how many times the card status will be checked
during one interrupt handler. A value greater than 1 helps avoid
data loss when there is a lot of traffic on the CAN bus.
The downside is that it increases the interrupt service time.
choice choice
prompt "Kvaser PCI CAN device type" prompt "Kvaser PCI CAN device type"
default CAN_KVASER_CHARDEV if CAN default CAN_KVASER_CHARDEV if CAN
+10 -8
View File
@@ -946,7 +946,10 @@ static void kvaser_chardev_interrupt(FAR struct kvaser_driver_s *priv)
{ {
uint8_t st = 0; uint8_t st = 0;
int i = 0; int i = 0;
int passes;
for (passes = 0; passes < CONFIG_CAN_KVASER_IRQ_PASSES; passes++)
{
for (i = 0; i < priv->count; i++) for (i = 0; i < priv->count; i++)
{ {
st = kvaser_getreg_sja(&priv->sja[i], SJA1000_INT_RAW_REG); st = kvaser_getreg_sja(&priv->sja[i], SJA1000_INT_RAW_REG);
@@ -955,12 +958,9 @@ static void kvaser_chardev_interrupt(FAR struct kvaser_driver_s *priv)
continue; continue;
} }
/* Receive interrupt */ /* Handle RX frames */
if (st & SJA1000_RX_INT_ST)
{
kvaser_chardev_receive(&priv->sja[i]); kvaser_chardev_receive(&priv->sja[i]);
}
/* Transmit interrupt */ /* Transmit interrupt */
@@ -977,6 +977,7 @@ static void kvaser_chardev_interrupt(FAR struct kvaser_driver_s *priv)
kvaser_chardev_error(&priv->sja[i], st); kvaser_chardev_error(&priv->sja[i], st);
#endif #endif
} }
}
} }
#endif /* CONFIG_CAN_KVASER_CHARDEV */ #endif /* CONFIG_CAN_KVASER_CHARDEV */
@@ -1487,7 +1488,10 @@ static void kvaser_sock_interrupt_work(FAR void *arg)
FAR struct kvaser_driver_s *priv = arg; FAR struct kvaser_driver_s *priv = arg;
uint8_t st = 0; uint8_t st = 0;
uint8_t i = 0; uint8_t i = 0;
int passes;
for (passes = 0; passes < CONFIG_CAN_KVASER_IRQ_PASSES; passes++)
{
for (i = 0; i < priv->count; i++) for (i = 0; i < priv->count; i++)
{ {
st = kvaser_getreg_sja(&priv->sja[i], SJA1000_INT_RAW_REG); st = kvaser_getreg_sja(&priv->sja[i], SJA1000_INT_RAW_REG);
@@ -1496,12 +1500,9 @@ static void kvaser_sock_interrupt_work(FAR void *arg)
continue; continue;
} }
/* Receive interrupt */ /* Handle RX frames */
if (st & SJA1000_RX_INT_ST)
{
kvaser_sock_receive(&priv->sja[i]); kvaser_sock_receive(&priv->sja[i]);
}
/* Transmit interrupt */ /* Transmit interrupt */
@@ -1524,6 +1525,7 @@ static void kvaser_sock_interrupt_work(FAR void *arg)
kvaser_sock_error(&priv->sja[i], st); kvaser_sock_error(&priv->sja[i], st);
#endif #endif
} }
}
} }
#endif /* CONFIG_CAN_KVASER_SOCKET */ #endif /* CONFIG_CAN_KVASER_SOCKET */