can: c_can: Fix buffer ordering
authorThomas Gleixner <tglx@linutronix.de>
Tue, 18 Mar 2014 17:19:10 +0000 (17:19 +0000)
committerMarc Kleine-Budde <mkl@pengutronix.de>
Tue, 1 Apr 2014 09:54:58 +0000 (11:54 +0200)
commit64f08f2f3544eb8b6b14fd35e6087d7d3ede77cd
treeea75d2125f91762caedc2d287ad90b496046ebd2
parent640916db2bf7de7c5ac13a1f470fa959459ccf6d
can: c_can: Fix buffer ordering

The buffer handling of c_can has been broken forever. That leads to
message reordering:

ksoftirqd/0-3     [000] ..s.    79.123776: c_can_poll: rx_poll: val: 00007fff
ksoftirqd/0-3     [000] ..s.    79.124101: c_can_poll: rx_poll: val: 00008001

What happens is:

CPU HW
queue new packet into obj 16 (0-15 are busy)
read obj 1-15
return because pending is 0
set pending obj 16 -> pending reg 8000
queue new packet into obj 1
set pending obj 1 -> pending reg 8001

So the current algorithmus reads the newest message first, which
violates the ordering rules of CAN.

Add proper handling of that situation by analyzing the contents of the
pending register for gaps.

This does NOT fix the message object corruption which can lead to
interrupt storms. Thats addressed in the next patches.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
[mkl: adjusted subject]
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
drivers/net/can/c_can/c_can.c