[openwrt/openwrt] realtek: ethernet: Improve SMI polling configuration based on DTS

LEDE Commits lede-commits at lists.infradead.org
Sun Oct 27 14:26:38 PDT 2024


robimarko pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/945a335f662086145969816297a233d1a280ba95

commit 945a335f662086145969816297a233d1a280ba95
Author: Markus Stockhausen <markus.stockhausen at gmx.de>
AuthorDate: Sun Sep 15 13:01:41 2024 -0400

    realtek: ethernet: Improve SMI polling configuration based on DTS
    
    Although Zyxel XGS1210 devices are not yet officially supported there
    are several patches floating around to enable them. This is a very imporant
    one because it fixes a SMI misconfiguration. In the known DTS the SFP+
    port settings are set as follows.
    
      phy26: ethernet-phy at 26 {
        compatible = "ethernet-phy-ieee802.3-c45";
        phy-is-integrated;
        reg = <26>;
        sds = < 8 >;
      };
    
      phy27: ethernet-phy at 27 {
        compatible = "ethernet-phy-ieee802.3-c45";
        phy-is-integrated;
        reg = <27>;
        sds = < 9 >;
      };
    
    So these are PHYs linked to an internal SerDes. During initialization
    rtl838x_mdio_init() generates smi_bus=0 & smi_addr=27/28 for these ports.
    Although this seems like a valid configuration integrated PHYs attached
    to an SerDes do not have an SMI bus. Later on the mdio reset wrongly feeds
    the SMI registers and as a result the PHYs on SMI bus 0 do not work.
    
    Without patch (loaded with rtk network on & initramfs):
    
    ...
    mdio_bus mdio-bus: MDIO device at address 0 is missing.
    mdio_bus mdio-bus: MDIO device at address 1 is missing.
    mdio_bus mdio-bus: MDIO device at address 2 is missing.
    mdio_bus mdio-bus: MDIO device at address 3 is missing.
    mdio_bus mdio-bus: MDIO device at address 4 is missing.
    mdio_bus mdio-bus: MDIO device at address 5 is missing.
    mdio_bus mdio-bus: MDIO device at address 6 is missing.
    mdio_bus mdio-bus: MDIO device at address 7 is missing.
    ...
    rtl83xx-switch ... : no phy at 0
    rtl83xx-switch ... : failed to connect to PHY: -ENODEV
    rtl83xx-switch ... : error -19 setting up PHY for tree 0, switch 0, port 0
    rtl83xx-switch ... : no phy at 1
    rtl83xx-switch ... : failed to connect to PHY: -ENODEV
    rtl83xx-switch ... : error -19 setting up PHY for tree 0, switch 0, port 1
    ...
    
    With patch (loaded with rtk network on & initramfs):
    
    ...
    rtl83xx-switch ... : PHY [mdio-bus:00] driver [REALTEK RTL8218D] (irq=POLL)
    rtl83xx-switch ... : PHY [mdio-bus:01] driver [REALTEK RTL8218D] (irq=POLL)
    ...
    
    Signed-off-by: Birger Koblitz <git at birger-koblitz.de>
    Signed-off-by: Markus Stockhausen <markus.stockhausen at gmx.de>
    Link: https://github.com/openwrt/openwrt/pull/16457
    Signed-off-by: Robert Marko <robimarko at gmail.com>
---
 .../files-6.6/drivers/net/ethernet/rtl838x_eth.c   | 41 +++++++++++++---------
 1 file changed, 25 insertions(+), 16 deletions(-)

