Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
[linux-2.6-microblaze.git] / drivers / net / ethernet / realtek / r8169_main.c
index c33c438..d47a038 100644 (file)
@@ -52,6 +52,7 @@
 #define FIRMWARE_8168G_3       "rtl_nic/rtl8168g-3.fw"
 #define FIRMWARE_8168H_1       "rtl_nic/rtl8168h-1.fw"
 #define FIRMWARE_8168H_2       "rtl_nic/rtl8168h-2.fw"
+#define FIRMWARE_8168FP_3      "rtl_nic/rtl8168fp-3.fw"
 #define FIRMWARE_8107E_1       "rtl_nic/rtl8107e-1.fw"
 #define FIRMWARE_8107E_2       "rtl_nic/rtl8107e-2.fw"
 #define FIRMWARE_8125A_3       "rtl_nic/rtl8125a-3.fw"
@@ -135,6 +136,7 @@ enum mac_version {
        RTL_GIGA_MAC_VER_49,
        RTL_GIGA_MAC_VER_50,
        RTL_GIGA_MAC_VER_51,
+       RTL_GIGA_MAC_VER_52,
        RTL_GIGA_MAC_VER_60,
        RTL_GIGA_MAC_VER_61,
        RTL_GIGA_MAC_NONE
@@ -202,6 +204,7 @@ static const struct {
        [RTL_GIGA_MAC_VER_49] = {"RTL8168ep/8111ep"                     },
        [RTL_GIGA_MAC_VER_50] = {"RTL8168ep/8111ep"                     },
        [RTL_GIGA_MAC_VER_51] = {"RTL8168ep/8111ep"                     },
+       [RTL_GIGA_MAC_VER_52] = {"RTL8168fp/RTL8117",  FIRMWARE_8168FP_3},
        [RTL_GIGA_MAC_VER_60] = {"RTL8125"                              },
        [RTL_GIGA_MAC_VER_61] = {"RTL8125",             FIRMWARE_8125A_3},
 };
@@ -680,6 +683,7 @@ struct rtl8169_private {
        struct rtl8169_counters *counters;
        struct rtl8169_tc_offsets tc_offset;
        u32 saved_wolopts;
+       int eee_adv;
 
        const char *fw_name;
        struct rtl_fw *rtl_fw;
@@ -712,6 +716,7 @@ MODULE_FIRMWARE(FIRMWARE_8168G_2);
 MODULE_FIRMWARE(FIRMWARE_8168G_3);
 MODULE_FIRMWARE(FIRMWARE_8168H_1);
 MODULE_FIRMWARE(FIRMWARE_8168H_2);
+MODULE_FIRMWARE(FIRMWARE_8168FP_3);
 MODULE_FIRMWARE(FIRMWARE_8107E_1);
 MODULE_FIRMWARE(FIRMWARE_8107E_2);
 MODULE_FIRMWARE(FIRMWARE_8125A_3);
@@ -741,12 +746,6 @@ static void rtl_unlock_config_regs(struct rtl8169_private *tp)
        RTL_W8(tp, Cfg9346, Cfg9346_Unlock);
 }
 
-static void rtl_tx_performance_tweak(struct rtl8169_private *tp, u16 force)
-{
-       pcie_capability_clear_and_set_word(tp->pci_dev, PCI_EXP_DEVCTL,
-                                          PCI_EXP_DEVCTL_READRQ, force);
-}
-
 static bool rtl_is_8125(struct rtl8169_private *tp)
 {
        return tp->mac_version >= RTL_GIGA_MAC_VER_60;
@@ -756,7 +755,7 @@ static bool rtl_is_8168evl_up(struct rtl8169_private *tp)
 {
        return tp->mac_version >= RTL_GIGA_MAC_VER_34 &&
               tp->mac_version != RTL_GIGA_MAC_VER_39 &&
-              tp->mac_version <= RTL_GIGA_MAC_VER_51;
+              tp->mac_version <= RTL_GIGA_MAC_VER_52;
 }
 
 static bool rtl_supports_eee(struct rtl8169_private *tp)
@@ -1092,6 +1091,39 @@ static void rtl_w0w1_phy(struct rtl8169_private *tp, int reg_addr, int p, int m)
        rtl_writephy(tp, reg_addr, (val & ~m) | p);
 }
 
+static void r8168d_modify_extpage(struct phy_device *phydev, int extpage,
+                                 int reg, u16 mask, u16 val)
+{
+       int oldpage = phy_select_page(phydev, 0x0007);
+
+       __phy_write(phydev, 0x1e, extpage);
+       __phy_modify(phydev, reg, mask, val);
+
+       phy_restore_page(phydev, oldpage, 0);
+}
+
+static void r8168d_phy_param(struct phy_device *phydev, u16 parm,
+                            u16 mask, u16 val)
+{
+       int oldpage = phy_select_page(phydev, 0x0005);
+
+       __phy_write(phydev, 0x05, parm);
+       __phy_modify(phydev, 0x06, mask, val);
+
+       phy_restore_page(phydev, oldpage, 0);
+}
+
+static void r8168g_phy_param(struct phy_device *phydev, u16 parm,
+                            u16 mask, u16 val)
+{
+       int oldpage = phy_select_page(phydev, 0x0a43);
+
+       __phy_write(phydev, 0x13, parm);
+       __phy_modify(phydev, 0x14, mask, val);
+
+       phy_restore_page(phydev, oldpage, 0);
+}
+
 DECLARE_RTL_COND(rtl_ephyar_cond)
 {
        return RTL_R32(tp, EPHYAR) & EPHYAR_FLAG;
@@ -1262,9 +1294,7 @@ static void rtl8168_driver_start(struct rtl8169_private *tp)
        case RTL_GIGA_MAC_VER_31:
                rtl8168dp_driver_start(tp);
                break;
-       case RTL_GIGA_MAC_VER_49:
-       case RTL_GIGA_MAC_VER_50:
-       case RTL_GIGA_MAC_VER_51:
+       case RTL_GIGA_MAC_VER_49 ... RTL_GIGA_MAC_VER_52:
                rtl8168ep_driver_start(tp);
                break;
        default:
@@ -1296,9 +1326,7 @@ static void rtl8168_driver_stop(struct rtl8169_private *tp)
        case RTL_GIGA_MAC_VER_31:
                rtl8168dp_driver_stop(tp);
                break;
-       case RTL_GIGA_MAC_VER_49:
-       case RTL_GIGA_MAC_VER_50:
-       case RTL_GIGA_MAC_VER_51:
+       case RTL_GIGA_MAC_VER_49 ... RTL_GIGA_MAC_VER_52:
                rtl8168ep_driver_stop(tp);
                break;
        default:
@@ -1326,9 +1354,7 @@ static bool r8168_check_dash(struct rtl8169_private *tp)
        case RTL_GIGA_MAC_VER_28:
        case RTL_GIGA_MAC_VER_31:
                return r8168dp_check_dash(tp);
-       case RTL_GIGA_MAC_VER_49:
-       case RTL_GIGA_MAC_VER_50:
-       case RTL_GIGA_MAC_VER_51:
+       case RTL_GIGA_MAC_VER_49 ... RTL_GIGA_MAC_VER_52:
                return r8168ep_check_dash(tp);
        default:
                return false;
@@ -1503,7 +1529,7 @@ static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts)
                break;
        case RTL_GIGA_MAC_VER_34:
        case RTL_GIGA_MAC_VER_37:
-       case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_51:
+       case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_52:
                options = RTL_R8(tp, Config2) & ~PME_SIGNAL;
                if (wolopts)
                        options |= PME_SIGNAL;
@@ -1571,7 +1597,7 @@ static netdev_features_t rtl8169_fix_features(struct net_device *dev,
 
        if (dev->mtu > JUMBO_1K &&
            tp->mac_version > RTL_GIGA_MAC_VER_06)
-               features &= ~NETIF_F_IP_CSUM;
+               features &= ~(NETIF_F_CSUM_MASK | NETIF_F_ALL_TSO);
 
        return features;
 }
@@ -2074,6 +2100,10 @@ static int rtl8169_set_eee(struct net_device *dev, struct ethtool_eee *data)
        }
 
        ret = phy_ethtool_set_eee(tp->phydev, data);
+
+       if (!ret)
+               tp->eee_adv = phy_read_mmd(dev->phydev, MDIO_MMD_AN,
+                                          MDIO_AN_EEE_ADV);
 out:
        pm_runtime_put_noidle(d);
        return ret;
@@ -2104,10 +2134,16 @@ static const struct ethtool_ops rtl8169_ethtool_ops = {
 static void rtl_enable_eee(struct rtl8169_private *tp)
 {
        struct phy_device *phydev = tp->phydev;
-       int supported = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE);
+       int adv;
+
+       /* respect EEE advertisement the user may have set */
+       if (tp->eee_adv >= 0)
+               adv = tp->eee_adv;
+       else
+               adv = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE);
 
-       if (supported > 0)
-               phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, supported);
+       if (adv >= 0)
+               phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, adv);
 }
 
 static void rtl8169_get_mac_version(struct rtl8169_private *tp)
@@ -2132,6 +2168,9 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp)
                { 0x7cf, 0x608, RTL_GIGA_MAC_VER_60 },
                { 0x7c8, 0x608, RTL_GIGA_MAC_VER_61 },
 
+               /* RTL8117 */
+               { 0x7cf, 0x54a, RTL_GIGA_MAC_VER_52 },
+
                /* 8168EP family. */
                { 0x7cf, 0x502, RTL_GIGA_MAC_VER_51 },
                { 0x7cf, 0x501, RTL_GIGA_MAC_VER_50 },
@@ -2260,14 +2299,6 @@ static void rtl_apply_firmware(struct rtl8169_private *tp)
                rtl_fw_write_firmware(tp, tp->rtl_fw);
 }
 
-static void rtl_apply_firmware_cond(struct rtl8169_private *tp, u8 reg, u16 val)
-{
-       if (rtl_readphy(tp, reg) != val)
-               netif_warn(tp, hw, tp->dev, "chipset not ready for firmware\n");
-       else
-               rtl_apply_firmware(tp);
-}
-
 static void rtl8168_config_eee_mac(struct rtl8169_private *tp)
 {
        /* Adjust EEE LED frequency */
@@ -2287,15 +2318,8 @@ static void rtl8168f_config_eee_phy(struct rtl8169_private *tp)
 {
        struct phy_device *phydev = tp->phydev;
 
-       phy_write(phydev, 0x1f, 0x0007);
-       phy_write(phydev, 0x1e, 0x0020);
-       phy_set_bits(phydev, 0x15, BIT(8));
-
-       phy_write(phydev, 0x1f, 0x0005);
-       phy_write(phydev, 0x05, 0x8b85);
-       phy_set_bits(phydev, 0x06, BIT(13));
-
-       phy_write(phydev, 0x1f, 0x0000);
+       r8168d_modify_extpage(phydev, 0x0020, 0x15, 0, BIT(8));
+       r8168d_phy_param(phydev, 0x8b85, 0, BIT(13));
 }
 
 static void rtl8168g_config_eee_phy(struct rtl8169_private *tp)
@@ -2392,13 +2416,7 @@ static void rtl8169s_hw_phy_config(struct rtl8169_private *tp)
 
 static void rtl8169sb_hw_phy_config(struct rtl8169_private *tp)
 {
-       static const struct phy_reg phy_reg_init[] = {
-               { 0x1f, 0x0002 },
-               { 0x01, 0x90d0 },
-               { 0x1f, 0x0000 }
-       };
-
-       rtl_writephy_batch(tp, phy_reg_init);
+       phy_write_paged(tp->phydev, 0x0002, 0x01, 0x90d0);
 }
 
 static void rtl8169scd_hw_phy_config_quirk(struct rtl8169_private *tp)
@@ -2409,9 +2427,7 @@ static void rtl8169scd_hw_phy_config_quirk(struct rtl8169_private *tp)
            (pdev->subsystem_device != 0xe000))
                return;
 
-       rtl_writephy(tp, 0x1f, 0x0001);
-       rtl_writephy(tp, 0x10, 0xf01b);
-       rtl_writephy(tp, 0x1f, 0x0000);
+       phy_write_paged(tp->phydev, 0x0001, 0x10, 0xf01b);
 }
 
 static void rtl8169scd_hw_phy_config(struct rtl8169_private *tp)
@@ -2516,54 +2532,28 @@ static void rtl8169sce_hw_phy_config(struct rtl8169_private *tp)
 
 static void rtl8168bb_hw_phy_config(struct rtl8169_private *tp)
 {
-       static const struct phy_reg phy_reg_init[] = {
-               { 0x10, 0xf41b },
-               { 0x1f, 0x0000 }
-       };
-
        rtl_writephy(tp, 0x1f, 0x0001);
        rtl_patchphy(tp, 0x16, 1 << 0);
-
-       rtl_writephy_batch(tp, phy_reg_init);
+       rtl_writephy(tp, 0x10, 0xf41b);
+       rtl_writephy(tp, 0x1f, 0x0000);
 }
 
 static void rtl8168bef_hw_phy_config(struct rtl8169_private *tp)
 {
-       static const struct phy_reg phy_reg_init[] = {
-               { 0x1f, 0x0001 },
-               { 0x10, 0xf41b },
-               { 0x1f, 0x0000 }
-       };
-
-       rtl_writephy_batch(tp, phy_reg_init);
+       phy_write_paged(tp->phydev, 0x0001, 0x10, 0xf41b);
 }
 
 static void rtl8168cp_1_hw_phy_config(struct rtl8169_private *tp)
 {
-       static const struct phy_reg phy_reg_init[] = {
-               { 0x1f, 0x0000 },
-               { 0x1d, 0x0f00 },
-               { 0x1f, 0x0002 },
-               { 0x0c, 0x1ec8 },
-               { 0x1f, 0x0000 }
-       };
-
-       rtl_writephy_batch(tp, phy_reg_init);
+       phy_write(tp->phydev, 0x1d, 0x0f00);
+       phy_write_paged(tp->phydev, 0x0002, 0x0c, 0x1ec8);
 }
 
 static void rtl8168cp_2_hw_phy_config(struct rtl8169_private *tp)
 {
-       static const struct phy_reg phy_reg_init[] = {
-               { 0x1f, 0x0001 },
-               { 0x1d, 0x3d98 },
-               { 0x1f, 0x0000 }
-       };
-
-       rtl_writephy(tp, 0x1f, 0x0000);
-       rtl_patchphy(tp, 0x14, 1 << 5);
-       rtl_patchphy(tp, 0x0d, 1 << 5);
-
-       rtl_writephy_batch(tp, phy_reg_init);
+       phy_set_bits(tp->phydev, 0x14, BIT(5));
+       phy_set_bits(tp->phydev, 0x0d, BIT(5));
+       phy_write_paged(tp->phydev, 0x0001, 0x1d, 0x3d98);
 }
 
 static void rtl8168c_1_hw_phy_config(struct rtl8169_private *tp)
@@ -2645,11 +2635,6 @@ static void rtl8168c_3_hw_phy_config(struct rtl8169_private *tp)
        rtl_writephy(tp, 0x1f, 0x0000);
 }
 
-static void rtl8168c_4_hw_phy_config(struct rtl8169_private *tp)
-{
-       rtl8168c_3_hw_phy_config(tp);
-}
-
 static const struct phy_reg rtl8168d_1_phy_reg_init_0[] = {
        /* Channel Estimation */
        { 0x1f, 0x0001 },
@@ -2700,6 +2685,21 @@ static const struct phy_reg rtl8168d_1_phy_reg_init_1[] = {
        { 0x1f, 0x0002 }
 };
 
+static void rtl8168d_apply_firmware_cond(struct rtl8169_private *tp, u16 val)
+{
+       u16 reg_val;
+
+       rtl_writephy(tp, 0x1f, 0x0005);
+       rtl_writephy(tp, 0x05, 0x001b);
+       reg_val = rtl_readphy(tp, 0x06);
+       rtl_writephy(tp, 0x1f, 0x0000);
+
+       if (reg_val != val)
+               netif_warn(tp, hw, tp->dev, "chipset not ready for firmware\n");
+       else
+               rtl_apply_firmware(tp);
+}
+
 static void rtl8168d_1_hw_phy_config(struct rtl8169_private *tp)
 {
        rtl_writephy_batch(tp, rtl8168d_1_phy_reg_init_0);
@@ -2733,15 +2733,8 @@ static void rtl8168d_1_hw_phy_config(struct rtl8169_private *tp)
                                rtl_writephy(tp, 0x0d, val | set[i]);
                }
        } else {
-               static const struct phy_reg phy_reg_init[] = {
-                       { 0x1f, 0x0002 },
-                       { 0x05, 0x6662 },
-                       { 0x1f, 0x0005 },
-                       { 0x05, 0x8330 },
-                       { 0x06, 0x6662 }
-               };
-
-               rtl_writephy_batch(tp, phy_reg_init);
+               phy_write_paged(tp->phydev, 0x0002, 0x05, 0x6662);
+               r8168d_phy_param(tp->phydev, 0x8330, 0xffff, 0x6662);
        }
 
        /* RSET couple improve */
@@ -2753,13 +2746,9 @@ static void rtl8168d_1_hw_phy_config(struct rtl8169_private *tp)
        rtl_writephy(tp, 0x1f, 0x0002);
        rtl_w0w1_phy(tp, 0x02, 0x0100, 0x0600);
        rtl_w0w1_phy(tp, 0x03, 0x0000, 0xe000);
-
-       rtl_writephy(tp, 0x1f, 0x0005);
-       rtl_writephy(tp, 0x05, 0x001b);
-
-       rtl_apply_firmware_cond(tp, MII_EXPANSION, 0xbf00);
-
        rtl_writephy(tp, 0x1f, 0x0000);
+
+       rtl8168d_apply_firmware_cond(tp, 0xbf00);
 }
 
 static void rtl8168d_2_hw_phy_config(struct rtl8169_private *tp)
@@ -2786,15 +2775,8 @@ static void rtl8168d_2_hw_phy_config(struct rtl8169_private *tp)
                                rtl_writephy(tp, 0x0d, val | set[i]);
                }
        } else {
-               static const struct phy_reg phy_reg_init[] = {
-                       { 0x1f, 0x0002 },
-                       { 0x05, 0x2642 },
-                       { 0x1f, 0x0005 },
-                       { 0x05, 0x8330 },
-                       { 0x06, 0x2642 }
-               };
-
-               rtl_writephy_batch(tp, phy_reg_init);
+               phy_write_paged(tp->phydev, 0x0002, 0x05, 0x2642);
+               r8168d_phy_param(tp->phydev, 0x8330, 0xffff, 0x2642);
        }
 
        /* Fine tune PLL performance */
@@ -2805,13 +2787,9 @@ static void rtl8168d_2_hw_phy_config(struct rtl8169_private *tp)
        /* Switching regulator Slew rate */
        rtl_writephy(tp, 0x1f, 0x0002);
        rtl_patchphy(tp, 0x0f, 0x0017);
-
-       rtl_writephy(tp, 0x1f, 0x0005);
-       rtl_writephy(tp, 0x05, 0x001b);
-
-       rtl_apply_firmware_cond(tp, MII_EXPANSION, 0xb300);
-
        rtl_writephy(tp, 0x1f, 0x0000);
+
+       rtl8168d_apply_firmware_cond(tp, 0xb300);
 }
 
 static void rtl8168d_3_hw_phy_config(struct rtl8169_private *tp)
@@ -2865,41 +2843,23 @@ static void rtl8168d_3_hw_phy_config(struct rtl8169_private *tp)
                { 0x04, 0xf800 },
                { 0x04, 0xf000 },
                { 0x1f, 0x0000 },
-
-               { 0x1f, 0x0007 },
-               { 0x1e, 0x0023 },
-               { 0x16, 0x0000 },
-               { 0x1f, 0x0000 }
        };
 
        rtl_writephy_batch(tp, phy_reg_init);
+
+       r8168d_modify_extpage(tp->phydev, 0x0023, 0x16, 0xffff, 0x0000);
 }
 
 static void rtl8168d_4_hw_phy_config(struct rtl8169_private *tp)
 {
-       static const struct phy_reg phy_reg_init[] = {
-               { 0x1f, 0x0001 },
-               { 0x17, 0x0cc0 },
-
-               { 0x1f, 0x0007 },
-               { 0x1e, 0x002d },
-               { 0x18, 0x0040 },
-               { 0x1f, 0x0000 }
-       };
-
-       rtl_writephy_batch(tp, phy_reg_init);
-       rtl_patchphy(tp, 0x0d, 1 << 5);
+       phy_write_paged(tp->phydev, 0x0001, 0x17, 0x0cc0);
+       r8168d_modify_extpage(tp->phydev, 0x002d, 0x18, 0xffff, 0x0040);
+       phy_set_bits(tp->phydev, 0x0d, BIT(5));
 }
 
 static void rtl8168e_1_hw_phy_config(struct rtl8169_private *tp)
 {
        static const struct phy_reg phy_reg_init[] = {
-               /* Enable Delay cap */
-               { 0x1f, 0x0005 },
-               { 0x05, 0x8b80 },
-               { 0x06, 0xc896 },
-               { 0x1f, 0x0000 },
-
                /* Channel estimation fine tune */
                { 0x1f, 0x0001 },
                { 0x0b, 0x6c20 },
@@ -2908,60 +2868,38 @@ static void rtl8168e_1_hw_phy_config(struct rtl8169_private *tp)
                { 0x1f, 0x0003 },
                { 0x14, 0x6420 },
                { 0x1f, 0x0000 },
-
-               /* Update PFM & 10M TX idle timer */
-               { 0x1f, 0x0007 },
-               { 0x1e, 0x002f },
-               { 0x15, 0x1919 },
-               { 0x1f, 0x0000 },
-
-               { 0x1f, 0x0007 },
-               { 0x1e, 0x00ac },
-               { 0x18, 0x0006 },
-               { 0x1f, 0x0000 }
        };
+       struct phy_device *phydev = tp->phydev;
 
        rtl_apply_firmware(tp);
 
+       /* Enable Delay cap */
+       r8168d_phy_param(phydev, 0x8b80, 0xffff, 0xc896);
+
        rtl_writephy_batch(tp, phy_reg_init);
 
+       /* Update PFM & 10M TX idle timer */
+       r8168d_modify_extpage(phydev, 0x002f, 0x15, 0xffff, 0x1919);
+
+       r8168d_modify_extpage(phydev, 0x00ac, 0x18, 0xffff, 0x0006);
+
        /* DCO enable for 10M IDLE Power */
-       rtl_writephy(tp, 0x1f, 0x0007);
-       rtl_writephy(tp, 0x1e, 0x0023);
-       rtl_w0w1_phy(tp, 0x17, 0x0006, 0x0000);
-       rtl_writephy(tp, 0x1f, 0x0000);
+       r8168d_modify_extpage(phydev, 0x0023, 0x17, 0x0000, 0x0006);
 
        /* For impedance matching */
-       rtl_writephy(tp, 0x1f, 0x0002);
-       rtl_w0w1_phy(tp, 0x08, 0x8000, 0x7f00);
-       rtl_writephy(tp, 0x1f, 0x0000);
+       phy_modify_paged(phydev, 0x0002, 0x08, 0x7f00, 0x8000);
 
        /* PHY auto speed down */
-       rtl_writephy(tp, 0x1f, 0x0007);
-       rtl_writephy(tp, 0x1e, 0x002d);
-       rtl_w0w1_phy(tp, 0x18, 0x0050, 0x0000);
-       rtl_writephy(tp, 0x1f, 0x0000);
-       rtl_w0w1_phy(tp, 0x14, 0x8000, 0x0000);
+       r8168d_modify_extpage(phydev, 0x002d, 0x18, 0x0000, 0x0050);
+       phy_set_bits(phydev, 0x14, BIT(15));
 
-       rtl_writephy(tp, 0x1f, 0x0005);
-       rtl_writephy(tp, 0x05, 0x8b86);
-       rtl_w0w1_phy(tp, 0x06, 0x0001, 0x0000);
-       rtl_writephy(tp, 0x1f, 0x0000);
+       r8168d_phy_param(phydev, 0x8b86, 0x0000, 0x0001);
+       r8168d_phy_param(phydev, 0x8b85, 0x2000, 0x0000);
 
-       rtl_writephy(tp, 0x1f, 0x0005);
-       rtl_writephy(tp, 0x05, 0x8b85);
-       rtl_w0w1_phy(tp, 0x06, 0x0000, 0x2000);
-       rtl_writephy(tp, 0x1f, 0x0007);
-       rtl_writephy(tp, 0x1e, 0x0020);
-       rtl_w0w1_phy(tp, 0x15, 0x0000, 0x1100);
-       rtl_writephy(tp, 0x1f, 0x0006);
-       rtl_writephy(tp, 0x00, 0x5a00);
-       rtl_writephy(tp, 0x1f, 0x0000);
-       rtl_writephy(tp, 0x0d, 0x0007);
-       rtl_writephy(tp, 0x0e, 0x003c);
-       rtl_writephy(tp, 0x0d, 0x4007);
-       rtl_writephy(tp, 0x0e, 0x0000);
-       rtl_writephy(tp, 0x0d, 0x0000);
+       r8168d_modify_extpage(phydev, 0x0020, 0x15, 0x1100, 0x0000);
+       phy_write_paged(phydev, 0x0006, 0x00, 0x5a00);
+
+       phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0x0000);
 }
 
 static void rtl_rar_exgmac_set(struct rtl8169_private *tp, u8 *addr)
@@ -2980,36 +2918,20 @@ static void rtl_rar_exgmac_set(struct rtl8169_private *tp, u8 *addr)
 
 static void rtl8168e_2_hw_phy_config(struct rtl8169_private *tp)
 {
-       static const struct phy_reg phy_reg_init[] = {
-               /* Enable Delay cap */
-               { 0x1f, 0x0004 },
-               { 0x1f, 0x0007 },
-               { 0x1e, 0x00ac },
-               { 0x18, 0x0006 },
-               { 0x1f, 0x0002 },
-               { 0x1f, 0x0000 },
-               { 0x1f, 0x0000 },
+       struct phy_device *phydev = tp->phydev;
 
-               /* Channel estimation fine tune */
-               { 0x1f, 0x0003 },
-               { 0x09, 0xa20f },
-               { 0x1f, 0x0000 },
-               { 0x1f, 0x0000 },
+       rtl_apply_firmware(tp);
 
-               /* Green Setting */
-               { 0x1f, 0x0005 },
-               { 0x05, 0x8b5b },
-               { 0x06, 0x9222 },
-               { 0x05, 0x8b6d },
-               { 0x06, 0x8000 },
-               { 0x05, 0x8b76 },
-               { 0x06, 0x8000 },
-               { 0x1f, 0x0000 }
-       };
+       /* Enable Delay cap */
+       r8168d_modify_extpage(phydev, 0x00ac, 0x18, 0xffff, 0x0006);
 
-       rtl_apply_firmware(tp);
+       /* Channel estimation fine tune */
+       phy_write_paged(phydev, 0x0003, 0x09, 0xa20f);
 
-       rtl_writephy_batch(tp, phy_reg_init);
+       /* Green Setting */
+       r8168d_phy_param(phydev, 0x8b5b, 0xffff, 0x9222);
+       r8168d_phy_param(phydev, 0x8b6d, 0xffff, 0x8000);
+       r8168d_phy_param(phydev, 0x8b76, 0xffff, 0x8000);
 
        /* For 4-corner performance improve */
        rtl_writephy(tp, 0x1f, 0x0005);
@@ -3018,25 +2940,14 @@ static void rtl8168e_2_hw_phy_config(struct rtl8169_private *tp)
        rtl_writephy(tp, 0x1f, 0x0000);
 
        /* PHY auto speed down */
-       rtl_writephy(tp, 0x1f, 0x0004);
-       rtl_writephy(tp, 0x1f, 0x0007);
-       rtl_writephy(tp, 0x1e, 0x002d);
-       rtl_w0w1_phy(tp, 0x18, 0x0010, 0x0000);
-       rtl_writephy(tp, 0x1f, 0x0002);
-       rtl_writephy(tp, 0x1f, 0x0000);
-       rtl_w0w1_phy(tp, 0x14, 0x8000, 0x0000);
+       r8168d_modify_extpage(phydev, 0x002d, 0x18, 0x0000, 0x0010);
+       phy_set_bits(phydev, 0x14, BIT(15));
 
        /* improve 10M EEE waveform */
-       rtl_writephy(tp, 0x1f, 0x0005);
-       rtl_writephy(tp, 0x05, 0x8b86);
-       rtl_w0w1_phy(tp, 0x06, 0x0001, 0x0000);
-       rtl_writephy(tp, 0x1f, 0x0000);
+       r8168d_phy_param(phydev, 0x8b86, 0x0000, 0x0001);
 
        /* Improve 2-pair detection performance */
-       rtl_writephy(tp, 0x1f, 0x0005);
-       rtl_writephy(tp, 0x05, 0x8b85);
-       rtl_w0w1_phy(tp, 0x06, 0x4000, 0x0000);
-       rtl_writephy(tp, 0x1f, 0x0000);
+       r8168d_phy_param(phydev, 0x8b85, 0x0000, 0x4000);
 
        rtl8168f_config_eee_phy(tp);
        rtl_enable_eee(tp);
@@ -3056,24 +2967,17 @@ static void rtl8168e_2_hw_phy_config(struct rtl8169_private *tp)
 
 static void rtl8168f_hw_phy_config(struct rtl8169_private *tp)
 {
+       struct phy_device *phydev = tp->phydev;
+
        /* For 4-corner performance improve */
-       rtl_writephy(tp, 0x1f, 0x0005);
-       rtl_writephy(tp, 0x05, 0x8b80);
-       rtl_w0w1_phy(tp, 0x06, 0x0006, 0x0000);
-       rtl_writephy(tp, 0x1f, 0x0000);
+       r8168d_phy_param(phydev, 0x8b80, 0x0000, 0x0006);
 
        /* PHY auto speed down */
-       rtl_writephy(tp, 0x1f, 0x0007);
-       rtl_writephy(tp, 0x1e, 0x002d);
-       rtl_w0w1_phy(tp, 0x18, 0x0010, 0x0000);
-       rtl_writephy(tp, 0x1f, 0x0000);
-       rtl_w0w1_phy(tp, 0x14, 0x8000, 0x0000);
+       r8168d_modify_extpage(phydev, 0x002d, 0x18, 0x0000, 0x0010);
+       phy_set_bits(phydev, 0x14, BIT(15));
 
        /* Improve 10M EEE waveform */
-       rtl_writephy(tp, 0x1f, 0x0005);
-       rtl_writephy(tp, 0x05, 0x8b86);
-       rtl_w0w1_phy(tp, 0x06, 0x0001, 0x0000);
-       rtl_writephy(tp, 0x1f, 0x0000);
+       r8168d_phy_param(phydev, 0x8b86, 0x0000, 0x0001);
 
        rtl8168f_config_eee_phy(tp);
        rtl_enable_eee(tp);
@@ -3081,52 +2985,31 @@ static void rtl8168f_hw_phy_config(struct rtl8169_private *tp)
 
 static void rtl8168f_1_hw_phy_config(struct rtl8169_private *tp)
 {
-       static const struct phy_reg phy_reg_init[] = {
-               /* Channel estimation fine tune */
-               { 0x1f, 0x0003 },
-               { 0x09, 0xa20f },
-               { 0x1f, 0x0000 },
+       struct phy_device *phydev = tp->phydev;
 
-               /* Modify green table for giga & fnet */
-               { 0x1f, 0x0005 },
-               { 0x05, 0x8b55 },
-               { 0x06, 0x0000 },
-               { 0x05, 0x8b5e },
-               { 0x06, 0x0000 },
-               { 0x05, 0x8b67 },
-               { 0x06, 0x0000 },
-               { 0x05, 0x8b70 },
-               { 0x06, 0x0000 },
-               { 0x1f, 0x0000 },
-               { 0x1f, 0x0007 },
-               { 0x1e, 0x0078 },
-               { 0x17, 0x0000 },
-               { 0x19, 0x00fb },
-               { 0x1f, 0x0000 },
+       rtl_apply_firmware(tp);
 
-               /* Modify green table for 10M */
-               { 0x1f, 0x0005 },
-               { 0x05, 0x8b79 },
-               { 0x06, 0xaa00 },
-               { 0x1f, 0x0000 },
+       /* Channel estimation fine tune */
+       phy_write_paged(phydev, 0x0003, 0x09, 0xa20f);
 
-               /* Disable hiimpedance detection (RTCT) */
-               { 0x1f, 0x0003 },
-               { 0x01, 0x328a },
-               { 0x1f, 0x0000 }
-       };
+       /* Modify green table for giga & fnet */
+       r8168d_phy_param(phydev, 0x8b55, 0xffff, 0x0000);
+       r8168d_phy_param(phydev, 0x8b5e, 0xffff, 0x0000);
+       r8168d_phy_param(phydev, 0x8b67, 0xffff, 0x0000);
+       r8168d_phy_param(phydev, 0x8b70, 0xffff, 0x0000);
+       r8168d_modify_extpage(phydev, 0x0078, 0x17, 0xffff, 0x0000);
+       r8168d_modify_extpage(phydev, 0x0078, 0x19, 0xffff, 0x00fb);
 
-       rtl_apply_firmware(tp);
+       /* Modify green table for 10M */
+       r8168d_phy_param(phydev, 0x8b79, 0xffff, 0xaa00);
 
-       rtl_writephy_batch(tp, phy_reg_init);
+       /* Disable hiimpedance detection (RTCT) */
+       phy_write_paged(phydev, 0x0003, 0x01, 0x328a);
 
        rtl8168f_hw_phy_config(tp);
 
        /* Improve 2-pair detection performance */
-       rtl_writephy(tp, 0x1f, 0x0005);
-       rtl_writephy(tp, 0x05, 0x8b85);
-       rtl_w0w1_phy(tp, 0x06, 0x4000, 0x0000);
-       rtl_writephy(tp, 0x1f, 0x0000);
+       r8168d_phy_param(phydev, 0x8b85, 0x0000, 0x4000);
 }
 
 static void rtl8168f_2_hw_phy_config(struct rtl8169_private *tp)
@@ -3138,77 +3021,43 @@ static void rtl8168f_2_hw_phy_config(struct rtl8169_private *tp)
 
 static void rtl8411_hw_phy_config(struct rtl8169_private *tp)
 {
-       static const struct phy_reg phy_reg_init[] = {
-               /* Channel estimation fine tune */
-               { 0x1f, 0x0003 },
-               { 0x09, 0xa20f },
-               { 0x1f, 0x0000 },
-
-               /* Modify green table for giga & fnet */
-               { 0x1f, 0x0005 },
-               { 0x05, 0x8b55 },
-               { 0x06, 0x0000 },
-               { 0x05, 0x8b5e },
-               { 0x06, 0x0000 },
-               { 0x05, 0x8b67 },
-               { 0x06, 0x0000 },
-               { 0x05, 0x8b70 },
-               { 0x06, 0x0000 },
-               { 0x1f, 0x0000 },
-               { 0x1f, 0x0007 },
-               { 0x1e, 0x0078 },
-               { 0x17, 0x0000 },
-               { 0x19, 0x00aa },
-               { 0x1f, 0x0000 },
-
-               /* Modify green table for 10M */
-               { 0x1f, 0x0005 },
-               { 0x05, 0x8b79 },
-               { 0x06, 0xaa00 },
-               { 0x1f, 0x0000 },
-
-               /* Disable hiimpedance detection (RTCT) */
-               { 0x1f, 0x0003 },
-               { 0x01, 0x328a },
-               { 0x1f, 0x0000 }
-       };
-
+       struct phy_device *phydev = tp->phydev;
 
        rtl_apply_firmware(tp);
 
        rtl8168f_hw_phy_config(tp);
 
        /* Improve 2-pair detection performance */
-       rtl_writephy(tp, 0x1f, 0x0005);
-       rtl_writephy(tp, 0x05, 0x8b85);
-       rtl_w0w1_phy(tp, 0x06, 0x4000, 0x0000);
-       rtl_writephy(tp, 0x1f, 0x0000);
+       r8168d_phy_param(phydev, 0x8b85, 0x0000, 0x4000);
 
-       rtl_writephy_batch(tp, phy_reg_init);
+       /* Channel estimation fine tune */
+       phy_write_paged(phydev, 0x0003, 0x09, 0xa20f);
+
+       /* Modify green table for giga & fnet */
+       r8168d_phy_param(phydev, 0x8b55, 0xffff, 0x0000);
+       r8168d_phy_param(phydev, 0x8b5e, 0xffff, 0x0000);
+       r8168d_phy_param(phydev, 0x8b67, 0xffff, 0x0000);
+       r8168d_phy_param(phydev, 0x8b70, 0xffff, 0x0000);
+       r8168d_modify_extpage(phydev, 0x0078, 0x17, 0xffff, 0x0000);
+       r8168d_modify_extpage(phydev, 0x0078, 0x19, 0xffff, 0x00aa);
+
+       /* Modify green table for 10M */
+       r8168d_phy_param(phydev, 0x8b79, 0xffff, 0xaa00);
+
+       /* Disable hiimpedance detection (RTCT) */
+       phy_write_paged(phydev, 0x0003, 0x01, 0x328a);
 
        /* Modify green table for giga */
-       rtl_writephy(tp, 0x1f, 0x0005);
-       rtl_writephy(tp, 0x05, 0x8b54);
-       rtl_w0w1_phy(tp, 0x06, 0x0000, 0x0800);
-       rtl_writephy(tp, 0x05, 0x8b5d);
-       rtl_w0w1_phy(tp, 0x06, 0x0000, 0x0800);
-       rtl_writephy(tp, 0x05, 0x8a7c);
-       rtl_w0w1_phy(tp, 0x06, 0x0000, 0x0100);
-       rtl_writephy(tp, 0x05, 0x8a7f);
-       rtl_w0w1_phy(tp, 0x06, 0x0100, 0x0000);
-       rtl_writephy(tp, 0x05, 0x8a82);
-       rtl_w0w1_phy(tp, 0x06, 0x0000, 0x0100);
-       rtl_writephy(tp, 0x05, 0x8a85);
-       rtl_w0w1_phy(tp, 0x06, 0x0000, 0x0100);
-       rtl_writephy(tp, 0x05, 0x8a88);
-       rtl_w0w1_phy(tp, 0x06, 0x0000, 0x0100);
-       rtl_writephy(tp, 0x1f, 0x0000);
+       r8168d_phy_param(phydev, 0x8b54, 0x0800, 0x0000);
+       r8168d_phy_param(phydev, 0x8b5d, 0x0800, 0x0000);
+       r8168d_phy_param(phydev, 0x8a7c, 0x0100, 0x0000);
+       r8168d_phy_param(phydev, 0x8a7f, 0x0000, 0x0100);
+       r8168d_phy_param(phydev, 0x8a82, 0x0100, 0x0000);
+       r8168d_phy_param(phydev, 0x8a85, 0x0100, 0x0000);
+       r8168d_phy_param(phydev, 0x8a88, 0x0100, 0x0000);
 
        /* uc same-seed solution */
-       rtl_writephy(tp, 0x1f, 0x0005);
-       rtl_writephy(tp, 0x05, 0x8b85);
-       rtl_w0w1_phy(tp, 0x06, 0x8000, 0x0000);
-       rtl_writephy(tp, 0x1f, 0x0000);
+       r8168d_phy_param(phydev, 0x8b85, 0x0000, 0x8000);
 
        /* Green feature */
        rtl_writephy(tp, 0x1f, 0x0003);
@@ -3228,12 +3077,8 @@ static void rtl8168g_phy_adjust_10m_aldps(struct rtl8169_private *tp)
 
        phy_modify_paged(phydev, 0x0bcc, 0x14, BIT(8), 0);
        phy_modify_paged(phydev, 0x0a44, 0x11, 0, BIT(7) | BIT(6));
-       phy_write(phydev, 0x1f, 0x0a43);
-       phy_write(phydev, 0x13, 0x8084);
-       phy_clear_bits(phydev, 0x14, BIT(14) | BIT(13));
-       phy_set_bits(phydev, 0x10, BIT(12) | BIT(1) | BIT(0));
-
-       phy_write(phydev, 0x1f, 0x0000);
+       r8168g_phy_param(phydev, 0x8084, 0x6000, 0x0000);
+       phy_modify_paged(phydev, 0x0a43, 0x10, 0x0000, 0x1003);
 }
 
 static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp)
@@ -3263,9 +3108,7 @@ static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp)
        phy_modify_paged(tp->phydev, 0x0a4b, 0x11, 0, BIT(2));
 
        /* Enable UC LPF tune function */
