• Thomas Gleixner's avatar
    can: c_can: Disable rx split as workaround · 2b9aecdc
    Thomas Gleixner authored
    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: default avatarThomas Gleixner <tglx@linutronix.de>
    Tested-by: default avatarAlexander Stein <alexander.stein@systec-electronic.com>
    Signed-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
    2b9aecdc
c_can.c 35.1 KB