linux/drivers/net/can
Thomas Gleixner 2b9aecdce2 can: c_can: Disable rx split as workaround
The RX buffer split causes packet loss in the hardware:

What happens is:

RX Packet 1 --> message buffer 1 (newdat bit is not cleared)
RX Packet 2 --> message buffer 2 (newdat bit is not cleared)
RX Packet 3 --> message buffer 3 (newdat bit is not cleared)
RX Packet 4 --> message buffer 4 (newdat bit is not cleared)
RX Packet 5 --> message buffer 5 (newdat bit is not cleared)
RX Packet 6 --> message buffer 6 (newdat bit is not cleared)
RX Packet 7 --> message buffer 7 (newdat bit is not cleared)
RX Packet 8 --> message buffer 8 (newdat bit is not cleared)

Clear newdat bit in message buffer 1
Clear newdat bit in message buffer 2
Clear newdat bit in message buffer 3
Clear newdat bit in message buffer 4
Clear newdat bit in message buffer 5
Clear newdat bit in message buffer 6
Clear newdat bit in message buffer 7
Clear newdat bit in message buffer 8

Now if during that clearing of newdat bits, a new message comes in,
the HW gets confused and drops it.

It does not matter how many of them you clear. I put a delay between
clear of buffer 1 and buffer 2 which was long enough that the message
should have been queued either in buffer 1 or buffer 9. But it did not
show up anywhere. The next message ended up in buffer 1. So the
hardware lost a packet of course without telling it via one of the
error handlers.

That does not happen on all clear newdat bit events. I see one of 10k
packets dropped in the scenario which allows us to reproduce. But the
trace looks always the same.

Not splitting the RX Buffer avoids the packet loss but can cause
reordering. It's hard to trigger, but it CAN happen.

With that mode we use the HW as it was probably designed for. We read
from the buffer 1 upwards and clear the buffer as we get the
message. That's how all microcontrollers use it. So I assume that the
way we handle the buffers was never really tested. According to the
public documentation it should just work :)

Let the user decide which evil is the lesser one.

[ Oliver Hartkopp: Provided a sane config option and help text and
  made me switch to favour potential and unlikely reordering over
  packet loss ]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Alexander Stein <alexander.stein@systec-electronic.com>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
2014-04-24 22:09:00 +02:00
..
c_can can: c_can: Disable rx split as workaround 2014-04-24 22:09:00 +02:00
cc770 can: Unify MTU settings for CAN interfaces 2014-03-17 09:20:16 +01:00
mscan can: Unify MTU settings for CAN interfaces 2014-03-17 09:20:16 +01:00
sja1000 Kconfig: rename HAS_IOPORT to HAS_IOPORT_MAP 2014-04-07 16:36:11 -07:00
softing can: populate netdev::dev_id for udev discrimination 2014-03-17 09:20:16 +01:00
usb linux-can-fixes-for-3.15-20140401 2014-04-01 17:49:50 -04:00
at91_can.c can: Unify MTU settings for CAN interfaces 2014-03-17 09:20:16 +01:00
bfin_can.c can: Unify MTU settings for CAN interfaces 2014-03-17 09:20:16 +01:00
dev.c can: add bittiming check at interface open for CAN FD 2014-03-07 09:18:23 +01:00
flexcan.c can: Unify MTU settings for CAN interfaces 2014-03-17 09:20:16 +01:00
grcan.c can: Unify MTU settings for CAN interfaces 2014-03-17 09:20:16 +01:00
janz-ican3.c can: Unify MTU settings for CAN interfaces 2014-03-17 09:20:16 +01:00
Kconfig can: flexcan: fix flexcan driver build for big endian on ARM and little endian on PowerPc 2014-01-29 20:23:22 +01:00
led.c net: pass info struct via netdevice notifier 2013-05-28 13:11:01 -07:00
Makefile can: add tx/rx LED trigger support 2013-01-26 16:58:59 +01:00
mcp251x.c can: mcp251x: Fix regulators operation without CONFIG_REGULATOR 2014-03-17 09:20:17 +01:00
pch_can.c can: Unify MTU settings for CAN interfaces 2014-03-17 09:20:16 +01:00
slcan.c can: Unify MTU settings for CAN interfaces 2014-03-17 09:20:16 +01:00
ti_hecc.c can: Unify MTU settings for CAN interfaces 2014-03-17 09:20:16 +01:00
vcan.c can: add destructor for self generated skbs 2014-01-30 16:25:49 -08:00