From: Greg Kroah-Hartman Date: Wed, 10 Oct 2012 00:40:47 +0000 (+0900) Subject: 3.0-stable patches X-Git-Tag: v3.0.46~19 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=930019a3759e94dfd095890a6fc3a0e35786561a;p=thirdparty%2Fkernel%2Fstable-queue.git 3.0-stable patches added patches: r8169-8168c-and-later-require-bit-0x20-to-be-set-in-config2-for-pme-signaling.patch r8169-call-netif_napi_del-at-errpaths-and-at-driver-unload.patch r8169-config1-is-read-only-on-8168c-and-later.patch r8169-don-t-enable-rx-when-shutdown.patch r8169-expand-received-packet-length-indication.patch r8169-fix-config2-msienable-bit-setting.patch r8169-fix-unsigned-int-wraparound-with-tso.patch r8169-fix-wake-on-lan-setting-for-non-8111e.patch r8169-increase-the-delay-parameter-of-pm_schedule_suspend.patch r8169-jumbo-fixes.patch r8169-missing-barriers.patch r8169-remove-erroneous-processing-of-always-set-bit.patch r8169-runtime-resume-before-shutdown.patch r8169-rx-fifo-overflow-fixes.patch --- diff --git a/queue-3.0/r8169-8168c-and-later-require-bit-0x20-to-be-set-in-config2-for-pme-signaling.patch b/queue-3.0/r8169-8168c-and-later-require-bit-0x20-to-be-set-in-config2-for-pme-signaling.patch new file mode 100644 index 00000000000..6f2a946d25d --- /dev/null +++ b/queue-3.0/r8169-8168c-and-later-require-bit-0x20-to-be-set-in-config2-for-pme-signaling.patch @@ -0,0 +1,44 @@ +From stable-owner@vger.kernel.org Sat Oct 6 06:49:20 2012 +From: Francois Romieu +Date: Fri, 5 Oct 2012 23:29:19 +0200 +Subject: r8169: 8168c and later require bit 0x20 to be set in Config2 for PME signaling. +To: stable@vger.kernel.org +Cc: Hayes Wang , Jonathan Nieder + +From: Francois Romieu + +commit d387b427c973974dd619a33549c070ac5d0e089f upstream. + +The new 84xx stopped flying below the radars. + +Signed-off-by: Francois Romieu +Cc: Hayes Wang +Reviewed-by: Jonathan Nieder +Acked-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/r8169.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/net/r8169.c ++++ b/drivers/net/r8169.c +@@ -299,6 +299,8 @@ enum rtl_registers { + Config0 = 0x51, + Config1 = 0x52, + Config2 = 0x53, ++#define PME_SIGNAL (1 << 5) /* 8168c and later */ ++ + Config3 = 0x54, + Config4 = 0x55, + Config5 = 0x56, +@@ -1249,6 +1251,10 @@ static void __rtl8169_set_wol(struct rtl + RTL_W8(Config1, options); + break; + default: ++ options = RTL_R8(Config2) & ~PME_SIGNAL; ++ if (wolopts) ++ options |= PME_SIGNAL; ++ RTL_W8(Config2, options); + break; + } + diff --git a/queue-3.0/r8169-call-netif_napi_del-at-errpaths-and-at-driver-unload.patch b/queue-3.0/r8169-call-netif_napi_del-at-errpaths-and-at-driver-unload.patch new file mode 100644 index 00000000000..2deefeeffae --- /dev/null +++ b/queue-3.0/r8169-call-netif_napi_del-at-errpaths-and-at-driver-unload.patch @@ -0,0 +1,42 @@ +From stable-owner@vger.kernel.org Sat Oct 6 06:49:17 2012 +From: Francois Romieu +Date: Fri, 5 Oct 2012 23:29:21 +0200 +Subject: r8169: call netif_napi_del at errpaths and at driver unload +To: stable@vger.kernel.org +Cc: Hayes Wang , Jonathan Nieder + +From: Devendra Naga + +commit ad1be8d345416a794dea39761a374032aa471a76 upstream. + +When register_netdev fails, the init'ed NAPIs by netif_napi_add must be +deleted with netif_napi_del, and also when driver unloads, it should +delete the NAPI before unregistering netdevice using unregister_netdev. + +Signed-off-by: Devendra Naga +Signed-off-by: David S. Miller +Reviewed-by: Jonathan Nieder +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/r8169.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/net/r8169.c ++++ b/drivers/net/r8169.c +@@ -3706,6 +3706,7 @@ out: + return rc; + + err_out_msi_4: ++ netif_napi_del(&tp->napi); + rtl_disable_msi(pdev, tp); + iounmap(ioaddr); + err_out_free_res_3: +@@ -3731,6 +3732,8 @@ static void __devexit rtl8169_remove_one + + cancel_delayed_work_sync(&tp->task); + ++ netif_napi_del(&tp->napi); ++ + unregister_netdev(dev); + + rtl_release_firmware(tp); diff --git a/queue-3.0/r8169-config1-is-read-only-on-8168c-and-later.patch b/queue-3.0/r8169-config1-is-read-only-on-8168c-and-later.patch new file mode 100644 index 00000000000..b7f07a3cab9 --- /dev/null +++ b/queue-3.0/r8169-config1-is-read-only-on-8168c-and-later.patch @@ -0,0 +1,62 @@ +From stable-owner@vger.kernel.org Sat Oct 6 06:49:23 2012 +From: Francois Romieu +Date: Fri, 5 Oct 2012 23:29:18 +0200 +Subject: r8169: Config1 is read-only on 8168c and later. +To: stable@vger.kernel.org +Cc: Hayes Wang , Jonathan Nieder + +From: Francois Romieu + +commit 851e60221926a53344b4227879858bef841b0477 upstream. + +Suggested by Hayes. + +Signed-off-by: Francois Romieu +Cc: Hayes Wang +Reviewed-by: Jonathan Nieder +Acked-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/r8169.c | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +--- a/drivers/net/r8169.c ++++ b/drivers/net/r8169.c +@@ -1223,7 +1223,6 @@ static void __rtl8169_set_wol(struct rtl + u16 reg; + u8 mask; + } cfg[] = { +- { WAKE_ANY, Config1, PMEnable }, + { WAKE_PHY, Config3, LinkUp }, + { WAKE_MAGIC, Config3, MagicPacket }, + { WAKE_UCAST, Config5, UWF }, +@@ -1231,16 +1230,28 @@ static void __rtl8169_set_wol(struct rtl + { WAKE_MCAST, Config5, MWF }, + { WAKE_ANY, Config5, LanWake } + }; ++ u8 options; + + RTL_W8(Cfg9346, Cfg9346_Unlock); + + for (i = 0; i < ARRAY_SIZE(cfg); i++) { +- u8 options = RTL_R8(cfg[i].reg) & ~cfg[i].mask; ++ options = RTL_R8(cfg[i].reg) & ~cfg[i].mask; + if (wolopts & cfg[i].opt) + options |= cfg[i].mask; + RTL_W8(cfg[i].reg, options); + } + ++ switch (tp->mac_version) { ++ case RTL_GIGA_MAC_VER_01 ... RTL_GIGA_MAC_VER_17: ++ options = RTL_R8(Config1) & ~PMEnable; ++ if (wolopts) ++ options |= PMEnable; ++ RTL_W8(Config1, options); ++ break; ++ default: ++ break; ++ } ++ + RTL_W8(Cfg9346, Cfg9346_Lock); + } + diff --git a/queue-3.0/r8169-don-t-enable-rx-when-shutdown.patch b/queue-3.0/r8169-don-t-enable-rx-when-shutdown.patch new file mode 100644 index 00000000000..18fe8b7761c --- /dev/null +++ b/queue-3.0/r8169-don-t-enable-rx-when-shutdown.patch @@ -0,0 +1,38 @@ +From stable-owner@vger.kernel.org Sat Oct 6 06:49:20 2012 +From: Francois Romieu +Date: Fri, 5 Oct 2012 23:29:09 +0200 +Subject: r8169: don't enable rx when shutdown. +To: stable@vger.kernel.org +Cc: Hayes Wang , Jonathan Nieder + +From: Hayes Wang + +commit aaa89c08d9ffa3739c93d65d98b73ec2aa2e93a5 upstream. + +Only 8111b needs to enable rx when shutdowning with WoL. + +Signed-off-by: Hayes Wang +Acked-by: Francois Romieu +Reviewed-by: Jonathan Nieder +Acked-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/r8169.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/net/r8169.c ++++ b/drivers/net/r8169.c +@@ -5391,8 +5391,11 @@ static void rtl_shutdown(struct pci_dev + spin_unlock_irq(&tp->lock); + + if (system_state == SYSTEM_POWER_OFF) { +- /* WoL fails with some 8168 when the receiver is disabled. */ +- if (tp->features & RTL_FEATURE_WOL) { ++ /* WoL fails with 8168b when the receiver is disabled. */ ++ if ((tp->mac_version == RTL_GIGA_MAC_VER_11 || ++ tp->mac_version == RTL_GIGA_MAC_VER_12 || ++ tp->mac_version == RTL_GIGA_MAC_VER_17) && ++ (tp->features & RTL_FEATURE_WOL)) { + pci_clear_master(pdev); + + RTL_W8(ChipCmd, CmdRxEnb); diff --git a/queue-3.0/r8169-expand-received-packet-length-indication.patch b/queue-3.0/r8169-expand-received-packet-length-indication.patch new file mode 100644 index 00000000000..0ab9c8f06ab --- /dev/null +++ b/queue-3.0/r8169-expand-received-packet-length-indication.patch @@ -0,0 +1,40 @@ +From stable-owner@vger.kernel.org Sat Oct 6 06:49:19 2012 +From: Francois Romieu +Date: Fri, 5 Oct 2012 23:29:12 +0200 +Subject: r8169: expand received packet length indication. +To: stable@vger.kernel.org +Cc: Hayes Wang , Jonathan Nieder +Message-ID: + +From: Francois Romieu + +commit deb9d93c89d311714a60809b28160e538e1cbb43 upstream. + +8168d and above allow jumbo frames beyond 8k. Bump the received +packet length check before enabling jumbo frames on these chipsets. + +Frame length indication covers bits 0..13 of the first Rx descriptor +32 bits for the 8169 and 8168. I only have authoritative documentation +for the allowed use of the extra (13) bit with the 8169 and 8168c. +Realtek's drivers use the same mask for the 816x and the fast ethernet +only 810x. + +Signed-off-by: Francois Romieu +Reviewed-by: Jonathan Nieder +Acked-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/r8169.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/r8169.c ++++ b/drivers/net/r8169.c +@@ -5137,7 +5137,7 @@ static int rtl8169_rx_interrupt(struct n + } else { + struct sk_buff *skb; + dma_addr_t addr = le64_to_cpu(desc->addr); +- int pkt_size = (status & 0x00001FFF) - 4; ++ int pkt_size = (status & 0x00003fff) - 4; + + /* + * The driver does not support incoming fragmented diff --git a/queue-3.0/r8169-fix-config2-msienable-bit-setting.patch b/queue-3.0/r8169-fix-config2-msienable-bit-setting.patch new file mode 100644 index 00000000000..9138ec4aedd --- /dev/null +++ b/queue-3.0/r8169-fix-config2-msienable-bit-setting.patch @@ -0,0 +1,82 @@ +From stable-owner@vger.kernel.org Sat Oct 6 06:49:19 2012 +From: Francois Romieu +Date: Fri, 5 Oct 2012 23:29:15 +0200 +Subject: r8169: fix Config2 MSIEnable bit setting. +To: stable@vger.kernel.org +Cc: Hayes Wang , Jonathan Nieder + + +From: françois romieu + +commit 2ca6cf06d988fea21e812a86be79353352677c9c upstream. + +The MSIEnable bit is only available for the 8169. + +Avoid Config2 writes for the post-8169 8168 and 810x. + +Reported-by: Su Kang Yin +Signed-off-by: Francois Romieu +Cc: Hayes Wang +Signed-off-by: David S. Miller +Reviewed-by: Jonathan Nieder +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/r8169.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +--- a/drivers/net/r8169.c ++++ b/drivers/net/r8169.c +@@ -448,7 +448,6 @@ enum rtl_register_content { + /* Config1 register p.24 */ + LEDS1 = (1 << 7), + LEDS0 = (1 << 6), +- MSIEnable = (1 << 5), /* Enable Message Signaled Interrupt */ + Speed_down = (1 << 4), + MEMMAP = (1 << 3), + IOMAP = (1 << 2), +@@ -456,6 +455,7 @@ enum rtl_register_content { + PMEnable = (1 << 0), /* Power Management Enable */ + + /* Config2 register p. 25 */ ++ MSIEnable = (1 << 5), /* 8169 only. Reserved in the 8168. */ + PCI_Clock_66MHz = 0x01, + PCI_Clock_33MHz = 0x00, + +@@ -3003,22 +3003,24 @@ static const struct rtl_cfg_info { + }; + + /* Cfg9346_Unlock assumed. */ +-static unsigned rtl_try_msi(struct pci_dev *pdev, void __iomem *ioaddr, ++static unsigned rtl_try_msi(struct rtl8169_private *tp, + const struct rtl_cfg_info *cfg) + { ++ void __iomem *ioaddr = tp->mmio_addr; + unsigned msi = 0; + u8 cfg2; + + cfg2 = RTL_R8(Config2) & ~MSIEnable; + if (cfg->features & RTL_FEATURE_MSI) { +- if (pci_enable_msi(pdev)) { +- dev_info(&pdev->dev, "no MSI. Back to INTx.\n"); ++ if (pci_enable_msi(tp->pci_dev)) { ++ netif_info(tp, hw, tp->dev, "no MSI. Back to INTx.\n"); + } else { + cfg2 |= MSIEnable; + msi = RTL_FEATURE_MSI; + } + } +- RTL_W8(Config2, cfg2); ++ if (tp->mac_version <= RTL_GIGA_MAC_VER_06) ++ RTL_W8(Config2, cfg2); + return msi; + } + +@@ -3588,7 +3590,7 @@ rtl8169_init_one(struct pci_dev *pdev, c + tp->features |= RTL_FEATURE_WOL; + if ((RTL_R8(Config5) & (UWF | BWF | MWF)) != 0) + tp->features |= RTL_FEATURE_WOL; +- tp->features |= rtl_try_msi(pdev, ioaddr, cfg); ++ tp->features |= rtl_try_msi(tp, cfg); + RTL_W8(Cfg9346, Cfg9346_Lock); + + if ((tp->mac_version <= RTL_GIGA_MAC_VER_06) && diff --git a/queue-3.0/r8169-fix-unsigned-int-wraparound-with-tso.patch b/queue-3.0/r8169-fix-unsigned-int-wraparound-with-tso.patch new file mode 100644 index 00000000000..f82f7aecf2b --- /dev/null +++ b/queue-3.0/r8169-fix-unsigned-int-wraparound-with-tso.patch @@ -0,0 +1,77 @@ +From stable-owner@vger.kernel.org Sat Oct 6 06:49:18 2012 +From: Francois Romieu +Date: Fri, 5 Oct 2012 23:29:20 +0200 +Subject: r8169: fix unsigned int wraparound with TSO +To: stable@vger.kernel.org +Cc: Hayes Wang , Jonathan Nieder + +From: Julien Ducourthial + +commit 477206a018f902895bfcd069dd820bfe94c187b1 upstream. + +The r8169 may get stuck or show bad behaviour after activating TSO : +the net_device is not stopped when it has no more TX descriptors. +This problem comes from TX_BUFS_AVAIL which may reach -1 when all +transmit descriptors are in use. The patch simply tries to keep positive +values. + +Tested with 8111d(onboard) on a D510MO, and with 8111e(onboard) on a +Zotac 890GXITX. + +Signed-off-by: Julien Ducourthial +Acked-by: Francois Romieu +Signed-off-by: David S. Miller +Reviewed-by: Jonathan Nieder +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/r8169.c | 16 ++++++++++------ + 1 file changed, 10 insertions(+), 6 deletions(-) + +--- a/drivers/net/r8169.c ++++ b/drivers/net/r8169.c +@@ -58,8 +58,12 @@ + #define R8169_MSG_DEFAULT \ + (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN) + +-#define TX_BUFFS_AVAIL(tp) \ +- (tp->dirty_tx + NUM_TX_DESC - tp->cur_tx - 1) ++#define TX_SLOTS_AVAIL(tp) \ ++ (tp->dirty_tx + NUM_TX_DESC - tp->cur_tx) ++ ++/* A skbuff with nr_frags needs nr_frags+1 entries in the tx queue */ ++#define TX_FRAGS_READY_FOR(tp,nr_frags) \ ++ (TX_SLOTS_AVAIL(tp) >= (nr_frags + 1)) + + /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). + The RTL chips use a 64 element hash table based on the Ethernet CRC. */ +@@ -4924,7 +4928,7 @@ static netdev_tx_t rtl8169_start_xmit(st + u32 opts[2]; + int frags; + +- if (unlikely(TX_BUFFS_AVAIL(tp) < skb_shinfo(skb)->nr_frags)) { ++ if (unlikely(!TX_FRAGS_READY_FOR(tp, skb_shinfo(skb)->nr_frags))) { + netif_err(tp, drv, dev, "BUG! Tx Ring full when queue awake!\n"); + goto err_stop_0; + } +@@ -4972,10 +4976,10 @@ static netdev_tx_t rtl8169_start_xmit(st + + RTL_W8(TxPoll, NPQ); + +- if (TX_BUFFS_AVAIL(tp) < MAX_SKB_FRAGS) { ++ if (!TX_FRAGS_READY_FOR(tp, MAX_SKB_FRAGS)) { + netif_stop_queue(dev); + smp_mb(); +- if (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS) ++ if (TX_FRAGS_READY_FOR(tp, MAX_SKB_FRAGS)) + netif_wake_queue(dev); + } + +@@ -5077,7 +5081,7 @@ static void rtl8169_tx_interrupt(struct + tp->dirty_tx = dirty_tx; + smp_mb(); + if (netif_queue_stopped(dev) && +- (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS)) { ++ TX_FRAGS_READY_FOR(tp, MAX_SKB_FRAGS)) { + netif_wake_queue(dev); + } + /* diff --git a/queue-3.0/r8169-fix-wake-on-lan-setting-for-non-8111e.patch b/queue-3.0/r8169-fix-wake-on-lan-setting-for-non-8111e.patch new file mode 100644 index 00000000000..e943afb0c51 --- /dev/null +++ b/queue-3.0/r8169-fix-wake-on-lan-setting-for-non-8111e.patch @@ -0,0 +1,38 @@ +From stable-owner@vger.kernel.org Sat Oct 6 06:49:16 2012 +From: Francois Romieu +Date: Fri, 5 Oct 2012 23:29:08 +0200 +Subject: r8169: fix wake on lan setting for non-8111E. +To: stable@vger.kernel.org +Cc: Hayes Wang , Jonathan Nieder + +From: Hayes Wang + +commit d4ed95d796e5126bba51466dc07e287cebc8bd19 upstream. + +Only 8111E needs enable RxConfig bit 0 ~ 3 when suspending or +shutdowning for wake on lan. + +Signed-off-by: Hayes Wang +Acked-by: Francois Romieu +Reviewed-by: Jonathan Nieder +Acked-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/r8169.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/net/r8169.c ++++ b/drivers/net/r8169.c +@@ -3126,8 +3126,10 @@ static void r8168_pll_power_down(struct + rtl_writephy(tp, 0x1f, 0x0000); + rtl_writephy(tp, MII_BMCR, 0x0000); + +- RTL_W32(RxConfig, RTL_R32(RxConfig) | +- AcceptBroadcast | AcceptMulticast | AcceptMyPhys); ++ if (tp->mac_version == RTL_GIGA_MAC_VER_32 || ++ tp->mac_version == RTL_GIGA_MAC_VER_33) ++ RTL_W32(RxConfig, RTL_R32(RxConfig) | AcceptBroadcast | ++ AcceptMulticast | AcceptMyPhys); + return; + } + diff --git a/queue-3.0/r8169-increase-the-delay-parameter-of-pm_schedule_suspend.patch b/queue-3.0/r8169-increase-the-delay-parameter-of-pm_schedule_suspend.patch new file mode 100644 index 00000000000..a44a425d618 --- /dev/null +++ b/queue-3.0/r8169-increase-the-delay-parameter-of-pm_schedule_suspend.patch @@ -0,0 +1,38 @@ +From stable-owner@vger.kernel.org Sat Oct 6 06:49:22 2012 +From: Francois Romieu +Date: Fri, 5 Oct 2012 23:29:13 +0200 +Subject: r8169: increase the delay parameter of pm_schedule_suspend +To: stable@vger.kernel.org +Cc: Hayes Wang , Jonathan Nieder +Message-ID: + + +From: hayeswang + +commit 10953db8e1a278742ef7e64a3d1491802bcfa98b upstream +The link down would occur when reseting PHY. And it would take about 2 ~ 5 +seconds from link down to link up. If the delay of pm_schedule_suspend is +not long enough, the device would enter runtime_suspend before link up. +After link up, the device would wake up and reset PHY again. Then, you +would find the driver keep in a loop of runtime_suspend and rumtime_resume. + +Signed-off-by: Hayes Wang +Acked-by: Francois Romieu +Signed-off-by: David S. Miller +Reviewed-by: Jonathan Nieder +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/r8169.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/r8169.c ++++ b/drivers/net/r8169.c +@@ -1157,7 +1157,7 @@ static void __rtl8169_check_link_status( + netif_carrier_off(dev); + netif_info(tp, ifdown, dev, "link down\n"); + if (pm) +- pm_schedule_suspend(&tp->pci_dev->dev, 100); ++ pm_schedule_suspend(&tp->pci_dev->dev, 5000); + } + spin_unlock_irqrestore(&tp->lock, flags); + } diff --git a/queue-3.0/r8169-jumbo-fixes.patch b/queue-3.0/r8169-jumbo-fixes.patch new file mode 100644 index 00000000000..6ce6cf6bd1e --- /dev/null +++ b/queue-3.0/r8169-jumbo-fixes.patch @@ -0,0 +1,470 @@ +From stable-owner@vger.kernel.org Sat Oct 6 06:49:24 2012 +From: Francois Romieu +Date: Fri, 5 Oct 2012 23:29:11 +0200 +Subject: r8169: jumbo fixes. +To: stable@vger.kernel.org +Cc: Hayes Wang , Jonathan Nieder + +From: Francois Romieu + +commit d58d46b5d85139d18eb939aa7279c160bab70484 upstream. + +- fix features : jumbo frames and checksumming can not be used at the + same time. + +- introduce hw_jumbo_{enable / disable} helpers. Their content has been + creatively extracted from Realtek's own drivers. As an illustration, + it would be nice to know how/if the MaxTxPacketSize register operates + when the device can work with a 9k jumbo frame as its documentation + (8168c) can not be applied beyond ~7k. + +- rtl_tx_performance_tweak is moved forward. No change. + +Signed-off-by: Francois Romieu +Reviewed-by: Jonathan Nieder +Acked-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/r8169.c | 302 ++++++++++++++++++++++++++++++++++++++++++---------- + 1 file changed, 247 insertions(+), 55 deletions(-) + +--- a/drivers/net/r8169.c ++++ b/drivers/net/r8169.c +@@ -140,82 +140,101 @@ enum rtl_tx_desc_version { + RTL_TD_1 = 1, + }; + +-#define _R(NAME,TD,FW) \ +- { .name = NAME, .txd_version = TD, .fw_name = FW } ++#define JUMBO_1K ETH_DATA_LEN ++#define JUMBO_4K (4*1024 - ETH_HLEN - 2) ++#define JUMBO_6K (6*1024 - ETH_HLEN - 2) ++#define JUMBO_7K (7*1024 - ETH_HLEN - 2) ++#define JUMBO_9K (9*1024 - ETH_HLEN - 2) ++ ++#define _R(NAME,TD,FW,SZ,B) { \ ++ .name = NAME, \ ++ .txd_version = TD, \ ++ .fw_name = FW, \ ++ .jumbo_max = SZ, \ ++ .jumbo_tx_csum = B \ ++} + + static const struct { + const char *name; + enum rtl_tx_desc_version txd_version; + const char *fw_name; ++ u16 jumbo_max; ++ bool jumbo_tx_csum; + } rtl_chip_infos[] = { + /* PCI devices. */ + [RTL_GIGA_MAC_VER_01] = +- _R("RTL8169", RTL_TD_0, NULL), ++ _R("RTL8169", RTL_TD_0, NULL, JUMBO_7K, true), + [RTL_GIGA_MAC_VER_02] = +- _R("RTL8169s", RTL_TD_0, NULL), ++ _R("RTL8169s", RTL_TD_0, NULL, JUMBO_7K, true), + [RTL_GIGA_MAC_VER_03] = +- _R("RTL8110s", RTL_TD_0, NULL), ++ _R("RTL8110s", RTL_TD_0, NULL, JUMBO_7K, true), + [RTL_GIGA_MAC_VER_04] = +- _R("RTL8169sb/8110sb", RTL_TD_0, NULL), ++ _R("RTL8169sb/8110sb", RTL_TD_0, NULL, JUMBO_7K, true), + [RTL_GIGA_MAC_VER_05] = +- _R("RTL8169sc/8110sc", RTL_TD_0, NULL), ++ _R("RTL8169sc/8110sc", RTL_TD_0, NULL, JUMBO_7K, true), + [RTL_GIGA_MAC_VER_06] = +- _R("RTL8169sc/8110sc", RTL_TD_0, NULL), ++ _R("RTL8169sc/8110sc", RTL_TD_0, NULL, JUMBO_7K, true), + /* PCI-E devices. */ + [RTL_GIGA_MAC_VER_07] = +- _R("RTL8102e", RTL_TD_1, NULL), ++ _R("RTL8102e", RTL_TD_1, NULL, JUMBO_1K, true), + [RTL_GIGA_MAC_VER_08] = +- _R("RTL8102e", RTL_TD_1, NULL), ++ _R("RTL8102e", RTL_TD_1, NULL, JUMBO_1K, true), + [RTL_GIGA_MAC_VER_09] = +- _R("RTL8102e", RTL_TD_1, NULL), ++ _R("RTL8102e", RTL_TD_1, NULL, JUMBO_1K, true), + [RTL_GIGA_MAC_VER_10] = +- _R("RTL8101e", RTL_TD_0, NULL), ++ _R("RTL8101e", RTL_TD_0, NULL, JUMBO_1K, true), + [RTL_GIGA_MAC_VER_11] = +- _R("RTL8168b/8111b", RTL_TD_0, NULL), ++ _R("RTL8168b/8111b", RTL_TD_0, NULL, JUMBO_4K, false), + [RTL_GIGA_MAC_VER_12] = +- _R("RTL8168b/8111b", RTL_TD_0, NULL), ++ _R("RTL8168b/8111b", RTL_TD_0, NULL, JUMBO_4K, false), + [RTL_GIGA_MAC_VER_13] = +- _R("RTL8101e", RTL_TD_0, NULL), ++ _R("RTL8101e", RTL_TD_0, NULL, JUMBO_1K, true), + [RTL_GIGA_MAC_VER_14] = +- _R("RTL8100e", RTL_TD_0, NULL), ++ _R("RTL8100e", RTL_TD_0, NULL, JUMBO_1K, true), + [RTL_GIGA_MAC_VER_15] = +- _R("RTL8100e", RTL_TD_0, NULL), ++ _R("RTL8100e", RTL_TD_0, NULL, JUMBO_1K, true), + [RTL_GIGA_MAC_VER_16] = +- _R("RTL8101e", RTL_TD_0, NULL), ++ _R("RTL8101e", RTL_TD_0, NULL, JUMBO_1K, true), + [RTL_GIGA_MAC_VER_17] = +- _R("RTL8168b/8111b", RTL_TD_0, NULL), ++ _R("RTL8168b/8111b", RTL_TD_1, NULL, JUMBO_4K, false), + [RTL_GIGA_MAC_VER_18] = +- _R("RTL8168cp/8111cp", RTL_TD_1, NULL), ++ _R("RTL8168cp/8111cp", RTL_TD_1, NULL, JUMBO_6K, false), + [RTL_GIGA_MAC_VER_19] = +- _R("RTL8168c/8111c", RTL_TD_1, NULL), ++ _R("RTL8168c/8111c", RTL_TD_1, NULL, JUMBO_6K, false), + [RTL_GIGA_MAC_VER_20] = +- _R("RTL8168c/8111c", RTL_TD_1, NULL), ++ _R("RTL8168c/8111c", RTL_TD_1, NULL, JUMBO_6K, false), + [RTL_GIGA_MAC_VER_21] = +- _R("RTL8168c/8111c", RTL_TD_1, NULL), ++ _R("RTL8168c/8111c", RTL_TD_1, NULL, JUMBO_6K, false), + [RTL_GIGA_MAC_VER_22] = +- _R("RTL8168c/8111c", RTL_TD_1, NULL), ++ _R("RTL8168c/8111c", RTL_TD_1, NULL, JUMBO_6K, false), + [RTL_GIGA_MAC_VER_23] = +- _R("RTL8168cp/8111cp", RTL_TD_1, NULL), ++ _R("RTL8168cp/8111cp", RTL_TD_1, NULL, JUMBO_6K, false), + [RTL_GIGA_MAC_VER_24] = +- _R("RTL8168cp/8111cp", RTL_TD_1, NULL), ++ _R("RTL8168cp/8111cp", RTL_TD_1, NULL, JUMBO_6K, false), + [RTL_GIGA_MAC_VER_25] = +- _R("RTL8168d/8111d", RTL_TD_1, FIRMWARE_8168D_1), ++ _R("RTL8168d/8111d", RTL_TD_1, FIRMWARE_8168D_1, ++ JUMBO_9K, false), + [RTL_GIGA_MAC_VER_26] = +- _R("RTL8168d/8111d", RTL_TD_1, FIRMWARE_8168D_2), ++ _R("RTL8168d/8111d", RTL_TD_1, FIRMWARE_8168D_2, ++ JUMBO_9K, false), + [RTL_GIGA_MAC_VER_27] = +- _R("RTL8168dp/8111dp", RTL_TD_1, NULL), ++ _R("RTL8168dp/8111dp", RTL_TD_1, NULL, JUMBO_9K, false), + [RTL_GIGA_MAC_VER_28] = +- _R("RTL8168dp/8111dp", RTL_TD_1, NULL), ++ _R("RTL8168dp/8111dp", RTL_TD_1, NULL, JUMBO_9K, false), + [RTL_GIGA_MAC_VER_29] = +- _R("RTL8105e", RTL_TD_1, FIRMWARE_8105E_1), ++ _R("RTL8105e", RTL_TD_1, FIRMWARE_8105E_1, ++ JUMBO_1K, true), + [RTL_GIGA_MAC_VER_30] = +- _R("RTL8105e", RTL_TD_1, FIRMWARE_8105E_1), ++ _R("RTL8105e", RTL_TD_1, FIRMWARE_8105E_1, ++ JUMBO_1K, true), + [RTL_GIGA_MAC_VER_31] = +- _R("RTL8168dp/8111dp", RTL_TD_1, NULL), ++ _R("RTL8168dp/8111dp", RTL_TD_1, NULL, JUMBO_9K, false), + [RTL_GIGA_MAC_VER_32] = +- _R("RTL8168e/8111e", RTL_TD_1, FIRMWARE_8168E_1), ++ _R("RTL8168e/8111e", RTL_TD_1, FIRMWARE_8168E_1, ++ JUMBO_9K, false), + [RTL_GIGA_MAC_VER_33] = +- _R("RTL8168e/8111e", RTL_TD_1, FIRMWARE_8168E_2) ++ _R("RTL8168e/8111e", RTL_TD_1, FIRMWARE_8168E_2, ++ JUMBO_9K, false) + }; + #undef _R + +@@ -443,8 +462,12 @@ enum rtl_register_content { + /* Config3 register p.25 */ + MagicPacket = (1 << 5), /* Wake up when receives a Magic Packet */ + LinkUp = (1 << 4), /* Wake up when the cable connection is re-established */ ++ Jumbo_En0 = (1 << 2), /* 8168 only. Reserved in the 8168b */ + Beacon_en = (1 << 0), /* 8168 only. Reserved in the 8168b */ + ++ /* Config4 register */ ++ Jumbo_En1 = (1 << 1), /* 8168 only. Reserved in the 8168b */ ++ + /* Config5 register p.27 */ + BWF = (1 << 6), /* Accept Broadcast wakeup frame */ + MWF = (1 << 5), /* Accept Multicast wakeup frame */ +@@ -653,6 +676,11 @@ struct rtl8169_private { + void (*up)(struct rtl8169_private *); + } pll_power_ops; + ++ struct jumbo_ops { ++ void (*enable)(struct rtl8169_private *); ++ void (*disable)(struct rtl8169_private *); ++ } jumbo_ops; ++ + int (*set_speed)(struct net_device *, u8 aneg, u16 sp, u8 dpx, u32 adv); + int (*get_settings)(struct net_device *, struct ethtool_cmd *); + void (*phy_reset_enable)(struct rtl8169_private *tp); +@@ -707,6 +735,21 @@ static int rtl8169_poll(struct napi_stru + static const unsigned int rtl8169_rx_config = + (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift); + ++static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force) ++{ ++ struct net_device *dev = pci_get_drvdata(pdev); ++ struct rtl8169_private *tp = netdev_priv(dev); ++ int cap = tp->pcie_cap; ++ ++ if (cap) { ++ u16 ctl; ++ ++ pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl); ++ ctl = (ctl & ~PCI_EXP_DEVCTL_READRQ) | force; ++ pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl); ++ } ++} ++ + static u32 ocp_read(struct rtl8169_private *tp, u8 mask, u16 reg) + { + void __iomem *ioaddr = tp->mmio_addr; +@@ -1375,9 +1418,15 @@ static int rtl8169_set_settings(struct n + + static u32 rtl8169_fix_features(struct net_device *dev, u32 features) + { ++ struct rtl8169_private *tp = netdev_priv(dev); ++ + if (dev->mtu > TD_MSS_MAX) + features &= ~NETIF_F_ALL_TSO; + ++ if (dev->mtu > JUMBO_1K && ++ !rtl_chip_infos[tp->mac_version].jumbo_tx_csum) ++ features &= ~NETIF_F_IP_CSUM; ++ + return features; + } + +@@ -3176,8 +3225,8 @@ static void r8168_pll_power_up(struct rt + r8168_phy_power_up(tp); + } + +-static void rtl_pll_power_op(struct rtl8169_private *tp, +- void (*op)(struct rtl8169_private *)) ++static void rtl_generic_op(struct rtl8169_private *tp, ++ void (*op)(struct rtl8169_private *)) + { + if (op) + op(tp); +@@ -3185,12 +3234,12 @@ static void rtl_pll_power_op(struct rtl8 + + static void rtl_pll_power_down(struct rtl8169_private *tp) + { +- rtl_pll_power_op(tp, tp->pll_power_ops.down); ++ rtl_generic_op(tp, tp->pll_power_ops.down); + } + + static void rtl_pll_power_up(struct rtl8169_private *tp) + { +- rtl_pll_power_op(tp, tp->pll_power_ops.up); ++ rtl_generic_op(tp, tp->pll_power_ops.up); + } + + static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp) +@@ -3237,6 +3286,149 @@ static void __devinit rtl_init_pll_power + } + } + ++static void rtl_hw_jumbo_enable(struct rtl8169_private *tp) ++{ ++ rtl_generic_op(tp, tp->jumbo_ops.enable); ++} ++ ++static void rtl_hw_jumbo_disable(struct rtl8169_private *tp) ++{ ++ rtl_generic_op(tp, tp->jumbo_ops.disable); ++} ++ ++static void r8168c_hw_jumbo_enable(struct rtl8169_private *tp) ++{ ++ void __iomem *ioaddr = tp->mmio_addr; ++ ++ RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0); ++ RTL_W8(Config4, RTL_R8(Config4) | Jumbo_En1); ++ rtl_tx_performance_tweak(tp->pci_dev, 0x2 << MAX_READ_REQUEST_SHIFT); ++} ++ ++static void r8168c_hw_jumbo_disable(struct rtl8169_private *tp) ++{ ++ void __iomem *ioaddr = tp->mmio_addr; ++ ++ RTL_W8(Config3, RTL_R8(Config3) & ~Jumbo_En0); ++ RTL_W8(Config4, RTL_R8(Config4) & ~Jumbo_En1); ++ rtl_tx_performance_tweak(tp->pci_dev, 0x5 << MAX_READ_REQUEST_SHIFT); ++} ++ ++static void r8168dp_hw_jumbo_enable(struct rtl8169_private *tp) ++{ ++ void __iomem *ioaddr = tp->mmio_addr; ++ ++ RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0); ++} ++ ++static void r8168dp_hw_jumbo_disable(struct rtl8169_private *tp) ++{ ++ void __iomem *ioaddr = tp->mmio_addr; ++ ++ RTL_W8(Config3, RTL_R8(Config3) & ~Jumbo_En0); ++} ++ ++static void r8168e_hw_jumbo_enable(struct rtl8169_private *tp) ++{ ++ void __iomem *ioaddr = tp->mmio_addr; ++ struct pci_dev *pdev = tp->pci_dev; ++ ++ RTL_W8(MaxTxPacketSize, 0x3f); ++ RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0); ++ RTL_W8(Config4, RTL_R8(Config4) | 0x01); ++ pci_write_config_byte(pdev, 0x79, 0x20); ++} ++ ++static void r8168e_hw_jumbo_disable(struct rtl8169_private *tp) ++{ ++ void __iomem *ioaddr = tp->mmio_addr; ++ struct pci_dev *pdev = tp->pci_dev; ++ ++ RTL_W8(MaxTxPacketSize, 0x0c); ++ RTL_W8(Config3, RTL_R8(Config3) & ~Jumbo_En0); ++ RTL_W8(Config4, RTL_R8(Config4) & ~0x01); ++ pci_write_config_byte(pdev, 0x79, 0x50); ++} ++ ++static void r8168b_0_hw_jumbo_enable(struct rtl8169_private *tp) ++{ ++ rtl_tx_performance_tweak(tp->pci_dev, ++ (0x2 << MAX_READ_REQUEST_SHIFT) | PCI_EXP_DEVCTL_NOSNOOP_EN); ++} ++ ++static void r8168b_0_hw_jumbo_disable(struct rtl8169_private *tp) ++{ ++ rtl_tx_performance_tweak(tp->pci_dev, ++ (0x5 << MAX_READ_REQUEST_SHIFT) | PCI_EXP_DEVCTL_NOSNOOP_EN); ++} ++ ++static void r8168b_1_hw_jumbo_enable(struct rtl8169_private *tp) ++{ ++ void __iomem *ioaddr = tp->mmio_addr; ++ ++ r8168b_0_hw_jumbo_enable(tp); ++ ++ RTL_W8(Config4, RTL_R8(Config4) | (1 << 0)); ++} ++ ++static void r8168b_1_hw_jumbo_disable(struct rtl8169_private *tp) ++{ ++ void __iomem *ioaddr = tp->mmio_addr; ++ ++ r8168b_0_hw_jumbo_disable(tp); ++ ++ RTL_W8(Config4, RTL_R8(Config4) & ~(1 << 0)); ++} ++ ++static void __devinit rtl_init_jumbo_ops(struct rtl8169_private *tp) ++{ ++ struct jumbo_ops *ops = &tp->jumbo_ops; ++ ++ switch (tp->mac_version) { ++ case RTL_GIGA_MAC_VER_11: ++ ops->disable = r8168b_0_hw_jumbo_disable; ++ ops->enable = r8168b_0_hw_jumbo_enable; ++ break; ++ case RTL_GIGA_MAC_VER_12: ++ case RTL_GIGA_MAC_VER_17: ++ ops->disable = r8168b_1_hw_jumbo_disable; ++ ops->enable = r8168b_1_hw_jumbo_enable; ++ break; ++ case RTL_GIGA_MAC_VER_18: /* Wild guess. Needs info from Realtek. */ ++ case RTL_GIGA_MAC_VER_19: ++ case RTL_GIGA_MAC_VER_20: ++ case RTL_GIGA_MAC_VER_21: /* Wild guess. Needs info from Realtek. */ ++ case RTL_GIGA_MAC_VER_22: ++ case RTL_GIGA_MAC_VER_23: ++ case RTL_GIGA_MAC_VER_24: ++ case RTL_GIGA_MAC_VER_25: ++ case RTL_GIGA_MAC_VER_26: ++ ops->disable = r8168c_hw_jumbo_disable; ++ ops->enable = r8168c_hw_jumbo_enable; ++ break; ++ case RTL_GIGA_MAC_VER_27: ++ case RTL_GIGA_MAC_VER_28: ++ ops->disable = r8168dp_hw_jumbo_disable; ++ ops->enable = r8168dp_hw_jumbo_enable; ++ break; ++ case RTL_GIGA_MAC_VER_31: /* Wild guess. Needs info from Realtek. */ ++ case RTL_GIGA_MAC_VER_32: ++ case RTL_GIGA_MAC_VER_33: ++ ops->disable = r8168e_hw_jumbo_disable; ++ ops->enable = r8168e_hw_jumbo_enable; ++ break; ++ ++ /* ++ * No action needed for jumbo frames with 8169. ++ * No jumbo for 810x at all. ++ */ ++ default: ++ ops->disable = NULL; ++ ops->enable = NULL; ++ break; ++ } ++} ++ + static void rtl_hw_reset(struct rtl8169_private *tp) + { + void __iomem *ioaddr = tp->mmio_addr; +@@ -3378,6 +3570,7 @@ rtl8169_init_one(struct pci_dev *pdev, c + + rtl_init_mdio_ops(tp); + rtl_init_pll_power_ops(tp); ++ rtl_init_jumbo_ops(tp); + + rtl8169_print_mac_version(tp); + +@@ -3462,6 +3655,12 @@ rtl8169_init_one(struct pci_dev *pdev, c + netif_info(tp, probe, dev, "%s at 0x%lx, %pM, XID %08x IRQ %d\n", + rtl_chip_infos[chipset].name, dev->base_addr, dev->dev_addr, + (u32)(RTL_R32(TxConfig) & 0x9cf0f8ff), dev->irq); ++ if (rtl_chip_infos[chipset].jumbo_max != JUMBO_1K) { ++ netif_info(tp, probe, dev, "jumbo features [frames: %d bytes, " ++ "tx checksumming: %s]\n", ++ rtl_chip_infos[chipset].jumbo_max, ++ rtl_chip_infos[chipset].jumbo_tx_csum ? "ok" : "ko"); ++ } + + if (tp->mac_version == RTL_GIGA_MAC_VER_27 || + tp->mac_version == RTL_GIGA_MAC_VER_28 || +@@ -3786,21 +3985,6 @@ static void rtl_hw_start_8169(struct net + RTL_W16(IntrMask, tp->intr_event); + } + +-static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force) +-{ +- struct net_device *dev = pci_get_drvdata(pdev); +- struct rtl8169_private *tp = netdev_priv(dev); +- int cap = tp->pcie_cap; +- +- if (cap) { +- u16 ctl; +- +- pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl); +- ctl = (ctl & ~PCI_EXP_DEVCTL_READRQ) | force; +- pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl); +- } +-} +- + static void rtl_csi_access_enable(void __iomem *ioaddr, u32 bits) + { + u32 csi; +@@ -4343,9 +4527,17 @@ static void rtl_hw_start_8101(struct net + + static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) + { +- if (new_mtu < ETH_ZLEN || new_mtu > SafeMtu) ++ struct rtl8169_private *tp = netdev_priv(dev); ++ ++ if (new_mtu < ETH_ZLEN || ++ new_mtu > rtl_chip_infos[tp->mac_version].jumbo_max) + return -EINVAL; + ++ if (new_mtu > ETH_DATA_LEN) ++ rtl_hw_jumbo_enable(tp); ++ else ++ rtl_hw_jumbo_disable(tp); ++ + dev->mtu = new_mtu; + netdev_update_features(dev); + diff --git a/queue-3.0/r8169-missing-barriers.patch b/queue-3.0/r8169-missing-barriers.patch new file mode 100644 index 00000000000..1e466666f5c --- /dev/null +++ b/queue-3.0/r8169-missing-barriers.patch @@ -0,0 +1,47 @@ +From stable-owner@vger.kernel.org Sat Oct 6 06:49:21 2012 +From: Francois Romieu +Date: Fri, 5 Oct 2012 23:29:16 +0200 +Subject: r8169: missing barriers. +To: stable@vger.kernel.org +Cc: Hayes Wang , Jonathan Nieder + + +commit 1e874e041fc7c222cbd85b20c4406070be1f687a upstream. + +Signed-off-by: Francois Romieu +Cc: Hayes Wang +Reviewed-by: Jonathan Nieder +Acked-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/r8169.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/drivers/net/r8169.c ++++ b/drivers/net/r8169.c +@@ -4957,7 +4957,7 @@ static netdev_tx_t rtl8169_start_xmit(st + + if (TX_BUFFS_AVAIL(tp) < MAX_SKB_FRAGS) { + netif_stop_queue(dev); +- smp_rmb(); ++ smp_mb(); + if (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS) + netif_wake_queue(dev); + } +@@ -5058,7 +5058,7 @@ static void rtl8169_tx_interrupt(struct + + if (tp->dirty_tx != dirty_tx) { + tp->dirty_tx = dirty_tx; +- smp_wmb(); ++ smp_mb(); + if (netif_queue_stopped(dev) && + (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS)) { + netif_wake_queue(dev); +@@ -5069,7 +5069,6 @@ static void rtl8169_tx_interrupt(struct + * of start_xmit activity is detected (if it is not detected, + * it is slow enough). -- FR + */ +- smp_rmb(); + if (tp->cur_tx != dirty_tx) + RTL_W8(TxPoll, NPQ); + } diff --git a/queue-3.0/r8169-remove-erroneous-processing-of-always-set-bit.patch b/queue-3.0/r8169-remove-erroneous-processing-of-always-set-bit.patch new file mode 100644 index 00000000000..98a1c4fab03 --- /dev/null +++ b/queue-3.0/r8169-remove-erroneous-processing-of-always-set-bit.patch @@ -0,0 +1,59 @@ +From stable-owner@vger.kernel.org Sat Oct 6 06:49:18 2012 +From: Francois Romieu +Date: Fri, 5 Oct 2012 23:29:10 +0200 +Subject: r8169: remove erroneous processing of always set bit. +To: stable@vger.kernel.org +Cc: Hayes Wang , Jonathan Nieder + +From: Francois Romieu + +commit e03f33af79f0772156e1a1a1e36bdddf8012b2e4 upstream. + +When set, RxFOVF (resp. RxBOVF) is always 1 (resp. 0). + +Signed-off-by: Francois Romieu +Cc: Hayes +Reviewed-by: Jonathan Nieder +Acked-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/r8169.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/net/r8169.c ++++ b/drivers/net/r8169.c +@@ -388,6 +388,7 @@ enum rtl_register_content { + RxOK = 0x0001, + + /* RxStatusDesc */ ++ RxBOVF = (1 << 24), + RxFOVF = (1 << 23), + RxRWT = (1 << 22), + RxRES = (1 << 21), +@@ -666,6 +667,7 @@ struct rtl8169_private { + struct mii_if_info mii; + struct rtl8169_counters counters; + u32 saved_wolopts; ++ u32 opts1_mask; + + const struct firmware *fw; + #define RTL_FIRMWARE_UNKNOWN ERR_PTR(-EAGAIN); +@@ -3442,6 +3444,9 @@ rtl8169_init_one(struct pci_dev *pdev, c + tp->intr_event = cfg->intr_event; + tp->napi_event = cfg->napi_event; + ++ tp->opts1_mask = (tp->mac_version != RTL_GIGA_MAC_VER_01) ? ++ ~(RxBOVF | RxFOVF) : ~0; ++ + init_timer(&tp->timer); + tp->timer.data = (unsigned long) dev; + tp->timer.function = rtl8169_phy_timer; +@@ -4920,7 +4925,7 @@ static int rtl8169_rx_interrupt(struct n + u32 status; + + rmb(); +- status = le32_to_cpu(desc->opts1); ++ status = le32_to_cpu(desc->opts1) & tp->opts1_mask; + + if (status & DescOwn) + break; diff --git a/queue-3.0/r8169-runtime-resume-before-shutdown.patch b/queue-3.0/r8169-runtime-resume-before-shutdown.patch new file mode 100644 index 00000000000..8db9d900fb3 --- /dev/null +++ b/queue-3.0/r8169-runtime-resume-before-shutdown.patch @@ -0,0 +1,58 @@ +From stable-owner@vger.kernel.org Sat Oct 6 06:49:16 2012 +From: Francois Romieu +Date: Fri, 5 Oct 2012 23:29:17 +0200 +Subject: r8169: runtime resume before shutdown. +To: stable@vger.kernel.org +Cc: Hayes Wang , Jonathan Nieder + + +From: françois romieu + +commit 2a15cd2ff488a9fdb55e5e34060f499853b27c77 upstream. + +With runtime PM, if the ethernet cable is disconnected, the device is +transitioned to D3 state to conserve energy. If the system is shutdown +in this state, any register accesses in rtl_shutdown are dropped on +the floor. As the device was programmed by .runtime_suspend() to wake +on link changes, it is thus brought back up as soon as the link recovers. + +Resuming every suspended device through the driver core would slow things +down and it is not clear how many devices really need it now. + +Original report and D0 transition patch by Sameer Nanda. Patch has been +changed to comply with advices by Rafael J. Wysocki and the PM folks. + +Reported-by: Sameer Nanda +Signed-off-by: Francois Romieu +Cc: Rafael J. Wysocki +Cc: Hayes Wang +Cc: Alan Stern +Acked-by: Rafael J. Wysocki +Signed-off-by: David S. Miller +Reviewed-by: Jonathan Nieder +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/r8169.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/net/r8169.c ++++ b/drivers/net/r8169.c +@@ -5570,6 +5570,9 @@ static void rtl_shutdown(struct pci_dev + struct net_device *dev = pci_get_drvdata(pdev); + struct rtl8169_private *tp = netdev_priv(dev); + void __iomem *ioaddr = tp->mmio_addr; ++ struct device *d = &pdev->dev; ++ ++ pm_runtime_get_sync(d); + + rtl8169_net_suspend(dev); + +@@ -5598,6 +5601,8 @@ static void rtl_shutdown(struct pci_dev + pci_wake_from_d3(pdev, true); + pci_set_power_state(pdev, PCI_D3hot); + } ++ ++ pm_runtime_put_noidle(d); + } + + static struct pci_driver rtl8169_pci_driver = { diff --git a/queue-3.0/r8169-rx-fifo-overflow-fixes.patch b/queue-3.0/r8169-rx-fifo-overflow-fixes.patch new file mode 100644 index 00000000000..924ff78d733 --- /dev/null +++ b/queue-3.0/r8169-rx-fifo-overflow-fixes.patch @@ -0,0 +1,184 @@ +From stable-owner@vger.kernel.org Sat Oct 6 06:49:24 2012 +From: Francois Romieu +Date: Fri, 5 Oct 2012 23:29:14 +0200 +Subject: r8169: Rx FIFO overflow fixes. +To: stable@vger.kernel.org +Cc: Hayes Wang , Jonathan Nieder +Message-ID: <4cf78ae52f10e00ad561db9700e2cda2f68bdacf.1349472883.git.romieu@fr.zoreil.com> + +From: Francois Romieu + +commit 811fd3010cf512f2e23e6c4c912aad54516dc706 upstream. + +Realtek has specified that the post 8168c gigabit chips and the post +8105e fast ethernet chips recover automatically from a Rx FIFO overflow. +The driver does not need to clear the RxFIFOOver bit of IntrStatus and +it should rather avoid messing it. + +The implementation deserves some explanation: +1. events outside of the intr_event bit mask are now ignored. It enforces + a no-processing policy for the events that either should not be there + or should be ignored. + +2. RxFIFOOver was already ignored in rtl_cfg_infos[RTL_CFG_1] for the + whole 8168 line of chips with two exceptions: + - RTL_GIGA_MAC_VER_22 since b5ba6d12bdac21bc0620a5089e0f24e362645efd + ("use RxFIFO overflow workaround for 8168c chipset."). + This one should now be correctly handled. + - RTL_GIGA_MAC_VER_11 (8168b) which requires a different Rx FIFO + overflow processing. + + Though it does not conform to Realtek suggestion above, the updated + driver includes no change for RTL_GIGA_MAC_VER_12 and RTL_GIGA_MAC_VER_17. + Both are 8168b. RTL_GIGA_MAC_VER_12 is common and a bit old so I'd rather + wait for experimental evidence that the change suggested by Realtek really + helps or does not hurt in unexpected ways. + + Removed case statements in rtl8169_interrupt are only 8168 relevant. + +3. RxFIFOOver is masked for post 8105e 810x chips, namely the sole 8105e + (RTL_GIGA_MAC_VER_30) itself. + +Signed-off-by: Francois Romieu +Cc: hayeswang +Signed-off-by: David S. Miller +Reviewed-by: Jonathan Nieder +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/r8169.c | 54 +++++++++++++++++++++++----------------------------- + 1 file changed, 24 insertions(+), 30 deletions(-) + +--- a/drivers/net/r8169.c ++++ b/drivers/net/r8169.c +@@ -1088,17 +1088,21 @@ static u8 rtl8168d_efuse_read(void __iom + return value; + } + +-static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr) ++static void rtl8169_irq_mask_and_ack(struct rtl8169_private *tp) + { +- RTL_W16(IntrMask, 0x0000); ++ void __iomem *ioaddr = tp->mmio_addr; + +- RTL_W16(IntrStatus, 0xffff); ++ RTL_W16(IntrMask, 0x0000); ++ RTL_W16(IntrStatus, tp->intr_event); ++ RTL_R8(ChipCmd); + } + +-static void rtl8169_asic_down(void __iomem *ioaddr) ++static void rtl8169_asic_down(struct rtl8169_private *tp) + { ++ void __iomem *ioaddr = tp->mmio_addr; ++ + RTL_W8(ChipCmd, 0x00); +- rtl8169_irq_mask_and_ack(ioaddr); ++ rtl8169_irq_mask_and_ack(tp); + RTL_R16(CPlusCmd); + } + +@@ -3817,7 +3821,7 @@ static void rtl8169_hw_reset(struct rtl8 + void __iomem *ioaddr = tp->mmio_addr; + + /* Disable interrupts */ +- rtl8169_irq_mask_and_ack(ioaddr); ++ rtl8169_irq_mask_and_ack(tp); + + if (tp->mac_version == RTL_GIGA_MAC_VER_27 || + tp->mac_version == RTL_GIGA_MAC_VER_28 || +@@ -4284,8 +4288,7 @@ static void rtl_hw_start_8168(struct net + RTL_W16(IntrMitigate, 0x5151); + + /* Work around for RxFIFO overflow. */ +- if (tp->mac_version == RTL_GIGA_MAC_VER_11 || +- tp->mac_version == RTL_GIGA_MAC_VER_22) { ++ if (tp->mac_version == RTL_GIGA_MAC_VER_11) { + tp->intr_event |= RxFIFOOver | PCSTimeout; + tp->intr_event &= ~RxOverflow; + } +@@ -4467,6 +4470,11 @@ static void rtl_hw_start_8101(struct net + void __iomem *ioaddr = tp->mmio_addr; + struct pci_dev *pdev = tp->pci_dev; + ++ if (tp->mac_version >= RTL_GIGA_MAC_VER_30) { ++ tp->intr_event &= ~RxFIFOOver; ++ tp->napi_event &= ~RxFIFOOver; ++ } ++ + if (tp->mac_version == RTL_GIGA_MAC_VER_13 || + tp->mac_version == RTL_GIGA_MAC_VER_16) { + int cap = tp->pcie_cap; +@@ -4738,7 +4746,7 @@ static void rtl8169_wait_for_quiescence( + /* Wait for any pending NAPI task to complete */ + napi_disable(&tp->napi); + +- rtl8169_irq_mask_and_ack(ioaddr); ++ rtl8169_irq_mask_and_ack(tp); + + tp->intr_mask = 0xffff; + RTL_W16(IntrMask, tp->intr_event); +@@ -5200,13 +5208,17 @@ static irqreturn_t rtl8169_interrupt(int + */ + status = RTL_R16(IntrStatus); + while (status && status != 0xffff) { ++ status &= tp->intr_event; ++ if (!status) ++ break; ++ + handled = 1; + + /* Handle all of the error cases first. These will reset + * the chip, so just exit the loop. + */ + if (unlikely(!netif_running(dev))) { +- rtl8169_asic_down(ioaddr); ++ rtl8169_asic_down(tp); + break; + } + +@@ -5214,27 +5226,9 @@ static irqreturn_t rtl8169_interrupt(int + switch (tp->mac_version) { + /* Work around for rx fifo overflow */ + case RTL_GIGA_MAC_VER_11: +- case RTL_GIGA_MAC_VER_22: +- case RTL_GIGA_MAC_VER_26: + netif_stop_queue(dev); + rtl8169_tx_timeout(dev); + goto done; +- /* Testers needed. */ +- case RTL_GIGA_MAC_VER_17: +- case RTL_GIGA_MAC_VER_19: +- case RTL_GIGA_MAC_VER_20: +- case RTL_GIGA_MAC_VER_21: +- case RTL_GIGA_MAC_VER_23: +- case RTL_GIGA_MAC_VER_24: +- case RTL_GIGA_MAC_VER_27: +- case RTL_GIGA_MAC_VER_28: +- case RTL_GIGA_MAC_VER_31: +- /* Experimental science. Pktgen proof. */ +- case RTL_GIGA_MAC_VER_12: +- case RTL_GIGA_MAC_VER_25: +- if (status == RxFIFOOver) +- goto done; +- break; + default: + break; + } +@@ -5329,7 +5323,7 @@ static void rtl8169_down(struct net_devi + + spin_lock_irq(&tp->lock); + +- rtl8169_asic_down(ioaddr); ++ rtl8169_asic_down(tp); + /* + * At this point device interrupts can not be enabled in any function, + * as netif_running is not true (rtl8169_interrupt, rtl8169_reset_task, +@@ -5583,7 +5577,7 @@ static void rtl_shutdown(struct pci_dev + + spin_lock_irq(&tp->lock); + +- rtl8169_asic_down(ioaddr); ++ rtl8169_asic_down(tp); + + spin_unlock_irq(&tp->lock); + diff --git a/queue-3.0/series b/queue-3.0/series index 6d0c96e35d8..a1ae5aa69be 100644 --- a/queue-3.0/series +++ b/queue-3.0/series @@ -58,3 +58,17 @@ drm-radeon-only-adjust-default-clocks-on-ni-gpus.patch drm-radeon-add-msi-quirk-for-gateway-rs690.patch drm-radeon-force-msis-on-rs690-asics.patch rcu-fix-day-one-dyntick-idle-stall-warning-bug.patch +r8169-fix-wake-on-lan-setting-for-non-8111e.patch +r8169-don-t-enable-rx-when-shutdown.patch +r8169-remove-erroneous-processing-of-always-set-bit.patch +r8169-jumbo-fixes.patch +r8169-expand-received-packet-length-indication.patch +r8169-increase-the-delay-parameter-of-pm_schedule_suspend.patch +r8169-rx-fifo-overflow-fixes.patch +r8169-fix-config2-msienable-bit-setting.patch +r8169-missing-barriers.patch +r8169-runtime-resume-before-shutdown.patch +r8169-config1-is-read-only-on-8168c-and-later.patch +r8169-8168c-and-later-require-bit-0x20-to-be-set-in-config2-for-pme-signaling.patch +r8169-fix-unsigned-int-wraparound-with-tso.patch +r8169-call-netif_napi_del-at-errpaths-and-at-driver-unload.patch