diff options
author | Bjørn Mork <bjorn@mork.no> | 2021-03-13 17:45:54 +0100 |
---|---|---|
committer | Hauke Mehrtens <hauke@hauke-m.de> | 2021-04-18 12:06:45 +0200 |
commit | 37920d6ee16267c216e890f9d9487ef1ef1eff17 (patch) | |
tree | a37e00f0a9315b02c3e0cfc557a272a79f97690a /target/linux | |
parent | 037dc6b251248dc459a41d8602fa027e2bff5d23 (diff) | |
download | upstream-37920d6ee16267c216e890f9d9487ef1ef1eff17.tar.gz upstream-37920d6ee16267c216e890f9d9487ef1ef1eff17.tar.bz2 upstream-37920d6ee16267c216e890f9d9487ef1ef1eff17.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>
(cherry picked from commit 963b2ae702510c11e912c9438fdb9222763a22d5)
Diffstat (limited to 'target/linux')
-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; } } |