-       rtl_writephy(tp, 0x1f, 0x0a43);
-       rtl_writephy(tp, 0x13, 0x8012);
-       rtl_w0w1_phy(tp, 0x14, 0x8000, 0x0000);
+       r8168g_phy_param(tp->phydev, 0x8012, 0x0000, 0x8000);
 
        phy_modify_paged(tp->phydev, 0x0c42, 0x11, BIT(13), BIT(14));
 
@@ -3295,73 +3138,48 @@ static void rtl8168g_2_hw_phy_config(struct rtl8169_private *tp)
 
 static void rtl8168h_1_hw_phy_config(struct rtl8169_private *tp)
 {
+       struct phy_device *phydev = tp->phydev;
        u16 dout_tapbin;
        u32 data;
 
        rtl_apply_firmware(tp);
 
        /* CHN EST parameters adjust - giga master */
-       rtl_writephy(tp, 0x1f, 0x0a43);
-       rtl_writephy(tp, 0x13, 0x809b);
-       rtl_w0w1_phy(tp, 0x14, 0x8000, 0xf800);
-       rtl_writephy(tp, 0x13, 0x80a2);
-       rtl_w0w1_phy(tp, 0x14, 0x8000, 0xff00);
-       rtl_writephy(tp, 0x13, 0x80a4);
-       rtl_w0w1_phy(tp, 0x14, 0x8500, 0xff00);
-       rtl_writephy(tp, 0x13, 0x809c);
-       rtl_w0w1_phy(tp, 0x14, 0xbd00, 0xff00);
-       rtl_writephy(tp, 0x1f, 0x0000);
+       r8168g_phy_param(phydev, 0x809b, 0xf800, 0x8000);
+       r8168g_phy_param(phydev, 0x80a2, 0xff00, 0x8000);
+       r8168g_phy_param(phydev, 0x80a4, 0xff00, 0x8500);
+       r8168g_phy_param(phydev, 0x809c, 0xff00, 0xbd00);
 
        /* CHN EST parameters adjust - giga slave */
-       rtl_writephy(tp, 0x1f, 0x0a43);
-       rtl_writephy(tp, 0x13, 0x80ad);
-       rtl_w0w1_phy(tp, 0x14, 0x7000, 0xf800);
-       rtl_writephy(tp, 0x13, 0x80b4);
-       rtl_w0w1_phy(tp, 0x14, 0x5000, 0xff00);
-       rtl_writephy(tp, 0x13, 0x80ac);
-       rtl_w0w1_phy(tp, 0x14, 0x4000, 0xff00);
-       rtl_writephy(tp, 0x1f, 0x0000);
+       r8168g_phy_param(phydev, 0x80ad, 0xf800, 0x7000);
+       r8168g_phy_param(phydev, 0x80b4, 0xff00, 0x5000);
+       r8168g_phy_param(phydev, 0x80ac, 0xff00, 0x4000);
 
        /* CHN EST parameters adjust - fnet */
-       rtl_writephy(tp, 0x1f, 0x0a43);
-       rtl_writephy(tp, 0x13, 0x808e);
-       rtl_w0w1_phy(tp, 0x14, 0x1200, 0xff00);
-       rtl_writephy(tp, 0x13, 0x8090);
-       rtl_w0w1_phy(tp, 0x14, 0xe500, 0xff00);
-       rtl_writephy(tp, 0x13, 0x8092);
-       rtl_w0w1_phy(tp, 0x14, 0x9f00, 0xff00);
-       rtl_writephy(tp, 0x1f, 0x0000);
+       r8168g_phy_param(phydev, 0x808e, 0xff00, 0x1200);
+       r8168g_phy_param(phydev, 0x8090, 0xff00, 0xe500);
+       r8168g_phy_param(phydev, 0x8092, 0xff00, 0x9f00);
 
        /* enable R-tune & PGA-retune function */
        dout_tapbin = 0;
-       rtl_writephy(tp, 0x1f, 0x0a46);
-       data = rtl_readphy(tp, 0x13);
+       data = phy_read_paged(phydev, 0x0a46, 0x13);
        data &= 3;
        data <<= 2;
        dout_tapbin |= data;
-       data = rtl_readphy(tp, 0x12);
+       data = phy_read_paged(phydev, 0x0a46, 0x12);
        data &= 0xc000;
        data >>= 14;
        dout_tapbin |= data;
        dout_tapbin = ~(dout_tapbin^0x08);
        dout_tapbin <<= 12;
        dout_tapbin &= 0xf000;
-       rtl_writephy(tp, 0x1f, 0x0a43);
-       rtl_writephy(tp, 0x13, 0x827a);
-       rtl_w0w1_phy(tp, 0x14, dout_tapbin, 0xf000);
-       rtl_writephy(tp, 0x13, 0x827b);
-       rtl_w0w1_phy(tp, 0x14, dout_tapbin, 0xf000);
-       rtl_writephy(tp, 0x13, 0x827c);
-       rtl_w0w1_phy(tp, 0x14, dout_tapbin, 0xf000);
-       rtl_writephy(tp, 0x13, 0x827d);
-       rtl_w0w1_phy(tp, 0x14, dout_tapbin, 0xf000);
-
-       rtl_writephy(tp, 0x1f, 0x0a43);
-       rtl_writephy(tp, 0x13, 0x0811);
-       rtl_w0w1_phy(tp, 0x14, 0x0800, 0x0000);
-       rtl_writephy(tp, 0x1f, 0x0a42);
-       rtl_w0w1_phy(tp, 0x16, 0x0002, 0x0000);
-       rtl_writephy(tp, 0x1f, 0x0000);
+
+       r8168g_phy_param(phydev, 0x827a, 0xf000, dout_tapbin);
+       r8168g_phy_param(phydev, 0x827b, 0xf000, dout_tapbin);
+       r8168g_phy_param(phydev, 0x827c, 0xf000, dout_tapbin);
+       r8168g_phy_param(phydev, 0x827d, 0xf000, dout_tapbin);
+       r8168g_phy_param(phydev, 0x0811, 0x0000, 0x0800);
+       phy_modify_paged(phydev, 0x0a42, 0x16, 0x0000, 0x0002);
 
        /* enable GPHY 10M */
        phy_modify_paged(tp->phydev, 0x0a44, 0x11, 0, BIT(11));
@@ -3369,22 +3187,13 @@ static void rtl8168h_1_hw_phy_config(struct rtl8169_private *tp)
        /* SAR ADC performance */
        phy_modify_paged(tp->phydev, 0x0bca, 0x17, BIT(12) | BIT(13), BIT(14));
 
-       rtl_writephy(tp, 0x1f, 0x0a43);
-       rtl_writephy(tp, 0x13, 0x803f);
-       rtl_w0w1_phy(tp, 0x14, 0x0000, 0x3000);
-       rtl_writephy(tp, 0x13, 0x8047);
-       rtl_w0w1_phy(tp, 0x14, 0x0000, 0x3000);
-       rtl_writephy(tp, 0x13, 0x804f);
-       rtl_w0w1_phy(tp, 0x14, 0x0000, 0x3000);
-       rtl_writephy(tp, 0x13, 0x8057);
-       rtl_w0w1_phy(tp, 0x14, 0x0000, 0x3000);
-       rtl_writephy(tp, 0x13, 0x805f);
-       rtl_w0w1_phy(tp, 0x14, 0x0000, 0x3000);
-       rtl_writephy(tp, 0x13, 0x8067);
-       rtl_w0w1_phy(tp, 0x14, 0x0000, 0x3000);
-       rtl_writephy(tp, 0x13, 0x806f);
-       rtl_w0w1_phy(tp, 0x14, 0x0000, 0x3000);
-       rtl_writephy(tp, 0x1f, 0x0000);
+       r8168g_phy_param(phydev, 0x803f, 0x3000, 0x0000);
+       r8168g_phy_param(phydev, 0x8047, 0x3000, 0x0000);
+       r8168g_phy_param(phydev, 0x804f, 0x3000, 0x0000);
+       r8168g_phy_param(phydev, 0x8057, 0x3000, 0x0000);
+       r8168g_phy_param(phydev, 0x805f, 0x3000, 0x0000);
+       r8168g_phy_param(phydev, 0x8067, 0x3000, 0x0000);
+       r8168g_phy_param(phydev, 0x806f, 0x3000, 0x0000);
 
        /* disable phy pfm mode */
        phy_modify_paged(tp->phydev, 0x0a44, 0x11, BIT(7), 0);
@@ -3397,24 +3206,18 @@ static void rtl8168h_1_hw_phy_config(struct rtl8169_private *tp)
 static void rtl8168h_2_hw_phy_config(struct rtl8169_private *tp)
 {
        u16 ioffset_p3, ioffset_p2, ioffset_p1, ioffset_p0;
+       struct phy_device *phydev = tp->phydev;
        u16 rlen;
        u32 data;
 
        rtl_apply_firmware(tp);
 
        /* CHIN EST parameter update */
-       rtl_writephy(tp, 0x1f, 0x0a43);
-       rtl_writephy(tp, 0x13, 0x808a);
-       rtl_w0w1_phy(tp, 0x14, 0x000a, 0x003f);
-       rtl_writephy(tp, 0x1f, 0x0000);
+       r8168g_phy_param(phydev, 0x808a, 0x003f, 0x000a);
 
        /* enable R-tune & PGA-retune function */
-       rtl_writephy(tp, 0x1f, 0x0a43);
-       rtl_writephy(tp, 0x13, 0x0811);
-       rtl_w0w1_phy(tp, 0x14, 0x0800, 0x0000);
-       rtl_writephy(tp, 0x1f, 0x0a42);
-       rtl_w0w1_phy(tp, 0x16, 0x0002, 0x0000);
-       rtl_writephy(tp, 0x1f, 0x0000);
+       r8168g_phy_param(phydev, 0x0811, 0x0000, 0x0800);
+       phy_modify_paged(phydev, 0x0a42, 0x16, 0x0000, 0x0002);
 
        /* enable GPHY 10M */
        phy_modify_paged(tp->phydev, 0x0a44, 0x11, 0, BIT(11));
@@ -3434,26 +3237,20 @@ static void rtl8168h_2_hw_phy_config(struct rtl8169_private *tp)
        data = (ioffset_p3<<12)|(ioffset_p2<<8)|(ioffset_p1<<4)|(ioffset_p0);
 
        if ((ioffset_p3 != 0x0f) || (ioffset_p2 != 0x0f) ||
-           (ioffset_p1 != 0x0f) || (ioffset_p0 != 0x0f)) {
-               rtl_writephy(tp, 0x1f, 0x0bcf);
-               rtl_writephy(tp, 0x16, data);
-               rtl_writephy(tp, 0x1f, 0x0000);
-       }
+           (ioffset_p1 != 0x0f) || (ioffset_p0 != 0x0f))
+               phy_write_paged(phydev, 0x0bcf, 0x16, data);
 
        /* Modify rlen (TX LPF corner frequency) level */
-       rtl_writephy(tp, 0x1f, 0x0bcd);
-       data = rtl_readphy(tp, 0x16);
+       data = phy_read_paged(phydev, 0x0bcd, 0x16);
        data &= 0x000f;
        rlen = 0;
        if (data > 3)
                rlen = data - 3;
        data = rlen | (rlen<<4) | (rlen<<8) | (rlen<<12);
-       rtl_writephy(tp, 0x17, data);
-       rtl_writephy(tp, 0x1f, 0x0bcd);
-       rtl_writephy(tp, 0x1f, 0x0000);
+       phy_write_paged(phydev, 0x0bcd, 0x17, data);
 
        /* disable phy pfm mode */
-       phy_modify_paged(tp->phydev, 0x0a44, 0x11, BIT(7), 0);
+       phy_modify_paged(phydev, 0x0a44, 0x11, BIT(7), 0);
 
        rtl8168g_disable_aldps(tp);
        rtl8168g_config_eee_phy(tp);
@@ -3462,22 +3259,21 @@ static void rtl8168h_2_hw_phy_config(struct rtl8169_private *tp)
 
 static void rtl8168ep_1_hw_phy_config(struct rtl8169_private *tp)
 {
+       struct phy_device *phydev = tp->phydev;
+
        /* Enable PHY auto speed down */
-       phy_modify_paged(tp->phydev, 0x0a44, 0x11, 0, BIT(3) | BIT(2));
+       phy_modify_paged(phydev, 0x0a44, 0x11, 0, BIT(3) | BIT(2));
 
        rtl8168g_phy_adjust_10m_aldps(tp);
 
        /* Enable EEE auto-fallback function */
-       phy_modify_paged(tp->phydev, 0x0a4b, 0x11, 0, BIT(2));
+       phy_modify_paged(phydev, 0x0a4b, 0x11, 0, BIT(2));
 
        /* Enable UC LPF tune function */
-       rtl_writephy(tp, 0x1f, 0x0a43);
-       rtl_writephy(tp, 0x13, 0x8012);
-       rtl_w0w1_phy(tp, 0x14, 0x8000, 0x0000);
-       rtl_writephy(tp, 0x1f, 0x0000);
+       r8168g_phy_param(phydev, 0x8012, 0x0000, 0x8000);
 
        /* set rg_sel_sdm_rate */
-       phy_modify_paged(tp->phydev, 0x0c42, 0x11, BIT(13), BIT(14));
+       phy_modify_paged(phydev, 0x0c42, 0x11, BIT(13), BIT(14));
 
        rtl8168g_disable_aldps(tp);
        rtl8168g_config_eee_phy(tp);
@@ -3486,63 +3282,38 @@ static void rtl8168ep_1_hw_phy_config(struct rtl8169_private *tp)
 
 static void rtl8168ep_2_hw_phy_config(struct rtl8169_private *tp)
 {
+       struct phy_device *phydev = tp->phydev;
+
        rtl8168g_phy_adjust_10m_aldps(tp);
 
        /* Enable UC LPF tune function */
-       rtl_writephy(tp, 0x1f, 0x0a43);
-       rtl_writephy(tp, 0x13, 0x8012);
-       rtl_w0w1_phy(tp, 0x14, 0x8000, 0x0000);
-       rtl_writephy(tp, 0x1f, 0x0000);
+       r8168g_phy_param(phydev, 0x8012, 0x0000, 0x8000);
 
        /* Set rg_sel_sdm_rate */
        phy_modify_paged(tp->phydev, 0x0c42, 0x11, BIT(13), BIT(14));
 
        /* Channel estimation parameters */
-       rtl_writephy(tp, 0x1f, 0x0a43);
-       rtl_writephy(tp, 0x13, 0x80f3);
-       rtl_w0w1_phy(tp, 0x14, 0x8b00, ~0x8bff);
-       rtl_writephy(tp, 0x13, 0x80f0);
-       rtl_w0w1_phy(tp, 0x14, 0x3a00, ~0x3aff);
-       rtl_writephy(tp, 0x13, 0x80ef);
-       rtl_w0w1_phy(tp, 0x14, 0x0500, ~0x05ff);
-       rtl_writephy(tp, 0x13, 0x80f6);
-       rtl_w0w1_phy(tp, 0x14, 0x6e00, ~0x6eff);
-       rtl_writephy(tp, 0x13, 0x80ec);
-       rtl_w0w1_phy(tp, 0x14, 0x6800, ~0x68ff);
-       rtl_writephy(tp, 0x13, 0x80ed);
-       rtl_w0w1_phy(tp, 0x14, 0x7c00, ~0x7cff);
-       rtl_writephy(tp, 0x13, 0x80f2);
-       rtl_w0w1_phy(tp, 0x14, 0xf400, ~0xf4ff);
-       rtl_writephy(tp, 0x13, 0x80f4);
-       rtl_w0w1_phy(tp, 0x14, 0x8500, ~0x85ff);
-       rtl_writephy(tp, 0x1f, 0x0a43);
-       rtl_writephy(tp, 0x13, 0x8110);
-       rtl_w0w1_phy(tp, 0x14, 0xa800, ~0xa8ff);
-       rtl_writephy(tp, 0x13, 0x810f);
-       rtl_w0w1_phy(tp, 0x14, 0x1d00, ~0x1dff);
-       rtl_writephy(tp, 0x13, 0x8111);
-       rtl_w0w1_phy(tp, 0x14, 0xf500, ~0xf5ff);
-       rtl_writephy(tp, 0x13, 0x8113);
-       rtl_w0w1_phy(tp, 0x14, 0x6100, ~0x61ff);
-       rtl_writephy(tp, 0x13, 0x8115);
-       rtl_w0w1_phy(tp, 0x14, 0x9200, ~0x92ff);
-       rtl_writephy(tp, 0x13, 0x810e);
-       rtl_w0w1_phy(tp, 0x14, 0x0400, ~0x04ff);
-       rtl_writephy(tp, 0x13, 0x810c);
-       rtl_w0w1_phy(tp, 0x14, 0x7c00, ~0x7cff);
-       rtl_writephy(tp, 0x13, 0x810b);
-       rtl_w0w1_phy(tp, 0x14, 0x5a00, ~0x5aff);
-       rtl_writephy(tp, 0x1f, 0x0a43);
-       rtl_writephy(tp, 0x13, 0x80d1);
-       rtl_w0w1_phy(tp, 0x14, 0xff00, ~0xffff);
-       rtl_writephy(tp, 0x13, 0x80cd);
-       rtl_w0w1_phy(tp, 0x14, 0x9e00, ~0x9eff);
-       rtl_writephy(tp, 0x13, 0x80d3);
-       rtl_w0w1_phy(tp, 0x14, 0x0e00, ~0x0eff);
-       rtl_writephy(tp, 0x13, 0x80d5);
-       rtl_w0w1_phy(tp, 0x14, 0xca00, ~0xcaff);
-       rtl_writephy(tp, 0x13, 0x80d7);
-       rtl_w0w1_phy(tp, 0x14, 0x8400, ~0x84ff);
+       r8168g_phy_param(phydev, 0x80f3, 0xff00, 0x8b00);
+       r8168g_phy_param(phydev, 0x80f0, 0xff00, 0x3a00);
+       r8168g_phy_param(phydev, 0x80ef, 0xff00, 0x0500);
+       r8168g_phy_param(phydev, 0x80f6, 0xff00, 0x6e00);
+       r8168g_phy_param(phydev, 0x80ec, 0xff00, 0x6800);
+       r8168g_phy_param(phydev, 0x80ed, 0xff00, 0x7c00);
+       r8168g_phy_param(phydev, 0x80f2, 0xff00, 0xf400);
+       r8168g_phy_param(phydev, 0x80f4, 0xff00, 0x8500);
+       r8168g_phy_param(phydev, 0x8110, 0xff00, 0xa800);
+       r8168g_phy_param(phydev, 0x810f, 0xff00, 0x1d00);
+       r8168g_phy_param(phydev, 0x8111, 0xff00, 0xf500);
+       r8168g_phy_param(phydev, 0x8113, 0xff00, 0x6100);
+       r8168g_phy_param(phydev, 0x8115, 0xff00, 0x9200);
+       r8168g_phy_param(phydev, 0x810e, 0xff00, 0x0400);
+       r8168g_phy_param(phydev, 0x810c, 0xff00, 0x7c00);
+       r8168g_phy_param(phydev, 0x810b, 0xff00, 0x5a00);
+       r8168g_phy_param(phydev, 0x80d1, 0xff00, 0xff00);
+       r8168g_phy_param(phydev, 0x80cd, 0xff00, 0x9e00);
+       r8168g_phy_param(phydev, 0x80d3, 0xff00, 0x0e00);
+       r8168g_phy_param(phydev, 0x80d5, 0xff00, 0xca00);
+       r8168g_phy_param(phydev, 0x80d7, 0xff00, 0x8400);
 
        /* Force PWM-mode */
        rtl_writephy(tp, 0x1f, 0x0bcd);
@@ -3561,6 +3332,46 @@ static void rtl8168ep_2_hw_phy_config(struct rtl8169_private *tp)
        rtl_enable_eee(tp);
 }
 
+static void rtl8117_hw_phy_config(struct rtl8169_private *tp)
+{
+       struct phy_device *phydev = tp->phydev;
+
+       /* CHN EST parameters adjust - fnet */
+       r8168g_phy_param(phydev, 0x808e, 0xff00, 0x4800);
+       r8168g_phy_param(phydev, 0x8090, 0xff00, 0xcc00);
+       r8168g_phy_param(phydev, 0x8092, 0xff00, 0xb000);
+
+       r8168g_phy_param(phydev, 0x8088, 0xff00, 0x6000);
+       r8168g_phy_param(phydev, 0x808b, 0x3f00, 0x0b00);
+       r8168g_phy_param(phydev, 0x808d, 0x1f00, 0x0600);
+       r8168g_phy_param(phydev, 0x808c, 0xff00, 0xb000);
+       r8168g_phy_param(phydev, 0x80a0, 0xff00, 0x2800);
+       r8168g_phy_param(phydev, 0x80a2, 0xff00, 0x5000);
+       r8168g_phy_param(phydev, 0x809b, 0xf800, 0xb000);
+       r8168g_phy_param(phydev, 0x809a, 0xff00, 0x4b00);
+       r8168g_phy_param(phydev, 0x809d, 0x3f00, 0x0800);
+       r8168g_phy_param(phydev, 0x80a1, 0xff00, 0x7000);
+       r8168g_phy_param(phydev, 0x809f, 0x1f00, 0x0300);
+       r8168g_phy_param(phydev, 0x809e, 0xff00, 0x8800);
+       r8168g_phy_param(phydev, 0x80b2, 0xff00, 0x2200);
+       r8168g_phy_param(phydev, 0x80ad, 0xf800, 0x9800);
+       r8168g_phy_param(phydev, 0x80af, 0x3f00, 0x0800);
+       r8168g_phy_param(phydev, 0x80b3, 0xff00, 0x6f00);
+       r8168g_phy_param(phydev, 0x80b1, 0x1f00, 0x0300);
+       r8168g_phy_param(phydev, 0x80b0, 0xff00, 0x9300);
+
+       r8168g_phy_param(phydev, 0x8011, 0x0000, 0x0800);
+
+       /* enable GPHY 10M */
+       phy_modify_paged(tp->phydev, 0x0a44, 0x11, 0, BIT(11));
+
+       r8168g_phy_param(phydev, 0x8016, 0x0000, 0x0400);
+
+       rtl8168g_disable_aldps(tp);
+       rtl8168h_config_eee_phy(tp);
+       rtl_enable_eee(tp);
+}
+
 static void rtl8102e_hw_phy_config(struct rtl8169_private *tp)
 {
        static const struct phy_reg phy_reg_init[] = {
@@ -3580,35 +3391,21 @@ static void rtl8102e_hw_phy_config(struct rtl8169_private *tp)
 
 static void rtl8105e_hw_phy_config(struct rtl8169_private *tp)
 {
-       static const struct phy_reg phy_reg_init[] = {
-               { 0x1f, 0x0005 },
-               { 0x1a, 0x0000 },
-               { 0x1f, 0x0000 },
-
-               { 0x1f, 0x0004 },
-               { 0x1c, 0x0000 },
-               { 0x1f, 0x0000 },
-
-               { 0x1f, 0x0001 },
-               { 0x15, 0x7701 },
-               { 0x1f, 0x0000 }
-       };
-
        /* Disable ALDPS before ram code */
-       rtl_writephy(tp, 0x1f, 0x0000);
-       rtl_writephy(tp, 0x18, 0x0310);
+       phy_write(tp->phydev, 0x18, 0x0310);
        msleep(100);
 
        rtl_apply_firmware(tp);
 
-       rtl_writephy_batch(tp, phy_reg_init);
+       phy_write_paged(tp->phydev, 0x0005, 0x1a, 0x0000);
+       phy_write_paged(tp->phydev, 0x0004, 0x1c, 0x0000);
+       phy_write_paged(tp->phydev, 0x0001, 0x15, 0x7701);
 }
 
 static void rtl8402_hw_phy_config(struct rtl8169_private *tp)
 {
        /* Disable ALDPS before setting firmware */
-       rtl_writephy(tp, 0x1f, 0x0000);
-       rtl_writephy(tp, 0x18, 0x0310);
+       phy_write(tp->phydev, 0x18, 0x0310);
        msleep(20);
 
        rtl_apply_firmware(tp);
@@ -3631,8 +3428,7 @@ static void rtl8106e_hw_phy_config(struct rtl8169_private *tp)
        };
 
        /* Disable ALDPS before ram code */
-       rtl_writephy(tp, 0x1f, 0x0000);
-       rtl_writephy(tp, 0x18, 0x0310);
+       phy_write(tp->phydev, 0x18, 0x0310);
        msleep(100);
 
        rtl_apply_firmware(tp);
@@ -3657,38 +3453,22 @@ static void rtl8125_1_hw_phy_config(struct rtl8169_private *tp)
        phy_modify_paged(phydev, 0xad1, 0x15, 0x0000, 0x03ff);
        phy_modify_paged(phydev, 0xad1, 0x16, 0x0000, 0x03ff);
 
-       phy_write(phydev, 0x1f, 0x0a43);
-       phy_write(phydev, 0x13, 0x80ea);
-       phy_modify(phydev, 0x14, 0xff00, 0xc400);
-       phy_write(phydev, 0x13, 0x80eb);
-       phy_modify(phydev, 0x14, 0x0700, 0x0300);
-       phy_write(phydev, 0x13, 0x80f8);
-       phy_modify(phydev, 0x14, 0xff00, 0x1c00);
-       phy_write(phydev, 0x13, 0x80f1);
-       phy_modify(phydev, 0x14, 0xff00, 0x3000);
-       phy_write(phydev, 0x13, 0x80fe);
-       phy_modify(phydev, 0x14, 0xff00, 0xa500);
-       phy_write(phydev, 0x13, 0x8102);
-       phy_modify(phydev, 0x14, 0xff00, 0x5000);
-       phy_write(phydev, 0x13, 0x8105);
-       phy_modify(phydev, 0x14, 0xff00, 0x3300);
-       phy_write(phydev, 0x13, 0x8100);
-       phy_modify(phydev, 0x14, 0xff00, 0x7000);
-       phy_write(phydev, 0x13, 0x8104);
-       phy_modify(phydev, 0x14, 0xff00, 0xf000);
-       phy_write(phydev, 0x13, 0x8106);
-       phy_modify(phydev, 0x14, 0xff00, 0x6500);
-       phy_write(phydev, 0x13, 0x80dc);
-       phy_modify(phydev, 0x14, 0xff00, 0xed00);
-       phy_write(phydev, 0x13, 0x80df);
-       phy_set_bits(phydev, 0x14, BIT(8));
-       phy_write(phydev, 0x13, 0x80e1);
-       phy_clear_bits(phydev, 0x14, BIT(8));
-       phy_write(phydev, 0x1f, 0x0000);
+       r8168g_phy_param(phydev, 0x80ea, 0xff00, 0xc400);
+       r8168g_phy_param(phydev, 0x80eb, 0x0700, 0x0300);
+       r8168g_phy_param(phydev, 0x80f8, 0xff00, 0x1c00);
+       r8168g_phy_param(phydev, 0x80f1, 0xff00, 0x3000);
+       r8168g_phy_param(phydev, 0x80fe, 0xff00, 0xa500);
+       r8168g_phy_param(phydev, 0x8102, 0xff00, 0x5000);
+       r8168g_phy_param(phydev, 0x8105, 0xff00, 0x3300);
+       r8168g_phy_param(phydev, 0x8100, 0xff00, 0x7000);
+       r8168g_phy_param(phydev, 0x8104, 0xff00, 0xf000);
+       r8168g_phy_param(phydev, 0x8106, 0xff00, 0x6500);
+       r8168g_phy_param(phydev, 0x80dc, 0xff00, 0xed00);
+       r8168g_phy_param(phydev, 0x80df, 0x0000, 0x0100);
+       r8168g_phy_param(phydev, 0x80e1, 0x0100, 0x0000);
 
        phy_modify_paged(phydev, 0xbf0, 0x13, 0x003f, 0x0038);
-       phy_write_paged(phydev, 0xa43, 0x13, 0x819f);
-       phy_write_paged(phydev, 0xa43, 0x14, 0xd0b6);
+       r8168g_phy_param(phydev, 0x819f, 0xffff, 0xd0b6);
 
        phy_write_paged(phydev, 0xbc3, 0x12, 0x5555);
        phy_modify_paged(phydev, 0xbf0, 0x15, 0x0e00, 0x0a00);
@@ -3743,22 +3523,16 @@ static void rtl8125_2_hw_phy_config(struct rtl8169_private *tp)
        phy_write(phydev, 0x14, 0x0002);
        for (i = 0; i < 25; i++)
                phy_write(phydev, 0x14, 0x0000);
-
-       phy_write(phydev, 0x13, 0x8257);
-       phy_write(phydev, 0x14, 0x020F);
-
-       phy_write(phydev, 0x13, 0x80EA);
-       phy_write(phydev, 0x14, 0x7843);
        phy_write(phydev, 0x1f, 0x0000);
 
+       r8168g_phy_param(phydev, 0x8257, 0xffff, 0x020F);
+       r8168g_phy_param(phydev, 0x80ea, 0xffff, 0x7843);
+
        rtl_apply_firmware(tp);
 
        phy_modify_paged(phydev, 0xd06, 0x14, 0x0000, 0x2000);
 
-       phy_write(phydev, 0x1f, 0x0a43);
-       phy_write(phydev, 0x13, 0x81a2);
-       phy_set_bits(phydev, 0x14, BIT(8));
-       phy_write(phydev, 0x1f, 0x0000);
+       r8168g_phy_param(phydev, 0x81a2, 0x0000, 0x0100);
 
        phy_modify_paged(phydev, 0xb54, 0x16, 0xff00, 0xdb00);
        phy_modify_paged(phydev, 0xa45, 0x12, 0x0001, 0x0000);
@@ -3796,7 +3570,7 @@ static void rtl_hw_phy_config(struct net_device *dev)
                [RTL_GIGA_MAC_VER_19] = rtl8168c_1_hw_phy_config,
                [RTL_GIGA_MAC_VER_20] = rtl8168c_2_hw_phy_config,
                [RTL_GIGA_MAC_VER_21] = rtl8168c_3_hw_phy_config,
-               [RTL_GIGA_MAC_VER_22] = rtl8168c_4_hw_phy_config,
+               [RTL_GIGA_MAC_VER_22] = rtl8168c_3_hw_phy_config,
                [RTL_GIGA_MAC_VER_23] = rtl8168cp_2_hw_phy_config,
                [RTL_GIGA_MAC_VER_24] = rtl8168cp_2_hw_phy_config,
                [RTL_GIGA_MAC_VER_25] = rtl8168d_1_hw_phy_config,
@@ -3826,6 +3600,7 @@ static void rtl_hw_phy_config(struct net_device *dev)
                [RTL_GIGA_MAC_VER_49] = rtl8168ep_1_hw_phy_config,
                [RTL_GIGA_MAC_VER_50] = rtl8168ep_2_hw_phy_config,
                [RTL_GIGA_MAC_VER_51] = rtl8168ep_2_hw_phy_config,
+               [RTL_GIGA_MAC_VER_52] = rtl8117_hw_phy_config,
                [RTL_GIGA_MAC_VER_60] = rtl8125_1_hw_phy_config,
                [RTL_GIGA_MAC_VER_61] = rtl8125_2_hw_phy_config,
        };
@@ -3919,7 +3694,7 @@ static void rtl_wol_suspend_quirk(struct rtl8169_private *tp)
        case RTL_GIGA_MAC_VER_32:
        case RTL_GIGA_MAC_VER_33:
        case RTL_GIGA_MAC_VER_34:
-       case RTL_GIGA_MAC_VER_37 ... RTL_GIGA_MAC_VER_51:
+       case RTL_GIGA_MAC_VER_37 ... RTL_GIGA_MAC_VER_52:
                RTL_W32(tp, RxConfig, RTL_R32(tp, RxConfig) |
                        AcceptBroadcast | AcceptMulticast | AcceptMyPhys);
                break;
@@ -3955,6 +3730,7 @@ static void rtl_pll_power_down(struct rtl8169_private *tp)
        case RTL_GIGA_MAC_VER_48:
        case RTL_GIGA_MAC_VER_50:
        case RTL_GIGA_MAC_VER_51:
+       case RTL_GIGA_MAC_VER_52:
        case RTL_GIGA_MAC_VER_60:
        case RTL_GIGA_MAC_VER_61:
                RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) & ~0x80);
@@ -3986,6 +3762,7 @@ static void rtl_pll_power_up(struct rtl8169_private *tp)
        case RTL_GIGA_MAC_VER_48:
        case RTL_GIGA_MAC_VER_50:
        case RTL_GIGA_MAC_VER_51:
+       case RTL_GIGA_MAC_VER_52:
        case RTL_GIGA_MAC_VER_60:
        case RTL_GIGA_MAC_VER_61:
                RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) | 0xc0);
