r8169: remove the firmware of RTL8111D.
authorfrançois romieu <romieu@fr.zoreil.com>
Mon, 3 Jan 2011 15:07:31 +0000 (15:07 +0000)
committerDavid S. Miller <davem@davemloft.net>
Tue, 4 Jan 2011 17:48:31 +0000 (09:48 -0800)
The binary file of the firmware is moved to linux-firmware repository.
The firmwares are rtl_nic/rtl8168d-1.fw and rtl_nic/rtl8168d-2.fw.
The driver goes along if the firmware couldn't be found. However, it
is suggested to be done with the suitable firmware.

Some wrong PHY parameters are directly corrected in the driver.

Simple firmware checking added per Ben Hutchings suggestion.

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Cc: Ben Hutchings <benh@debian.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/Kconfig
drivers/net/r8169.c

index 89be23340ee42ec4e32320a2a91ae607756b42f0..3fda24a28d2fb565e6820d88fceed115674201e0 100644 (file)
@@ -2233,6 +2233,7 @@ config YELLOWFIN
 config R8169
        tristate "Realtek 8169 gigabit ethernet support"
        depends on PCI
+       select FW_LOADER
        select CRC32
        select MII
        ---help---
index e165d96ec7df269f260bcd22b55b0781bc62fd10..312446234509f3dc706fc33053351b57ab2e7247 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
 #include <linux/pm_runtime.h>
+#include <linux/firmware.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -33,6 +34,9 @@
 #define MODULENAME "r8169"
 #define PFX MODULENAME ": "
 
+#define FIRMWARE_8168D_1       "rtl_nic/rtl8168d-1.fw"
+#define FIRMWARE_8168D_2       "rtl_nic/rtl8168d-2.fw"
+
 #ifdef RTL8169_DEBUG
 #define assert(expr) \
        if (!(expr)) {                                  \
@@ -514,6 +518,8 @@ module_param_named(debug, debug.msg_enable, int, 0);
 MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 16=all)");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(RTL8169_VERSION);
+MODULE_FIRMWARE(FIRMWARE_8168D_1);
+MODULE_FIRMWARE(FIRMWARE_8168D_2);
 
 static int rtl8169_open(struct net_device *dev);
 static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
@@ -1393,6 +1399,65 @@ static void rtl_phy_write(void __iomem *ioaddr, const struct phy_reg *regs, int
        }
 }
 
+#define PHY_READ               0x00000000
+#define PHY_DATA_OR            0x10000000
+#define PHY_DATA_AND           0x20000000
+#define PHY_BJMPN              0x30000000
+#define PHY_READ_EFUSE         0x40000000
+#define PHY_READ_MAC_BYTE      0x50000000
+#define PHY_WRITE_MAC_BYTE     0x60000000
+#define PHY_CLEAR_READCOUNT    0x70000000
+#define PHY_WRITE              0x80000000
+#define PHY_READCOUNT_EQ_SKIP  0x90000000
+#define PHY_COMP_EQ_SKIPN      0xa0000000
+#define PHY_COMP_NEQ_SKIPN     0xb0000000
+#define PHY_WRITE_PREVIOUS     0xc0000000
+#define PHY_SKIPN              0xd0000000
+#define PHY_DELAY_MS           0xe0000000
+#define PHY_WRITE_ERI_WORD     0xf0000000
+
+static void
+rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw)
+{
+       void __iomem *ioaddr = tp->mmio_addr;
+       __le32 *phytable = (__le32 *)fw->data;
+       struct net_device *dev = tp->dev;
+       size_t i;
+
+       if (fw->size % sizeof(*phytable)) {
+               netif_err(tp, probe, dev, "odd sized firmware %zd\n", fw->size);
+               return;
+       }
+
+       for (i = 0; i < fw->size / sizeof(*phytable); i++) {
+               u32 action = le32_to_cpu(phytable[i]);
+
+               if (!action)
+                       break;
+
+               if ((action & 0xf0000000) != PHY_WRITE) {
+                       netif_err(tp, probe, dev,
+                                 "unknown action 0x%08x\n", action);
+                       return;
+               }
+       }
+
+       while (i-- != 0) {
+               u32 action = le32_to_cpu(*phytable);
+               u32 data = action & 0x0000ffff;
+               u32 reg = (action & 0x0fff0000) >> 16;
+
+               switch(action & 0xf0000000) {
+               case PHY_WRITE:
+                       mdio_write(ioaddr, reg, data);
+                       phytable++;
+                       break;
+               default:
+                       BUG();
+               }
+       }
+}
+
 static void rtl8169s_hw_phy_config(void __iomem *ioaddr)
 {
        static const struct phy_reg phy_reg_init[] = {
@@ -1725,9 +1790,10 @@ static void rtl8168c_4_hw_phy_config(void __iomem *ioaddr)
        rtl8168c_3_hw_phy_config(ioaddr);
 }
 
-static void rtl8168d_1_hw_phy_config(void __iomem *ioaddr)
+static void rtl8168d_1_hw_phy_config(struct rtl8169_private *tp)
 {
        static const struct phy_reg phy_reg_init_0[] = {
+               /* Channel Estimation */
                { 0x1f, 0x0001 },
                { 0x06, 0x4064 },
                { 0x07, 0x2863 },
@@ -1744,379 +1810,41 @@ static void rtl8168d_1_hw_phy_config(void __iomem *ioaddr)
                { 0x12, 0xf49f },
                { 0x13, 0x070b },
                { 0x1a, 0x05ad },
-               { 0x14, 0x94c0 }
-       };
-       static const struct phy_reg phy_reg_init_1[] = {
+               { 0x14, 0x94c0 },
+
+               /*
+                * Tx Error Issue
+                * enhance line driver power
+                */
                { 0x1f, 0x0002 },
                { 0x06, 0x5561 },
                { 0x1f, 0x0005 },
                { 0x05, 0x8332 },
-               { 0x06, 0x5561 }
-       };
-       static const struct phy_reg phy_reg_init_2[] = {
-               { 0x1f, 0x0005 },
-               { 0x05, 0xffc2 },
-               { 0x1f, 0x0005 },
-               { 0x05, 0x8000 },
-               { 0x06, 0xf8f9 },
-               { 0x06, 0xfaef },
-               { 0x06, 0x59ee },
-               { 0x06, 0xf8ea },
-               { 0x06, 0x00ee },
-               { 0x06, 0xf8eb },
-               { 0x06, 0x00e0 },
-               { 0x06, 0xf87c },
-               { 0x06, 0xe1f8 },
-               { 0x06, 0x7d59 },
-               { 0x06, 0x0fef },
-               { 0x06, 0x0139 },
-               { 0x06, 0x029e },
-               { 0x06, 0x06ef },
-               { 0x06, 0x1039 },
-               { 0x06, 0x089f },
-               { 0x06, 0x2aee },
-               { 0x06, 0xf8ea },
-               { 0x06, 0x00ee },
-               { 0x06, 0xf8eb },
-               { 0x06, 0x01e0 },
-               { 0x06, 0xf87c },
-               { 0x06, 0xe1f8 },
-               { 0x06, 0x7d58 },
-               { 0x06, 0x409e },
-               { 0x06, 0x0f39 },
-               { 0x06, 0x46aa },
-               { 0x06, 0x0bbf },
-               { 0x06, 0x8290 },
-               { 0x06, 0xd682 },
-               { 0x06, 0x9802 },
-               { 0x06, 0x014f },
-               { 0x06, 0xae09 },
-               { 0x06, 0xbf82 },
-               { 0x06, 0x98d6 },
-               { 0x06, 0x82a0 },
-               { 0x06, 0x0201 },
-               { 0x06, 0x4fef },
-               { 0x06, 0x95fe },
-               { 0x06, 0xfdfc },
-               { 0x06, 0x05f8 },
-               { 0x06, 0xf9fa },
-               { 0x06, 0xeef8 },
-               { 0x06, 0xea00 },
-               { 0x06, 0xeef8 },
-               { 0x06, 0xeb00 },
-               { 0x06, 0xe2f8 },
-               { 0x06, 0x7ce3 },
-               { 0x06, 0xf87d },
-               { 0x06, 0xa511 },
-               { 0x06, 0x1112 },
-               { 0x06, 0xd240 },
-               { 0x06, 0xd644 },
-               { 0x06, 0x4402 },
-               { 0x06, 0x8217 },
-               { 0x06, 0xd2a0 },
-               { 0x06, 0xd6aa },
-               { 0x06, 0xaa02 },
-               { 0x06, 0x8217 },
-               { 0x06, 0xae0f },
-               { 0x06, 0xa544 },
-               { 0x06, 0x4402 },
-               { 0x06, 0xae4d },
-               { 0x06, 0xa5aa },
-               { 0x06, 0xaa02 },
-               { 0x06, 0xae47 },
-               { 0x06, 0xaf82 },
-               { 0x06, 0x13ee },
-               { 0x06, 0x834e },
-               { 0x06, 0x00ee },
-               { 0x06, 0x834d },
-               { 0x06, 0x0fee },
-               { 0x06, 0x834c },
-               { 0x06, 0x0fee },
-               { 0x06, 0x834f },
-               { 0x06, 0x00ee },
-               { 0x06, 0x8351 },
-               { 0x06, 0x00ee },
-               { 0x06, 0x834a },
-               { 0x06, 0xffee },
-               { 0x06, 0x834b },
-               { 0x06, 0xffe0 },
-               { 0x06, 0x8330 },
-               { 0x06, 0xe183 },
-               { 0x06, 0x3158 },
-               { 0x06, 0xfee4 },
-               { 0x06, 0xf88a },
-               { 0x06, 0xe5f8 },
-               { 0x06, 0x8be0 },
-               { 0x06, 0x8332 },
-               { 0x06, 0xe183 },
-               { 0x06, 0x3359 },
-               { 0x06, 0x0fe2 },
-               { 0x06, 0x834d },
-               { 0x06, 0x0c24 },
-               { 0x06, 0x5af0 },
-               { 0x06, 0x1e12 },
-               { 0x06, 0xe4f8 },
-               { 0x06, 0x8ce5 },
-               { 0x06, 0xf88d },
-               { 0x06, 0xaf82 },
-               { 0x06, 0x13e0 },
-               { 0x06, 0x834f },
-               { 0x06, 0x10e4 },
-               { 0x06, 0x834f },
-               { 0x06, 0xe083 },
-               { 0x06, 0x4e78 },
-               { 0x06, 0x009f },
-               { 0x06, 0x0ae0 },
-               { 0x06, 0x834f },
-               { 0x06, 0xa010 },
-               { 0x06, 0xa5ee },
-               { 0x06, 0x834e },
-               { 0x06, 0x01e0 },
-               { 0x06, 0x834e },
-               { 0x06, 0x7805 },
-               { 0x06, 0x9e9a },
-               { 0x06, 0xe083 },
-               { 0x06, 0x4e78 },
-               { 0x06, 0x049e },
-               { 0x06, 0x10e0 },
-               { 0x06, 0x834e },
-               { 0x06, 0x7803 },
-               { 0x06, 0x9e0f },
-               { 0x06, 0xe083 },
-               { 0x06, 0x4e78 },
-               { 0x06, 0x019e },
-               { 0x06, 0x05ae },
-               { 0x06, 0x0caf },
-               { 0x06, 0x81f8 },
-               { 0x06, 0xaf81 },
-               { 0x06, 0xa3af },
-               { 0x06, 0x81dc },
-               { 0x06, 0xaf82 },
-               { 0x06, 0x13ee },
-               { 0x06, 0x8348 },
-               { 0x06, 0x00ee },
-               { 0x06, 0x8349 },
-               { 0x06, 0x00e0 },
-               { 0x06, 0x8351 },
-               { 0x06, 0x10e4 },
-               { 0x06, 0x8351 },
-               { 0x06, 0x5801 },
-               { 0x06, 0x9fea },
-               { 0x06, 0xd000 },
-               { 0x06, 0xd180 },
-               { 0x06, 0x1f66 },
-               { 0x06, 0xe2f8 },
-               { 0x06, 0xeae3 },
-               { 0x06, 0xf8eb },
-               { 0x06, 0x5af8 },
-               { 0x06, 0x1e20 },
-               { 0x06, 0xe6f8 },
-               { 0x06, 0xeae5 },
-               { 0x06, 0xf8eb },
-               { 0x06, 0xd302 },
-               { 0x06, 0xb3fe },
-               { 0x06, 0xe2f8 },
-               { 0x06, 0x7cef },
-               { 0x06, 0x325b },
-               { 0x06, 0x80e3 },
-               { 0x06, 0xf87d },
-               { 0x06, 0x9e03 },
-               { 0x06, 0x7dff },
-               { 0x06, 0xff0d },
-               { 0x06, 0x581c },
-               { 0x06, 0x551a },
-               { 0x06, 0x6511 },
-               { 0x06, 0xa190 },
-               { 0x06, 0xd3e2 },
-               { 0x06, 0x8348 },
-               { 0x06, 0xe383 },
-               { 0x06, 0x491b },
-               { 0x06, 0x56ab },
-               { 0x06, 0x08ef },
-               { 0x06, 0x56e6 },
-               { 0x06, 0x8348 },
-               { 0x06, 0xe783 },
-               { 0x06, 0x4910 },
-               { 0x06, 0xd180 },
-               { 0x06, 0x1f66 },
-               { 0x06, 0xa004 },
-               { 0x06, 0xb9e2 },
-               { 0x06, 0x8348 },
-               { 0x06, 0xe383 },
-               { 0x06, 0x49ef },
-               { 0x06, 0x65e2 },
-               { 0x06, 0x834a },
-               { 0x06, 0xe383 },
-               { 0x06, 0x4b1b },
-               { 0x06, 0x56aa },
-               { 0x06, 0x0eef },
-               { 0x06, 0x56e6 },
-               { 0x06, 0x834a },
-               { 0x06, 0xe783 },
-               { 0x06, 0x4be2 },
-               { 0x06, 0x834d },
-               { 0x06, 0xe683 },
-               { 0x06, 0x4ce0 },
-               { 0x06, 0x834d },
-               { 0x06, 0xa000 },
-               { 0x06, 0x0caf },
-               { 0x06, 0x81dc },
-               { 0x06, 0xe083 },
-               { 0x06, 0x4d10 },
-               { 0x06, 0xe483 },
-               { 0x06, 0x4dae },
-               { 0x06, 0x0480 },
-               { 0x06, 0xe483 },
-               { 0x06, 0x4de0 },
-               { 0x06, 0x834e },
-               { 0x06, 0x7803 },
-               { 0x06, 0x9e0b },
-               { 0x06, 0xe083 },
-               { 0x06, 0x4e78 },
-               { 0x06, 0x049e },
-               { 0x06, 0x04ee },
-               { 0x06, 0x834e },
-               { 0x06, 0x02e0 },
-               { 0x06, 0x8332 },
-               { 0x06, 0xe183 },
-               { 0x06, 0x3359 },
-               { 0x06, 0x0fe2 },
-               { 0x06, 0x834d },
-               { 0x06, 0x0c24 },
-               { 0x06, 0x5af0 },
-               { 0x06, 0x1e12 },
-               { 0x06, 0xe4f8 },
-               { 0x06, 0x8ce5 },
-               { 0x06, 0xf88d },
-               { 0x06, 0xe083 },
-               { 0x06, 0x30e1 },
-               { 0x06, 0x8331 },
-               { 0x06, 0x6801 },
-               { 0x06, 0xe4f8 },
-               { 0x06, 0x8ae5 },
-               { 0x06, 0xf88b },
-               { 0x06, 0xae37 },
-               { 0x06, 0xee83 },
-               { 0x06, 0x4e03 },
-               { 0x06, 0xe083 },
-               { 0x06, 0x4ce1 },
-               { 0x06, 0x834d },
-               { 0x06, 0x1b01 },
-               { 0x06, 0x9e04 },
-               { 0x06, 0xaaa1 },
-               { 0x06, 0xaea8 },
-               { 0x06, 0xee83 },
-               { 0x06, 0x4e04 },
-               { 0x06, 0xee83 },
-               { 0x06, 0x4f00 },
-               { 0x06, 0xaeab },
-               { 0x06, 0xe083 },
-               { 0x06, 0x4f78 },
-               { 0x06, 0x039f },
-               { 0x06, 0x14ee },
-               { 0x06, 0x834e },
-               { 0x06, 0x05d2 },
-               { 0x06, 0x40d6 },
-               { 0x06, 0x5554 },
-               { 0x06, 0x0282 },
-               { 0x06, 0x17d2 },
-               { 0x06, 0xa0d6 },
-               { 0x06, 0xba00 },
-               { 0x06, 0x0282 },
-               { 0x06, 0x17fe },
-               { 0x06, 0xfdfc },
-               { 0x06, 0x05f8 },
-               { 0x06, 0xe0f8 },
-               { 0x06, 0x60e1 },
-               { 0x06, 0xf861 },
-               { 0x06, 0x6802 },
-               { 0x06, 0xe4f8 },
-               { 0x06, 0x60e5 },
-               { 0x06, 0xf861 },
-               { 0x06, 0xe0f8 },
-               { 0x06, 0x48e1 },
-               { 0x06, 0xf849 },
-               { 0x06, 0x580f },
-               { 0x06, 0x1e02 },
-               { 0x06, 0xe4f8 },
-               { 0x06, 0x48e5 },
-               { 0x06, 0xf849 },
-               { 0x06, 0xd000 },
-               { 0x06, 0x0282 },
-               { 0x06, 0x5bbf },
-               { 0x06, 0x8350 },
-               { 0x06, 0xef46 },
-               { 0x06, 0xdc19 },
-               { 0x06, 0xddd0 },
-               { 0x06, 0x0102 },
-               { 0x06, 0x825b },
-               { 0x06, 0x0282 },
-               { 0x06, 0x77e0 },
-               { 0x06, 0xf860 },
-               { 0x06, 0xe1f8 },
-               { 0x06, 0x6158 },
-               { 0x06, 0xfde4 },
-               { 0x06, 0xf860 },
-               { 0x06, 0xe5f8 },
-               { 0x06, 0x61fc },
-               { 0x06, 0x04f9 },
-               { 0x06, 0xfafb },
-               { 0x06, 0xc6bf },
-               { 0x06, 0xf840 },
-               { 0x06, 0xbe83 },
-               { 0x06, 0x50a0 },
-               { 0x06, 0x0101 },
-               { 0x06, 0x071b },
-               { 0x06, 0x89cf },
-               { 0x06, 0xd208 },
-               { 0x06, 0xebdb },
-               { 0x06, 0x19b2 },
-               { 0x06, 0xfbff },
-               { 0x06, 0xfefd },
-               { 0x06, 0x04f8 },
-               { 0x06, 0xe0f8 },
-               { 0x06, 0x48e1 },
-               { 0x06, 0xf849 },
-               { 0x06, 0x6808 },
-               { 0x06, 0xe4f8 },
-               { 0x06, 0x48e5 },
-               { 0x06, 0xf849 },
-               { 0x06, 0x58f7 },
-               { 0x06, 0xe4f8 },
-               { 0x06, 0x48e5 },
-               { 0x06, 0xf849 },
-               { 0x06, 0xfc04 },
-               { 0x06, 0x4d20 },
-               { 0x06, 0x0002 },
-               { 0x06, 0x4e22 },
-               { 0x06, 0x0002 },
-               { 0x06, 0x4ddf },
-               { 0x06, 0xff01 },
-               { 0x06, 0x4edd },
-               { 0x06, 0xff01 },
-               { 0x05, 0x83d4 },
-               { 0x06, 0x8000 },
-               { 0x05, 0x83d8 },
-               { 0x06, 0x8051 },
-               { 0x02, 0x6010 },
-               { 0x03, 0xdc00 },
-               { 0x05, 0xfff6 },
-               { 0x06, 0x00fc },
-               { 0x1f, 0x0000 },
+               { 0x06, 0x5561 },
+
+               /*
+                * Can not link to 1Gbps with bad cable
+                * Decrease SNR threshold form 21.07dB to 19.04dB
+                */
+               { 0x1f, 0x0001 },
+               { 0x17, 0x0cc0 },
 
                { 0x1f, 0x0000 },
-               { 0x0d, 0xf880 },
-               { 0x1f, 0x0000 }
+               { 0x0d, 0xf880 }
        };
+       void __iomem *ioaddr = tp->mmio_addr;
+       const struct firmware *fw;
 
        rtl_phy_write(ioaddr, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0));
 
+       /*
+        * Rx Error Issue
+        * Fine Tune Switching regulator parameter
+        */
        mdio_write(ioaddr, 0x1f, 0x0002);
        mdio_plus_minus(ioaddr, 0x0b, 0x0010, 0x00ef);
        mdio_plus_minus(ioaddr, 0x0c, 0xa200, 0x5d00);
 
-       rtl_phy_write(ioaddr, phy_reg_init_1, ARRAY_SIZE(phy_reg_init_1));
-
        if (rtl8168d_efuse_read(ioaddr, 0x01) == 0xb1) {
                static const struct phy_reg phy_reg_init[] = {
                        { 0x1f, 0x0002 },
@@ -2157,20 +1885,33 @@ static void rtl8168d_1_hw_phy_config(void __iomem *ioaddr)
                rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
        }
 
+       /* RSET couple improve */
        mdio_write(ioaddr, 0x1f, 0x0002);
        mdio_patch(ioaddr, 0x0d, 0x0300);
        mdio_patch(ioaddr, 0x0f, 0x0010);
 
+       /* Fine tune PLL performance */
        mdio_write(ioaddr, 0x1f, 0x0002);
        mdio_plus_minus(ioaddr, 0x02, 0x0100, 0x0600);
        mdio_plus_minus(ioaddr, 0x03, 0x0000, 0xe000);
 
-       rtl_phy_write(ioaddr, phy_reg_init_2, ARRAY_SIZE(phy_reg_init_2));
+       mdio_write(ioaddr, 0x1f, 0x0005);
+       mdio_write(ioaddr, 0x05, 0x001b);
+       if (mdio_read(ioaddr, 0x06) == 0xbf00 &&
+           request_firmware(&fw, FIRMWARE_8168D_1, &tp->pci_dev->dev) == 0) {
+               rtl_phy_write_fw(tp, fw);
+               release_firmware(fw);
+       } else {
+               netif_warn(tp, probe, tp->dev, "unable to apply firmware patch\n");
+       }
+
+       mdio_write(ioaddr, 0x1f, 0x0000);
 }
 
-static void rtl8168d_2_hw_phy_config(void __iomem *ioaddr)
+static void rtl8168d_2_hw_phy_config(struct rtl8169_private *tp)
 {
        static const struct phy_reg phy_reg_init_0[] = {
+               /* Channel Estimation */
                { 0x1f, 0x0001 },
                { 0x06, 0x4064 },
                { 0x07, 0x2863 },
@@ -2189,324 +1930,28 @@ static void rtl8168d_2_hw_phy_config(void __iomem *ioaddr)
                { 0x1a, 0x05ad },
                { 0x14, 0x94c0 },
 
+               /*
+                * Tx Error Issue
+                * enhance line driver power
+                */
                { 0x1f, 0x0002 },
                { 0x06, 0x5561 },
                { 0x1f, 0x0005 },
                { 0x05, 0x8332 },
-               { 0x06, 0x5561 }
-       };
-       static const struct phy_reg phy_reg_init_1[] = {
-               { 0x1f, 0x0005 },
-               { 0x05, 0xffc2 },
-               { 0x1f, 0x0005 },
-               { 0x05, 0x8000 },
-               { 0x06, 0xf8f9 },
-               { 0x06, 0xfaee },
-               { 0x06, 0xf8ea },
-               { 0x06, 0x00ee },
-               { 0x06, 0xf8eb },
-               { 0x06, 0x00e2 },
-               { 0x06, 0xf87c },
-               { 0x06, 0xe3f8 },
-               { 0x06, 0x7da5 },
-               { 0x06, 0x1111 },
-               { 0x06, 0x12d2 },
-               { 0x06, 0x40d6 },
-               { 0x06, 0x4444 },
-               { 0x06, 0x0281 },
-               { 0x06, 0xc6d2 },
-               { 0x06, 0xa0d6 },
-               { 0x06, 0xaaaa },
-               { 0x06, 0x0281 },
-               { 0x06, 0xc6ae },
-               { 0x06, 0x0fa5 },
-               { 0x06, 0x4444 },
-               { 0x06, 0x02ae },
-               { 0x06, 0x4da5 },
-               { 0x06, 0xaaaa },
-               { 0x06, 0x02ae },
-               { 0x06, 0x47af },
-               { 0x06, 0x81c2 },
-               { 0x06, 0xee83 },
-               { 0x06, 0x4e00 },
-               { 0x06, 0xee83 },
-               { 0x06, 0x4d0f },
-               { 0x06, 0xee83 },
-               { 0x06, 0x4c0f },
-               { 0x06, 0xee83 },
-               { 0x06, 0x4f00 },
-               { 0x06, 0xee83 },
-               { 0x06, 0x5100 },
-               { 0x06, 0xee83 },
-               { 0x06, 0x4aff },
-               { 0x06, 0xee83 },
-               { 0x06, 0x4bff },
-               { 0x06, 0xe083 },
-               { 0x06, 0x30e1 },
-               { 0x06, 0x8331 },
-               { 0x06, 0x58fe },
-               { 0x06, 0xe4f8 },
-               { 0x06, 0x8ae5 },
-               { 0x06, 0xf88b },
-               { 0x06, 0xe083 },
-               { 0x06, 0x32e1 },
-               { 0x06, 0x8333 },
-               { 0x06, 0x590f },
-               { 0x06, 0xe283 },
-               { 0x06, 0x4d0c },
-               { 0x06, 0x245a },
-               { 0x06, 0xf01e },
-               { 0x06, 0x12e4 },
-               { 0x06, 0xf88c },
-               { 0x06, 0xe5f8 },
-               { 0x06, 0x8daf },
-               { 0x06, 0x81c2 },
-               { 0x06, 0xe083 },
-               { 0x06, 0x4f10 },
-               { 0x06, 0xe483 },
-               { 0x06, 0x4fe0 },
-               { 0x06, 0x834e },
-               { 0x06, 0x7800 },
-               { 0x06, 0x9f0a },
-               { 0x06, 0xe083 },
-               { 0x06, 0x4fa0 },
-               { 0x06, 0x10a5 },
-               { 0x06, 0xee83 },
-               { 0x06, 0x4e01 },
-               { 0x06, 0xe083 },
-               { 0x06, 0x4e78 },
-               { 0x06, 0x059e },
-               { 0x06, 0x9ae0 },
-               { 0x06, 0x834e },
-               { 0x06, 0x7804 },
-               { 0x06, 0x9e10 },
-               { 0x06, 0xe083 },
-               { 0x06, 0x4e78 },
-               { 0x06, 0x039e },
-               { 0x06, 0x0fe0 },
-               { 0x06, 0x834e },
-               { 0x06, 0x7801 },
-               { 0x06, 0x9e05 },
-               { 0x06, 0xae0c },
-               { 0x06, 0xaf81 },
-               { 0x06, 0xa7af },
-               { 0x06, 0x8152 },
-               { 0x06, 0xaf81 },
-               { 0x06, 0x8baf },
-               { 0x06, 0x81c2 },
-               { 0x06, 0xee83 },
-               { 0x06, 0x4800 },
-               { 0x06, 0xee83 },
-               { 0x06, 0x4900 },
-               { 0x06, 0xe083 },
-               { 0x06, 0x5110 },
-               { 0x06, 0xe483 },
-               { 0x06, 0x5158 },
-               { 0x06, 0x019f },
-               { 0x06, 0xead0 },
-               { 0x06, 0x00d1 },
-               { 0x06, 0x801f },
-               { 0x06, 0x66e2 },
-               { 0x06, 0xf8ea },
-               { 0x06, 0xe3f8 },
-               { 0x06, 0xeb5a },
-               { 0x06, 0xf81e },
-               { 0x06, 0x20e6 },
-               { 0x06, 0xf8ea },
-               { 0x06, 0xe5f8 },
-               { 0x06, 0xebd3 },
-               { 0x06, 0x02b3 },
-               { 0x06, 0xfee2 },
-               { 0x06, 0xf87c },
-               { 0x06, 0xef32 },
-               { 0x06, 0x5b80 },
-               { 0x06, 0xe3f8 },
-               { 0x06, 0x7d9e },
-               { 0x06, 0x037d },
-               { 0x06, 0xffff },
-               { 0x06, 0x0d58 },
-               { 0x06, 0x1c55 },
-               { 0x06, 0x1a65 },
-               { 0x06, 0x11a1 },
-               { 0x06, 0x90d3 },
-               { 0x06, 0xe283 },
-               { 0x06, 0x48e3 },
-               { 0x06, 0x8349 },
-               { 0x06, 0x1b56 },
-               { 0x06, 0xab08 },
-               { 0x06, 0xef56 },
-               { 0x06, 0xe683 },
-               { 0x06, 0x48e7 },
-               { 0x06, 0x8349 },
-               { 0x06, 0x10d1 },
-               { 0x06, 0x801f },
-               { 0x06, 0x66a0 },
-               { 0x06, 0x04b9 },
-               { 0x06, 0xe283 },
-               { 0x06, 0x48e3 },
-               { 0x06, 0x8349 },
-               { 0x06, 0xef65 },
-               { 0x06, 0xe283 },
-               { 0x06, 0x4ae3 },
-               { 0x06, 0x834b },
-               { 0x06, 0x1b56 },
-               { 0x06, 0xaa0e },
-               { 0x06, 0xef56 },
-               { 0x06, 0xe683 },
-               { 0x06, 0x4ae7 },
-               { 0x06, 0x834b },
-               { 0x06, 0xe283 },
-               { 0x06, 0x4de6 },
-               { 0x06, 0x834c },
-               { 0x06, 0xe083 },
-               { 0x06, 0x4da0 },
-               { 0x06, 0x000c },
-               { 0x06, 0xaf81 },
-               { 0x06, 0x8be0 },
-               { 0x06, 0x834d },
-               { 0x06, 0x10e4 },
-               { 0x06, 0x834d },
-               { 0x06, 0xae04 },
-               { 0x06, 0x80e4 },
-               { 0x06, 0x834d },
-               { 0x06, 0xe083 },
-               { 0x06, 0x4e78 },
-               { 0x06, 0x039e },
-               { 0x06, 0x0be0 },
-               { 0x06, 0x834e },
-               { 0x06, 0x7804 },
-               { 0x06, 0x9e04 },
-               { 0x06, 0xee83 },
-               { 0x06, 0x4e02 },
-               { 0x06, 0xe083 },
-               { 0x06, 0x32e1 },
-               { 0x06, 0x8333 },
-               { 0x06, 0x590f },
-               { 0x06, 0xe283 },
-               { 0x06, 0x4d0c },
-               { 0x06, 0x245a },
-               { 0x06, 0xf01e },
-               { 0x06, 0x12e4 },
-               { 0x06, 0xf88c },
-               { 0x06, 0xe5f8 },
-               { 0x06, 0x8de0 },
-               { 0x06, 0x8330 },
-               { 0x06, 0xe183 },
-               { 0x06, 0x3168 },
-               { 0x06, 0x01e4 },
-               { 0x06, 0xf88a },
-               { 0x06, 0xe5f8 },
-               { 0x06, 0x8bae },
-               { 0x06, 0x37ee },
-               { 0x06, 0x834e },
-               { 0x06, 0x03e0 },
-               { 0x06, 0x834c },
-               { 0x06, 0xe183 },
-               { 0x06, 0x4d1b },
-               { 0x06, 0x019e },
-               { 0x06, 0x04aa },
-               { 0x06, 0xa1ae },
-               { 0x06, 0xa8ee },
-               { 0x06, 0x834e },
-               { 0x06, 0x04ee },
-               { 0x06, 0x834f },
-               { 0x06, 0x00ae },
-               { 0x06, 0xabe0 },
-               { 0x06, 0x834f },
-               { 0x06, 0x7803 },
-               { 0x06, 0x9f14 },
-               { 0x06, 0xee83 },
-               { 0x06, 0x4e05 },
-               { 0x06, 0xd240 },
-               { 0x06, 0xd655 },
-               { 0x06, 0x5402 },
-               { 0x06, 0x81c6 },
-               { 0x06, 0xd2a0 },
-               { 0x06, 0xd6ba },
-               { 0x06, 0x0002 },
-               { 0x06, 0x81c6 },
-               { 0x06, 0xfefd },
-               { 0x06, 0xfc05 },
-               { 0x06, 0xf8e0 },
-               { 0x06, 0xf860 },
-               { 0x06, 0xe1f8 },
-               { 0x06, 0x6168 },
-               { 0x06, 0x02e4 },
-               { 0x06, 0xf860 },
-               { 0x06, 0xe5f8 },
-               { 0x06, 0x61e0 },
-               { 0x06, 0xf848 },
-               { 0x06, 0xe1f8 },
-               { 0x06, 0x4958 },
-               { 0x06, 0x0f1e },
-               { 0x06, 0x02e4 },
-               { 0x06, 0xf848 },
-               { 0x06, 0xe5f8 },
-               { 0x06, 0x49d0 },
-               { 0x06, 0x0002 },
-               { 0x06, 0x820a },
-               { 0x06, 0xbf83 },
-               { 0x06, 0x50ef },
-               { 0x06, 0x46dc },
-               { 0x06, 0x19dd },
-               { 0x06, 0xd001 },
-               { 0x06, 0x0282 },
-               { 0x06, 0x0a02 },
-               { 0x06, 0x8226 },
-               { 0x06, 0xe0f8 },
-               { 0x06, 0x60e1 },
-               { 0x06, 0xf861 },
-               { 0x06, 0x58fd },
-               { 0x06, 0xe4f8 },
-               { 0x06, 0x60e5 },
-               { 0x06, 0xf861 },
-               { 0x06, 0xfc04 },
-               { 0x06, 0xf9fa },
-               { 0x06, 0xfbc6 },
-               { 0x06, 0xbff8 },
-               { 0x06, 0x40be },
-               { 0x06, 0x8350 },
-               { 0x06, 0xa001 },
-               { 0x06, 0x0107 },
-               { 0x06, 0x1b89 },
-               { 0x06, 0xcfd2 },
-               { 0x06, 0x08eb },
-               { 0x06, 0xdb19 },
-               { 0x06, 0xb2fb },
-               { 0x06, 0xfffe },
-               { 0x06, 0xfd04 },
-               { 0x06, 0xf8e0 },
-               { 0x06, 0xf848 },
-               { 0x06, 0xe1f8 },
-               { 0x06, 0x4968 },
-               { 0x06, 0x08e4 },
-               { 0x06, 0xf848 },
-               { 0x06, 0xe5f8 },
-               { 0x06, 0x4958 },
-               { 0x06, 0xf7e4 },
-               { 0x06, 0xf848 },
-               { 0x06, 0xe5f8 },
-               { 0x06, 0x49fc },
-               { 0x06, 0x044d },
-               { 0x06, 0x2000 },
-               { 0x06, 0x024e },
-               { 0x06, 0x2200 },
-               { 0x06, 0x024d },
-               { 0x06, 0xdfff },
-               { 0x06, 0x014e },
-               { 0x06, 0xddff },
-               { 0x06, 0x0100 },
-               { 0x05, 0x83d8 },
-               { 0x06, 0x8000 },
-               { 0x03, 0xdc00 },
-               { 0x05, 0xfff6 },
-               { 0x06, 0x00fc },
-               { 0x1f, 0x0000 },
+               { 0x06, 0x5561 },
+
+               /*
+                * Can not link to 1Gbps with bad cable
+                * Decrease SNR threshold form 21.07dB to 19.04dB
+                */
+               { 0x1f, 0x0001 },
+               { 0x17, 0x0cc0 },
 
                { 0x1f, 0x0000 },
-               { 0x0d, 0xf880 },
-               { 0x1f, 0x0000 }
+               { 0x0d, 0xf880 }
        };
+       void __iomem *ioaddr = tp->mmio_addr;
+       const struct firmware *fw;
 
        rtl_phy_write(ioaddr, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0));
 
@@ -2550,17 +1995,26 @@ static void rtl8168d_2_hw_phy_config(void __iomem *ioaddr)
                rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
        }
 