diff --git a/target/linux/realtek/files-6.6/drivers/net/ethernet/rtl838x_eth.c b/target/linux/realtek/files-6.6/drivers/net/ethernet/rtl838x_eth.c
index 710c65bc11..4b79090696 100644
--- a/target/linux/realtek/files-6.6/drivers/net/ethernet/rtl838x_eth.c
+++ b/target/linux/realtek/files-6.6/drivers/net/ethernet/rtl838x_eth.c
@@ -195,7 +195,7 @@ struct rtl838x_eth_priv {
 	u32 lastEvent;
 	u16 rxrings;
 	u16 rxringlen;
-	u8 smi_bus[MAX_PORTS];
+	int smi_bus[MAX_PORTS];
 	u8 smi_addr[MAX_PORTS];
 	u32 sds_id[MAX_PORTS];
 	bool smi_bus_isc45[MAX_SMI_BUSSES];
@@ -2008,8 +2008,9 @@ static int rtmdio_930x_reset(struct mii_bus *bus)
 	for (int i = 0; i < RTL930X_CPU_PORT; i++) {
 		int pos;
 
-		if (priv->smi_bus[i] > 3)
+		if (priv->smi_bus[i] < 0)
 			continue;
+
 		pos = (i % 6) * 5;
 		sw_w32_mask(0x1f << pos, priv->smi_addr[i] << pos,
 			    RTL930X_SMI_PORT0_5_ADDR + (i / 6) * 4);
@@ -2114,9 +2115,12 @@ static int rtmdio_931x_reset(struct mii_bus *bus)
 	mdc_on[0] = mdc_on[1] = mdc_on[2] = mdc_on[3] = false;
 	/* Mapping of port to phy-addresses on an SMI bus */
 	poll_sel[0] = poll_sel[1] = poll_sel[2] = poll_sel[3] = 0;
-	for (int i = 0; i < 56; i++) {
+	for (int i = 0; i < RTL931X_CPU_PORT; i++) {
 		u32 pos;
 
+		if (priv->smi_bus[i] < 0)
+			continue;
+
 		pos = (i % 6) * 5;
 		sw_w32_mask(0x1f << pos, priv->smi_addr[i] << pos, RTL931X_SMI_PORT_ADDR + (i / 6) * 4);
 		pos = (i * 2) % 32;
@@ -2282,30 +2286,35 @@ static int rtl838x_mdio_init(struct rtl838x_eth_priv *priv)
 		if (of_property_read_u32(dn, "reg", &pn))
 			continue;
 
-		if (of_property_read_u32_array(dn, "rtl9300,smi-address", &smi_addr[0], 2)) {
-			smi_addr[0] = 0;
-			smi_addr[1] = pn;
+		if (pn >= MAX_PORTS) {
+			pr_err("%s: illegal port number %d\n", __func__, pn);
+			return -ENODEV;
 		}
 
 		if (of_property_read_u32(dn, "sds", &priv->sds_id[pn]))
 			priv->sds_id[pn] = -1;
-		else {
+		else
 			pr_info("set sds port %d to %d\n", pn, priv->sds_id[pn]);
-		}
 
-		if (pn < MAX_PORTS) {
+		if (of_property_read_u32_array(dn, "rtl9300,smi-address", &smi_addr[0], 2)) {
+			priv->smi_bus[pn] = 0;
+			priv->smi_addr[pn] = pn;
+		} else {
 			priv->smi_bus[pn] = smi_addr[0];
 			priv->smi_addr[pn] = smi_addr[1];
-		} else {
-			pr_err("%s: illegal port number %d\n", __func__, pn);
 		}
 
-		if (of_device_is_compatible(dn, "ethernet-phy-ieee802.3-c45"))
-			priv->smi_bus_isc45[smi_addr[0]] = true;
-
-		if (of_property_read_bool(dn, "phy-is-integrated")) {
-			priv->phy_is_internal[pn] = true;
+		if (priv->smi_bus[pn] >= MAX_SMI_BUSSES) {
+			pr_err("%s: illegal SMI bus number %d\n", __func__, priv->smi_bus[pn]);
+			return -ENODEV;
 		}
+
+		priv->phy_is_internal[pn] = of_property_read_bool(dn, "phy-is-integrated");
+
+		if (priv->phy_is_internal[pn] && priv->sds_id[pn] >= 0)
+			priv->smi_bus[pn]= -1;
+		else if (of_device_is_compatible(dn, "ethernet-phy-ieee802.3-c45"))
+			priv->smi_bus_isc45[priv->smi_bus[pn]] = true;
 	}
 
 	dn = of_find_compatible_node(NULL, NULL, "realtek,rtl83xx-switch");




More information about the lede-commits mailing list