From 3cab11ad13d795650be4745815ad2829e74d430f Mon Sep 17 00:00:00 2001
From: Birger Koblitz <git@birger-koblitz.de>
Date: Sun, 23 Jan 2022 12:03:17 +0100
Subject: [PATCH] realtek: Fix link status detection on RTL9302 for SFP modules

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>
---
 .../files-5.10/drivers/net/dsa/rtl83xx/dsa.c   | 18 +++++++++++++++---
 .../drivers/net/dsa/rtl83xx/rtl838x.h          |  8 ++++++++
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/dsa.c b/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/dsa.c
index 98080320bf5..8c4cd0b4a21 100644
--- a/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/dsa.c
+++ b/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/dsa.c
@@ -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;
 }
diff --git a/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/rtl838x.h b/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/rtl838x.h
index e41f81b8348..2c63885881e 100644
--- a/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/rtl838x.h
+++ b/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/rtl838x.h
@@ -148,6 +148,7 @@
 #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)
@@ -217,6 +218,7 @@
 #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)
@@ -225,10 +227,16 @@
 #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)
-- 
GitLab