+       /* Fine tune PLL performance */
        mdio_write(ioaddr, 0x1f, 0x0002);
        mdio_plus_minus(ioaddr, 0x02, 0x0100, 0x0600);
        mdio_plus_minus(ioaddr, 0x03, 0x0000, 0xe000);
 
-       mdio_write(ioaddr, 0x1f, 0x0001);
-       mdio_write(ioaddr, 0x17, 0x0cc0);
-
+       /* Switching regulator Slew rate */
        mdio_write(ioaddr, 0x1f, 0x0002);
        mdio_patch(ioaddr, 0x0f, 0x0017);
 
-       rtl_phy_write(ioaddr, phy_reg_init_1, ARRAY_SIZE(phy_reg_init_1));
+       mdio_write(ioaddr, 0x1f, 0x0005);
+       mdio_write(ioaddr, 0x05, 0x001b);
+       if (mdio_read(ioaddr, 0x06) == 0xb300 &&
+           request_firmware(&fw, FIRMWARE_8168D_2, &tp->pci_dev->dev) == 0) {
+               rtl_phy_write_fw(tp, fw);
+               release_firmware(fw);
+       } else {
+               netif_warn(tp, probe, tp->dev, "unable to apply firmware patch\n");
+       }
+
+       mdio_write(ioaddr, 0x1f, 0x0000);
 }
 
 static void rtl8168d_3_hw_phy_config(void __iomem *ioaddr)
@@ -2698,10 +2152,10 @@ static void rtl_hw_phy_config(struct net_device *dev)
                rtl8168cp_2_hw_phy_config(ioaddr);
                break;
        case RTL_GIGA_MAC_VER_25:
-               rtl8168d_1_hw_phy_config(ioaddr);
+               rtl8168d_1_hw_phy_config(tp);
                break;
        case RTL_GIGA_MAC_VER_26:
-               rtl8168d_2_hw_phy_config(ioaddr);
+               rtl8168d_2_hw_phy_config(tp);
                break;
        case RTL_GIGA_MAC_VER_27:
                rtl8168d_3_hw_phy_config(ioaddr);