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 <info@gerhard-bertelsmann.de> Cc: linux-stable <stable@vger.kernel.org> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
This commit is contained in:
committed by
Marc Kleine-Budde
parent
fb5f0b3ef6
commit
4dcf924c2e
@@ -539,6 +539,13 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
|
|||||||
}
|
}
|
||||||
stats->rx_over_errors++;
|
stats->rx_over_errors++;
|
||||||
stats->rx_errors++;
|
stats->rx_errors++;
|
||||||
|
|
||||||
|
/* reset the CAN IP by entering reset mode
|
||||||
|
* ignoring timeout error
|
||||||
|
*/
|
||||||
|
set_reset_mode(dev);
|
||||||
|
set_normal_mode(dev);
|
||||||
|
|
||||||
/* clear bit */
|
/* clear bit */
|
||||||
sun4i_can_write_cmdreg(priv, SUN4I_CMD_CLEAR_OR_FLAG);
|
sun4i_can_write_cmdreg(priv, SUN4I_CMD_CLEAR_OR_FLAG);
|
||||||
}
|
}
|
||||||
@@ -653,8 +660,9 @@ static irqreturn_t sun4i_can_interrupt(int irq, void *dev_id)
|
|||||||
netif_wake_queue(dev);
|
netif_wake_queue(dev);
|
||||||
can_led_event(dev, CAN_LED_EVENT_TX);
|
can_led_event(dev, CAN_LED_EVENT_TX);
|
||||||
}
|
}
|
||||||
if (isrc & SUN4I_INT_RBUF_VLD) {
|
if ((isrc & SUN4I_INT_RBUF_VLD) &&
|
||||||
/* receive interrupt */
|
!(isrc & SUN4I_INT_DATA_OR)) {
|
||||||
|
/* receive interrupt - don't read if overrun occurred */
|
||||||
while (status & SUN4I_STA_RBUF_RDY) {
|
while (status & SUN4I_STA_RBUF_RDY) {
|
||||||
/* RX buffer is not empty */
|
/* RX buffer is not empty */
|
||||||
sun4i_can_rx(dev);
|
sun4i_can_rx(dev);
|
||||||
|
|||||||
Reference in New Issue
Block a user