aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/r8169.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/r8169.c')
-rw-r--r--drivers/net/r8169.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 83c47d95c3aa..0fe2fc90f207 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:
@@ -3224,6 +3235,10 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
3224 flush_scheduled_work(); 3235 flush_scheduled_work();
3225 3236
3226 unregister_netdev(dev); 3237 unregister_netdev(dev);
3238
3239 /* restore original MAC address */
3240 rtl_rar_set(tp, dev->perm_addr);
3241
3227 rtl_disable_msi(pdev, tp); 3242 rtl_disable_msi(pdev, tp);
3228 rtl8169_release_board(pdev, dev, tp->mmio_addr); 3243 rtl8169_release_board(pdev, dev, tp->mmio_addr);
3229 pci_set_drvdata(pdev, NULL); 3244 pci_set_drvdata(pdev, NULL);
@@ -3232,9 +3247,9 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
3232static void rtl8169_set_rxbufsize(struct rtl8169_private *tp, 3247static void rtl8169_set_rxbufsize(struct rtl8169_private *tp,
3233 struct net_device *dev) 3248 struct net_device *dev)
3234{ 3249{
3235 unsigned int mtu = dev->mtu; 3250 unsigned int max_frame = dev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN;
3236 3251
3237 tp->rx_buf_sz = (mtu > RX_BUF_SIZE) ? mtu + ETH_HLEN + 8 : RX_BUF_SIZE; 3252 tp->rx_buf_sz = (max_frame > RX_BUF_SIZE) ? max_frame : RX_BUF_SIZE;
3238} 3253}
3239 3254
3240static int rtl8169_open(struct net_device *dev) 3255static int rtl8169_open(struct net_device *dev)
@@ -3368,7 +3383,7 @@ static u16 rtl_rw_cpluscmd(void __iomem *ioaddr)
3368static void rtl_set_rx_max_size(void __iomem *ioaddr, unsigned int rx_buf_sz) 3383static void rtl_set_rx_max_size(void __iomem *ioaddr, unsigned int rx_buf_sz)
3369{ 3384{
3370 /* Low hurts. Let's disable the filtering. */ 3385 /* Low hurts. Let's disable the filtering. */
3371 RTL_W16(RxMaxSize, rx_buf_sz); 3386 RTL_W16(RxMaxSize, rx_buf_sz + 1);
3372} 3387}
3373 3388
3374static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version) 3389static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version)
@@ -4870,6 +4885,9 @@ static void rtl_shutdown(struct pci_dev *pdev)
4870 4885
4871 rtl8169_net_suspend(dev); 4886 rtl8169_net_suspend(dev);
4872 4887
4888 /* restore original MAC address */
4889 rtl_rar_set(tp, dev->perm_addr);
4890
4873 spin_lock_irq(&tp->lock); 4891 spin_lock_irq(&tp->lock);
4874 4892
4875 rtl8169_asic_down(ioaddr); 4893 rtl8169_asic_down(ioaddr);