summaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorBen Hutchings2015-03-03 01:52:08 +0100
committerDavid S. Miller2015-03-03 03:30:56 +0100
commit6ded286555c2518be2f2d438f83dfaba3f0100fd (patch)
tree5d2c9472a929d67cf4e1f810b02cc1fd67d45c51 /drivers/net
parentsh_eth: Ensure proper ordering of descriptor active bit write/read (diff)
downloadkernel-qcow2-linux-6ded286555c2518be2f2d438f83dfaba3f0100fd.tar.gz
kernel-qcow2-linux-6ded286555c2518be2f2d438f83dfaba3f0100fd.tar.xz
kernel-qcow2-linux-6ded286555c2518be2f2d438f83dfaba3f0100fd.zip
sh_eth: Fix RX recovery on R-Car in case of RX ring underrun
In case of RX ring underrun (RDE), we attempt to reset the software descriptor pointers (dirty_rx and cur_rx) to match where the hardware will read the next descriptor from, as that might not be the first dirty descriptor. This relies on reading RDFAR, but that register doesn't exist on all supported chips - specifically, not on the R-Car chips. This will result in unpredictable behaviour on those chips after an RDE. Make this pointer reset conditional and assume that it isn't needed on the R-Car chips. This fix also assumes that RDFAR is never exposed at offset 0 in the memory map - this is currently true, and a subsequent commit will fix the ambiguity between offset 0 and no-offset in the register offset maps. Fixes: 79fba9f51755 ("net: sh_eth: fix the rxdesc pointer when rx ...") Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethernet/renesas/sh_eth.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index 5c212a833bcf..3309494d12ad 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -1543,7 +1543,7 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota)
/* If we don't need to check status, don't. -KDU */
if (!(sh_eth_read(ndev, EDRRR) & EDRRR_R)) {
/* fix the values for the next receiving if RDE is set */
- if (intr_status & EESR_RDE) {
+ if (intr_status & EESR_RDE && mdp->reg_offset[RDFAR] != 0) {
u32 count = (sh_eth_read(ndev, RDFAR) -
sh_eth_read(ndev, RDLAR)) >> 4;