]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
realtek: pcs: add media type for PCB 22814/head
authorJonas Jelonek <jelonek.jonas@gmail.com>
Mon, 2 Feb 2026 22:30:05 +0000 (22:30 +0000)
committerRobert Marko <robimarko@gmail.com>
Tue, 14 Apr 2026 09:50:55 +0000 (11:50 +0200)
Previous commits carved out some TX configuration from different places
into a dedicated function. A cause of this is a behavioral change where
the TX amplifier values aren't applied anymore if it isn't a "fiber
mode". To restore this behavior and make the media/TX-RX configuration
more generic, we need a dedicated media type. The existing ones only
cover fiber and DACs, but not the other left case where a PHY is
attached to the SerDes. This now calls set_media for USXGMII and XSGMII
modes intentionally, both to prepare for future changes and to restore
previous behavior.

We do not have a reliable way to distinct between the actually used
media types, this is still a TODO. But several parts of the code already
have different values applied based on this information. Moreover, this
is especially needed for DAC cables to work properly. While this is
missing, we need to rely on inferring the media from the SerDes mode.

While at it, improve the call site of media handling since there's a
media type for all cases now. This allows to reduce the number of
function calls by moving it out and just have the media type in the
decision block.

Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/22814
Signed-off-by: Robert Marko <robimarko@gmail.com>
target/linux/realtek/files-6.18/drivers/net/pcs/pcs-rtl-otto.c

index 60ea15c4709021897189a4c4a2cf9ca96516eb45..dad4bf18251a2c9881331a4eb26df89013324968 100644 (file)
@@ -138,6 +138,7 @@ enum rtpcs_sds_media {
        RTPCS_SDS_MEDIA_FIBER,
        RTPCS_SDS_MEDIA_DAC_SHORT,      /*  < 3m */
        RTPCS_SDS_MEDIA_DAC_LONG,       /* >= 3m */
+       RTPCS_SDS_MEDIA_PCB,
 };
 
 enum rtpcs_sds_pll_type {
@@ -479,6 +480,16 @@ static int rtpcs_sds_determine_hw_mode(struct rtpcs_serdes *sds,
        return 0;
 }
 
+static bool rtpcs_sds_mode_is_usxgmii(enum rtpcs_sds_mode hw_mode)
+{
+       return (hw_mode == RTPCS_SDS_MODE_USXGMII_10GSXGMII ||
+               hw_mode == RTPCS_SDS_MODE_USXGMII_10GDXGMII ||
+               hw_mode == RTPCS_SDS_MODE_USXGMII_10GQXGMII ||
+               hw_mode == RTPCS_SDS_MODE_USXGMII_5GSXGMII ||
+               hw_mode == RTPCS_SDS_MODE_USXGMII_5GDXGMII ||
+               hw_mode == RTPCS_SDS_MODE_USXGMII_2_5GSXGMII);
+}
+
 /* Generic auto-negotiation config */
 
 static int rtpcs_generic_sds_set_autoneg(struct rtpcs_serdes *sds, unsigned int neg_mode,
@@ -3657,7 +3668,9 @@ static int rtpcs_931x_sds_set_media(struct rtpcs_serdes *sds, enum rtpcs_sds_med
 
        is_dac = (sds_media == RTPCS_SDS_MEDIA_DAC_SHORT ||
                  sds_media == RTPCS_SDS_MEDIA_DAC_LONG);
-       is_10g = (hw_mode == RTPCS_SDS_MODE_10GBASER);
+       is_10g = (hw_mode == RTPCS_SDS_MODE_10GBASER ||
+                 hw_mode == RTPCS_SDS_MODE_XSGMII ||
+                 rtpcs_sds_mode_is_usxgmii(hw_mode));
 
        rtpcs_sds_write_bits(sds, 0x20, 0x0, 11, 10, 0x0);
        rtpcs_sds_write_bits(sds, 0x2a, 0x7, 15, 15, is_dac ? 0x1 : 0x0);
@@ -3787,6 +3800,7 @@ static int rtpcs_931x_setup_serdes(struct rtpcs_serdes *sds,
 {
        struct rtpcs_serdes *even_sds = rtpcs_sds_get_even(sds);
        struct rtpcs_ctrl *ctrl = sds->ctrl;
+       enum rtpcs_sds_media sds_media;
        u32 sds_id = sds->id;
        u32 val;
        int ret;
@@ -3835,17 +3849,23 @@ static int rtpcs_931x_setup_serdes(struct rtpcs_serdes *sds,
 
        switch (hw_mode) {
        case RTPCS_SDS_MODE_OFF:
-               ret = rtpcs_931x_sds_set_media(sds, RTPCS_SDS_MEDIA_NONE, hw_mode);
+               sds_media = RTPCS_SDS_MEDIA_NONE;
                break;
        case RTPCS_SDS_MODE_SGMII:
        case RTPCS_SDS_MODE_1000BASEX:
        case RTPCS_SDS_MODE_2500BASEX:
        case RTPCS_SDS_MODE_10GBASER:
-               ret = rtpcs_931x_sds_set_media(sds, RTPCS_SDS_MEDIA_FIBER, hw_mode);
+               sds_media = RTPCS_SDS_MEDIA_FIBER;
                break;
        default:
+               sds_media = RTPCS_SDS_MEDIA_PCB;
                break;
        }
+       ret = rtpcs_931x_sds_set_media(sds, sds_media, hw_mode);
+       if (ret < 0) {
+               dev_err(ctrl->dev, "failed to config SerDes for media: %d\n", ret);
+               return ret;
+       }
 
        rtpcs_931x_sds_set_polarity(sds, sds->tx_pol_inv, sds->rx_pol_inv);