[PATCH 6/6] realtek: enable SerDes NWAY and SGMII negotiation
Birger Koblitz
mail at birger-koblitz.de
Wed Mar 10 19:19:05 GMT 2021
ACK, please merge,
Birger
On 09/03/2021 22:12, Bjørn Mork wrote:
> This allows copper SFPs to negotiate speeds lower than 1gig.
>
> Signed-off-by: Bjørn Mork <bjorn at mork.no>
> ---
> .../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 197a96f8ad13..6940afa7f2a1 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 512f5351bf17..f7b9aca7a7c0 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 openwrt-devel
mailing list