--- /dev/null
+From stable-owner@vger.kernel.org Sat Oct 6 06:49:20 2012
+From: Francois Romieu <romieu@fr.zoreil.com>
+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 <hayeswang@realtek.com>, Jonathan Nieder <jrnieder@gmail.com>
+
+From: Francois Romieu <romieu@fr.zoreil.com>
+
+commit d387b427c973974dd619a33549c070ac5d0e089f upstream.
+
+The new 84xx stopped flying below the radars.
+
+Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
+Cc: Hayes Wang <hayeswang@realtek.com>
+Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
+Acked-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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;
+ }
+
--- /dev/null
+From stable-owner@vger.kernel.org Sat Oct 6 06:49:17 2012
+From: Francois Romieu <romieu@fr.zoreil.com>
+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 <hayeswang@realtek.com>, Jonathan Nieder <jrnieder@gmail.com>
+
+From: Devendra Naga <devendra.aaru@gmail.com>
+
+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 <devendra.aaru@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);
--- /dev/null
+From stable-owner@vger.kernel.org Sat Oct 6 06:49:23 2012
+From: Francois Romieu <romieu@fr.zoreil.com>
+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 <hayeswang@realtek.com>, Jonathan Nieder <jrnieder@gmail.com>
+
+From: Francois Romieu <romieu@fr.zoreil.com>
+
+commit 851e60221926a53344b4227879858bef841b0477 upstream.
+
+Suggested by Hayes.
+
+Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
+Cc: Hayes Wang <hayeswang@realtek.com>
+Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
+Acked-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);
+ }
+
--- /dev/null
+From stable-owner@vger.kernel.org Sat Oct 6 06:49:20 2012
+From: Francois Romieu <romieu@fr.zoreil.com>
+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 <hayeswang@realtek.com>, Jonathan Nieder <jrnieder@gmail.com>
+
+From: Hayes Wang <hayeswang@realtek.com>
+
+commit aaa89c08d9ffa3739c93d65d98b73ec2aa2e93a5 upstream.
+
+Only 8111b needs to enable rx when shutdowning with WoL.
+
+Signed-off-by: Hayes Wang <hayeswang@realtek.com>
+Acked-by: Francois Romieu <romieu@fr.zoreil.com>
+Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
+Acked-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);
--- /dev/null
+From stable-owner@vger.kernel.org Sat Oct 6 06:49:19 2012
+From: Francois Romieu <romieu@fr.zoreil.com>
+Date: Fri, 5 Oct 2012 23:29:12 +0200
+Subject: r8169: expand received packet length indication.
+To: stable@vger.kernel.org
+Cc: Hayes Wang <hayeswang@realtek.com>, Jonathan Nieder <jrnieder@gmail.com>
+Message-ID: <f5c42d7ca0e9c908b778f1f1e978a71fb3b92e04.1349472883.git.romieu@fr.zoreil.com>
+
+From: Francois Romieu <romieu@fr.zoreil.com>
+
+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 <romieu@fr.zoreil.com>
+Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
+Acked-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
--- /dev/null
+From stable-owner@vger.kernel.org Sat Oct 6 06:49:19 2012
+From: Francois Romieu <romieu@fr.zoreil.com>
+Date: Fri, 5 Oct 2012 23:29:15 +0200
+Subject: r8169: fix Config2 MSIEnable bit setting.
+To: stable@vger.kernel.org
+Cc: Hayes Wang <hayeswang@realtek.com>, Jonathan Nieder <jrnieder@gmail.com>
+
+
+From: françois romieu <romieu@fr.zoreil.com>
+
+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 <cantona@cantona.net>
+Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
+Cc: Hayes Wang <hayeswang@realtek.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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) &&
--- /dev/null
+From stable-owner@vger.kernel.org Sat Oct 6 06:49:18 2012
+From: Francois Romieu <romieu@fr.zoreil.com>
+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 <hayeswang@realtek.com>, Jonathan Nieder <jrnieder@gmail.com>
+
+From: Julien Ducourthial <jducourt@free.fr>
+
+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 <jducourt@free.fr>
+Acked-by: Francois Romieu <romieu@fr.zoreil.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);
+ }
+ /*
--- /dev/null
+From stable-owner@vger.kernel.org Sat Oct 6 06:49:16 2012
+From: Francois Romieu <romieu@fr.zoreil.com>
+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 <hayeswang@realtek.com>, Jonathan Nieder <jrnieder@gmail.com>
+
+From: Hayes Wang <hayeswang@realtek.com>
+
+commit d4ed95d796e5126bba51466dc07e287cebc8bd19 upstream.
+
+Only 8111E needs enable RxConfig bit 0 ~ 3 when suspending or
+shutdowning for wake on lan.
+
+Signed-off-by: Hayes Wang <hayeswang@realtek.com>
+Acked-by: Francois Romieu <romieu@fr.zoreil.com>
+Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
+Acked-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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;
+ }
+
--- /dev/null
+From stable-owner@vger.kernel.org Sat Oct 6 06:49:22 2012
+From: Francois Romieu <romieu@fr.zoreil.com>
+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 <hayeswang@realtek.com>, Jonathan Nieder <jrnieder@gmail.com>
+Message-ID: <b576bc58a53d1f576dc7802adface174fce2f644.1349472883.git.romieu@fr.zoreil.com>
+
+
+From: hayeswang <hayeswang@realtek.com>
+
+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 <hayeswang@realtek.com>
+Acked-by: Francois Romieu <romieu@fr.zoreil.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);
+ }
--- /dev/null
+From stable-owner@vger.kernel.org Sat Oct 6 06:49:24 2012
+From: Francois Romieu <romieu@fr.zoreil.com>
+Date: Fri, 5 Oct 2012 23:29:11 +0200
+Subject: r8169: jumbo fixes.
+To: stable@vger.kernel.org
+Cc: Hayes Wang <hayeswang@realtek.com>, Jonathan Nieder <jrnieder@gmail.com>
+
+From: Francois Romieu <romieu@fr.zoreil.com>
+
+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 <romieu@fr.zoreil.com>
+Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
+Acked-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);
+
--- /dev/null
+From stable-owner@vger.kernel.org Sat Oct 6 06:49:21 2012
+From: Francois Romieu <romieu@fr.zoreil.com>
+Date: Fri, 5 Oct 2012 23:29:16 +0200
+Subject: r8169: missing barriers.
+To: stable@vger.kernel.org
+Cc: Hayes Wang <hayeswang@realtek.com>, Jonathan Nieder <jrnieder@gmail.com>
+
+
+commit 1e874e041fc7c222cbd85b20c4406070be1f687a upstream.
+
+Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
+Cc: Hayes Wang <hayeswang@realtek.com>
+Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
+Acked-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);
+ }
--- /dev/null
+From stable-owner@vger.kernel.org Sat Oct 6 06:49:18 2012
+From: Francois Romieu <romieu@fr.zoreil.com>
+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 <hayeswang@realtek.com>, Jonathan Nieder <jrnieder@gmail.com>
+
+From: Francois Romieu <romieu@fr.zoreil.com>
+
+commit e03f33af79f0772156e1a1a1e36bdddf8012b2e4 upstream.
+
+When set, RxFOVF (resp. RxBOVF) is always 1 (resp. 0).
+
+Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
+Cc: Hayes <hayeswang@realtek.com>
+Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
+Acked-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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;
--- /dev/null
+From stable-owner@vger.kernel.org Sat Oct 6 06:49:16 2012
+From: Francois Romieu <romieu@fr.zoreil.com>
+Date: Fri, 5 Oct 2012 23:29:17 +0200
+Subject: r8169: runtime resume before shutdown.
+To: stable@vger.kernel.org
+Cc: Hayes Wang <hayeswang@realtek.com>, Jonathan Nieder <jrnieder@gmail.com>
+
+
+From: françois romieu <romieu@fr.zoreil.com>
+
+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 <snanda@chromium.org>
+Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
+Cc: Rafael J. Wysocki <rjw@sisk.pl>
+Cc: Hayes Wang <hayeswang@realtek.com>
+Cc: Alan Stern <stern@rowland.harvard.edu>
+Acked-by: Rafael J. Wysocki <rjw@sisk.pl>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 = {
--- /dev/null
+From stable-owner@vger.kernel.org Sat Oct 6 06:49:24 2012
+From: Francois Romieu <romieu@fr.zoreil.com>
+Date: Fri, 5 Oct 2012 23:29:14 +0200
+Subject: r8169: Rx FIFO overflow fixes.
+To: stable@vger.kernel.org
+Cc: Hayes Wang <hayeswang@realtek.com>, Jonathan Nieder <jrnieder@gmail.com>
+Message-ID: <4cf78ae52f10e00ad561db9700e2cda2f68bdacf.1349472883.git.romieu@fr.zoreil.com>
+
+From: Francois Romieu <romieu@fr.zoreil.com>
+
+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 <romieu@fr.zoreil.com>
+Cc: hayeswang <hayeswang@realtek.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);
+
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