r8169: add RTL8125 PHY initialization
authorHeiner Kallweit <hkallweit1@gmail.com>
Wed, 28 Aug 2019 20:28:32 +0000 (22:28 +0200)
committerDavid S. Miller <davem@davemloft.net>
Fri, 30 Aug 2019 00:47:27 +0000 (17:47 -0700)
This patch adds PHY initialization magic copied from the r8125 vendor
driver. In addition it supports loading the firmware for chip version
RTL_GIGA_MAC_VER_61.

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/realtek/r8169_main.c

index 4d1779e3917597efc1d73a4c8cf5c798c5299d54..99176a9a8a68662cb8b5c48c1307e14d98d96a53 100644 (file)
@@ -55,6 +55,7 @@
 #define FIRMWARE_8168H_2       "rtl_nic/rtl8168h-2.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"
 
 #define R8169_MSG_DEFAULT \
        (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN)
@@ -203,7 +204,7 @@ static const struct {
        [RTL_GIGA_MAC_VER_50] = {"RTL8168ep/8111ep"                     },
        [RTL_GIGA_MAC_VER_51] = {"RTL8168ep/8111ep"                     },
        [RTL_GIGA_MAC_VER_60] = {"RTL8125"                              },
-       [RTL_GIGA_MAC_VER_61] = {"RTL8125"                              },
+       [RTL_GIGA_MAC_VER_61] = {"RTL8125",             FIRMWARE_8125A_3},
 };
 
 static const struct pci_device_id rtl8169_pci_tbl[] = {
@@ -714,6 +715,7 @@ MODULE_FIRMWARE(FIRMWARE_8168H_1);
 MODULE_FIRMWARE(FIRMWARE_8168H_2);
 MODULE_FIRMWARE(FIRMWARE_8107E_1);
 MODULE_FIRMWARE(FIRMWARE_8107E_2);
+MODULE_FIRMWARE(FIRMWARE_8125A_3);
 
 static inline struct device *tp_to_dev(struct rtl8169_private *tp)
 {
@@ -3619,6 +3621,128 @@ static void rtl8106e_hw_phy_config(struct rtl8169_private *tp)
        rtl_eri_write(tp, 0x1d0, ERIAR_MASK_0011, 0x0000);
 }
 
+static void rtl8125_1_hw_phy_config(struct rtl8169_private *tp)
+{
+       struct phy_device *phydev = tp->phydev;
+
+       phy_modify_paged(phydev, 0xad4, 0x10, 0x03ff, 0x0084);
+       phy_modify_paged(phydev, 0xad4, 0x17, 0x0000, 0x0010);
+       phy_modify_paged(phydev, 0xad1, 0x13, 0x03ff, 0x0006);
+       phy_modify_paged(phydev, 0xad3, 0x11, 0x003f, 0x0006);
+       phy_modify_paged(phydev, 0xac0, 0x14, 0x0000, 0x1100);
+       phy_modify_paged(phydev, 0xac8, 0x15, 0xf000, 0x7000);
+       phy_modify_paged(phydev, 0xad1, 0x14, 0x0000, 0x0400);
+       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);
+
+       phy_modify_paged(phydev, 0xbf0, 0x13, 0x003f, 0x0038);
+       phy_write_paged(phydev, 0xa43, 0x13, 0x819f);
+       phy_write_paged(phydev, 0xa43, 0x14, 0xd0b6);
+
+       phy_write_paged(phydev, 0xbc3, 0x12, 0x5555);
+       phy_modify_paged(phydev, 0xbf0, 0x15, 0x0e00, 0x0a00);
+       phy_modify_paged(phydev, 0xa5c, 0x10, 0x0400, 0x0000);
+       phy_modify_paged(phydev, 0xa44, 0x11, 0x0000, 0x0800);
+}
+
+static void rtl8125_2_hw_phy_config(struct rtl8169_private *tp)
+{
+       struct phy_device *phydev = tp->phydev;
+       int i;
+
+       phy_modify_paged(phydev, 0xad4, 0x17, 0x0000, 0x0010);
+       phy_modify_paged(phydev, 0xad1, 0x13, 0x03ff, 0x03ff);
+       phy_modify_paged(phydev, 0xad3, 0x11, 0x003f, 0x0006);
+       phy_modify_paged(phydev, 0xac0, 0x14, 0x1100, 0x0000);
+       phy_modify_paged(phydev, 0xacc, 0x10, 0x0003, 0x0002);
+       phy_modify_paged(phydev, 0xad4, 0x10, 0x00e7, 0x0044);
+       phy_modify_paged(phydev, 0xac1, 0x12, 0x0080, 0x0000);
+       phy_modify_paged(phydev, 0xac8, 0x10, 0x0300, 0x0000);
+       phy_modify_paged(phydev, 0xac5, 0x17, 0x0007, 0x0002);
+       phy_write_paged(phydev, 0xad4, 0x16, 0x00a8);
+       phy_write_paged(phydev, 0xac5, 0x16, 0x01ff);
+       phy_modify_paged(phydev, 0xac8, 0x15, 0x00f0, 0x0030);
+
+       phy_write(phydev, 0x1f, 0x0b87);
+       phy_write(phydev, 0x16, 0x80a2);
+       phy_write(phydev, 0x17, 0x0153);
+       phy_write(phydev, 0x16, 0x809c);
+       phy_write(phydev, 0x17, 0x0153);
+       phy_write(phydev, 0x1f, 0x0000);
+
+       phy_write(phydev, 0x1f, 0x0a43);
+       phy_write(phydev, 0x13, 0x81B3);
+       phy_write(phydev, 0x14, 0x0043);
+       phy_write(phydev, 0x14, 0x00A7);
+       phy_write(phydev, 0x14, 0x00D6);
+       phy_write(phydev, 0x14, 0x00EC);
+       phy_write(phydev, 0x14, 0x00F6);
+       phy_write(phydev, 0x14, 0x00FB);
+       phy_write(phydev, 0x14, 0x00FD);
+       phy_write(phydev, 0x14, 0x00FF);
+       phy_write(phydev, 0x14, 0x00BB);
+       phy_write(phydev, 0x14, 0x0058);
+       phy_write(phydev, 0x14, 0x0029);
+       phy_write(phydev, 0x14, 0x0013);
+       phy_write(phydev, 0x14, 0x0009);
+       phy_write(phydev, 0x14, 0x0004);
+       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);
+
+       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);
+
+       phy_modify_paged(phydev, 0xb54, 0x16, 0xff00, 0xdb00);
+       phy_modify_paged(phydev, 0xa45, 0x12, 0x0001, 0x0000);
+       phy_modify_paged(phydev, 0xa5d, 0x12, 0x0000, 0x0020);
+       phy_modify_paged(phydev, 0xad4, 0x17, 0x0010, 0x0000);
+       phy_modify_paged(phydev, 0xa86, 0x15, 0x0001, 0x0000);
+       phy_modify_paged(phydev, 0xa44, 0x11, 0x0000, 0x0800);
+}
+
 static void rtl_hw_phy_config(struct net_device *dev)
 {
        static const rtl_generic_fct phy_configs[] = {
@@ -3674,8 +3798,8 @@ 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_60] = NULL,
-               [RTL_GIGA_MAC_VER_61] = NULL,
+               [RTL_GIGA_MAC_VER_60] = rtl8125_1_hw_phy_config,
+               [RTL_GIGA_MAC_VER_61] = rtl8125_2_hw_phy_config,
        };
        struct rtl8169_private *tp = netdev_priv(dev);