realtek: pcs: rtl930x: use SerDes hw mode for mode setting

Set and configure the SerDes mode using the SerDes hardware mode types
instead of PHY_INTERFACE_MODE_*.

Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/21565
Signed-off-by: Robert Marko <robimarko@gmail.com>
This commit is contained in:
Jonas Jelonek 2026-01-08 12:43:02 +00:00 committed by Robert Marko
parent d48e7bbacd
commit eba83bc57e

View file

@ -955,11 +955,11 @@ static void rtpcs_930x_sds_submode_set(struct rtpcs_serdes *sds,
}
static void rtpcs_930x_sds_rx_reset(struct rtpcs_serdes *sds,
phy_interface_t phy_if)
enum rtpcs_sds_mode hw_mode)
{
int page = 0x2e; /* 10GR and USXGMII */
if (phy_if == PHY_INTERFACE_MODE_1000BASEX)
if (hw_mode == RTPCS_SDS_MODE_1000BASEX)
page = 0x24;
rtpcs_sds_write_bits(sds, page, 0x15, 4, 4, 0x1);
@ -1100,7 +1100,7 @@ static void rtpcs_930x_sds_reconfigure_pll(struct rtpcs_serdes *sds, int pll)
}
static int rtpcs_930x_sds_config_pll(struct rtpcs_serdes *sds,
phy_interface_t interface)
enum rtpcs_sds_mode hw_mode)
{
struct rtpcs_serdes *nb_sds = rtpcs_sds_get_neighbor(sds);
int neighbor_speed, neighbor_mode, neighbor_pll;
@ -1129,12 +1129,12 @@ static int rtpcs_930x_sds_config_pll(struct rtpcs_serdes *sds,
neighbor_mode = rtpcs_930x_sds_get_internal_mode(nb_sds);
rtpcs_930x_sds_get_pll_data(nb_sds, &neighbor_pll, &neighbor_speed);
if ((interface == PHY_INTERFACE_MODE_1000BASEX) ||
(interface == PHY_INTERFACE_MODE_SGMII))
if ((hw_mode == RTPCS_SDS_MODE_1000BASEX) ||
(hw_mode == RTPCS_SDS_MODE_SGMII))
speed = RTSDS_930X_PLL_1000;
else if (interface == PHY_INTERFACE_MODE_2500BASEX)
else if (hw_mode == RTPCS_SDS_MODE_2500BASEX)
speed = RTSDS_930X_PLL_2500;
else if (interface == PHY_INTERFACE_MODE_10GBASER)
else if (hw_mode == RTPCS_SDS_MODE_10GBASER)
speed = RTSDS_930X_PLL_10000;
else
return -ENOTSUPP;
@ -1159,8 +1159,8 @@ static int rtpcs_930x_sds_config_pll(struct rtpcs_serdes *sds,
if (speed_changed)
rtpcs_930x_sds_reset_cmu(sds);
pr_info("%s: SDS %d using %s PLL for %s\n", __func__, sds->id,
pll == RTSDS_930X_PLL_LC ? "LC" : "ring", phy_modes(interface));
pr_info("%s: SDS %d using %s PLL for mode %d\n", __func__, sds->id,
pll == RTSDS_930X_PLL_LC ? "LC" : "ring", hw_mode);
return 0;
}
@ -1174,11 +1174,11 @@ static void rtpcs_930x_sds_reset_state_machine(struct rtpcs_serdes *sds)
}
static int rtpcs_930x_sds_init_state_machine(struct rtpcs_serdes *sds,
phy_interface_t interface)
enum rtpcs_sds_mode hw_mode)
{
int loopback, link, cnt = 20, ret = -EBUSY;
if (interface != PHY_INTERFACE_MODE_10GBASER)
if (hw_mode != RTPCS_SDS_MODE_10GBASER)
return 0;
/*
* After a SerDes mode change it takes some time until the frontend state machine
@ -1203,9 +1203,9 @@ static int rtpcs_930x_sds_init_state_machine(struct rtpcs_serdes *sds,
}
static void rtpcs_930x_sds_force_mode(struct rtpcs_serdes *sds,
phy_interface_t interface)
enum rtpcs_sds_mode hw_mode)
{
int mode;
u32 mode_val;
/*
* TODO: Usually one would expect that it is enough to modify the SDS_MODE_SEL_*
@ -1214,68 +1214,67 @@ static void rtpcs_930x_sds_force_mode(struct rtpcs_serdes *sds,
* if this sequence should quit early in case of errors.
*/
switch (interface) {
case PHY_INTERFACE_MODE_SGMII:
mode = RTL930X_SDS_MODE_SGMII;
switch (hw_mode) {
case RTPCS_SDS_MODE_SGMII:
mode_val = RTL930X_SDS_MODE_SGMII;
break;
case PHY_INTERFACE_MODE_1000BASEX:
mode = RTL930X_SDS_MODE_1000BASEX;
case RTPCS_SDS_MODE_1000BASEX:
mode_val = RTL930X_SDS_MODE_1000BASEX;
break;
case PHY_INTERFACE_MODE_2500BASEX:
mode = RTL930X_SDS_MODE_2500BASEX;
case RTPCS_SDS_MODE_2500BASEX:
mode_val = RTL930X_SDS_MODE_2500BASEX;
break;
case PHY_INTERFACE_MODE_10GBASER:
mode = RTL930X_SDS_MODE_10GBASER;
case RTPCS_SDS_MODE_10GBASER:
mode_val = RTL930X_SDS_MODE_10GBASER;
break;
case PHY_INTERFACE_MODE_NA:
mode = RTL930X_SDS_OFF;
case RTPCS_SDS_MODE_OFF:
mode_val = RTL930X_SDS_OFF;
break;
default:
pr_err("%s: SDS %d does not support %s\n", __func__,
sds->id, phy_modes(interface));
pr_err("%s: SDS %d does not support mode %d\n", __func__,
sds->id, hw_mode);
return;
}
rtpcs_930x_sds_set_power(sds, false);
rtpcs_930x_sds_set_internal_mode(sds, RTL930X_SDS_OFF);
if (interface == PHY_INTERFACE_MODE_NA)
if (hw_mode == RTPCS_SDS_MODE_OFF)
return;
if (rtpcs_930x_sds_config_pll(sds, interface))
pr_err("%s: SDS %d could not configure PLL for %s\n", __func__,
sds->id, phy_modes(interface));
if (rtpcs_930x_sds_config_pll(sds, hw_mode))
pr_err("%s: SDS %d could not configure PLL for mode %d\n", __func__,
sds->id, hw_mode);
rtpcs_930x_sds_set_internal_mode(sds, mode);
rtpcs_930x_sds_set_internal_mode(sds, mode_val);
if (rtpcs_930x_sds_wait_clock_ready(sds))
pr_err("%s: SDS %d could not sync clock\n", __func__, sds->id);
if (rtpcs_930x_sds_init_state_machine(sds, interface))
if (rtpcs_930x_sds_init_state_machine(sds, hw_mode))
pr_err("%s: SDS %d could not reset state machine\n", __func__,
sds->id);
rtpcs_930x_sds_set_power(sds, true);
rtpcs_930x_sds_rx_reset(sds, interface);
rtpcs_930x_sds_rx_reset(sds, hw_mode);
}
static void rtpcs_930x_sds_mode_set(struct rtpcs_serdes *sds,
phy_interface_t phy_mode)
enum rtpcs_sds_mode hw_mode)
{
u32 mode;
u32 submode;
u32 mode_val, submode_val;
switch (phy_mode) {
case PHY_INTERFACE_MODE_SGMII:
case PHY_INTERFACE_MODE_1000BASEX:
case PHY_INTERFACE_MODE_2500BASEX:
case PHY_INTERFACE_MODE_10GBASER:
rtpcs_930x_sds_force_mode(sds, phy_mode);
switch (hw_mode) {
case RTPCS_SDS_MODE_SGMII:
case RTPCS_SDS_MODE_1000BASEX:
case RTPCS_SDS_MODE_2500BASEX:
case RTPCS_SDS_MODE_10GBASER:
rtpcs_930x_sds_force_mode(sds, hw_mode);
return;
case PHY_INTERFACE_MODE_10G_QXGMII:
mode = RTL930X_SDS_MODE_USXGMII;
submode = RTL930X_SDS_SUBMODE_USXGMII_QX;
case RTPCS_SDS_MODE_USXGMII_10GQXGMII:
mode_val = RTL930X_SDS_MODE_USXGMII;
submode_val = RTL930X_SDS_SUBMODE_USXGMII_QX;
break;
default:
pr_warn("%s: unsupported mode %s\n", __func__, phy_modes(phy_mode));
pr_warn("%s: unsupported mode %d\n", __func__, hw_mode);
return;
}
@ -1283,11 +1282,11 @@ static void rtpcs_930x_sds_mode_set(struct rtpcs_serdes *sds,
rtpcs_930x_sds_set(sds, RTL930X_SDS_OFF);
/* Set the mode. */
rtpcs_930x_sds_set(sds, mode);
rtpcs_930x_sds_set(sds, mode_val);
/* Set the submode if needed. */
if (phy_mode == PHY_INTERFACE_MODE_10G_QXGMII)
rtpcs_930x_sds_submode_set(sds, submode);
if (hw_mode == RTPCS_SDS_MODE_USXGMII_10GQXGMII)
rtpcs_930x_sds_submode_set(sds, submode_val);
}
static void rtpcs_930x_sds_tx_config(struct rtpcs_serdes *sds,
@ -1868,7 +1867,7 @@ static void rtpcs_930x_sds_do_rx_calibration_2_2(struct rtpcs_serdes *sds)
/* Force Rx-Run = 0 */
rtpcs_sds_write_bits(sds, 0x2e, 0x15, 8, 8, 0x0);
rtpcs_930x_sds_rx_reset(sds, PHY_INTERFACE_MODE_10GBASER);
rtpcs_930x_sds_rx_reset(sds, RTPCS_SDS_MODE_10GBASER);
}
static void rtpcs_930x_sds_do_rx_calibration_2_3(struct rtpcs_serdes *sds)
@ -1920,7 +1919,7 @@ static void rtpcs_930x_sds_do_rx_calibration_2_3(struct rtpcs_serdes *sds)
static void rtpcs_930x_sds_do_rx_calibration_2(struct rtpcs_serdes *sds)
{
rtpcs_930x_sds_rx_reset(sds, PHY_INTERFACE_MODE_10GBASER);
rtpcs_930x_sds_rx_reset(sds, RTPCS_SDS_MODE_10GBASER);
rtpcs_930x_sds_do_rx_calibration_2_1(sds);
rtpcs_930x_sds_do_rx_calibration_2_2(sds);
rtpcs_930x_sds_do_rx_calibration_2_3(sds);
@ -2560,7 +2559,7 @@ static int rtpcs_930x_setup_serdes(struct rtpcs_serdes *sds,
rtpcs_930x_sds_set_polarity(sds, sds->tx_pol_inv, sds->rx_pol_inv);
/* Enable SDS in desired mode */
rtpcs_930x_sds_mode_set(sds, if_mode);
rtpcs_930x_sds_mode_set(sds, hw_mode);
/* Enable Fiber RX */
rtpcs_sds_write_bits(sds, 0x20, 2, 12, 12, 0);