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

View file

@ -273,6 +273,16 @@ config 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
prompt "Kvaser PCI CAN device type"
default CAN_KVASER_CHARDEV if CAN

View file

@ -946,7 +946,10 @@ static void kvaser_chardev_interrupt(FAR struct kvaser_driver_s *priv)
{
uint8_t st = 0;
int i = 0;
int passes;
for (passes = 0; passes < CONFIG_CAN_KVASER_IRQ_PASSES; passes++)
{
for (i = 0; i < priv->count; i++)
{
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;
}
/* Receive interrupt */
/* Handle RX frames */
if (st & SJA1000_RX_INT_ST)
{
kvaser_chardev_receive(&priv->sja[i]);
}
/* Transmit interrupt */
@ -977,6 +977,7 @@ static void kvaser_chardev_interrupt(FAR struct kvaser_driver_s *priv)
kvaser_chardev_error(&priv->sja[i], st);
#endif
}
}
}
#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;
uint8_t st = 0;
uint8_t i = 0;
int passes;
for (passes = 0; passes < CONFIG_CAN_KVASER_IRQ_PASSES; passes++)
{
for (i = 0; i < priv->count; i++)
{
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;
}
/* Receive interrupt */
/* Handle RX frames */
if (st & SJA1000_RX_INT_ST)
{
kvaser_sock_receive(&priv->sja[i]);
}
/* Transmit interrupt */
@ -1524,6 +1525,7 @@ static void kvaser_sock_interrupt_work(FAR void *arg)
kvaser_sock_error(&priv->sja[i], st);
#endif
}
}
}
#endif /* CONFIG_CAN_KVASER_SOCKET */