diff options
author | Bjørn Mork <bjorn@mork.no> | 2021-03-13 17:45:54 +0100 |
---|---|---|
committer | Petr Štetiar <ynezz@true.cz> | 2021-03-17 10:01:21 +0100 |
commit | 963b2ae702510c11e912c9438fdb9222763a22d5 (patch) | |
tree | 60ccba037bff9316f7d8d5a97baf9f4f02202250 /target/linux/realtek | |
parent | 07bf5aaa4c12d6e7eb797b3871a7586f90a46e67 (diff) | |
download | upstream-963b2ae702510c11e912c9438fdb9222763a22d5.tar.gz upstream-963b2ae702510c11e912c9438fdb9222763a22d5.tar.bz2 upstream-963b2ae702510c11e912c9438fdb9222763a22d5.zip |
realtek: enable SerDes NWAY and SGMII negotiation
This allows copper SFPs to negotiate speeds lower than 1gig.
Acked-by: Birger Koblitz <mail@birger-koblitz.de>
Signed-off-by: Bjørn Mork <bjorn@mork.no>
Diffstat (limited to 'target/linux/realtek')
-rw-r--r-- | target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/common.c | 4 | ||||
-rw-r--r-- | target/linux/realtek/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; } } |