@@ -4017,7 +3794,7 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp)
        case RTL_GIGA_MAC_VER_38:
                RTL_W32(tp, RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST);
                break;
-       case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_51:
+       case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_52:
                RTL_W32(tp, RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST | RX_EARLY_OFF);
                break;
        case RTL_GIGA_MAC_VER_60 ... RTL_GIGA_MAC_VER_61:
@@ -4039,14 +3816,12 @@ static void r8168c_hw_jumbo_enable(struct rtl8169_private *tp)
 {
        RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0);
        RTL_W8(tp, Config4, RTL_R8(tp, Config4) | Jumbo_En1);
-       rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_512B);
 }
 
 static void r8168c_hw_jumbo_disable(struct rtl8169_private *tp)
 {
        RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0);
        RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~Jumbo_En1);
-       rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B);
 }
 
 static void r8168dp_hw_jumbo_enable(struct rtl8169_private *tp)
@@ -4064,7 +3839,6 @@ static void r8168e_hw_jumbo_enable(struct rtl8169_private *tp)
        RTL_W8(tp, MaxTxPacketSize, 0x3f);
        RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0);
        RTL_W8(tp, Config4, RTL_R8(tp, Config4) | 0x01);
-       rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_512B);
 }
 
 static void r8168e_hw_jumbo_disable(struct rtl8169_private *tp)
