From: Jonas Jelonek Date: Mon, 27 Jul 2026 18:46:36 +0000 (+0000) Subject: realtek: pcs: rtl931x: lock manual mode before reset values X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=01765ff044a281d347929eccb455fdf5f6b7cdef;p=thirdparty%2Fopenwrt.git realtek: pcs: rtl931x: lock manual mode before reset values reset_leq_dfe() wrote reset values for LEQ and VTH/TAP0-4 before setting their manual-mode enable mask, matching the vendor SDK's own instruction order. On a first-ever call this is harmless, but calibration may leave those in continuous live auto-adapt when it returns, so on a second calibration attempt those fields can still be adapt-driven at the moment reset_leq_dfe() writes "0" into them - the adapt engine can overwrite that write before the enable-mask lands a few instructions later, locking in whatever it had drifted to instead of the intended baseline. Set the manual-mode enable mask first instead, so the fields are guaranteed passive before their reset values are written, regardless of what state a previous calibration pass left them in. Testing on hardware suggests that this matters at least for VTH/TAP0-4, showing a drift of coefficients throughout multiple calibration runs without this change. With this change, it remains stable across runs. Link: https://github.com/openwrt/openwrt/pull/24542 Signed-off-by: Jonas Jelonek --- 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 4f4ff7a2e9a..c54dc7f35ce 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 @@ -3277,10 +3277,17 @@ static int rtpcs_931x_sds_rxeq_vth_get(struct rtpcs_serdes *sds, unsigned int *v */ static int rtpcs_931x_sds_reset_leq_dfe(struct rtpcs_serdes *sds) { + rtpcs_931x_sds_rxeq_leq_set_adapt(sds, false); rtpcs_931x_sds_rxeq_leq_set_coef(sds, 0); /* bits [1:0] are undocumented but part of the known-good reset value */ rtpcs_sds_write_bits(sds, PAGE_ANA_10G, 0xd, 1, 0, 0x0); - rtpcs_931x_sds_rxeq_leq_set_adapt(sds, false); + + /* + * Force manual mode before writing values - not after like the vendor + * SDK does - to prevent the adapt engine from overwriting '0' in the + * short timeframe. + */ + rtpcs_sds_write_bits(sds, PAGE_ANA_10G, 0xf, 12, 6, 0x7f); rtpcs_931x_sds_rxeq_tap_set_value(sds, 0, 0x1e, 0); rtpcs_931x_sds_rxeq_tap_set_value(sds, 1, 0, 0); @@ -3288,9 +3295,6 @@ static int rtpcs_931x_sds_reset_leq_dfe(struct rtpcs_serdes *sds) rtpcs_931x_sds_rxeq_tap_set_value(sds, 3, 0, 0); rtpcs_931x_sds_rxeq_tap_set_value(sds, 4, 0, 0); - /* manual-mode enable mask for VTH + TAP0-4, bits [12:6] */ - rtpcs_sds_write_bits(sds, PAGE_ANA_10G, 0xf, 12, 6, 0x7f); - rtpcs_931x_sds_rxeq_vth_set_value(sds, 0xa, 0xa); /* bits [15:12] and [3:0] are undocumented but part of the known-good reset value */ rtpcs_sds_write_bits(sds, PAGE_ANA_10G_EXT, 0x12, 15, 12, 0x0);