Skip to content

Commit

Permalink
r8169: fix Ethernet Hangup for RTL8110SC rev d
Browse files Browse the repository at this point in the history
The 8110SC rev d chip on our board shows a regression which the 8110SB chip
did not have. When inbound traffic is overflowing the receive descriptor queue,
"holes" in the ring buffer may occur which lead to a hangup until the buffer
is filled again. The packets are than completely processed, but the ring
remains porous and no packets are processed until the next overflow. Setting
the interface down and up can fix the problem temporary from userspace.

For some reason we don't know, this behaviour is not occuring if the RxVlan
bit for hardware VLAN untagging is set. There is another "Work around for
AMD plateform" in the current code which checks the VLAN status
word in receive descriptors, but does never come to effect when hardware
VLAN support is enabled. We assume that this is a bug in the chip.

The following patch fixes the problem. Without the patch we could reproduce
the hang within minutes (given other devices also generating lots of
interrupts), without we couldn't reproduce within a few days of long term
testing.

This version contains minor style adjustments and is sent with mutt which
will hopefully not destroy the formatting again.

Signed-off-by: Bernhard Schmidt <bernhard.schmidt@saxnet.de>
Signed-off-by: Simon Wunderlich <simon.wunderlich@saxnet.de>
Acked-by: Francois Romieu <romieu@zoreil.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Simon Wunderlich authored and David S. Miller committed Oct 24, 2009
1 parent db51914 commit 05af214
Showing 1 changed file with 12 additions and 1 deletion.
13 changes: 12 additions & 1 deletion drivers/net/r8169.c
Original file line number Diff line number Diff line change
Expand Up @@ -1029,7 +1029,10 @@ static void rtl8169_vlan_rx_register(struct net_device *dev,

spin_lock_irqsave(&tp->lock, flags);
tp->vlgrp = grp;
if (tp->vlgrp)
/*
* Do not disable RxVlan on 8110SCd.
*/
if (tp->vlgrp || (tp->mac_version == RTL_GIGA_MAC_VER_05))
tp->cp_cmd |= RxVlan;
else
tp->cp_cmd &= ~RxVlan;
Expand Down Expand Up @@ -3197,6 +3200,14 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
}

rtl8169_init_phy(dev, tp);

/*
* Pretend we are using VLANs; This bypasses a nasty bug where
* Interrupts stop flowing on high load on 8110SCd controllers.
*/
if (tp->mac_version == RTL_GIGA_MAC_VER_05)
RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) | RxVlan);

device_set_wakeup_enable(&pdev->dev, tp->features & RTL_FEATURE_WOL);

out:
Expand Down

0 comments on commit 05af214

Please sign in to comment.