[openwrt/openwrt] realtek: enable SerDes NWAY and SGMII negotiation

LEDE Commits lede-commits at lists.infradead.org
Sun Apr 18 13:15:42 BST 2021


hauke pushed a commit to openwrt/openwrt.git, branch openwrt-21.02:
https://git.openwrt.org/37920d6ee16267c216e890f9d9487ef1ef1eff17

commit 37920d6ee16267c216e890f9d9487ef1ef1eff17
Author: Bjørn Mork <bjorn at mork.no>
AuthorDate: Sat Mar 13 17:45:54 2021 +0100

    realtek: enable SerDes NWAY and SGMII negotiation
    
    This allows copper SFPs to negotiate speeds lower than 1gig.
    
    Acked-by: Birger Koblitz <mail at birger-koblitz.de>
    Signed-off-by: Bjørn Mork <bjorn at mork.no>
    (cherry picked from commit 963b2ae702510c11e912c9438fdb9222763a22d5)
---
 .../files-5.4/drivers/net/dsa/rtl83xx/common.c     |  4 +--
 .../files-5.4/drivers/net/dsa/rtl83xx/dsa.c        | 41 +++++++++++++++++++++-
 2 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/common.c b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/common.c
index 197a96f8ad..6940afa7f2 100644
--- a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/common.c
+++ b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/common.c
@@ -368,8 +368,8 @@ static int __init rtl83xx_mdio_probe(struct rtl838x_switch_priv *priv)
 
 	/* Enable PHY control via SoC */
 	if (priv->family_id == RTL8380_FAMILY_ID) {
-		/* Enable PHY control via SoC */
-		sw_w32_mask(0, BIT(15), RTL838X_SMI_GLB_CTRL);
+		/* Enable SerDes NWAY and PHY control via SoC */
+		sw_w32_mask(BIT(7), BIT(15), RTL838X_SMI_GLB_CTRL);
 	} else {
 		/* Disable PHY polling via SoC */
 		sw_w32_mask(BIT(7), 0, RTL839X_SMI_GLB_CTRL);
diff --git a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/dsa.c b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/dsa.c
index 2c49ea27a1..987b47dc8f 100644
--- a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/dsa.c
+++ b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/dsa.c
@@ -344,6 +344,44 @@ static int rtl83xx_phylink_mac_link_state(struct dsa_switch *ds, int port,
 	return 1;
 }
 
+
+static void rtl83xx_config_interface(int port, phy_interface_t interface)
+{
+	u32 old, int_shift, sds_shift;
+
+	switch (port) {
+	case 24:
+		int_shift = 0;
+		sds_shift = 5;
+		break;
+	case 26:
+		int_shift = 3;
+		sds_shift = 0;
+		break;
+	default:
+		return;
+	}
+
+	old = sw_r32(RTL838X_SDS_MODE_SEL);
+	switch (interface) {
+	case PHY_INTERFACE_MODE_1000BASEX:
+		if ((old >> sds_shift & 0x1f) == 4)
+			return;
+		sw_w32_mask(0x7 << int_shift, 1 << int_shift, RTL838X_INT_MODE_CTRL);
+		sw_w32_mask(0x1f << sds_shift, 4 << sds_shift, RTL838X_SDS_MODE_SEL);
+		break;
+	case PHY_INTERFACE_MODE_SGMII:
+		if ((old >> sds_shift & 0x1f) == 2)
+			return;
+		sw_w32_mask(0x7 << int_shift, 2 << int_shift, RTL838X_INT_MODE_CTRL);
+		sw_w32_mask(0x1f << sds_shift, 2 << sds_shift, RTL838X_SDS_MODE_SEL);
+		break;
+	default:
+		return;
+	}
+	pr_debug("configured port %d for interface %s\n", port, phy_modes(interface));
+}
+
 static void rtl83xx_phylink_mac_config(struct dsa_switch *ds, int port,
 					unsigned int mode,
 					const struct phylink_link_state *state)
@@ -377,10 +415,11 @@ static void rtl83xx_phylink_mac_config(struct dsa_switch *ds, int port,
 	reg = sw_r32(priv->r->mac_force_mode_ctrl(port));
 	/* Auto-Negotiation does not work for MAC in RTL8390 */
 	if (priv->family_id == RTL8380_FAMILY_ID) {
-		if (mode == MLO_AN_PHY) {
+		if (mode == MLO_AN_PHY || phylink_autoneg_inband(mode)) {
 			pr_debug("PHY autonegotiates\n");
 			reg |= BIT(2);
 			sw_w32(reg, priv->r->mac_force_mode_ctrl(port));
+			rtl83xx_config_interface(port, state->interface);
 			return;
 		}
 	}



More information about the lede-commits mailing list