@@ -4072,32 +3846,15 @@ static void r8168e_hw_jumbo_disable(struct rtl8169_private *tp)
        RTL_W8(tp, MaxTxPacketSize, 0x0c);
        RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0);
        RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~0x01);
-       rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B);
-}
-
-static void r8168b_0_hw_jumbo_enable(struct rtl8169_private *tp)
-{
-       rtl_tx_performance_tweak(tp,
-               PCI_EXP_DEVCTL_READRQ_512B | PCI_EXP_DEVCTL_NOSNOOP_EN);
-}
-
-static void r8168b_0_hw_jumbo_disable(struct rtl8169_private *tp)
-{
-       rtl_tx_performance_tweak(tp,
-               PCI_EXP_DEVCTL_READRQ_4096B | PCI_EXP_DEVCTL_NOSNOOP_EN);
 }
 
 static void r8168b_1_hw_jumbo_enable(struct rtl8169_private *tp)
 {
-       r8168b_0_hw_jumbo_enable(tp);
-
        RTL_W8(tp, Config4, RTL_R8(tp, Config4) | (1 << 0));
 }
 
 static void r8168b_1_hw_jumbo_disable(struct rtl8169_private *tp)
 {
-       r8168b_0_hw_jumbo_disable(tp);
-
        RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~(1 << 0));
 }
 
