Commit b5849857 authored by Pavel Pisa's avatar Pavel Pisa

driver: do not exceed quota in ctucan_rx_poll and suppress excessive Rx irq.

The RXBNEI has to be masked the first before interrupt is cleared
because source is level triggered and would cause interrupt
flip-flop to be set again before masking in next step.

Correct receive loop to respect quota value.
Signed-off-by: Pavel Pisa's avatarPavel Pisa <pisa@cmp.felk.cvut.cz>
parent 5d070a12
Pipeline #6989 passed with stage
in 44 seconds
...@@ -489,16 +489,13 @@ static int ctucan_rx_poll(struct napi_struct *napi, int quota) ...@@ -489,16 +489,13 @@ static int ctucan_rx_poll(struct napi_struct *napi, int quota)
int work_done = 0; int work_done = 0;
union ctu_can_fd_status status; union ctu_can_fd_status status;
u32 framecnt; u32 framecnt;
u32 i;
//netdev_dbg(ndev, "ctucan_rx_poll"); //netdev_dbg(ndev, "ctucan_rx_poll");
framecnt = ctu_can_fd_get_rx_frame_count(&priv->p); framecnt = ctu_can_fd_get_rx_frame_count(&priv->p);
netdev_dbg(ndev, "rx_poll: %d frames in RX FIFO", framecnt);
while (framecnt && work_done < quota) { while (framecnt && work_done < quota) {
netdev_dbg(ndev, "rx_poll: %d frames in RX FIFO", framecnt); ctucan_rx(ndev);
for (i = 0; i < framecnt; ++i) { work_done++;
ctucan_rx(ndev);
work_done++;
}
framecnt = ctu_can_fd_get_rx_frame_count(&priv->p); framecnt = ctu_can_fd_get_rx_frame_count(&priv->p);
} }
...@@ -528,7 +525,7 @@ static int ctucan_rx_poll(struct napi_struct *napi, int quota) ...@@ -528,7 +525,7 @@ static int ctucan_rx_poll(struct napi_struct *napi, int quota)
if (work_done) if (work_done)
can_led_event(ndev, CAN_LED_EVENT_RX); can_led_event(ndev, CAN_LED_EVENT_RX);
if (work_done < quota) { if (!framecnt) {
if (napi_complete_done(napi, work_done)) { if (napi_complete_done(napi, work_done)) {
union ctu_can_fd_int_stat iec; union ctu_can_fd_int_stat iec;
/* Clear and enable RBNEI. It is level-triggered, so /* Clear and enable RBNEI. It is level-triggered, so
...@@ -689,11 +686,12 @@ static irqreturn_t ctucan_interrupt(int irq, void *dev_id) ...@@ -689,11 +686,12 @@ static irqreturn_t ctucan_interrupt(int irq, void *dev_id)
netdev_dbg(ndev, "RXBNEI"); netdev_dbg(ndev, "RXBNEI");
icr.u32 = 0; icr.u32 = 0;
icr.s.rbnei = 1; icr.s.rbnei = 1;
/* Clear and mask RXBNEI, schedule NAPI. /* Mask RXBNEI the first then clear interrupt,
* Even if another IRQ fires, isr.s.rbnei will always * then schedule NAPI. Even if another IRQ fires,
* be 0 (masked). */ * isr.s.rbnei will always be 0 (masked).
ctu_can_fd_int_clr(&priv->p, icr); */
ctu_can_fd_int_mask_set(&priv->p, icr); ctu_can_fd_int_mask_set(&priv->p, icr);
ctu_can_fd_int_clr(&priv->p, icr);
// set_bit(CTUCAN_FLAG_RX_SCHED, &priv->drv_flags); // set_bit(CTUCAN_FLAG_RX_SCHED, &priv->drv_flags);
napi_schedule(&priv->napi); napi_schedule(&priv->napi);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment