]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
realtek: pcs: rtl931x: lock manual mode before reset values
authorJonas Jelonek <jelonek.jonas@gmail.com>
Mon, 27 Jul 2026 18:46:36 +0000 (18:46 +0000)
committerJonas Jelonek <jelonek.jonas@gmail.com>
Tue, 4 Aug 2026 07:51:28 +0000 (09:51 +0200)
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 <jelonek.jonas@gmail.com>
target/linux/realtek/files-6.18/drivers/net/pcs/pcs-rtl-otto.c

index 4f4ff7a2e9a9cdc278a3a413e71288ebfbb6fe1e..c54dc7f35cee56567dbd95be03bac2108502a17c 100644 (file)
@@ -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);