@@ -4105,9 +3862,6 @@ static void rtl_hw_jumbo_enable(struct rtl8169_private *tp)
 {
        rtl_unlock_config_regs(tp);
        switch (tp->mac_version) {
-       case RTL_GIGA_MAC_VER_11:
-               r8168b_0_hw_jumbo_enable(tp);
-               break;
        case RTL_GIGA_MAC_VER_12:
        case RTL_GIGA_MAC_VER_17:
                r8168b_1_hw_jumbo_enable(tp);
@@ -4131,9 +3885,6 @@ static void rtl_hw_jumbo_disable(struct rtl8169_private *tp)
 {
        rtl_unlock_config_regs(tp);
        switch (tp->mac_version) {
-       case RTL_GIGA_MAC_VER_11:
-               r8168b_0_hw_jumbo_disable(tp);
-               break;
        case RTL_GIGA_MAC_VER_12:
        case RTL_GIGA_MAC_VER_17:
                r8168b_1_hw_jumbo_disable(tp);
@@ -4229,7 +3980,7 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp)
                rtl_udelay_loop_wait_low(tp, &rtl_npq_cond, 20, 42*42);
                break;
        case RTL_GIGA_MAC_VER_34 ... RTL_GIGA_MAC_VER_38:
-       case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_51:
+       case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_52:
                RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq);
                rtl_udelay_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 666);
                break;
@@ -4454,18 +4205,11 @@ static void rtl8168g_set_pause_thresholds(struct rtl8169_private *tp,
        rtl_eri_write(tp, 0xd0, ERIAR_MASK_0001, high);
 }
 
-static void rtl_hw_start_8168bb(struct rtl8169_private *tp)
+static void rtl_hw_start_8168b(struct rtl8169_private *tp)
 {
        RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en);
 }
 
-static void rtl_hw_start_8168bef(struct rtl8169_private *tp)
-{
-       rtl_hw_start_8168bb(tp);
-
-       RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~(1 << 0));
-}
-
 static void __rtl_hw_start_8168cp(struct rtl8169_private *tp)
 {
        RTL_W8(tp, Config1, RTL_R8(tp, Config1) | Speed_down);
@@ -4557,19 +4301,6 @@ static void rtl_hw_start_8168d(struct rtl8169_private *tp)
        rtl_set_def_aspm_entry_latency(tp);
 
        rtl_disable_clock_request(tp);
-
-       if (tp->dev->mtu <= ETH_DATA_LEN)
-               rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B);
-}
-
-static void rtl_hw_start_8168dp(struct rtl8169_private *tp)
-{
-       rtl_set_def_aspm_entry_latency(tp);
-
-       if (tp->dev->mtu <= ETH_DATA_LEN)
-               rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B);
-
-       rtl_disable_clock_request(tp);
 }
 
 static void rtl_hw_start_8168d_4(struct rtl8169_private *tp)
@@ -4583,8 +4314,6 @@ static void rtl_hw_start_8168d_4(struct rtl8169_private *tp)
 
        rtl_set_def_aspm_entry_latency(tp);
 
-       rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B);
-
        rtl_ephy_init(tp, e_info_8168d_4);
 
        rtl_enable_clock_request(tp);
