realtek: rtl839x: support rtl8214fc on rtl8393
authorStijn Tintel <stijn@linux-ipv6.be>
Thu, 18 Apr 2024 14:53:58 +0000 (17:53 +0300)
committerStijn Tintel <stijn@linux-ipv6.be>
Tue, 7 May 2024 14:55:43 +0000 (17:55 +0300)
Returning ENODEV in rtl8214fc_phy_probe when an RTL8393 SoC is detected
makes it impossible to use an external RTL8214FC PHY on the SoC.
Instead, just skip rtl8380_configure_rtl8214fc on RTL8393. This seems to
make both combo and SFP-only ports on the Edgecore ECS4100-12PH work
properly.

However, this will probably break ports connected to RTL8218B PHYs at
addresses 24 or higher, as both RTL8214FC and RTL8218B have the same PHY
id, and rtl8214fc_match_phy_device matches devices with that ID and PHY
addr above 24 (e.g D-Link DGS-1210-52).

target/linux/realtek/files-5.15/drivers/net/phy/rtl83xx-phy.c

index 490020989f6eae718d5dafd85a6ce0e287bbd889..13972786438f00384416587eccd437c9fefeae32 100644 (file)
@@ -230,6 +230,13 @@ int rtl839x_read_sds_phy(int phy_addr, int phy_reg)
        int reg;
        u32 val;
 
+       /* not sure about this one, but without it we get a "ghost" internal SERDES on addr 63 which causes breakage
+        * [    3.076655] rtl8393_serdes_probe: id: 63
+        * [    3.081135] Realtek RTL8393 SERDES rtl838x slave mii-0:3f: Detected internal RTL8390 SERDES
+        */
+       if (phy_addr > RTL839X_CPU_PORT)
+               return -EIO;
+
        if (phy_addr == 49)
                offset = 0x100;
 
@@ -3673,10 +3680,6 @@ static int rtl8214fc_phy_probe(struct phy_device *phydev)
        int addr = phydev->mdio.addr;
        int ret = 0;
 
-       /* 839x has internal SerDes */
-       if (soc_info.id == 0x8393)
-               return -ENODEV;
-
        /* All base addresses of the PHYs start at multiples of 8 */
        devm_phy_package_join(dev, phydev, addr & (~7),
                                sizeof(struct rtl83xx_shared_private));
@@ -3684,10 +3687,12 @@ static int rtl8214fc_phy_probe(struct phy_device *phydev)
        if (!(addr % 8)) {
                struct rtl83xx_shared_private *shared = phydev->shared->priv;
                shared->name = "RTL8214FC";
-               /* Configuration must be done while patching still possible */
-               ret = rtl8380_configure_rtl8214fc(phydev);
-               if (ret)
-                       return ret;
+               if (soc_info.id != 0x8393) {
+                       /* Configuration must be done while patching still possible */
+                       ret = rtl8380_configure_rtl8214fc(phydev);
+                       if (ret)
+                               return ret;
+               }
        }
 
        return phy_sfp_probe(phydev, &rtl8214fc_sfp_ops);