niu: Fix readq implementation when architecture does not provide one.
commit2e7cb04dcda1dd2dcc49f3a679da9bf59f1cabec
authorDavid S. Miller <davem@davemloft.net>
Wed, 12 Nov 2008 22:32:54 +0000 (12 14:32 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Sat, 13 Dec 2008 23:29:12 +0000 (13 15:29 -0800)
tree499eb5d05cdc1687e16eb22bee25ce0a5a368a40
parent0a2093552fba5f5e06bd81e413f62f60880dd182
niu: Fix readq implementation when architecture does not provide one.

[ Upstream commit e23a59e1ca6d177a57a7791b3629db93ff1d9813 ]

This fixes a TX hang reported by Jesper Dangaard Brouer.

When an architecutre cannot provide a fully functional
64-bit atomic readq/writeq, the driver must implement
it's own.  This is because only the driver can say whether
doing something like using two 32-bit reads to implement
the full 64-bit read will actually work properly.

In particular one of the issues is whether the top 32-bits
or the bottom 32-bits of the 64-bit register should be read
first.  There could be side effects, and in fact that is
exactly the problem here.

The TX_CS register has counters in the upper 32-bits and
state bits in the lower 32-bits.  A read clears the state
bits.

We would read the counter half before the state bit half.
That first read would clear the state bits, and then the
driver thinks that no interrupts are pending because the
interrupt indication state bits are seen clear every time.

Fix this by reading the bottom half before the upper half.

Tested-by: Jesper Dangaard Brouer <jdb@comx.dk>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/net/niu.c