@@ -4659,8 +4388,6 @@ static void rtl_hw_start_8168f(struct rtl8169_private *tp)
 {
        rtl_set_def_aspm_entry_latency(tp);
 
-       rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B);
-
        rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000);
        rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000);
        rtl_set_fifo_size(tp, 0x10, 0x10, 0x02, 0x06);
@@ -4723,8 +4450,6 @@ static void rtl_hw_start_8168g(struct rtl8169_private *tp)
 
        rtl_set_def_aspm_entry_latency(tp);
 
-       rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B);
-
        rtl_reset_packet_filter(tp);
        rtl_eri_write(tp, 0x2f8, ERIAR_MASK_0011, 0x1d8f);
 
@@ -4775,8 +4500,7 @@ static void rtl_hw_start_8168g_2(struct rtl8169_private *tp)
        rtl_hw_start_8168g(tp);
 
        /* disable aspm and clock request before access ephy */
-       RTL_W8(tp, Config2, RTL_R8(tp, Config2) & ~ClkReqEn);
-       RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~ASPM_en);
+       rtl_hw_aspm_clkreq_enable(tp, false);
        rtl_ephy_init(tp, e_info_8168g_2);
 }
 
@@ -4961,8 +4685,6 @@ static void rtl_hw_start_8168h_1(struct rtl8169_private *tp)
 
        rtl_set_def_aspm_entry_latency(tp);
 
-       rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B);
-
        rtl_reset_packet_filter(tp);
 
        rtl_eri_set_bits(tp, 0xdc, ERIAR_MASK_1111, BIT(4));
@@ -5020,8 +4742,6 @@ static void rtl_hw_start_8168ep(struct rtl8169_private *tp)
 
        rtl_set_def_aspm_entry_latency(tp);
 
-       rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B);
-
        rtl_reset_packet_filter(tp);
 
        rtl_eri_set_bits(tp, 0xd4, ERIAR_MASK_1111, 0x1f80);
@@ -5106,6 +4826,71 @@ static void rtl_hw_start_8168ep_3(struct rtl8169_private *tp)
        rtl_hw_aspm_clkreq_enable(tp, true);
 }
 
+static void rtl_hw_start_8117(struct rtl8169_private *tp)
+{
+       static const struct ephy_info e_info_8117[] = {
+               { 0x19, 0x0040, 0x1100 },
+               { 0x59, 0x0040, 0x1100 },
+       };
+       int rg_saw_cnt;
+
+       rtl8168ep_stop_cmac(tp);
+
+       /* disable aspm and clock request before access ephy */
+       rtl_hw_aspm_clkreq_enable(tp, false);
+       rtl_ephy_init(tp, e_info_8117);
+
+       rtl_set_fifo_size(tp, 0x08, 0x10, 0x02, 0x06);
+       rtl8168g_set_pause_thresholds(tp, 0x2f, 0x5f);
+
+       rtl_set_def_aspm_entry_latency(tp);
+
+       rtl_reset_packet_filter(tp);
+
+       rtl_eri_set_bits(tp, 0xd4, ERIAR_MASK_1111, 0x1f90);
+
+       rtl_eri_write(tp, 0x5f0, ERIAR_MASK_0011, 0x4f87);
+
+       RTL_W32(tp, MISC, RTL_R32(tp, MISC) & ~RXDV_GATED_EN);
+
+       rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000);
+       rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000);
+
+       rtl8168_config_eee_mac(tp);
+
+       RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~PFM_EN);
+       RTL_W8(tp, MISC_1, RTL_R8(tp, MISC_1) & ~PFM_D3COLD_EN);
+
+       RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~TX_10M_PS_EN);
+
+       rtl_eri_clear_bits(tp, 0x1b0, ERIAR_MASK_0011, BIT(12));
+
+       rtl_pcie_state_l2l3_disable(tp);
+
+       rg_saw_cnt = phy_read_paged(tp->phydev, 0x0c42, 0x13) & 0x3fff;
+       if (rg_saw_cnt > 0) {
+               u16 sw_cnt_1ms_ini;
+
+               sw_cnt_1ms_ini = (16000000 / rg_saw_cnt) & 0x0fff;
+               r8168_mac_ocp_modify(tp, 0xd412, 0x0fff, sw_cnt_1ms_ini);
+       }
+
+       r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0070);
+       r8168_mac_ocp_write(tp, 0xea80, 0x0003);
+       r8168_mac_ocp_modify(tp, 0xe052, 0x0000, 0x0009);
+       r8168_mac_ocp_modify(tp, 0xd420, 0x0fff, 0x047f);
+
+       r8168_mac_ocp_write(tp, 0xe63e, 0x0001);
+       r8168_mac_ocp_write(tp, 0xe63e, 0x0000);
+       r8168_mac_ocp_write(tp, 0xc094, 0x0000);
+       r8168_mac_ocp_write(tp, 0xc09e, 0x0000);
+
+       /* firmware is for MAC only */
+       rtl_apply_firmware(tp);
+
+       rtl_hw_aspm_clkreq_enable(tp, true);
+}
+
 static void rtl_hw_start_8102e_1(struct rtl8169_private *tp)
 {
        static const struct ephy_info e_info_8102e_1[] = {
@@ -5124,8 +4909,6 @@ static void rtl_hw_start_8102e_1(struct rtl8169_private *tp)
 
        RTL_W8(tp, DBG_REG, FIX_NAK_1);
 
-       rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B);
-
        RTL_W8(tp, Config1,
               LEDS1 | LEDS0 | Speed_down | MEMMAP | IOMAP | VPD | PMEnable);
        RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en);
@@ -5141,8 +4924,6 @@ static void rtl_hw_start_8102e_2(struct rtl8169_private *tp)
 {
        rtl_set_def_aspm_entry_latency(tp);
 
-       rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B);
-
        RTL_W8(tp, Config1, MEMMAP | IOMAP | VPD | PMEnable);
        RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en);
 }
@@ -5203,8 +4984,6 @@ static void rtl_hw_start_8402(struct rtl8169_private *tp)
 
        rtl_ephy_init(tp, e_info_8402);
 
-       rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B);
-
        rtl_set_fifo_size(tp, 0x00, 0x00, 0x02, 0x06);
        rtl_reset_packet_filter(tp);
        rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000);
@@ -5358,13 +5137,13 @@ static void rtl_hw_config(struct rtl8169_private *tp)
                [RTL_GIGA_MAC_VER_08] = rtl_hw_start_8102e_3,
                [RTL_GIGA_MAC_VER_09] = rtl_hw_start_8102e_2,
                [RTL_GIGA_MAC_VER_10] = NULL,
-               [RTL_GIGA_MAC_VER_11] = rtl_hw_start_8168bb,
-               [RTL_GIGA_MAC_VER_12] = rtl_hw_start_8168bef,
+               [RTL_GIGA_MAC_VER_11] = rtl_hw_start_8168b,
+               [RTL_GIGA_MAC_VER_12] = rtl_hw_start_8168b,
                [RTL_GIGA_MAC_VER_13] = NULL,
                [RTL_GIGA_MAC_VER_14] = NULL,
                [RTL_GIGA_MAC_VER_15] = NULL,
                [RTL_GIGA_MAC_VER_16] = NULL,
-               [RTL_GIGA_MAC_VER_17] = rtl_hw_start_8168bef,
+               [RTL_GIGA_MAC_VER_17] = rtl_hw_start_8168b,
                [RTL_GIGA_MAC_VER_18] = rtl_hw_start_8168cp_1,
                [RTL_GIGA_MAC_VER_19] = rtl_hw_start_8168c_1,
                [RTL_GIGA_MAC_VER_20] = rtl_hw_start_8168c_2,
@@ -5378,7 +5157,7 @@ static void rtl_hw_config(struct rtl8169_private *tp)
                [RTL_GIGA_MAC_VER_28] = rtl_hw_start_8168d_4,
                [RTL_GIGA_MAC_VER_29] = rtl_hw_start_8105e_1,
                [RTL_GIGA_MAC_VER_30] = rtl_hw_start_8105e_2,
-               [RTL_GIGA_MAC_VER_31] = rtl_hw_start_8168dp,
+               [RTL_GIGA_MAC_VER_31] = rtl_hw_start_8168d,
                [RTL_GIGA_MAC_VER_32] = rtl_hw_start_8168e_1,
                [RTL_GIGA_MAC_VER_33] = rtl_hw_start_8168e_1,
                [RTL_GIGA_MAC_VER_34] = rtl_hw_start_8168e_2,
@@ -5399,6 +5178,7 @@ static void rtl_hw_config(struct rtl8169_private *tp)
                [RTL_GIGA_MAC_VER_49] = rtl_hw_start_8168ep_1,
                [RTL_GIGA_MAC_VER_50] = rtl_hw_start_8168ep_2,
                [RTL_GIGA_MAC_VER_51] = rtl_hw_start_8168ep_3,
+               [RTL_GIGA_MAC_VER_52] = rtl_hw_start_8117,
                [RTL_GIGA_MAC_VER_60] = rtl_hw_start_8125_1,
                [RTL_GIGA_MAC_VER_61] = rtl_hw_start_8125_2,
        };
@@ -5420,11 +5200,6 @@ static void rtl_hw_start_8125(struct rtl8169_private *tp)
 
 static void rtl_hw_start_8168(struct rtl8169_private *tp)
 {
-       if (tp->mac_version == RTL_GIGA_MAC_VER_13 ||
-           tp->mac_version == RTL_GIGA_MAC_VER_16)
-               pcie_capability_set_word(tp->pci_dev, PCI_EXP_DEVCTL,
-                                        PCI_EXP_DEVCTL_NOSNOOP_EN);
-
        if (rtl_is_8168evl_up(tp))
                RTL_W8(tp, MaxTxPacketSize, EarlySize);
        else
@@ -5573,18 +5348,15 @@ static int rtl8169_rx_fill(struct rtl8169_private *tp)
 
                data = rtl8169_alloc_rx_data(tp, tp->RxDescArray + i);
                if (!data) {
-                       rtl8169_make_unusable_by_asic(tp->RxDescArray + i);
-                       goto err_out;
+                       rtl8169_rx_clear(tp);
+                       return -ENOMEM;
                }
                tp->Rx_databuff[i] = data;
        }
 
        rtl8169_mark_as_last_descriptor(tp->RxDescArray + NUM_RX_DESC - 1);
-       return 0;
 
-err_out:
-       rtl8169_rx_clear(tp);
-       return -ENOMEM;
+       return 0;
 }
 
 static int rtl8169_init_ring(struct rtl8169_private *tp)
@@ -6953,7 +6725,7 @@ static void rtl_hw_init_8125(struct rtl8169_private *tp)
 static void rtl_hw_initialize(struct rtl8169_private *tp)
 {
        switch (tp->mac_version) {
-       case RTL_GIGA_MAC_VER_49 ... RTL_GIGA_MAC_VER_51:
+       case RTL_GIGA_MAC_VER_49 ... RTL_GIGA_MAC_VER_52:
                rtl8168ep_stop_cmac(tp);
                /* fall through */
        case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_48:
@@ -7063,6 +6835,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        tp->pci_dev = pdev;
        tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT);
        tp->supports_gmii = ent->driver_data == RTL_CFG_NO_GBIT ? 0 : 1;
+       tp->eee_adv = -1;
 
        /* Get the *optional* external "ether_clk" used on some boards */
        rc = rtl_get_ether_clk(tp);