Skip to content

Commit 4dcf924

Browse files
GBertmarckleinebudde
authored andcommitted
can: sun4i: handle overrun in RX FIFO
SUN4Is CAN IP has a 64 byte deep FIFO buffer. If the buffer is not drained fast enough (overrun) it's getting mangled. Already received frames are dropped - the data can't be restored. Signed-off-by: Gerhard Bertelsmann <[email protected]> Cc: linux-stable <[email protected]> Signed-off-by: Marc Kleine-Budde <[email protected]>
1 parent fb5f0b3 commit 4dcf924

File tree

1 file changed

+10
-2
lines changed

1 file changed

+10
-2
lines changed

drivers/net/can/sun4i_can.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,13 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
539539
}
540540
stats->rx_over_errors++;
541541
stats->rx_errors++;
542+
543+
/* reset the CAN IP by entering reset mode
544+
* ignoring timeout error
545+
*/
546+
set_reset_mode(dev);
547+
set_normal_mode(dev);
548+
542549
/* clear bit */
543550
sun4i_can_write_cmdreg(priv, SUN4I_CMD_CLEAR_OR_FLAG);
544551
}
@@ -653,8 +660,9 @@ static irqreturn_t sun4i_can_interrupt(int irq, void *dev_id)
653660
netif_wake_queue(dev);
654661
can_led_event(dev, CAN_LED_EVENT_TX);
655662
}
656-
if (isrc & SUN4I_INT_RBUF_VLD) {
657-
/* receive interrupt */
663+
if ((isrc & SUN4I_INT_RBUF_VLD) &&
664+
!(isrc & SUN4I_INT_DATA_OR)) {
665+
/* receive interrupt - don't read if overrun occurred */
658666
while (status & SUN4I_STA_RBUF_RDY) {
659667
/* RX buffer is not empty */
660668
sun4i_can_rx(dev);

0 commit comments

Comments
 (0)