realtek: Fix link status detection on RTL9302 for SFP modules
authorBirger Koblitz <git@birger-koblitz.de>
Sun, 23 Jan 2022 11:03:17 +0000 (12:03 +0100)
committerDaniel Golle <daniel@makrotopia.org>
Thu, 17 Feb 2022 15:21:47 +0000 (15:21 +0000)
For SFP slots on the RTL9302, the link status is not correctly detected.
Use the link media status instead.

Signed-off-by: Birger Koblitz <git@birger-koblitz.de>
target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/dsa.c
target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/rtl838x.h

index 98080320bf565e51fee793cab80fb16f9f9de5a5..8c4cd0b4a21cd57be2128376c1455c0c667bca6c 100644 (file)
@@ -474,6 +474,7 @@ static int rtl93xx_phylink_mac_link_state(struct dsa_switch *ds, int port,
        struct rtl838x_switch_priv *priv = ds->priv;
        u64 speed;
        u64 link;
+       u64 media;
 
        if (port < 0 || port > priv->cpu_port)
                return -EINVAL;
@@ -489,8 +490,18 @@ static int rtl93xx_phylink_mac_link_state(struct dsa_switch *ds, int port,
        link = priv->r->get_port_reg_le(priv->r->mac_link_sts);
        if (link & BIT_ULL(port))
                state->link = 1;
-       pr_debug("%s: link state port %d: %llx, media %08x\n", __func__, port,
-                link & BIT_ULL(port), sw_r32(RTL930X_MAC_LINK_MEDIA_STS));
+
+       if (priv->family_id == RTL9310_FAMILY_ID)
+               media = priv->r->get_port_reg_le(RTL931X_MAC_LINK_MEDIA_STS);
+
+       if (priv->family_id == RTL9300_FAMILY_ID)
+               media = sw_r32(RTL930X_MAC_LINK_MEDIA_STS);
+
+       if (media & BIT_ULL(port))
+               state->link = 1;
+
+       pr_debug("%s: link state port %d: %llx, media %llx\n", __func__, port,
+                link & BIT_ULL(port), media);
 
        state->duplex = 0;
        if (priv->r->get_port_reg_le(priv->r->mac_link_dup_sts) & BIT_ULL(port))
@@ -1052,7 +1063,8 @@ static int rtl83xx_port_enable(struct dsa_switch *ds, int port,
                sw_w32_mask(0, BIT(port), RTL930X_L2_PORT_DABLK_CTRL);
        }
 
-       priv->ports[port].sds_num = rtl93xx_get_sds(phydev);
+       if (priv->ports[port].sds_num < 0)
+               priv->ports[port].sds_num = rtl93xx_get_sds(phydev);
 
        return 0;
 }
index e41f81b834835b69eb7b9a6d6876ba0cc908b735..2c63885881e917927d34a3af1b0a9f715cc7f088 100644 (file)
 #define RTL930X_MAC_RX_PAUSE_STS               (0xCB30)
 #define RTL931X_MAC_RX_PAUSE_STS               (0x0F00)
 #define RTL930X_MAC_LINK_MEDIA_STS             (0xCB14)
+#define RTL931X_MAC_LINK_MEDIA_STS             (0x0EC8)
 
 /* MAC link state bits */
 #define RTL838X_FORCE_EN                       (1 << 0)
 #define RTL838X_TBL_ACCESS_L2_DATA(idx)                (0x6908 + ((idx) << 2))
 #define RTL839X_TBL_ACCESS_L2_DATA(idx)                (0x1184 + ((idx) << 2))
 #define RTL930X_TBL_ACCESS_L2_DATA(idx)                (0xab08 + ((idx) << 2))
+
 #define RTL838X_L2_TBL_FLUSH_CTRL              (0x3370)
 #define RTL839X_L2_TBL_FLUSH_CTRL              (0x3ba0)
 #define RTL930X_L2_TBL_FLUSH_CTRL              (0x9404)
 #define RTL838X_L2_LRN_CONSTRT                 (0x329C)
 #define RTL839X_L2_LRN_CONSTRT                 (0x3910)
 #define RTL930X_L2_LRN_CONSTRT_CTRL            (0x909c)
+#define RTL931X_L2_LRN_CONSTRT_CTRL            (0xC964)
+
 #define RTL838X_L2_FLD_PMSK                    (0x3288)
 #define RTL839X_L2_FLD_PMSK                    (0x38EC)
 #define RTL930X_L2_BC_FLD_PMSK                 (0x9068)
+#define RTL931X_L2_BC_FLD_PMSK                 (0xC8FC)
+
 #define RTL930X_L2_UNKN_UC_FLD_PMSK            (0x9064)
+#define RTL931X_L2_UNKN_UC_FLD_PMSK            (0xC8F4)
+
 #define RTL838X_L2_LRN_CONSTRT_EN              (0x3368)
 #define RTL838X_L2_PORT_LRN_CONSTRT            (0x32A0)
 #define RTL839X_L2_PORT_LRN_CONSTRT            (0x3914)