diff --git a/target/linux/realtek/files-6.18/drivers/net/pcs/pcs-rtl-otto.c b/target/linux/realtek/files-6.18/drivers/net/pcs/pcs-rtl-otto.c index 92c7c06f10..ea1c445289 100644 --- a/target/linux/realtek/files-6.18/drivers/net/pcs/pcs-rtl-otto.c +++ b/target/linux/realtek/files-6.18/drivers/net/pcs/pcs-rtl-otto.c @@ -215,6 +215,7 @@ struct rtpcs_serdes { const struct rtpcs_sds_ops *ops; const struct rtpcs_sds_regs *regs; enum rtpcs_sds_type type; + DECLARE_BITMAP(supported_modes, RTPCS_SDS_MODE_MAX); struct { struct regmap_field *mac_mode; struct regmap_field *mac_mode_force; /* nullable, 931x only */ @@ -493,10 +494,11 @@ static int rtpcs_sds_determine_hw_mode(struct rtpcs_serdes *sds, *hw_mode = RTPCS_SDS_MODE_USXGMII_10GQXGMII; break; default: - return -ENOTSUPP; + return -EOPNOTSUPP; } - /* TODO: check if the particular SerDes supports the mode */ + if (!test_bit(*hw_mode, sds->supported_modes)) + return -EOPNOTSUPP; return 0; } @@ -784,21 +786,16 @@ static void rtpcs_838x_sds_reset(struct rtpcs_serdes *sds) dev_info(sds->ctrl->dev, "SerDes %d reset\n", sds->id); } -static bool rtpcs_838x_sds_is_hw_mode_supported(struct rtpcs_serdes *sds, - enum rtpcs_sds_mode hw_mode) +static void rtpcs_838x_sds_fill_caps(struct rtpcs_serdes *sds) { - switch (sds->id) { - case 0 ... 3: - return hw_mode == RTPCS_SDS_MODE_QSGMII; - case 4: - return hw_mode == RTPCS_SDS_MODE_QSGMII || - hw_mode == RTPCS_SDS_MODE_SGMII || - hw_mode == RTPCS_SDS_MODE_1000BASEX; - case 5: - return hw_mode == RTPCS_SDS_MODE_SGMII || - hw_mode == RTPCS_SDS_MODE_1000BASEX; - default: - return false; + __set_bit(RTPCS_SDS_MODE_OFF, sds->supported_modes); + + if (sds->id <= 4) + __set_bit(RTPCS_SDS_MODE_QSGMII, sds->supported_modes); + + if (sds->id >= 4) { + __set_bit(RTPCS_SDS_MODE_SGMII, sds->supported_modes); + __set_bit(RTPCS_SDS_MODE_1000BASEX, sds->supported_modes); } } @@ -914,6 +911,8 @@ static int rtpcs_838x_sds_probe(struct rtpcs_serdes *sds) sds->type = RTPCS_SDS_TYPE_5G; + rtpcs_838x_sds_fill_caps(sds); + /* * SDS_MODE_SEL packs 5-bit fields in reverse order: SDS 0 at [25:29], * SDS 5 at [0:4]. @@ -937,9 +936,6 @@ static int rtpcs_838x_setup_serdes(struct rtpcs_serdes *sds, { int ret; - if (!rtpcs_838x_sds_is_hw_mode_supported(sds, hw_mode)) - return -ENOTSUPP; - rtpcs_838x_sds_deactivate(sds); /* take reset */ @@ -1034,6 +1030,22 @@ static void rtpcs_839x_sds_reset(struct rtpcs_serdes *sds) rtpcs_sds_write(odd_sds, 0x0, 0x3, 0x7106); } +static void rtpcs_839x_sds_fill_caps(struct rtpcs_serdes *sds) +{ + __set_bit(RTPCS_SDS_MODE_OFF, sds->supported_modes); + + if (sds->id <= 12) + __set_bit(RTPCS_SDS_MODE_QSGMII, sds->supported_modes); + + /* Uncomment this when modes are supported + if (sds->id >= 12) { + __set_bit(RTPCS_SDS_MODE_SGMII, sds->supported_modes); + __set_bit(RTPCS_SDS_MODE_100BASEX, sds->supported_modes); + __set_bit(RTPCS_SDS_MODE_1000BASEX, sds->supported_modes); + } + */ +} + static int rtpcs_839x_sds_probe(struct rtpcs_serdes *sds) { u8 id = sds->id; @@ -1052,6 +1064,8 @@ static int rtpcs_839x_sds_probe(struct rtpcs_serdes *sds) else sds->type = RTPCS_SDS_TYPE_5G; + rtpcs_839x_sds_fill_caps(sds); + /* * This function is quite "mystic". It has been taken over from the vendor SDK function * rtl839x_serdes_patch_init(). There is not much documentation about it but one could @@ -1530,6 +1544,34 @@ static int rtpcs_93xx_sds_set_ip_mode(struct rtpcs_serdes *sds, enum rtpcs_sds_m return rtpcs_sds_write_bits(sds, 0x1f, 0x09, 11, 6, raw << 1 | BIT(0)); } +static void rtpcs_93xx_sds_fill_caps(struct rtpcs_serdes *sds) +{ + __set_bit(RTPCS_SDS_MODE_OFF, sds->supported_modes); + + switch (sds->type) { + case RTPCS_SDS_TYPE_5G: + __set_bit(RTPCS_SDS_MODE_QSGMII, sds->supported_modes); + break; + case RTPCS_SDS_TYPE_10G: + __set_bit(RTPCS_SDS_MODE_SGMII, sds->supported_modes); + __set_bit(RTPCS_SDS_MODE_XSGMII, sds->supported_modes); + __set_bit(RTPCS_SDS_MODE_USXGMII_10GSXGMII, sds->supported_modes); + __set_bit(RTPCS_SDS_MODE_USXGMII_10GDXGMII, sds->supported_modes); + __set_bit(RTPCS_SDS_MODE_USXGMII_10GQXGMII, sds->supported_modes); + __set_bit(RTPCS_SDS_MODE_USXGMII_5GSXGMII, sds->supported_modes); + __set_bit(RTPCS_SDS_MODE_USXGMII_5GDXGMII, sds->supported_modes); + __set_bit(RTPCS_SDS_MODE_USXGMII_2_5GSXGMII, sds->supported_modes); + + __set_bit(RTPCS_SDS_MODE_1000BASEX, sds->supported_modes); + __set_bit(RTPCS_SDS_MODE_2500BASEX, sds->supported_modes); + __set_bit(RTPCS_SDS_MODE_10GBASER, sds->supported_modes); + break; + case RTPCS_SDS_TYPE_UNKNOWN: + default: + break; + } +} + /* RTL930X */ /* This mapping is not coherent so it cannot be expressed arithmetically */ @@ -3117,6 +3159,8 @@ static int rtpcs_930x_sds_probe(struct rtpcs_serdes *sds) else sds->type = RTPCS_SDS_TYPE_UNKNOWN; + rtpcs_93xx_sds_fill_caps(sds); + sds->swcore_regs.mac_mode = devm_regmap_field_alloc(dev, map, rtpcs_930x_mac_mode_fields[id]); if (IS_ERR(sds->swcore_regs.mac_mode)) @@ -3937,6 +3981,8 @@ static int rtpcs_931x_sds_probe(struct rtpcs_serdes *sds) else sds->type = RTPCS_SDS_TYPE_UNKNOWN; + rtpcs_93xx_sds_fill_caps(sds); + /* * Width is 7 bits (lsb..lsb+6) so every MAC mode write also clears * bit 5 (FEC enable) and bit 6 (10G speedup). These are mode-dependent