realtek: pcs: rtl931x: streamline hardware mode setting

The SDK and our code for finally applying the hardware mode are quite
confusing. There are two different "places" where a mode can be set,
in a SerDes register and in a global SerDes mode register. Neither the
SDK nor any of the datasheet/documentation serve any explanation for
that. The functions are just named "fiber_mode_set" and "mii_mode_set"
which is basically as useless as it can be to understand it.

Try to get rid off this confusion by naming the functions
'sds_set_mac_mode' and 'sds_set_ip_mode' to make clear where the mode
is set. While at it, also clarify the naming of 'config_mode' by
renaming it to 'config_hw_mode'.

The naming is based on the following assumption:

> Realtek uses an SerDes IP core design (probably from another vendor)
> in their switch. This supports a variety of modes and must be
> configured properly for each mode. Usually, changing the mode in the
> MAC's registers triggers a proper configuration of the SerDes IP block
> in the background.

> However, for some modes this seems to be incomplete, at least missing
> important parts so it doesn't work on its own in the end. In this
> case, the SerDes IP block needs to be configured manually with the
> missing bits to make it work.

There are several places in the SDK that support this assumption, both
for RTL931X and RTL930X (as they are somewhat similar), e.g. [1].

[1] f7f85ffc14/sources/rtk-dms1250/src/dal/longan/dal_longan_sds.c (L1746)

Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/20736
Signed-off-by: Robert Marko <robimarko@gmail.com>
This commit is contained in:
Jonas Jelonek 2025-12-20 23:34:10 +00:00 committed by Robert Marko
parent d5a4387ac5
commit 9efcc52a7b

View file

@ -2377,7 +2377,12 @@ static int rtpcs_931x_sds_power(struct rtpcs_serdes *sds, bool power_on)
BIT(sds->id), en_val);
}
static int rtpcs_931x_sds_mii_mode_set(struct rtpcs_serdes *sds,
/*
* rtpcs_931x_sds_set_mac_mode
*
* Set the SerDes mode in the MAC's registers.
*/
static int rtpcs_931x_sds_set_mac_mode(struct rtpcs_serdes *sds,
enum rtpcs_sds_mode hw_mode)
{
u32 mode_val;
@ -2417,14 +2422,19 @@ static int rtpcs_931x_sds_mii_mode_set(struct rtpcs_serdes *sds,
0xff << shift, mode_val << shift);
}
static int rtpcs_931x_sds_fiber_mode_set(struct rtpcs_serdes *sds,
enum rtpcs_sds_mode hw_mode)
/*
* rtpcs_931x_sds_set_ip_mode
*
* Set the SerDes mode in the SerDes IP block's registers.
*/
static int rtpcs_931x_sds_set_ip_mode(struct rtpcs_serdes *sds,
enum rtpcs_sds_mode hw_mode)
{
u32 mode_val;
/* clear symbol error count before changing mode */
rtpcs_931x_sds_clear_symerr(sds, hw_mode);
rtpcs_931x_sds_mii_mode_set(sds, RTPCS_SDS_MODE_OFF);
rtpcs_931x_sds_set_mac_mode(sds, RTPCS_SDS_MODE_OFF);
switch (hw_mode) {
case RTPCS_SDS_MODE_OFF:
@ -2735,8 +2745,9 @@ static int rtpcs_931x_sds_config_fiber_1g(struct rtpcs_serdes *sds)
return 0;
}
static int rtpcs_931x_sds_config_mode(struct rtpcs_serdes *sds,
enum rtpcs_sds_mode hw_mode, int chiptype)
static int rtpcs_931x_sds_config_hw_mode(struct rtpcs_serdes *sds,
enum rtpcs_sds_mode hw_mode,
int chiptype)
{
struct rtpcs_serdes *even_sds = rtpcs_sds_get_even(sds);
@ -2912,7 +2923,7 @@ static int rtpcs_931x_setup_serdes(struct rtpcs_serdes *sds,
return -ENOTSUPP;
}
ret = rtpcs_931x_sds_config_mode(sds, hw_mode, chiptype);
ret = rtpcs_931x_sds_config_hw_mode(sds, hw_mode, chiptype);
if (ret < 0)
return ret;
@ -2945,9 +2956,9 @@ static int rtpcs_931x_setup_serdes(struct rtpcs_serdes *sds,
mode == PHY_INTERFACE_MODE_SGMII ||
mode == PHY_INTERFACE_MODE_USXGMII) {
if (mode == PHY_INTERFACE_MODE_XGMII)
ret = rtpcs_931x_sds_mii_mode_set(sds, hw_mode);
ret = rtpcs_931x_sds_set_mac_mode(sds, hw_mode);
else
ret = rtpcs_931x_sds_fiber_mode_set(sds, hw_mode);
ret = rtpcs_931x_sds_set_ip_mode(sds, hw_mode);
}
if (ret < 0)