100 Commits
Author SHA1 Message Date
Jonas Jelonek 2a9f30361e realtek: pcs: rtl931x: drop unused link status getter
rtpcs_931x_sds_link_sts_get() is marked __always_unused and has no
callers. The active PCS paths now contain the status handling they
require, so remove the dormant SDK-derived diagnostic helper.

Link: https://github.com/openwrt/openwrt/pull/24986
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-09-04 22:25:54 +02:00
Jonas Jelonek 8d14167c13 realtek: pcs: split pcs_get_state link state sources
pcs_get_state always read the MAC-side link/speed mirror registers,
regardless of SerDes mode. For Clause 37 modes, that mirror can go stale:
a speed renegotiated purely at the SGMII/PCS level is visible in the SerDes
LPA register immediately, but the MAC-side mirror only refreshes when the
MAC force-enable selector is pulsed.

Read the SerDes Clause 22/37 BMSR and LPA registers directly for SGMII,
1000BASE-X and 2500BASE-X, and decode them with the standard phylink helper.
Read BMSR twice because its link status is latched low. Keep all other
SerDes modes on the existing MAC-side mirror path.

When SGMII operates without in-band negotiation, preserve the speed,
duplex and pause settings supplied by phylink; the PCS decoder only updates
link state in that mode.

This fixes PCS state reporting for the SGMII speed-change bug reported on
RTL930x SFP ports. Refreshing the MAC datapath with a force-enable pulse will
be handled separately later.

Link: https://github.com/openwrt/openwrt/issues/23055
Link: https://github.com/openwrt/openwrt/pull/24986
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-09-04 22:25:54 +02:00
Jonas Jelonek db825a4e86 realtek: pcs: make 10gr link helper generic to rtl93xx
Both RTL93xx variants use the same link status bit for 10GR links.
Rename the RTL931x helper to rtl93xx so it can be shared by both
variants.

The link status is latched low, so discard the first read and return
the current state from the second. Use the helper in the RTL930x
state-machine initialization instead of open-coding the two reads.

Link: https://github.com/openwrt/openwrt/pull/24986
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-09-04 22:25:53 +02:00
Jonas Jelonek c1992346fc realtek: increase memory size for Zyxel XMG1915
The commit adding support for the Zyxel XMG1915-10E didn't carry a
dedicated memory node in the DTS. The device has actually 256MiB, but
because this node is missing from the DTS, it falls back to the
128MiB-sized memory node in rtl930x.dtsi.

The commits refactoring support for XMG1915-10E and adding support for
XMG1915-10EP didn't fix that either. Thus, add the needed memory node to
unlock the full memory.

Fixes: 94607d6285 ("realtek: add support for Zyxel XMG1915-10E")
Fixes: bdddc753c5 ("realtek: add support for Zyxel XMG1915-10EP")
Link: https://github.com/openwrt/openwrt/pull/24984
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-09-01 23:43:46 +02:00
Jonas Jelonek bdd5115cae realtek: fix IMAGE_SIZE for TL-ST1008F
Fix the image size limit for TP-Link TL-ST1008F to 29696k. The firmware
partition has a size of 0x1d00000, thus the previous limit is wrong. It
was just copied without proper checking from another device.

Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-09-01 19:14:59 +00:00
Jonas Jelonek d3814507b1 generic: 6.18: refresh patches
Refresh patches to fix CI builds. The refresh was missed with the former
change adding an additional backport patch.

Refreshed with 'make target/linux/refresh V=99'.

Fixes: 5322f1d79b ("generic: 6.18: mxl862xx enable assisted learning on CPU port")
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-09-01 19:05:57 +00:00
Jonas Jelonek 0cc0f5f64c realtek: pse: replace pending with backport patches
The Realtek PSE MCU driver patches have been accepted upstream, being
available in v7.3. Replace the current pending patches with the
backported variants. This requires some additional DTS changes since the
final version differs from what was merged as pending.

Link: https://github.com/openwrt/openwrt/pull/24821
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-08-21 17:50:22 +02:00
Jonas Jelonek ee6ef8d27e realtek: pcs: discover SerDes MDIO bus via phandle
The driver located its SerDes MDIO bus by scanning the whole DT for a
node with the generic "realtek,otto-serdes-mdio" compatible. That
compatible exists only as a search key for this driver, doesn't
describe real hardware, and can't disambiguate more than one match.

Add an explicit "mdio-parent-bus" phandle from the pcs node to the
mdio-serdes node instead, following the same property already used by
mdio-mux-mmioreg and the ksz DSA driver for referencing a secondary
MDIO controller. Use dev_err_probe() for the lookup failures, which
also quiets the log during the expected -EPROBE_DEFER retries while
the MDIO bus driver comes up. Adjust the naming of local variables and
function a bit.

While at it, this also fixes a pre-existing bug where the MDIO bus
device hasn't been 'put' in driver unload/remove. Thus the refcount was
not reduced as expected by of_mdio_find_bus.

Drop the now stale 'realtek,otto-serdes-mdio' compatibles from the
device trees.

Link: https://github.com/openwrt/openwrt/pull/24718
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-08-15 22:37:18 +02:00
Jonas Jelonek 228ef9a1dd realtek: pcs: rtl931x: merge TX config into caller
rtpcs_931x_sds_config_tx is a thin wrapper around the TX configuration
selection, originally being intended to be called alongside a config_rx
helper with dedicated settings. Since the RX helper isn't intended to be
used anymore and has been dropped, only little justification for the TX
helper is left. Thus, drop it to make the code a little bit simpler and
more concise.

This leads to a small reordering, now the TX amplifier settings are
applied after some writes instead of before. Verified on hardware that
this is irrelevant, and now it matches the SDK order more than before.
Though the SDK also sets this in other places.

Link: https://github.com/openwrt/openwrt/pull/24714
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-08-15 22:36:30 +02:00
Jonas Jelonek 1caa77895e realtek: pcs: rtl931x: apply SerDes type gate to full attachment config
The SDK gates the TX amp configuration for 10G modes only, which are
exclusive to 10G-capable SerDes. Move the RTPCS_SDS_TYPE_10G check from
rtpcs_931x_sds_config_tx into rtpcs_931x_sds_config_attachment so it
covers the entire attachment configuration path, not just the TX config
sub-function. The SDK does similar by gating the 10gMedia_set function
for 10G ports, which can only be present on 10G SerDes.

Link: https://github.com/openwrt/openwrt/pull/24714
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-08-15 22:36:30 +02:00
Jonas Jelonek 3dd164f89e realtek: pcs: rtl931x: some smaller cleanup
Do some small cleanup around the config_attachment function:
- drop unused config_rx function and its call site since it's unused and
  not intended to be used right now or in the near future
- drop some less helpful comments
- return result of last call instead of hardcoded 0

Link: https://github.com/openwrt/openwrt/pull/24714
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-08-15 22:36:29 +02:00
Jonas Jelonek 1df1744f9e realtek: pcs: rtl931x: add more register field defines
Replace raw write_bits calls with named register field defines
inferred from related register definitions or SDK code.

Link: https://github.com/openwrt/openwrt/pull/24714
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-08-15 22:36:29 +02:00
Jonas Jelonek 684201c991 realtek: pcs: rtl931x: replace reset full-writes with narrow toggle
The full-register writes 0xc10/0xc30 in rx_reset only differ in
the FRC_RX_EN field (forced off -> forced on). Replace them with
targeted write_mask calls to clarify intent and avoid clobbering
other fields.

Link: https://github.com/openwrt/openwrt/pull/24714
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-08-15 22:36:29 +02:00
Jonas Jelonek ae81b8892a realtek: pcs: rtl931x: add defines for FRC_CMU_EN fields
Replace raw write_bits calls for the FRC_CMU_EN field pair in
config_attachment with write_mask and named macros, demystifying the
function further and improving readability. One of the FRC_CMU_EN
assertions can be dropped since it sets the same value already written
by an earlier call.

Link: https://github.com/openwrt/openwrt/pull/24714
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-08-15 22:36:28 +02:00
Jonas Jelonek 8c6af4e95e realtek: pcs: rtl931x: move a clock gate to activate/deactivate
A bit in the digital SerDes block was enabled at the start of
config_attachment and conditionally disabled at the end for
non-10G/non-XSGMII modes. This is lifecycle logic and still a leftover
from the SDK's 10gMedia_set function which mixes lifecycle with
configuration. Since there is no apparent cycling of this needed for
any configuration within config_attachment, this can be moved to
deactivate/activate without having to expect issues.

The exact block this bit gates is unknown. Empirically, all modes
except USXGMII and 10GBASE-R need the clock running so only clear
the gate for those modes during activation. The register definitions of
RTL8295 - itself being very similar to RTL930X, the predecessor to
RTL931X - name this bit STOP_GLI_CLK. While this doesn't fully resolve
the purpose, it suits the behavior that it seems to gate the clock to a
digital block. Thus, assign this name to that bit.

Link: https://github.com/openwrt/openwrt/pull/24714
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-08-15 22:36:28 +02:00
Jonas Jelonek 7526c05f63 realtek: pcs: rtl931x: move on/off pattern out of attachment config
Bracket deactivate()/activate() with the same FRC_PDOWN/FRC_RX_EN
forcing 930x's set_power() already does, instead of setting them as
part of config_attachment's baseline write. Drop the now-redundant
write from config_attachment.

Link: https://github.com/openwrt/openwrt/pull/24714
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-08-15 22:36:28 +02:00
Jonas Jelonek de7cfc4c33 realtek: pcs: add write_mask primitive
The PCS driver still contains a lot of blind full-register writes whose
meaning is either partially known or completely unknown. The improve the
overall understanding of the hardware, one goal is to decompose these
writes into smaller pieces and give them a name. Those writes often
effectively only touch a few bits of a register, mostly even
non-contiguous. Decomposing those with the existing set of write helpers
however will cause a significant increase of bus transactions. They would
have to be rewritten using single write_bits calls covering only contiguous
parts.

To avoid this, introduce a new write_mask primitive which mirrors
several kernel APIs taking a mask and a 'set' value, specifying which
bits to alter. This allows for non-contiguous writes, in turn allowing
to turn blind full-register writes into reduced, named writes while
retaining the number of actual bus transaction. At some point, this may
replace most of the current write calls since it allows to use defines
for named fields in a better way.

It is intended as a required operation and wired into all variants' ops
exactly like the other read/write helpers. 930X needs a special helper
while all others can use the generic implementation.

Also introduce first users of this, being extended with subsequent
commits. This includes breaking up blind full-register writes into mask
combinations. Some bitfields are omitted on purpose since they do not
differ throughout various calls within the function and according to
hardware tests are equal to the state after reset.

Link: https://github.com/openwrt/openwrt/pull/24714
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-08-15 22:36:27 +02:00
Jonas Jelonek 670af42281 realtek: pcs: rtl931x: drop truly redundant write
Drop a truly redundant write in 931x's config_attachment which sets bits
to the exact same value as the write before, just narrowed to fewer
bits. Drop the comment that already points to this too.

Link: https://github.com/openwrt/openwrt/pull/24714
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-08-15 22:36:27 +02:00
Jonas Jelonek 830a7821c0 realtek: pcs: rtl931x: drop unneeded sleep after RX reset
Drop the unneeded sleep in leq_adapt after the RX reset. rx_reset
already has a final sleep for 50ms and the additional 10ms doesn't add
any value.

Link: https://github.com/openwrt/openwrt/pull/24714
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-08-15 22:36:27 +02:00
Jonas Jelonek 9df24525af realtek: pcs: rtl931x: dedupe 10G analog pre/post sequence
The writes described with "media none behavior" in config_attachment and
the 'is_10g'-gated block towards the end of the same function are a
byte-for-byte copy of what rx_reset already does in its two halves.
Extract the shared triples into rtpcs_931x_sds_10g_ana_pre()/_post()
and use them in both places instead of duplicating the register writes.

With that extracted, rx_reset can also reuse these. This retains its own
power cycling that is specific to the reset.

Link: https://github.com/openwrt/openwrt/pull/24714
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-08-15 22:36:26 +02:00
Jonas Jelonek 39f152cdec realtek: pcs: rtl931x: narrow register write for baseline
Bits [11:6]/[5:0] of this register [ANA_10G_EXT; 0x00] are the
DFE_TAP3_ODD/EVEN taps, which post_config's RX calibration paths already
own. Stop clobbering them from rx_reset and config_attachment where they
are applied as kind of a baseline, and only touch the bits these
functions actually care about.

Link: https://github.com/openwrt/openwrt/pull/24714
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-08-15 22:36:26 +02:00
Jonas Jelonek 51680917b3 realtek: pcs: rtl93xx: rename rxcal_ accessors to rxeq_
Split naming convention: rxeq_* accessors control equalizer state
(get/set a coefficient, toggle adapt); rxcal_* functions run an actual
calibration procedure (measure, decide, retry). 930x's accessor layer
predates this split and still used rxcal_ throughout; rename it to
match the convention already applied consistently on 931x.

dfe_taps_adapt/dfe_disable move too - despite looping over TAP1-4,
they just apply a fixed control action with no measurement or
decision-making, same as the single-coefficient accessors. init,
fgcal, leq_adapt_lock and vth_tap0_adapt_lock stay rxcal_ - they're
the calibration-flow entry points that call these accessors as
building blocks, and the *_adapt_lock ones specifically read back a
result to decide what to lock in.

Also rename 931x's dfe_disable_5g to rxeq_dfe_disable_5g for the same
reason - it's a fixed control action, not a calibration procedure.

Link: https://github.com/openwrt/openwrt/pull/24542
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-08-04 09:51:29 +02:00
Jonas Jelonek 4e7a9a7969 realtek: pcs: rtl931x: gate symErr success on actual link status
symErr reads 0 both when the link is clean and when there's no signal
at all to decode errors from - the counter only increments when the
PCS is actively decoding something and finds a mismatch, so a dead
link and a healthy one are indistinguishable from symErr alone.
Confirmed on hardware: symErr read 0x0 while the port had no link.

Add rtpcs_931x_sds_10gr_link_up(), reading the same status bit as the
vendor SDK's _phy_rtl9310_linkSts_get() default case, and require it
alongside a low symErr count before declaring a calibration check
successful. A link that isn't actually up yet now keeps the retry
loop going instead of being misread as a clean, working link.

Also observed on hardware: the retry budget sometimes runs out while
symErr is still nonzero, but the link comes up and works fine anyway -
the count just hasn't fully settled within the budget. Since that's
not an actual problem, keep the final message at dev_dbg when
link_up is true; only warn when the link genuinely never came up.

Link: https://github.com/openwrt/openwrt/pull/24542
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-08-04 09:51:29 +02:00
Jonas Jelonek 7ed1c1d472 realtek: pcs: rtl931x: average VTH samples instead of one point-sample
rxcal_fiber_adapt() locked in whatever a single rxeq_vth_get() call
returned after a fixed 200ms adapt window - no check that the reading
was representative rather than a transient/noisy excursion. Observed
on hardware: whenever the locked VTH wasn't 0xa (the reset baseline),
the link behaved worse; recalibrating a link that was already working
could leave it worse than before, which a single unlucky sample
locked in as final is a plausible cause of.

RTL930x's own analogous case (leq_adapt_lock) already avoids exactly
this by sampling 10 times over ~100ms and averaging rather than
trusting one read. Do the same here: settle for 100ms, then sample
VTH 10 times over ~100ms and lock in the rounded average, using
DIV_ROUND_CLOSEST() rather than an open-coded round-to-nearest.

Link: https://github.com/openwrt/openwrt/pull/24542
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-08-04 09:51:29 +02:00
Jonas Jelonek 01765ff044 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 <jelonek.jonas@gmail.com>
2026-08-04 09:51:28 +02:00
Jonas Jelonek e2baaf421d realtek: pcs: rtl931x: add some debug prints to RX calibration
Add some debugging aid to the RX calibration, making it easier to spot
eventual issues caused by calibration. While the calibration has been
tested, this happened only on a small set of devices.

Adds rtpcs_931x_sds_rxeq_leq_get_coef() to read back where LEQ
auto-adapt actually settles in rxcal_leq_adapt(), mirroring what
rxcal_fiber_adapt() already does for VTH. Shares the existing
930x gray-to-binary helper since it's pure bit math, not
variant-specific. Promote it to a generic helper instead of
930x-specific.

Link: https://github.com/openwrt/openwrt/pull/24542
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-08-04 09:51:28 +02:00
Jonas Jelonek 16021f68ad realtek: pcs: rtl931x: replace open-coded writes with named setters
Replace the plain field writes in rtpcs_931x_sds_reset_leq_dfe() with
the rxeq_* setters, now that both wire-up commits have given them real
calibration callers. Keeps the register-level detail out of the reset
sequence and gives it named accessors instead of raw write_bits() calls.

Some bits touched by the original reset writes fall outside any known
coefficient field (reg 0xd bits [1:0], reg 0x12 bits [15:12]/[3:0]).
These are kept as separate, explicitly commented raw writes rather than
folded into the setters, since the setters are scoped to match the
vendor SDK's real per-field accessors and narrowing them silently would
drop those undocumented-but-required bits.

Link: https://github.com/openwrt/openwrt/pull/24542
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-08-04 09:51:28 +02:00
Jonas Jelonek 3c63abd609 realtek: pcs: rtl931x: wire up RX calibration for 10G fiber
Port the vendor SDK's _phy_rtl9310_fiber_adapt() as
rtpcs_931x_sds_rxcal_fiber_adapt(), dispatched from post_config for
RTPCS_SDS_ATTACH_FIBER when hw_mode is 10GBase-R (1G/100M fiber isn't
calibrated by the vendor SDK either).

Add the rxeq_tap_*/rxeq_vth_* setters (set_value, set_adapt) needed to
drive it: fiber calibration runs VTH/TAP0 auto-adapt for 200ms, then
samples the auto-adapted VTH and locks it in, forces TAP0 to a fixed
value (31, per the vendor SDK), and re-locks manual mode, before letting
DFE TAP1-4 auto-adapt freely and verifying via a symbol-error recheck
loop.

Sampling VTH needs the SerDes' debug-readback routing. Add
rtpcs_931x_sds_set_debug() and rxeq_vth_get() for it, mirroring
_phy_rtl9310_dbg_set()/_phy_rtl9310_dfe_get().

The final symbol-error recheck deliberately deviates from the vendor
SDK's shape (adapt once, recheck 3x at 150ms, require exactly 0):
symErr's field is only 8 bits wide and reads as a saturated 0xff right
after rx_reset(), which looks like "link hasn't relocked yet" rather
than a genuine error count - 10G optical relock can plausibly take
longer than 150ms. Instead, recheck more times with more patience per
check and no reset in between (so a settling link isn't interrupted),
and tolerate a small nonzero symbol-error count rather than requiring
exactly 0.

rtpcs_931x_sds_fiber_get_symerr() already existed but was unused;
wire it up alongside the existing rtpcs_931x_sds_clear_symerr().

Link: https://github.com/openwrt/openwrt/pull/24542
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-08-04 09:51:27 +02:00
Jonas Jelonek 58e896eb70 realtek: pcs: rtl931x: wire up RX calibration for PHY-attached ports
Add post_config, run after activate() like on RTL930x, dispatching RX
calibration by attachment. Port the vendor SDK's _phy_rtl9310_leq_adapt()
as rtpcs_931x_sds_rxcal_leq_adapt() for the PHY-attached case, built on
new rxeq_leq_set_coef()/rxeq_leq_set_adapt() setters and the
existing but unused rx_reset().

Add rtpcs_931x_sds_dfe_disable_5g() for the one-shot operation the SDK
issues before calibrating PHY-attached and PCB-adapt ports. Presumably,
this quiesces DFE auto-adapt on the 5G companion analog block to prevent
it from interfering with DFE adaption during calibration.

Fiber and DAC attachments remain a TODO in post_config's dispatch.

Link: https://github.com/openwrt/openwrt/pull/24542
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-08-04 09:51:27 +02:00
Jonas Jelonek db2fbb25ab realtek: board: add patch to fix boot hang
Add a patch to fix boot hang on some devices after 7cc31af7bd
("realtek: convert to generic machine initialization"), reusing
upstream's implementation of Realtek board setup. The issue came up on a
Linksys LGS352C device, causing total silence and a hang after
rt-loader's last line "Booting kernel from 0x80100000 ...".

While the OpenWrt downstream version operated on the plain appended
device tree using a pointer, the upstream implementation copies the FDT
into a 16 KiB buffer. Given the following survey, this may be too small
for some devices:

  rtl9311_linksys_lgs352c:                21278 bytes
  rtl9313_ubnt_usw-pro-xg-8-poe:          12809 bytes
  rtl9313_hasivo_f5800w-12s-plus:         13103 bytes
  rtl9313_xikestor_sks8300-12x-v1:        13630 bytes
  rtl9313_zyxel_xs1930-12f:               14488 bytes
  rtl9313_zyxel_xs1930-12hp:              15234 bytes
  rtl9313_hasivo_s1300wp-8xgt-4s-plus:    15341 bytes

To fix this, the patch increases the buffer size, leaving some more
headroom for further outliers.

Fixes: 7cc31af7bd ("realtek: convert to generic machine initialization")
Assisted-by: Claude:claude-sonnet-5
Link: https://github.com/openwrt/openwrt/pull/24541
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-08-03 08:43:52 +02:00
Jonas Jelonek 52da343855 realtek: dsa: rtl931x: downgrade print_matrix to debug
Downgrade rtldsa_931x_print_matrix from pr_info to pr_debug to reduce
the massive amount printed during boot (64 lines). There doesn't seem
any benefit right now for keeping this at info level. And RTL931X is
the only variant that uses info-level print right now, all others
already use pr_debug.

Debug output can be activated individually for people who need this for
testing/debugging.

Link: https://github.com/openwrt/openwrt/pull/24507
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-08-02 11:55:26 +02:00
Jonas Jelonek c9833b993d realtek: pcs: move USXGMII submodes out of sds_mode enum
Carrying all six USXGMII submodes as distinct rtpcs_sds_mode values
forced every switch/case over hw_mode to enumerate them individually,
even though almost none of that code actually cares which submode is
active; a couple of places on 930X do, but only to tell SXGMII/QXGMII
apart from the rest.

Collapse them into a single RTPCS_SDS_MODE_USXGMII and introduce
rtpcs_sds_usxgmii_submode for the cases that still need the
distinction, threading it explicitly through hw-mode selection and
set_hw_mode instead of overloading the mode enum for it.

Link: https://github.com/openwrt/openwrt/pull/24494
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-31 17:32:11 +02:00
Jonas Jelonek 22d05b6a95 realtek: pcs: fold usxgmii_config parameters into the function
Both call sites always pass the same constants; there's no actual
variation to justify exposing opcode/am_period/an_table/sync_bit as
parameters. Inline them and keep their names as comments so the
meaning of each write isn't lost. Also clarify the QHSG naming in the
function's leading comment.

Link: https://github.com/openwrt/openwrt/pull/24494
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-31 17:32:10 +02:00
Jonas Jelonek f7638a7da7 realtek: pcs: simplify USXGMII alignment marker config
The USXGMII config took a parameter to set for all USXGMII alignment
markers. However, we and the SDK always set all markers to zero except
for some special cases. Since this doesn't require a parameter, just
break it down to clearing the alignment markers.

To reduce the number of calls and writes, the pattern writing the two
halves of a register separately is reduced to a write of the full
register.

Link: https://github.com/openwrt/openwrt/pull/24494
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-31 17:32:10 +02:00
Jonas Jelonek a16802a797 realtek: pcs: drop rtpcs_sds_reg_field abstraction
reg and bit position for the autoneg control fields are identical
across all variants; only the page differs, and only for 931x. Since
that's the only axis that actually varies, replace the per-field
struct-of-structs with a single phy_page in rtpcs_config denoting the
page mirroring standard PHY registers for that variant.

Given that, there is now justification left to keep this abstraction.
Drop it for now. If needed in the future, it can be added back with a
proper user then.

Link: https://github.com/openwrt/openwrt/pull/24494
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-31 17:32:10 +02:00
Jonas Jelonek 8b7d23179a realtek: pcs: adjust init/probe prints
Drop a useless debug print that 838x_probe still has.
Also move the pcs_config print informing about the configuration to the
end of the configuration, now just showing up after the SerDes has been
configured successfully, not upfront.

Link: https://github.com/openwrt/openwrt/pull/24494
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-31 17:32:09 +02:00
Jonas Jelonek 0134faa5d5 realtek: pcs: replace pr_ prints with dev_
There are still several pr_* prints in the driver, however using dev_*
equivalents are preferred. They add information about the attached
device. Switch all remaining pr_* calls to dev_*, adjusting the log
level of some of them to something more accurate (e.g. info -> debug,
info -> error).

Link: https://github.com/openwrt/openwrt/pull/24494
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-31 17:32:09 +02:00
Jonas Jelonek 597f6a7548 realtek: pcs: shorten some comments
Some comments have some unneeded information included, especially those
naming register fields often carrying CFG_ or REGX_ prefixes. They add
nothing useful to the purpose of a field. Drop them to slim down those
comments a bit.

Also adjust and drop some comments not needed anymore, mostly since the
information is already preserved elsewhere.

Link: https://github.com/openwrt/openwrt/pull/24494
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-31 17:32:08 +02:00
Jonas Jelonek 04a7753dea hostapd: reset PKG_RELEASE
Reset PKG_RELEASE to 1 since the package has been updated to a newer
upstream version. This reset was missed during update.

Fixes: 345404476a ("hostapd: update to 2026-07-09")
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-26 00:14:49 +02:00
Jonas Jelonek 4894562049 realtek: pcs: drop unneeded pointer cast
The return value of device_get_match_data was still explicitly casted to
the driver-internal type. However, since this function returns 'const
void *' and in C void pointers are automatically casted, this isn't
needed. Thus, drop it.

Link: https://github.com/openwrt/openwrt/pull/24310
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-20 15:45:54 +02:00
Jonas Jelonek e1a6d77124 realtek: pcs: rtl930x: apply only needed patching
For 10GBase-R and 2500Base-X, the patching sequences for the slower
modes are also applied. This mirrors the SDK which uses some automatic
detection and only does a one-time initialization. However, Linux works
different. The PCS is configured to a specific mode on demand. Thus,
there is no need to apply the other patching when it isn't really
needed.

Those patching sequences seem to initialize AFE blocks within the
SerDes, thus a 1G AFE shouldn't be needed for 10GBase-R. Testing
confirms this so far, no difference in any link characteristics when
e.g. 1G and 2.5G sequences aren't applied for a 10GBase-R link.

Link: https://github.com/openwrt/openwrt/pull/24310
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-20 15:45:54 +02:00
Jonas Jelonek e05153e47e realtek: pcs: rtl931x: do not configure 1000Base-X for 10GBase-R
So far, the 10GBase-R configuration mirrored the SDK which in addition
also sets up 1000Base-X and lets it run in a special mode having
autodetection of 10G/1G. This doesn't make that much sense given that
Linux will trigger PCS reconfiguration once the interface mode has
changed. Thus, we should only provide that for each mode standalone, not
for some proprietary and special mixed auto mode.

Link: https://github.com/openwrt/openwrt/pull/24310
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-20 15:45:54 +02:00
Jonas Jelonek b253af3698 realtek: pcs: rtl931x: add info to config bits
Give two SerDes register writes some meaningful information, since they
line up with usual PHY registers.

Link: https://github.com/openwrt/openwrt/pull/24310
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-20 15:45:53 +02:00
Jonas Jelonek b489ab0d86 realtek: pcs: rtl931x: drop RX channel resets during USXGMII config
The mode configuration calls LEQ/DFE reset and RX reset before doing
USXGMII configuration. Though the SDK does that similar, these calls are
actually unneeded because essentially the same is executed later again
in the attachment configuration. This is also the place where it
rather belongs. Thus, drop those calls in mode configuration.

Link: https://github.com/openwrt/openwrt/pull/24310
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-20 15:45:53 +02:00
Jonas Jelonek d9fdf451f1 realtek: pcs: rtl931x: drop unused helper
Drop the unused helper rtpcs_931x_sds_reset because it is unused and -
if it was used - would actively mess with the defined SerDes
deactivation/activation in pcs_config.

Link: https://github.com/openwrt/openwrt/pull/24310
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-20 15:45:53 +02:00
Jonas Jelonek 39cd3f8954 realtek: pcs: rtl931x: fix 1000Base-X config
Commit 7899dfa6ef ("realtek: pcs: rtl931x: separate and reuse
1000base-x config") introduced an issue by accident, using the register
value 0x12 instead of 0x13. A regression hasn't been noticed before, for
yet unknown reasons the 1000Base-X still worked here and there. Probably
due to some external setup.

However, this currently breaks 1000Base-X functionality on at least one
switch. Correcting the register value instantly restores 1000Base-X,
allowing the link to come up. It is unclear yet what this field means,
according to the SerDes register defines from related RTL8295 this might
be TX mode configuration field.

Also add another write which is present in several SDK versions.
Referring from related RTL8295, this might be a field called
EN_LINK_FIB1G, enabling 1000Base-X operation.

Fixes: 7899dfa6ef ("realtek: pcs: rtl931x: separate and reuse 1000base-x config")
Link: https://github.com/openwrt/openwrt/pull/24310
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-20 15:45:52 +02:00
Jonas Jelonek 3ec398f0c3 tools: firmware-utils: update to Git HEAD (2026-07-19)
1ab209233682 mkzynfw: rename macros from RTL93XX to RTL_OTTO
606f25ef3ca2 mkzynfw: add board definitions for Zyxel GS1920 v2 series
162fa533b309 mkzynfw: add board definitions for GS2210 series
b2d46a825a53 mkzynfw: add board definitions for Zyxel GS1920 v1 series
5c5df244b8a1 Revert "mkzynfw: add board definitions for Zyxel GS1920 v1 series"
7f28bfbc4b5a Revert "mkzynfw: add board definitions for GS2210 series"
5e1b83d1fc2b mkzynfw: add board definitions for GS2210 series
3e6b426938e8 mkzynfw: add board definitions for Zyxel GS1920 v1 series

Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-19 21:45:08 +00:00
Jonas Jelonek 52c0274e55 realtek: add PoE support for GS1920-24HP
Add PoE support for GS1920-24HP by providing the device tree
definition and selecting the Realtek PSE MCU driver package for build.
Support includes both versions of the device since they basically share
the same PSE frontend. The common DTSI includes the shared definitions,
the device DTS files then set the correct compatibles.

Link: https://github.com/openwrt/openwrt/pull/24239
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-17 19:34:46 +02:00
Jonas Jelonek b76acc1b1a realtek: add PoE support for USW XG Pro 8 PoE
Add device tree definition for PoE support using the Realtek PSE MCU
driver. Select the kernel package for the driver in DEVICE_PACKAGES
accordingly.

Link: https://github.com/openwrt/openwrt/pull/24239
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-17 19:34:46 +02:00
Jonas Jelonek d3e2f2df83 realtek: add PoE support for XGS1930-28HP
Add support for PoE on Zyxel XGS1930-28HP by leveraging the new Realtek
PSE driver. Define the PSE controller with all its properties in DTS of
the device and link it to the PHYs.

Link: https://github.com/openwrt/openwrt/pull/24239
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-17 19:34:45 +02:00
Jonas Jelonek 5b527dc7a4 realtek: switch to PSE driver for Plasma Cloud PSX28
Use the kernel PSE driver for PoE functionality on this device instead
relying on userspace apps. Drop the automatic selection for poemgr in
favor of the driver module.

Link: https://github.com/openwrt/openwrt/pull/24239
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-17 19:34:45 +02:00
Jonas JelonekandJan-Henrik Bruhn f306a19481 realtek: add PoE support for Linksys LGS328MPCv2
Add PoE support to Linksys LGS328MPCv2 by adding the required device
tree definition and select the needed kernel module package, making use
of the Realtek PSE MCU driver.

Co-authored-by: Jan-Henrik Bruhn <git@jhbruhn.de>
Link: https://github.com/openwrt/openwrt/pull/24239
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-17 19:34:45 +02:00
Jonas Jelonek 2f9484a2d8 realtek: add macro for pse-pi
Add a macro PSE_PI for the common pse-pi definition, helping with
devices which make use of the Realtek PSE MCU driver. While those
definitions stay manageable for low port counts, this adds too much
visual boilerplate with 24 or even 48 ports. The macro keeps it short
with one line per pse-pi.

Also make use of this macro directly for the two devices XS1930-12HP and
XMG1915-10EP.

Link: https://github.com/openwrt/openwrt/pull/24239
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-17 19:34:44 +02:00
Jonas Jelonek 464560fc35 realtek: fix fan control for Plasma Cloud PSX28/ESX28
Commit 82ddc472d7 ("realtek: dts: convert to upstream switch
notation") adjusted the switch description in the device tree to match
upstream. This was a correct change, however it broke the fan control
script for Plasma Cloud PSX28/ESX28 devices because it uses a
full-fledged platform device path including the switch node (because the
I2C is a child of the switch):

/sys/devices/platform/1b000000.switchcore/1b000000.switchcore:i2c@100c/i2c-4/4-002e/hwmon/

Since the mentioned change, this path doesn't exist anymore. Instead of
just changing the intermediate parts to match the DT structure again, do
not rely on that at all. Instead, use

/sys/bus/i2c/devices/4-002e/hwmon/

as the path which relies less on the DT structure and still points to
the same device. This makes fan control on those device work again,
reducing the fan speed during boot which has been broken since the
commit.

Fixes: 82ddc472d7 ("realtek: dts: convert to upstream switch notation")
Fixes: 2b5555c195 ("realtek: rtl931x: Add support for Plasma Cloud PSX28 Switch")
Link: https://github.com/openwrt/openwrt/pull/24248
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-16 22:22:07 +02:00
Jonas Jelonek 0f1019db1d realtek: pcs: rtl930x: gate WDIG 10G-mode bit on real baud rate
This bit was set unconditionally for any 10G-capable SerDes regardless
of hw_mode, including SGMII/1000BASEX/2500BASEX running on 10G-capable
silicon. The vendor SDK's dal_longan_construct_mac_default_10gmedia_fiber
gates it on the port's declared protocol class instead, applying it to
PHY-attached XSGMII/USXGMII as well as genuine fiber - the "medium to
fiber" naming doesn't match its actual condition.

Gate on speed == RTPCS_SDS_PLL_SPD_10000 instead, matching the real
10G-class protocol family, and actively clear it for 1G/2.5G modes so a
prior 10G-class configuration doesn't leave it stuck across a runtime
downshift. 0 also matches this register's confirmed hardware reset
default on an unconfigured SerDes.

Link: https://github.com/openwrt/openwrt/pull/24232
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-15 19:37:01 +02:00
Jonas Jelonek 7f063b1f95 realtek: pcs: rtl930x: gate TX tuning on attachment and baud rate
TX amp/pre-emphasis tuning depends on the SerDes' real baud rate class
rather than hw_mode, so key config_attachment's dispatch on that instead.

At 1G/2.5G, attachment doesn't change meaningful: even a non-adaptive
fiber receiver needs little compensation on a short trace, so
PHY-attached and fiber links already use the same config there. At 10G,
real channel loss is high enough that it matters: PHY-attached links
equalize on the PHY's own far-end receiver and need less amp drive,
while genuine fiber/DAC links, which have no adaptive receiver
downstream, need the full config. Real DAC-vs-fiber detection doesn't
exist yet, so both of those still share one config for now.

Make use of the PLL speed enum for now, though it is a bit blurry and
may not represent the real baud rate in some cases, e.g. QSGMII (1.25G
PLL with multiplier -> 5G).

Link: https://github.com/openwrt/openwrt/pull/24232
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-15 19:37:01 +02:00
Jonas Jelonek 629c5c8b11 realtek: pcs: rtl930x: refactor TX config
Replace the on-stack, hardcoded pre/main/post-amp locals with static
const rtpcs_sds_tx_config data, one struct per speed class (1g, 2g5,
10g), instead of duplicating the same literals inline on every call.

Move the decision logic about which values are applied to the
config_media function. The tx_config should only be about what is set,
decision logic is handled one layer above. This also prepares further
refactoring.

Link: https://github.com/openwrt/openwrt/pull/24232
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-15 19:37:01 +02:00
Jonas Jelonek f8afbb637b realtek: pcs: rtl93xx: commit attachment only after successful config
sds->attachment was written right after selection, before
config_attachment() ran, so a failed config call would leave it
reflecting a value that was never actually applied to hardware. Move
the assignment after the call succeeds, matching how sds->hw_mode is
only committed after set_hw_mode() succeeds.

Link: https://github.com/openwrt/openwrt/pull/24232
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-15 19:37:00 +02:00
Jonas Jelonek 8d2bd202c4 realtek: pcs: rtl93xx: rename media to attachment
"media" doesn't fit well once PHY sits alongside FIBER/DAC_SHORT/
DAC_LONG as a value: a PHY isn't a transmission medium, whereas what
actually matters here is what electrically terminates the SerDes lane
on the other end. Rename the enum, struct field, ops vtable member,
and both variants' config functions accordingly. Calling it 'attachment'
better fits what it actually is, doesn't confuse with the variants and
also fits to the PMA (Physical Medium Attachment) sublayer that lives
below PCS.

Link: https://github.com/openwrt/openwrt/pull/24232
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-15 19:37:00 +02:00
Jonas Jelonek 5f6896209d realtek: pcs: rtl93xx: rename MEDIA_PCB to MEDIA_PHY
Every SerDes lane runs over some PCB trace before reaching the port,
even fiber/DAC ones, so PCB doesn't describe what actually
distinguishes this case: the SerDes terminates directly into a PHY
chip rather than a fiber module or DAC cable.

Link: https://github.com/openwrt/openwrt/pull/24232
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-15 19:37:00 +02:00
Jonas Jelonek 4212598948 realtek: pcs: rtl930x: classify SGMII as PHY-attached media
SGMII always terminates in a PHY, whether on-board or embedded in an
SFP copper module, so it belongs with QSGMII/XSGMII/USXGMII rather
than the direct fiber/DAC modes. The PHY equalizes on its own far-end
receiver in either case, so no media-dependent TX tuning is needed.

Link: https://github.com/openwrt/openwrt/pull/24232
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-15 19:36:59 +02:00
Jonas Jelonek bf2c9a5d8b realtek: pcs: rtl930x: only apply TX config for 10G SerDes
So far, there was only a misleading and confusing gate to avoid applying
the TX config to SerDes which do not need it or where it even breaks
some modes. This is achieved by not applying any configuration for
QSGMII mode. While this fits the real-world cases we know so far where
QSGMII is only used on SerDes 0/1 but never on others, it implicates
that this is true too for QSGMII on 10G SerDes. Looking at the SDK, this
assumption doesn't hold.

To fix this, drop out of config_media in case a non-10G SerDes is
delivered. The SDK does the same in various ways, ending up with the
config just being applied for SerDes 2 - 9.

Link: https://github.com/openwrt/openwrt/pull/24232
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-15 19:36:59 +02:00
Jonas Jelonek 8eaa84d2e9 realtek: pcs: rtl930x: use cmu_page getter for tx_config
Derive the CMU page from rtpcs_93xx_sds_get_cmu_page() instead of
hardcoding it per hw_mode case. Also change the function to return
int and propagate errors instead of silently doing nothing.

Link: https://github.com/openwrt/openwrt/pull/24232
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-15 19:36:59 +02:00
Jonas Jelonek 146d0fb6e0 realtek: pcs: rtl93xx: make cmu_page getter generic
Rename rtpcs_931x_sds_cmu_page_get() to rtpcs_93xx_sds_get_cmu_page()
and move it next to the other 93xx-shared helpers, so RTL930X can
reuse it instead of duplicating the same hw_mode-to-CMU-page switch.
Also fix the wrong -ENOTSUPP return to -EOPNOTSUPP.

Link: https://github.com/openwrt/openwrt/pull/24232
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-15 19:36:58 +02:00
Jonas Jelonek e9aa5bea9f realtek: add PoE support for XS1930-12HP
Add support for PoE functionality using the realtek-pse-mcu driver
(kmod-pse-realtek-mcu-i2c) interfacing the on-board PoE MCU and RTL8239
PSE chips.

This doesn't include any support for PoE-related LEDs.

Link: https://github.com/openwrt/openwrt/pull/23222
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-14 23:45:30 +02:00
Jonas Jelonek f57de02350 realtek: use realtek-pse-mcu kernel driver for PoE on XMG1915-10EP
Instead of relying on the userspace implementation, make this device the
first user of the new realtek-pse kernel driver (kmod-pse-realtek-mcu-uart)
based on the PSE-PD framework to interface PoE functionality of that
switch. Control of PoE functionality happens via ethtool / netifd now.
Drop selecting realtek-poe for this device.

This doesn't include any support for PoE-related LEDs.

Link: https://github.com/openwrt/openwrt/pull/23222
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-14 23:45:30 +02:00
Jonas Jelonek 184f70a44d realtek: pse: add patch for sysfs detection control
Add a patch which modifies the Realtek PSE MCU driver backport to add a
sysfs control to control detection mode per port. Some older,
bad-designed devices aren't detected properly in standard mode on some
switches, though vendor firmware powers them properly. Testing shows
that enabling the detection of legacy PDs by allowing wider resistance,
more input capacitance and using a wider detection window, solves this
issue.

The legacy detection can be activated by writing 1 to
portN/detection_legacy in the device's sysfs, e.g.

  echo 1 > /sys/bus/i2c/devices/3-0020/port0/detection_legacy

This patch is kept downstream for now, upstreaming will be attempted
though it is likely that upstream prefers a generic pse-pd approach.

Link: https://github.com/openwrt/openwrt/pull/23222
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-14 23:45:29 +02:00
Jonas Jelonek 301d98f81f realtek: add Realtek PSE MCU driver
Add pending patches which add a PSE driver for the PSE setup found on
most of Realtek-based switches. An MCU with a Realtek-defined firmware
and protocol fronts one or more PSE chips (from Realtek or Broadcom) as
a management controller.

The driver provides both I2C/SMBus and UART communication, which varies
among our supported switches. There is no need for complicated userspace
handling anymore, the PSE setup is defined in the device tree and
interfaced in userspace via ethtool, netlink and netifd support.

Those patches have progressed far enough upstream, the bindings are
reviewed. Thus, we can keep this intermediate version downstream to open
it up earlier for usage. Only little changes are expected til the final
version lands.

Link: https://github.com/openwrt/openwrt/pull/23222
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-14 23:45:29 +02:00
Jonas Jelonek 96ecf8dd24 generic: pse-pd: add patches for module-based PSE drivers
Add a backport patch and pending patches needed by upcoming PSE drivers
which are built as modules and probed after the MAC/PHY.

The net effect for module-built PSE controllers: attachment to PHYs
happens via the lifecycle notifier rather than via probe-time
-EPROBE_DEFER coupling, so the MDIO/DSA probe no longer sees any
PSE-originated -EPROBE_DEFER and the probe-retry storm is gone.

Link: https://github.com/openwrt/openwrt/pull/23222
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-14 23:45:29 +02:00
Jonas Jelonek 32e4796045 Revert "realtek: add support for Ubiquiti UniFi USW Pro Max 24 PoE"
This reverts commit b519bc3b76.

The partition layout wasn't tested properly on the device and has major
issues, possibly soft-bricking the device on first boot. Thus, the
installation procedure in the commit message is faulty. Revert for now.

Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-09 10:47:21 +02:00
Jonas Jelonek b519bc3b76 realtek: add support for Ubiquiti UniFi USW Pro Max 24 PoE
Add support for RTL9302B-based Ubiquiti UniFi USW Pro Max 24 PoE switch
with 16x GbE and 8x 2.5G RJ45 ports, 2x SFP+, and a front display.

Hardware
========

  - RTL9302B switch SoC
  - 512 MiB RAM
  - 32 MiB SPI-NOR flash
  - 16x 100M/1G RJ45 ports via 2x RTL8218E
  - 8x 100M/1G/2.5G RJ45 ports via 2x RTL8224
  - PoE:
      - 400W total budget
      - 8x 802.3at, 32W per port (ports 1-8)
      - 16x 802.3bt, 60W per port (ports 9-24)
  - 2x SFP+ ports
  - Buttons: 1x Reset
  - LEDs: RGBW LED per port (Etherlighting)
  - Front touch display via USB ACM (see below)
  - Console: TTL 3.3V, 115200 8N1 (internal pin header close to SoC;
    layout front to back: VCC RX TX GND)
  - Etherlighting feature (lighting patterns and color control)
  - Vendor firmware: U-Boot + LEDE-based Ubiquiti OS

MAC address
===========

Single MAC address in EEPROM partition, applied to all ports.

Front touch display
===================

The unit has a touch-capable front display, driven by a dedicated
STM32-based MCU. Unlike other Ubiquiti switches where the MCU is
connected to the SoC via UART directly, here it is exposed as a USB
CDC-ACM serial device through an on-board Genesys Logic GL850G USB hub.
The MCU runs Ubiquiti's LCM firmware and exposes a high-level JSON
protocol (page selection, button-press events, etc.); arbitrary
pixel-level control is not possible without replacing the MCU firmware.
Display support therefore depends on both USB host support and a driver
for the LCM protocol, neither of which is currently available.

Known issues
============

  - PoE not available, depends on WIP Realtek PSE MCU driver
  - Etherlighting not controllable, driver WIP. Port LEDs for link work
    though. By default, the controller keeps the LEDs in a breathing
    state, gated by the link state delivered by the Realtek SoC.

Disclaimer
==========

Stock firmware uses a dual-bank layout (kernel0/kernel1, ~15 MiB each).
OpenWrt replaces both banks with a single contiguous firmware partition.
Flashing OpenWrt overwrites both stock kernel slots; U-Boot remains
intact and can be used for recovery.

Installation
============

1. Enable SSH on the stock UniFi OS and log in with user account.

2. Copy the OpenWrt sysupgrade image to /tmp on the switch (e.g. via
   scp).

3. Adjust IMG below to point at the copied file, then run the block as a
   whole. It writes kernel0, splits into kernel1 if the image is larger
   than that slot (otherwise invalidates kernel1 so U-Boot cannot pick
   a stale bank), and reboots:

   IMG=/tmp/openwrt-realtek-rtl930x-ubnt_usw-pro-max-24-poe-squashfs-sysupgrade.bin
   K0_BLOCKS=$((0xec0000 / 0x10000))

   dd if="$IMG" of=/dev/mtdblock2 bs=64k count=$K0_BLOCKS conv=fsync
   if [ "$(wc -c < "$IMG")" -gt $((0xec0000)) ]; then
       dd if="$IMG" of=/dev/mtdblock3 bs=64k skip=$K0_BLOCKS conv=fsync
   else
       dd if=/dev/zero of=/dev/mtdblock3 bs=64k count=1 conv=fsync
   fi
   sync
   reboot

   The switch comes up in OpenWrt after reboot.

4. It is recommended to modify the bootcmd to speed up the boot and
   prevent any issues due to the dual-boot selection. Since U-Boot by
   default uses bootubnt which does a lot of (unneeded) RTK
   initialization, quite some time passes until Linux is started.
   Additionally, the U-Boot logic fiddles with some bits on flash which
   causes JFFS2 errors in OpenWrt. While this doesn't seem to cause
   issues yet, be defensive and set the bootcmd to:

     bootm 0xb4150000

   This directly boots the uImage from flash, without doing all the
   initialization. OpenWrt is able to bootstrap the networking
   completely on its own.

It does not matter which bank stock booted from when the dd block
runs: both banks are touched in the same pass (kernel0 written, kernel1
either written or invalidated). With kernel1 invalidated, U-Boot's
internal fallback kicks in and permanently switches to kernel0 on the
next boot, so the device stays on OpenWrt as long as kernel0 is
bootable.

Recovery
========

Since the installation procedure invalidates or partially overwrites
the second bank, recovery requires serial console access (see Hardware
above for pinout).

1. Interrupt U-Boot autoboot by spamming a key during early boot to
   drop into the U-Boot prompt.

2. Bring up networking:

   rtk network on

3. Transfer an OpenWrt initramfs image via TFTP and boot it:

   tftpboot 0x82000000 <server>:<initramfs.bin>
   bootm 0x82000000

4. From the running initramfs OpenWrt, do a sysupgrade to reflash
   OpenWrt or whatever you want to recover. There is no need for the
   complicated procedure from installation since OpenWrt sees the
   firmware partition already as a whole.

Return to stock firmware
========================

There is no fully-supported revert path. The stock firmware blob is a
Ubiquiti UBNT archive (header + parts, see firmware-utils' fw.h) that
embeds a u-boot and a kernel0 uImage payload; only the latter is
relevant when writing back to the kernel partitions.

The snippet below extracts the kernel0 uImage from such a blob by
locating the uImage magic and using the size carried in the uImage
header itself, without parsing any UBNT framing. It is provided as a
best-effort starting point; verify the result before flashing,
otherwise you're on your own:

   BLOB=<firmware.bin>
   OFF=$(grep -aboF $'\x27\x05\x19\x56' "$BLOB" | head -1 | cut -d: -f1)
   SIZE=$(( $(dd if="$BLOB" bs=1 skip=$((OFF + 12)) count=4 2>/dev/null \
               | hexdump -e '1/4 "%u"') + 64 ))
   dd if="$BLOB" of=kernel0.uImage bs=1 skip="$OFF" count="$SIZE"

Once you have a clean uImage, write it to the kernel partition from
within OpenWrt. If you adjusted the bootcmd during installation, make
sure to restore it to the default "bootcmd=bootubnt". After a reboot,
Ubiquiti's firmware should boot.

Or, if you made backups of the flash before installation, just write
the backup back to flash.

Link: https://github.com/openwrt/openwrt/pull/24110
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-08 23:17:13 +02:00
Jonas Jelonek f03899aef4 realtek: add support for Ubiquiti UniFi USW Pro XG 8 PoE
Add support for RTL9313-based Ubiquiti UniFi USW Pro XG 8 PoE switch
with 8x 10G RJ45 and 2x SFP+ ports.

Hardware
========

  - RTL9313 switch SoC
  - 512 MiB RAM
  - 32 MiB SPI-NOR flash
  - 8x 100M/1G/2.5G/5G/10G RJ45 ports via 2x RTL8264B
  - PoE: 8x 802.3bt, 60W per port, 155W total budget
  - 2x 1G/2.5G/10G SFP+ ports
  - Buttons: 1x Reset
  - LEDs:
    - System LED white/blue
    - RGBW LED per port
  - Console: TTL 3.3V, 115200 8N1, populated 4-pin header
    (device must be opened to access header)
  - Etherlighting feature (lighting patterns and color control)
  - Vendor firmware: U-Boot + LEDE-based Ubiquiti OS

MAC address
===========

Single MAC address in EEPROM partition, applied to all ports.

Known issues
============

  - PoE not available, depends on WIP Realtek PSE MCU driver
  - Etherlighting not controllable, driver WIP. Port LEDs for link work
    though. By default, the controller keeps the LEDs in a breathing
    state, gated by the link state delivered by the Realtek SoC.

Disclaimer
==========

Stock firmware uses a dual-bank layout (kernel0/kernel1, ~15 MiB each).
OpenWrt replaces both banks with a single contiguous firmware partition.
Flashing OpenWrt overwrites both stock kernel slots; U-Boot remains
intact and can be used for recovery.

Installation
============

1. Enable SSH on the stock UniFi OS and log in with user account.

(at this stage you may make backups of the flash, just to be sure)

2. Copy the OpenWrt sysupgrade image to /tmp on the switch (e.g. via
   scp).

3. Adjust IMG below to point at the copied file, then run the block as a
   whole. It writes kernel0, splits into kernel1 if the image is larger
   than that slot (otherwise invalidates kernel1 so U-Boot cannot pick
   a stale bank), and reboots:

   IMG=/tmp/openwrt-realtek-rtl931x-ubnt_usw-pro-xg-8-poe-squashfs-sysupgrade.bin
   K0_BLOCKS=$((0xec0000 / 0x10000))

   dd if="$IMG" of=/dev/mtdblock2 bs=64k count=$K0_BLOCKS conv=fsync
   if [ "$(wc -c < "$IMG")" -gt $((0xec0000)) ]; then
       dd if="$IMG" of=/dev/mtdblock3 bs=64k skip=$K0_BLOCKS conv=fsync
   else
       dd if=/dev/zero of=/dev/mtdblock3 bs=64k count=1 conv=fsync
   fi
   sync

   Then reboot the switch, it comes up in OpenWrt after reboot.

   You may also install the image in any other way, just make sure to
   write it to the kernel0 partition and if the image is larger than
   16MiB, write the rest to the kernel1 partition, otherwise invalidate
   it so U-Boot cannot boot from the second bank.

4. It is recommended to modify the bootcmd to speedup the boot and prevent
   any issues due to the dual-boot selection. Since U-Boot by default
   uses bootubnt which does a lot of (unneeded) RTK initialization,
   quite some time passes until Linux is started. Additionally, the
   U-boot logic fiddles with some bits on flash which causes JFFS2
   errors in OpenWrt. While this doesn't seem to cause issues yet, be
   defensive and set the bootcmd to:

     bootm 0xb4150000

   This directly boots the uImage from flash, without doing all the
   initialization. OpenWrt is able to bootstrap the networking completely
   on its own.

It does not matter which bank stock booted from when the dd block
runs: both banks are touched in the same pass (kernel0 written, kernel1
either written or invalidated). With kernel1 invalidated, U-Boot's
internal fallback kicks in and permanently switches to kernel0 on the
next boot, so the device stays on OpenWrt as long as kernel0 is
bootable.

Recovery
========

Since the installation procedure invalidates or partially overwrites
the second bank, recovery requires serial console access (see Hardware
above for pinout).

1. Interrupt U-Boot autoboot by spamming a key during early boot to
   drop into the U-Boot prompt.

2. Bring up networking:

   rtk network on

3. Transfer an OpenWrt initramfs image via TFTP and boot it:

   tftpboot 0x82000000 <server>:<initramfs.bin>
   bootm 0x82000000

4. From the running initramfs OpenWrt, do a sysupgrade to reflash
   OpenWrt or whatever you want to recover. There is no need for the
   complicated procedure from installation since OpenWrt sees the
   firmware partition already as a whole.

Return to stock firmware
========================

There is no fully-supported revert path. The stock firmware blob is a
Ubiquiti UBNT archive (header + parts, see firmware-utils' fw.h) that
embeds a u-boot and a kernel0 uImage payload; only the latter is
relevant when writing back to the kernel partitions.

The snippet below extracts the kernel0 uImage from such a blob by
locating the uImage magic and using the size carried in the uImage
header itself, without parsing any UBNT framing. It is provided as a
best-effort starting point; verify the result before flashing,
otherwise you're on your own:

   BLOB=US3.rtl93xx_7.4.1+X.Y.Z.bin
   OFF=$(grep -aboF $'\x27\x05\x19\x56' "$BLOB" | head -1 | cut -d: -f1)
   SIZE=$(( $(dd if="$BLOB" bs=1 skip=$((OFF + 12)) count=4 2>/dev/null \
               | hexdump -e '1/4 "%u"') + 64 ))
   dd if="$BLOB" of=kernel0.uImage bs=1 skip="$OFF" count="$SIZE"

Once you have a clean uImage, it can be written to the kernel partition
from within OpenWrt. If you adjusted the bootcmd during installation,
make sure to restore it to the default "bootcmd=bootubnt". After a reboot,
Ubiquiti's firmware should boot.

Or, if you did backups of the flash before, just write the backup to the
flash.

Link: https://github.com/openwrt/openwrt/pull/24010
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-06 22:38:13 +02:00
Jonas Jelonek ba2467954e realtek: pcs: rtl930x: some more calibration init cleanup
Some more cleanup for the calibration cleanup, removing some stray
whitespaces and collapsing subsequent writes in the same registers. The
former aren't helping anymore after the page -> named field conversion.
The latter can be collapsed because there is no reason to keep them
separate and thus, calls can be reduced.

Link: https://github.com/openwrt/openwrt/pull/24091
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-06 22:36:25 +02:00
Jonas Jelonek c56a15b149 realtek: pcs: rtl930x: replace mdelay with msleep/usleep_range
All calibration and SerDes config code runs in process context, so
busy-waiting with mdelay is unnecessary. Use usleep_range for delays
up to 10ms and msleep for longer ones to yield the CPU instead.

Add explicit linux/delay.h include to document the dependency.

Link: https://github.com/openwrt/openwrt/pull/24091
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-06 22:36:24 +02:00
Jonas Jelonek b1cb70feb0 realtek: pcs: rtl930x: add some context to calibration init
Replace SDK-style step numbering (1.1.1, 1.1.2, ...) with descriptive
section headers and inline register name comments. This makes it easier
to follow the calibration sequence without cross-referencing the SDK.
Also correct the LEQ acronym expansion and tidy up variable comments.

Link: https://github.com/openwrt/openwrt/pull/24091
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-06 22:36:24 +02:00
Jonas Jelonek eb857ca10e realtek: pcs: rtl930x: use VTH/TAP helpers in calibration init
Replace the raw register writes in rxcal_init with the previously
cleaned-up VTH and TAP helpers. Beyond readability, this also fixes two
latent bugs in the original tap4 initialisation: tap4_even was written
twice (both to PAGE_ANA_10G_EXT 0x01[5:0]) and tap4_odd was never
written at all (PAGE_ANA_10G 0x06[11:6]). Using tap_set_value(sds, 4,
0, 0) writes both fields correctly.

Also apply stage-then-latch ordering to the VTH init: write the value
registers before asserting the manual bit, consistent with the rest of
the calibration lock path.

Link: https://github.com/openwrt/openwrt/pull/24091
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-06 22:36:24 +02:00
Jonas Jelonek 89f145112b realtek: pcs: rtl930x: cleanup TAP helpers
Split tap_manual() into tap_set_adapt() and tap_set_value(), separating
mode control from value writes. Replace manual sign-magnitude bit
manipulation with rtpcs_sign_mag_encode/decode helpers. Update tap_get()
to use individual signed output pointers instead of an array and add
error propagation. Apply stage-then-latch ordering consistently: value
is written before the manual bit is set.

Remove the usleep from tap_set_adapt(enable=true). Callers already
carry explicit delays: vth_tap0_adapt_lock has msleep(200) and
dfe_taps_adapt has msleep(30) after enabling auto-adapt. The 10ms per
call was redundant and added 40ms to dfe_taps_adapt needlessly.

Link: https://github.com/openwrt/openwrt/pull/24091
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-06 22:36:23 +02:00
Jonas Jelonek 75de4464fa realtek: pcs: rtl930x: cleanup VTH helpers
Split vth_manual() into vth_set_adapt() and vth_set_value(), separating
mode control from value writes, consistent with DCVS and LEQ helpers.
Rename vth_get() to match and switch from an array parameter to
individual pointers. Invert the manual boolean to 'enable' (true means
auto-adapt is running). Add error propagation throughout and demote the
read-out print from pr_info to pr_debug.

Remove the usleep from vth_set_adapt(enable=true). The only caller is
vth_tap0_adapt_lock which already has an explicit msleep(200) to wait
for adaptation to complete, making the embedded 10ms redundant. Delay
belongs at the call site, not baked into the setter.

Link: https://github.com/openwrt/openwrt/pull/24091
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-06 22:36:23 +02:00
Jonas Jelonek 8d6a9e10d2 realtek: pcs: rtl930x: cleanup LEQ helpers
Split leq_manual() into leq_set_adapt() and leq_set_coef(), separating
mode control from coefficient writes, consistent with the DCVS helpers.
Rename leq_get() to leq_get_coef() and leq_get_bin() to
leq_get_coef_bin() to match. Add error propagation throughout.

Link: https://github.com/openwrt/openwrt/pull/24091
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-06 22:36:23 +02:00
Jonas Jelonek cfa212ad79 realtek: pcs: rtl930x: use DCVS helpers in calibration init
Replace the nine raw register writes that enable auto-adapt for all six
DCVS channels with a loop over dcvs_set_adapt(), consistent with how
TAP and VTH init was already converted.

Link: https://github.com/openwrt/openwrt/pull/24091
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-06 22:36:22 +02:00
Jonas Jelonek 4fc1dea129 realtek: pcs: rtl930x: cleanup DCVS helpers
Split the DCVS setter into two functions, separating mode control from
coefficient setting. The old pattern, combining everything in one
function, was still kept from the SDK but is rather confusing and makes
the function rather complex. Splitting this simplifies it a lot.

Cleanup the DCVS getter, making it consistent with the setters. Though
not used right now, kept for documentation purpose. So at least keep it
in a good style.

Remove the usleep from dcvs_set_adapt(enable=true). There is no lock
flow for DCVS that polls a result after enabling auto-adapt, so no
caller needs the delay. rxcal_init also enables VTH and TAP auto-adapt
via the load_in_init bulk write with no delay, confirming it is not
needed here either.

Link: https://github.com/openwrt/openwrt/pull/24091
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-06 22:36:22 +02:00
Jonas Jelonek 27d6b62fda realtek: pcs: rtl930x: fix DCVS setter
The (currently unused) DCVS setter (_dcvs_manual) is still based on the
XGS1210 SDK. Comparing this with other SDKs we have available (DMS1250,
TEG7124WS), a discrepancy between the setters can be seen. The variant
from XGS1210 SDK uses different fields for DCVS0 and DCVS4. They do not
match the other SDK variants, and also not the settings in
do_rx_calibration_1 where DCVS is initialized.

Adjust that to what the majority of SDK variants uses and to what makes
it consistent overall.

Link: https://github.com/openwrt/openwrt/pull/24091
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-06 22:36:22 +02:00
Jonas Jelonek ab49df2643 realtek: pcs: rtl930x: carve out debug selection
The three SerDes writes setting a debug output is heavily used by the
calibration code. But right now, it is duplicated in every user site. To
reduce duplication, carve out into a dedicated helper.

Link: https://github.com/openwrt/openwrt/pull/24091
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-06 22:36:21 +02:00
Jonas Jelonek 87e02936a4 realtek: pcs: rtl930x: rename last numbered calibration function
One calibration function was renamed from the numbered naming before,
mostly because its full purpose wasn't known yet. This has changed now,
so rename that function to "rxcal_init" to reflect what it's doing.

Link: https://github.com/openwrt/openwrt/pull/24091
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-06 22:36:21 +02:00
Jonas Jelonek 8b0ce8e4e3 realtek: pcs: rtl930x: simplify DCVS/VTH/TAP calibration helpers
Reduce repetition in dcvs_manual, dcvs_get, vth_manual and tap_manual
by hoisting the per-channel enable bit write out of per-case branches
and encoding per-channel register/bit mappings as lookup tables where
the pattern is uniform across channels.

This also fixes two bugs in dcvs_get that were hidden in the switch:

- DCVS1 read never populated dcvs_sign_out; it wrote the sign bit read
  (0x14[4:4]) into dcvs_coef_bin and then immediately overwrote it with
  the coefficient read, leaving the sign always zero for that channel.

- DCVS3 assigned the manual bit read directly to a bool without the !!
  normalisation applied to all other cases.

Link: https://github.com/openwrt/openwrt/pull/23983
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-06-28 23:38:37 +02:00
Jonas Jelonek 393d5b01fb realtek: pcs: rtl930x: fix LEQ calibration to use media type
Replace the mode-based approximation in the LEQ adapt+lock step with
proper media-based logic using the newly stored sds->media field. Those
adjustments are based on SDK code and digging through some basics of
signal conditioning.

PCB connections route through an external PHY (PHY-attached); that PHY
handles its own equalization so the SerDes LEQ is left in free-running
auto-adapt with no correction offset. DAC and fiber SFP connect directly
to the SerDes without an intermediate PHY and require a calibrated lock.

Replace the SDK's dacLongCableOffset/eqHoldEnable variable pair with a
single direct_serdes bool and encode the full per-media LEQ correction
into one switch: fiber +3 (direct SerDes, no cable), DAC short +4
(base 3 + 1), DAC long +6 (base 3 + 3).

Fix the MAXHOLD_EN bit (0x17[7]) and the 0x0c[8] write to be gated on
direct_serdes; both were previously conditioned on PCB which is the
PHY-attached case and thus wrong. Fix the LEQ lock to apply to all
direct SerDes connections (DAC + fiber), not just PCB. Also drop the
spurious dead-code branch that was an artifact of the original
transplanting.

No behavioral change because this particular function of calibration is
not used right now but will be in the future.

Link: https://github.com/openwrt/openwrt/pull/23983
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-06-28 23:38:36 +02:00
Jonas Jelonek 8dd1c280ae realtek: pcs: store active media type in SerDes state
Track the resolved media type in struct rtpcs_serdes alongside hw_mode,
storing it as soon as rtpcs_sds_select_media() resolves it so all
subsequent ops (set_hw_mode, activate, post_config) can access it.

This is unused for now and will be used only in dead code in next
patches. Though, this dead code is going to be used with subsequent
patches.

Link: https://github.com/openwrt/openwrt/pull/23983
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-06-28 23:38:36 +02:00
Jonas Jelonek d5615c1df6 realtek: pcs: rtl930x: give some calibration functions meaningful names
Adapted from the SDK, the calibration functions are just named after
their sequential logic and with a numbering scheme. This doesn't help
understanding what the code is doing. Instead, give some of them
meaningful names where possible, revealing kind of a logical structure.

Link: https://github.com/openwrt/openwrt/pull/23983
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-06-28 23:38:36 +02:00
Jonas Jelonek f33b49d0a7 realtek: pcs: rtl930x: reduce calibration code nesting
The calibration code is deeply nested with multiple function using
numeric nesting. Though it tries to follow the SDK pattern, this makes
it just unnecessarily complex and confusing. Dissolve some of this
unneeded nesting, together with some minor cleanup here and there.

Link: https://github.com/openwrt/openwrt/pull/23983
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-06-28 23:38:35 +02:00
Jonas Jelonek 6b16b96e43 realtek: dsa: rtl93xx: allow to adjust LED_CLK
The LED_GLB_CTRL register has a field to select the clock used for LED
output, either for serial LED output or for the external auxiliary MDIO
to connect a RTL8231. While the default value for the period time of
400ns is the correct one for most applications, some special devices
require a dedicated setting, e.g. UniFi switches with Etherlighting.

Support the generic DT property "clock-frequency" within the LED node,
and read + apply during LED configuration. In case the property isn't
specified, no change is applied to keep previous behavior. In case an
unsupported value is supplied, the default is used as a fallback

Link: https://github.com/openwrt/openwrt/pull/23944
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-06-27 10:24:21 +02:00
Jonas Jelonek 55efd11f27 layerscape: drop 6.12 files
Remove kernel configs and patches for 6.12, now that layerscape target
was switched to 6.18. This was missed during the 6.12 -> 6.18 PR.

Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-06-26 18:57:52 +02:00
Jonas Jelonek 47aa3ec222 realtek: mdio: add polling setup support for RTL8264B
Add polling setup support for RTL8264B PHY to avoid 'skip polling'
message during boot. Rely on the default register values for polling for
now, similar to RTL8261.

Link: https://github.com/openwrt/openwrt/pull/23946
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-06-26 17:34:38 +02:00
Jonas Jelonek 82f26df15c toolchain: binutils: change default to 2.46
Change default to latest upstream release.

Link: https://github.com/openwrt/openwrt/pull/23907
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-06-26 14:51:16 +02:00
Jonas Jelonek 4a31f8e544 realtek: pcs: replace hardcoded page values with named fields
Replace all hardcoded page values in various calls and definitions with
the previously added defines. This should help readability, giving those
various values a name and making it easier to compare and track within
the context of what is being set.

Link: https://github.com/openwrt/openwrt/pull/23915
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-06-26 11:54:56 +02:00
Jonas Jelonek fe5edcf985 realtek: pcs: add SerDes page definitions
To reduce having magic values all over the place in the whole driver,
add definitions for the SerDes register pages. They are equal among all
variants and can be clearly named, as already done in the debugfs output
of the realtek-otto-serdes-mdio driver. This should ease comparison,
code understanding and very likely is a step forward towards
upstream-readyness.

Also define two macros to cover the special cases for RTL931x's digital
SerDes via 0x40/0x80 page offset.

Link: https://github.com/openwrt/openwrt/pull/23915
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-06-26 11:54:55 +02:00
Jonas Jelonek 8ebf189e60 realtek: pcs: drop unused cmu_band code
For RTL930x and RTL931x, there were some functions to get and set the
CMU band. However, they were used nearly nowhere and even the SDK
doesn't use them for active SerDes configuration. Drop them to reduce
dead code.

Dropping the cmu_band_set call from RTL931x configuration has no
negative effect. We do not know where this call originally came from.
It was introduced 51c8f76612 ("realtek: improve MAC config handling for
all SoCs") but without any explanation why and where it came from. The
SDK doesn't have it and it may be overwritten again in the later CMU
setup when parts of the SerDes are reset.

Link: https://github.com/openwrt/openwrt/pull/23904
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-06-22 13:02:07 +02:00
Jonas Jelonek 0a7becdce1 realtek: pcs: rtl931x: use xsg_write instead of open-coded pattern
The xsg_write operation for RTL931x already offers the correct procedure
writing to both page + 0x40 and page + 0x80. Though, this wasn't used
so far because this pattern was still open-coded where needed. Replace
that with the xsg_write helper call.

In clear_symerr, this deliberately changes the exact sequence of
operations a bit. However, this shouldn't have any practical effect and
testing shows no issues.

Link: https://github.com/openwrt/openwrt/pull/23904
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-06-22 13:02:07 +02:00
Jonas Jelonek f3b7cfcb58 realtek: pcs: rename 'determine_hw_mode' to 'select_hw_mode'
Rename the 'determine_hw_mode' to 'select_hw_mode' to better express
what the function does. Based on the requested interface, the number of
links on a SerDes and the capabilities, it selects a suitable hardware
mode. 'determine' is clunkier and less expressive in this case.

Link: https://github.com/openwrt/openwrt/pull/23904
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-06-22 13:02:06 +02:00
Jonas Jelonek 4ac14efb86 realtek: pcs: drop wrong __maybe_unused
Some functions specify __maybe_unused from former times although they
are clearly used. Remove those attributes.

Link: https://github.com/openwrt/openwrt/pull/23904
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-06-22 13:02:06 +02:00
Jonas Jelonek 06cb5f1b21 realtek: pcs: drop unused modify helper
Drop the unused rtpcs_sds_modify helper. Other helpers already provide
what we need.

Link: https://github.com/openwrt/openwrt/pull/23904
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-06-22 13:02:06 +02:00