74924 Commits
Author SHA1 Message Date
Felix Fietkau e6bd2af652 wifi-scripts: only manage wdev interfaces recorded in the statefile
wdev.uc adopted every operstate-down netdev on the phy and then removed any
not in its new config. hostapd BSS netdevs are legitimately operstate-down
while stopped (co-located STA down, or start_disabled), so a reload deleted
them and hostapd, seeing an unchanged config, never recreated them. Drop the
adopt-existing step; the statefile already tracks the interfaces wdev.uc
owns.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:22 +02:00
Felix Fietkau 1789118599 wifi-scripts: give the OWE-transition BSS its own MAC address
The transition BSS is a copy of the main BSS with the MAC already set, so
iface.prepare() was a no-op and both BSSes emitted the same bssid; with a
fixed or random MAC the duplicate was never reassigned and the second
interface failed to come up. Clear the address (and stale flags) and
prepare a fresh one, plumbing the phy/num_global/macaddr_base through
iface_setup().

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:22 +02:00
Felix Fietkau 4062d625ae wifi-scripts: emit per-line hostapd options correctly
append() space-joins list options into one line, which breaks hostapd
options that are parsed one entry per line: anqp_elem, nai_realm,
venue_name, venue_url, hs20_conn_capab and the radius req_attr lists (a
parse error there fails the whole phy). Add append_list() to emit one line
per element and route those options through it. vendor_elements is instead
a single concatenated hex blob (join ''), and iface_interworking() no
longer overwrites domain_name with the 3GPP cell-net data (and uses ';').

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:22 +02:00
Felix Fietkau 56d466a75d wifi-scripts: use country_code for iw reg set in setup_phy
validate() converts the country alias to country_code and deletes country
before setup_phy() runs, so the iw reg set branch tested a null
config.country and never ran, leaving wdev-only radios (adhoc/mesh/monitor)
on the world regdomain. Use config.country_code.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:22 +02:00
Felix Fietkau f3cbf55143 hostapd: ucode: keep comment lines out of the config comparison data
The generator emits a '# Setup interface: <ifname>' comment before each
interface, so the first one landed in config.radio.data and made the radio
comparison depend on the first BSS's ifname: renaming it forced a full
radio restart instead of the rename path. Skip comment lines when parsing
radio.data/bss.data.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:22 +02:00
Felix Fietkau 26a4d50806 hostapd: ucode: filter MLD loops by phy in phy_set_state/phy_status
The per-wiphy radio-mask loops iterated all MLDs without checking the phy,
so a stop/start or status query for one wiphy touched MLDs on another wiphy
with the same radio index (clearing present bits, tearing links down, or
reporting a foreign MLD). Skip MLDs that do not belong to the phy, matching
mld_update_phy().

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:22 +02:00
Felix Fietkau 73c35f97f3 wifi-scripts: quote dpp_connector in the station config
dpp_connector was emitted unquoted, but wpa_supplicant parses it as a
string and hex-decodes an unquoted value; a base64url connector then failed
to parse and the network block was rejected. Emit it via the quoted-string
list. dpp_csign/dpp_netaccesskey stay raw, as they are hex.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:22 +02:00
Felix Fietkau dd128675c5 hostapd: ucode: unregister ucode/ubus objects when deleting an unstarted BSS
hostapd_free_hapd_data() skips hostapd_ucode_free_bss()/hostapd_ubus_free_bss()
for a bss that never started, so bss.delete() on such a bss freed hapd while
the ucode registry entry and ubus object still referenced it. Call both
explicitly before os_free(); they are idempotent for the started case.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:22 +02:00
Felix Fietkau b2755b0402 hostapd: ucode: initialise conf in iface.add_bss
The early error path jumps to out: before conf is assigned, where
hostapd_config_free(conf) frees an indeterminate pointer. Initialise it to
NULL (hostapd_config_free tolerates NULL).

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:22 +02:00
Felix Fietkau 139f14717f hostapd: ucode: pass phy to the bss_remove callback
hostapd_ucode_free_bss() pushed only two arguments, but the bss_remove
handler (like bss_add/bss_reload) takes three (phy, name, obj), so name
received the bss resource: the DPP hook was never removed and the removal
event was malformed. Push the phy as well.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:22 +02:00
Felix Fietkau 06b3ef0ff5 wifi-scripts: use the base phy name for config_get_macaddr_list
phydev.name is already radio-suffixed, and the hostapd handler re-applies
the suffix, so on multi-radio phys the lookup missed and the returned MAC
list was always empty, letting wdev.uc reuse a MAC hostapd had reserved for
an AP BSS. Pass the base phy and radio index.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:22 +02:00
Felix Fietkau 97e8911c9b wifi-scripts: pass device config to parse_encryption for station mode
setup_sta() called parse_encryption() without the device config, so the
sae-compat branch dereferenced a null dev_config.band and threw, aborting
the whole radio setup. Pass the device config through.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:22 +02:00
Felix Fietkau 0bab595808 wifi-scripts: map the configured pairwise cipher for station mode
Only an exact GCMP cipher was mapped to the network block; other explicit
ciphers (CCMP-256, GCMP-256, TKIP variants) left pairwise unset, so
wpa_supplicant offered its default set and could not associate with an AP
restricted to the configured cipher. Pass wpa_pairwise through, keeping the
GCMP special case that also pins group.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:22 +02:00
Felix Fietkau 105dd239ac wifi-scripts: do not treat WDS-station VLAN subinterfaces as the base wdev
The hotplug match /(.+)\.sta.+/ also matched VLAN subinterfaces of a WDS
station (e.g. wlan0.sta1.100 -> wlan0), so the tagged subinterface was added
into the vif base networks, breaking VLAN separation. Anchor the pattern to
the plain station suffix.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:22 +02:00
Felix Fietkau dc33d7bcb1 wifi-scripts: pass multicast_to_unicast as an integer
handle_link() passed the option as a ucode boolean, but the netifd
device_set binding reads it with prop_get_int (UC_INTEGER only) and ignored
a boolean, so the option was a no-op. Convert it to 0/1.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:22 +02:00
Felix Fietkau fedefbf50f wifi-scripts: reset the retry counter on successful setup
retry was only reset on config change/start, never on a successful setup,
so occasional transient setup failures accumulated over a device lifetime
and latched retry_setup_failed after three cumulative failures. Reset it
when the device comes up.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:22 +02:00
Felix Fietkau 5379d034e0 wifi-scripts: fix VLAN key for service-injected wifi-iface
Service data VLANs were stored under vif_data.vlans, but every consumer
reads vif.vlan, so per-VLAN config from a procd service was silently
dropped. Use the singular key, matching the adjacent station handling.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:22 +02:00
Felix Fietkau 39507969ff wifi-scripts: return the interface-creation result from wdev_add
wdev_add() dropped the wdev_create() result, so every caller's error check
was dead and an nl80211 NEW_INTERFACE failure was silently ignored (hostapd
and wpa_supplicant then proceeded on a missing netdev with stale MLD
bookkeeping). Return the result.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:22 +02:00
Felix Fietkau 1a58efdb5d hostapd: ucode: fix dead reload-all check in mld_set_config
new_config was tested against the freshly emptied new_mld object, so it was
always false and the reload-all-interfaces block never ran. Test the
incoming config instead, so the first MLD config re-adds the spliced-out
MLD BSSes.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:22 +02:00
Felix Fietkau f536d79fcd hostapd: ucode: force restart on unresolvable static BSSID conflict
The guard meant to bail to a full restart read `!mac_idx < 0`, which parses
as `(!mac_idx) < 0` and is always false, so a static BSSID colliding with
the first (or a foreign-owned) BSS fell through and reassigned the wrong
BSS's address. Use `mac_idx <= 0`.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:22 +02:00
Felix Fietkau 28c6f5e6f7 wifi-scripts: fix extended-feature bit test
device_extended_features() used bitwise OR instead of AND, so every
extended-feature query returned true regardless of the driver bitmap:
ftm_responder and radar_background were always reported present.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:21 +02:00
Felix Fietkau 5917907471 wifi-scripts: do not report a disabled wifi-device as up
A disabled wifi-device is intentionally still run through the setup path
(with no interfaces) to reliably tear down hostapd/wpa_supplicant and to
handle disabled/enabled flapping, so it reaches state "up" and status
reported up: true alongside disabled: true. Exclude disabled devices from
the up state in status instead.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:21 +02:00
Felix Fietkau e7cf46369b hostapd: ucode: clear start_disabled when reloading a started BSS
On a radio shared with a STA every AP BSS is generated with
start_disabled=1. A smart reload that takes the full bss.set_config() path
restarts the BSS but never cleared start_disabled, so hostapd_start_beacon()
skipped beaconing and the AP went silently quiet until an unrelated
apsta_state event. Clear it when the BSS was already started, matching the
add_bss path.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:21 +02:00
Felix Fietkau 5b47cec245 wifi-scripts: emit a raw 64-hex PSK unquoted for station mode
A 64-character hex PSK was always quoted, but wpa_supplicant rejects a
quoted passphrase longer than 63 characters, so the network block failed
and the STA never associated while netifd still reported the radio up. Emit
the key unquoted when it is a 64-character raw PMK, matching the AP path.
The sae_password branch keeps quoting, as SAE passwords are arbitrary
strings.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:21 +02:00
Felix Fietkau 830ae67b44 wifi-scripts: honour a cancelled setup when the handler reports up
stop() and destroy() set cancel_setup while a setup handler is running, but
nothing read it, so a device brought down (or removed) mid-setup still went
up and stayed up, holding its interface links. Check the flag (and
autostart/delete) in wdev_mark_up and tear the device down instead of
completing the up transition.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:21 +02:00
Felix Fietkau f3ff33c8a9 hostapd: ucode: fix per-station PSK list parsing in sta_auth
Two defects handling the psk array returned by an auth handler: strlen()
ran before the string was validated (strlen(NULL) on a non-string entry),
and the hex-PMK branch tested the array length instead of the entry length.
A 64-character passphrase therefore reached the passphrase branch and its
memcpy of str_len + 1 overflowed passphrase[MAX_PASSPHRASE_LEN + 1] by one
byte. Validate the type first and branch on the string length.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:21 +02:00
Felix Fietkau eb5ccabf0e wifi-scripts: fix undeclared variable in service wifi-device injection
The wifi-device injection path used object shorthand `name` where no such
variable is in scope (the loop binds radio/config), so under the strict VM
config_init threw and the whole wireless configuration for that reload was
skipped. Use the radio key as the device name.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:21 +02:00
Felix Fietkau 06a7b0245f hostapd: ucode: handle null config in iface_set_config again
config_reset and shutdown call iface_set_config(name) with no config, but
the null-config guard was dropped in the MLO rework, so config.phy
dereferenced null and threw: config_reset reset nothing and shutdown left
hostapd-created interfaces behind. Restore the guard, removing the stale
config entry and tearing the interface down via iface_config_remove.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:21 +02:00
Felix Fietkau c6d20bbf51 hostapd: ucode: restart on config-initiated channel switch failure
iface.switch_channel() only reports whether a CSA was started, not whether
it completed, so a config-driven channel switch that the driver never
finishes would leave the AP stuck without recovery. After issuing the CSA,
arm a timer and, if the switch has not completed by the deadline
(csa_in_progress still set), fall back to a full interface restart. The
timer is armed only on the config-initiated path, so ubus- and
apsta-triggered channel switches keep their own recovery.

Add an iface.csa_in_progress() ucode method wrapping hostapd_csa_in_progress().

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:21 +02:00
Felix Fietkau 55b9263596 hostapd: ucode: apply channel/width changes via CSA instead of restart
A config change that only alters the channel or channel width previously
failed the radio comparison in iface_reload_config() and forced a full
interface restart, disconnecting every client. Classify the radio diff:
apply a channel/width-only change through iface.switch_channel() (CSA) so
clients stay associated, keep the full restart for any other radio change.

When a co-located STA on the same band owns the runtime channel
(#channel_owned_by_sta), the change is a no-op on the AP side, which keeps
following the STA via apsta_state. MLD APs and DFS targets fall back to a
full restart, as a single iface-level CSA cannot handle them.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:21 +02:00
Felix Fietkau b0d8ab4fef wifi-scripts: emit frequency and STA-channel markers in hostapd config
Emit #frequency (the target channel frequency, already computed during phy
setup) and #channel_owned_by_sta (set when a co-located STA/mesh/adhoc on
the same band dictates the runtime channel) into the generated config.
The hostapd daemon uses these to decide whether a channel change can be
applied via CSA instead of a full restart.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:21 +02:00
Felix Fietkau 247595eac1 hostapd: ucode: parse frequency and STA-channel radio markers
Lift the #frequency and #channel_owned_by_sta markers (emitted by the
config generator) onto config.radio and keep them out of radio.data so
they do not perturb the radio comparison. These feed the config-driven
channel switch handling added next.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:21 +02:00
Felix Fietkau a2c5be2783 hostapd: ucode: compute 6 GHz segment centre in iface_freq_info
On 6 GHz there is no HT Operation IE, so a 0 secondary-channel offset made
freq_info() return without a segment centre frequency, leaving wide-channel
switches (80/160/320 MHz) on the stale centre. Pass a null offset for wide
6 GHz channels so the centre is auto-derived.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:21 +02:00
Felix Fietkau c5c316b0ab hostapd: ucode: support 320 MHz in freq_info
uc_wpa_freq_info() rejected any operating width above 160 MHz, returning
null for EHT320 (width 3). Add the 320 MHz case; the existing segment-0
centre arithmetic (8 << width / 4 << width) extends correctly to width 3.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:21 +02:00
Felix Fietkau b92df1e8da hostapd: ucode: fix CSA bandwidth for 320 MHz and 80+80 channels
switch_channel computed the CSA bandwidth as 40 << oper_chwidth, which
mismaps oper_chwidth 3 (80+80, must be 80 MHz plus center_freq2) to 320
and 9 (320 MHz) to 20480. Map the operating channel width to the actual
MHz bandwidth explicitly.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:21 +02:00
Robert MarkoandRobert Marko 5625dadb4b airoha: an7583: update ethernet node for new PCS implementation
With new PCS implementation, the pcs property needs to be updated to the
new name of 'pcs-handle' to correctly work with PCS fwnode
consumer/provider.

Fixes: 4d5f579a81 ("airoha: update PCS node in DTSI for new PCS implementation")
Signed-off-by: Robert Marko <robert.marko@sartura.hr>
2026-07-16 11:42:02 +02:00
Robert MarkoandRobert Marko 5882239031 qualcommbe: i2c-an7581: depend only on target
i2c-an7581 (In reality its just i2c-mt7621) should depend on the airoha
target in general and not on an7581 as an7583 also uses it.

Signed-off-by: Robert Marko <robert.marko@sartura.hr>
2026-07-16 11:33:02 +02:00
Robert MarkoandRobert Marko b0a38a4c30 qualcommbe: an7583: correct I2C controller compatible
AN7583 DTS currently uses a non existant compatible that only exists in the
Airoha SDK.

It should just be changed to the generic MT7621 compatible as AN7581 uses
as well.

Signed-off-by: Robert Marko <robert.marko@sartura.hr>
2026-07-16 11:33:02 +02:00
Rosen PenevandJonas Jelonek 9e43544bc6 mpc85xx: use regulator for USB power
Use upstream solution for managing GPIO power for USB devices.

A small patch is needed to make the whole thing work as this is an older
USB driver that does not use the PHY framework.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/16842
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-15 20:25:52 +02:00
Qingfang DengandJonas Jelonek 867c857b93 kernel: disable pcrypt
The obsolete pcrypt module is being removed upstream.

Signed-off-by: Qingfang Deng <dqfext@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/24222
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-15 20:18:09 +02:00
Zoltan SzalayandJonas Jelonek 2644302c14 ath79: fix u-boot-env nvmem-layout on enterasys,ws-ap3705i
The u-boot-env0 partition on this board stores a redundant U-Boot
environment (4-byte CRC32 + 1-byte flag + data), with the flag byte
differing between the u-boot-env0/u-boot-env1 copies (0x00 vs 0x01).
The actual environment size used by U-Boot for the CRC calculation is
0x1000 bytes, not the full 0x10000 byte partition.

The DTS declared this as the plain, non-redundant "u-boot,env" layout
with no env-size, so the kernel's u-boot-env nvmem-layout driver
miscomputes the CRC and fails to probe:

  u-boot-env-layout ...nvmem-layout: Invalid calculated CRC32: 0xbc490a68 (expected: 0xfae56b95)
  u-boot-env-layout ...nvmem-layout: probe with driver u-boot-env-layout failed with error -22

Because the probe fails, the macaddr_uboot_ethaddr nvmem cell is never
created, so eth0's nvmem-cells reference never resolves and the
ag71xx-legacy platform device is stuck in "deferred probe pending"
forever - the device boots with no functioning Ethernet interface at
all.

Switch to "u-boot,env-redundant-count" (matching the redundant-env
layout already used on other boards from this vendor lineage, e.g.
qca9557_extreme-networks_ws-ap3805i.dts) and set env-size to the
verified 0x1000, which fixes CRC validation and lets eth0 probe
successfully.

Verified on real hardware: before the fix, eth0 never comes up
(confirmed against the official 25.12.5 release, matching CRC values
exactly); after the fix, eth0 links up normally and dmesg is free of
any CRC/nvmem-layout errors.

Signed-off-by: Zoltan Szalay <dealer@ddsweb.hu>
Signed-off-by: Zoltan Szalay <szazo@halycomp.hu>
Link: https://github.com/openwrt/openwrt/pull/24134
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-07-15 20:13:11 +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