aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/r8169.c
diff options
context:
space:
mode:
authorSimon Wunderlich <simon.wunderlich@saxnet.de>2009-10-24 09:47:33 -0400
committerDavid S. Miller <davem@davemloft.net>2009-10-24 09:47:33 -0400
commit05af2142d09845de2f4ae34181c72addd72d5ef9 (patch)
tree52bbe354a7f013f4977b546d870fcf42fd435102 /drivers/net/r8169.c
parentdb519144243de6b17ff0c56c26f06059743110a7 (diff)
r8169: fix Ethernet Hangup for RTL8110SC rev d
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>
Diffstat (limited to 'drivers/net/r8169.c')
-rw-r--r--drivers/net/r8169.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 83c47d95c3aa..f98ef523f525 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1029,7 +1029,10 @@ static void rtl8169_vlan_rx_register(struct net_device *dev,
1029 1029
1030 spin_lock_irqsave(&tp->lock, flags); 1030 spin_lock_irqsave(&tp->lock, flags);
1031 tp->vlgrp = grp; 1031 tp->vlgrp = grp;
1032 if (tp->vlgrp) 1032 /*
1033 * Do not disable RxVlan on 8110SCd.
1034 */
1035 if (tp->vlgrp || (tp->mac_version == RTL_GIGA_MAC_VER_05))
1033 tp->cp_cmd |= RxVlan; 1036 tp->cp_cmd |= RxVlan;
1034 else 1037 else
1035 tp->cp_cmd &= ~RxVlan; 1038 tp->cp_cmd &= ~RxVlan;
@@ -3197,6 +3200,14 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
3197 } 3200 }
3198 3201
3199 rtl8169_init_phy(dev, tp); 3202 rtl8169_init_phy(dev, tp);
3203
3204 /*
3205 * Pretend we are using VLANs; This bypasses a nasty bug where
3206 * Interrupts stop flowing on high load on 8110SCd controllers.
3207 */
3208 if (tp->mac_version == RTL_GIGA_MAC_VER_05)
3209 RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) | RxVlan);
3210
3200 device_set_wakeup_enable(&pdev->dev, tp->features & RTL_FEATURE_WOL); 3211 device_set_wakeup_enable(&pdev->dev, tp->features & RTL_FEATURE_WOL);
3201 3212
3202out: 3213out: