Commit Graph

1868 Commits

Author SHA1 Message Date
Jonas Jelonek
80a44d6a52
realtek: pcs: reject SerDes modes unsupported by the instance
Add a per-SerDes supported_modes bitmap, filled at probe by each
variant from the SerDes id or type, and reject unsupported modes in
determine_hw_mode() via test_bit().

This replaces the rtl838x is_hw_mode_supported() switch and adds the
same gating to rtl839x/rtl93xx, which previously relied only on the
per-variant mode-value table. Unlike that table, the bitmap is per
SerDes instance, so it also rejects modes the table can encode but that
a given SerDes cannot actually use. Rejection uses the uapi -EOPNOTSUPP
instead of the internal -ENOTSUPP.

Link: https://github.com/openwrt/openwrt/pull/23608
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-06-01 09:17:15 +02:00
Jonas Jelonek
e74d236e07
realtek: pcs: drop dead SerDes modes
SerDes modes HISGMII and QHSGMII are practically dead but were added/kept
for documentation purposes. However, these modes will likely never be
used and we have other documentation than in the code. Drop them to
reduce the modes to what we actually use.

Link: https://github.com/openwrt/openwrt/pull/23608
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-06-01 09:17:15 +02:00
Jonas Jelonek
ed2a36afae
realtek: fix macro usage in F1100W-4SX-4XGT DTSI
A recent target-wide change missed the DTSI for a few devices causing a
build issue for RTL930x. Fix that.

Fixes: 43562f97e7 ("realtek: dts: add link index cell to pcs-handle phandles")
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-05-31 12:51:56 +00:00
Manuel Stocker
267886991a realtek: mdio: skip over ethernet-phy-package nodes
When we look up the PHY for each switch port, we traverse to the parent
node to find the corresponding MDIO bus. This approach breaks down
when an explicit ethernet-phy-package is used to bundle multiple
PHYs in the same chip.

Signed-off-by: Manuel Stocker <mensi@mensi.ch>
Link: https://github.com/openwrt/openwrt/pull/23591
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-05-31 13:07:38 +02:00
Jonas Jelonek
ee6e8c88dc
realtek: dsa,pcs: drop rtpcs_create
Drop the shared rtpcs_create function and references in both drivers
since that is now done via the fwnode PCS provider framework.

Link: https://github.com/openwrt/openwrt/pull/23539
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-05-31 12:52:41 +02:00
Jonas Jelonek
a4965dbf48
realtek: migrate PCS to fwnode_pcs provider/consumer API
PCS driver registers each SerDes as an fwnode_pcs provider in probe;
the resolver returns the cached or freshly-allocated rtpcs_link for
the requested (sds, link_idx) cell. DSA glue stops calling
rtpcs_create directly, drops .mac_select_pcs, and instead populates
phylink_config.num_available_pcs / fill_available_pcs from each
port's pcs-handle in phylink_get_caps. The rtl838x_port.pcs pointer
becomes a has_pcs bool populated at port probe via fwnode_property_
present, since nothing assigns the actual phylink_pcs anymore but the
"does this port use a PCS?" checks elsewhere still need a presence
flag.

Without .mac_select_pcs, phylink_major_config only searches the
pcs_list when state->interface is set in phylink_config.pcs_interfaces
(drivers/net/phy/phylink.c:1378). Populate it per port whenever the
port has a pcs-handle, listing the SerDes-routable interface modes for
each SoC variant -- without this, pcs_config / pcs_link_up are never
called and the SerDes is left unconfigured.

pcs_get_state still needs the MAC port number to index per-port link
status registers. Recover it at probe via rtpcs_map_links: walk the
sibling switch's ethernet-ports subtree (same backwards topology
lookup the sibling MDIO driver does for phy-handle), and for every
port whose pcs-handle resolves to one of our SerDes, store the port's
reg in sds->link_port[]. The resolver consults link_port[] when
allocating rtpcs_link and fails with -ENODEV if a consumer requested
a link the map step didn't record. Avoids a driver-side port_base
table that would have to encode per-SoC SerDes-to-port wiring (and
would silently break on non-contiguous variants); the DT is the
single source of truth.

Kconfig selects FWNODE_PCS.

Assisted-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Link: https://github.com/openwrt/openwrt/pull/23539
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-05-31 12:52:41 +02:00
Jonas Jelonek
c4f5c34fa4
realtek: pcs: add per-link port storage to rtpcs_serdes
Add an s16 link_port[] array to struct rtpcs_serdes, initialised to
-1 in probe. This is preparatory storage for the port number that
each link serves; it will be populated in the follow-up fwnode_pcs
migration commit by scanning consumer DT nodes for their reg, and
consumed by the resolver when allocating rtpcs_link.

Assisted-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Link: https://github.com/openwrt/openwrt/pull/23539
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-05-31 12:52:41 +02:00
Jonas Jelonek
dbd9a35bf3
realtek: pcs: index links per SerDes via pcs-handle cell
Move the rtpcs_link pointer array from rtpcs_ctrl (keyed by global
DSA port) into rtpcs_serdes (keyed by the per-SerDes link index).
This matches how the hardware is structured -- a SerDes hosts up to
RTPCS_MAX_LINKS_PER_SDS PCS links -- and aligns the in-driver
addressing with the cell the DTSes just gained on pcs-handle, so the
upcoming fwnode_pcs resolver becomes a direct sds->link[cell] lookup.

rtpcs_create() takes a new link_idx parameter and stores into
sds->link[link_idx] instead of ctrl->link[port]; the DSA glue switches
its phandle lookup to of_parse_phandle_with_args() and forwards the
cell. The port number stays on rtpcs_link for legacy callers that
still need it. Bounds and double-bind checks (-EINVAL, -EBUSY) guard
against malformed DT references that would otherwise OOB or silently
overwrite an existing link.

Drops RTPCS_PORT_CNT, whose only user was the relocated array, and
fixes a pre-existing of_node_put leak on the pcs-handle phandle in
the DSA glue as a side effect of the parse-with-args conversion.

Link: https://github.com/openwrt/openwrt/pull/23539
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-05-31 12:52:40 +02:00
Jonas Jelonek
43562f97e7
realtek: dts: add link index cell to pcs-handle phandles
A SerDes can host multiple PCS links: QSGMII binds four ports to one
SerDes, USXGMII variants up to eight. Today pcs-handle references the
SerDes as a whole, with no way to express which link inside the SerDes
a port wants. The driver gets away with this because it carries its own
port->link bookkeeping and the link slot is implicit in DSA's port
iteration order -- functional, but the wiring information lives nowhere
in DT.

The upcoming fwnode_pcs migration moves PCS lookup to the generic
fwnode provider API, which disambiguates multiple instances per fwnode
via phandle cells. To make that landable as small, code-only commits,
the DT needs to carry the link index ahead of time.

Bump #pcs-cells from 0 to 1 on every SerDes node in the four SoC DTSIs
and append the link cell to every pcs-handle reference across boards
and the SWITCH_PORT_* macros. Cell values match the existing wiring:
0 for single-link SerDes (10GBase-R, SGMII, fiber, single-link
USXGMII), 0..3 per SerDes for QSGMII and USXGMII-QX, 0..7 for the
RTL9311 octal USXGMII layout.

No code reads the new cell yet -- of_parse_phandle_with_args() in the
PCS driver already cooperates with cells = 0 or 1, and the DSA glue
uses of_parse_phandle() which ignores cells entirely. The change is
runtime-neutral on its own; it exists so the follow-up code patches
can be a few lines each instead of dragging a bridge counter into the
driver to invent slot numbers DT could have provided directly.

Link: https://github.com/openwrt/openwrt/pull/23539
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-05-31 12:52:40 +02:00
Jonas Jelonek
b3faefcc32
realtek: pcs: store SerDes fwnode instead of device_node
Switch rtpcs_serdes from struct device_node * to struct fwnode_handle *
in preparation for fwnode_pcs_add_provider, which keys providers by
fwnode. Storing the fwnode directly avoids of_fwnode_handle() wrappers
at every API boundary.

The conversion is mechanical: of_node_get/put become fwnode_handle_get/
put (same refcount on OF-backed fwnodes), polarity helpers drop their
of_fwnode_handle() wrapping, and the link counter compares fwnodes
directly via of_fwnode_handle(arg_np). No behavior change.

Link: https://github.com/openwrt/openwrt/pull/23539
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-05-31 12:52:39 +02:00
Carlo Szelinsky
d048137e85 realtek: add Hasivo MCU watchdog driver
Add a watchdog driver for the external management MCU on Hasivo /
Horaco network switches, reachable over I2C. Without periodic
keepalive the MCU resets the board every ~3 minutes.

The driver arms the MCU at probe and registers a struct
watchdog_device with WDOG_HW_RUNNING so the watchdog core feeds the
chip via a kernel timer until userspace opens the watchdog node.
Timeout is fixed at 15s; the hardware threshold is baked into MCU
firmware and is not software-configurable.

The I2C address is supplied per-board in the device tree via the
`reg` property. The driver does not constrain or probe a specific
address. Known addresses across current Hasivo / Horaco silicon:

  - 0x6F: Hasivo S1300WP-8XGT-4S+, Hasivo F5800W-12S+,
          Horaco ZX-SW82TS-L2P (default / most common)
  - 0x6E: alternate Hasivo / Horaco variant

The driver, its device-tree binding and the Kconfig/Makefile wiring
are added to the kernel tree as a realtek target patch and exposed as
the kmod-hasivo-mcu-wdt KernelPackage. Keeping the binding in the
kernel tree lets dt_binding_check exercise it during the build and
makes the whole driver easy to drop once it lands upstream.

Tested on Hasivo S1300WP-8XGT-4S+ (RTL9313). Unbinding the driver
causes the MCU to power-cycle the board within ~15s.

Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
Link: https://github.com/openwrt/openwrt/pull/23418
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-05-31 10:57:26 +02:00
Jonas Jelonek
c9406df918
realtek: fix SFP support on Plasma Cloud ESX28/PSX28
Like other RTL931x devices, the Plasma Cloud ESX28 and PSX28 also have
inverted polarity on the SerDes which drive the SFP ports. Commonly,
those always seem to have inverted TX polarity. This was missing from
when the devices were added at which time SFP on RTL931x wasn't working
at all yet. Add the polarity to the DTS now.

Verified on Plasma Cloud PSX28.

Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-05-30 21:00:12 +00:00
Markus Stockhausen
2b4503c7c9 realtek: eth: convert to page_pool
Drop the legacy receive handling and convert the driver to make
use of a zero-copy receive path. To save memory use the page
pool fragment feature. This way two SKBs will fit into one 4KB
page. With the parametrization of this patch the driver will
allocate about 600KB of receive buffers (2 rings with 300KB
each. This already includes space for the SKB header.

iperf3 benchmark gives:

RTL930x
- 1x stream send / from switch 170 Mbit -> 170 MBit
- 4x stream send / from switch 150 MBit -> 150 MBit
- 1x stream receive / to switch 320 MBit -> 400 MBit
- 4x stream receive / to switch 260 MBit -> 300 MBit

Link: https://github.com/openwrt/openwrt/pull/23483
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-05-30 08:50:00 +02:00
Markus Stockhausen
8fd3e2fbec realtek: eth: avoid TX buffer memory leak
Although never observed, a transmit timeout might happen.
In that case there is a resource leak inside rteth_tx_timeout().
This happens when rteth_setup_ring_buffer() reinitializes the
transmit buffers and overwrites all transmit slots. Any linked
SKB is lost and leaked at this point.

Be defensive and add a cleanup rteth_free_tx_buffers() function.
Call this alongside rteth_free_rx_buffers() where needed.

Link: https://github.com/openwrt/openwrt/pull/23483
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-05-30 08:50:00 +02:00
Markus Stockhausen
b0e263a5ed realtek: eth: Use right helper for SKB cleanup
There are two helpers to cleanup SKBs that call iternally
dev_kfree_skb_any_reason() but with different error codes.

- dev_kfree_skb_any() reason SKB_DROP_REASON_NOT_SPECIFIED
- dev_consume_skb_any() reason SKB_CONSUMED

The driver does not distinct between the two. Change this and
clean up a SKB that was handed over to the hardware with
dev_consume_skb_any(). This way kernel knows that everything
went well.

Link: https://github.com/openwrt/openwrt/pull/23483
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-05-30 08:50:00 +02:00
Markus Stockhausen
934de59abe realtek: eth: drop device managed netdev registration
The cleanup order of the driver is quite confusing. At least
two issues exist.

- phylink_destroy() is missing
- The implicit unregister_netdev() at the end of rteth_remove() is called
  too late. The manually managed resources are removed before. This can
  lead to stale data access.

Convert to register_netdev() and bring rteth_remove() into a meaningful
order to avoid such issues when converting to page_pool.

Link: https://github.com/openwrt/openwrt/pull/23483
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-05-30 08:50:00 +02:00
Markus Stockhausen
8508bcb42e realtek: eth: Add return value to rteth_setup_ring_buffer()
In the future this function will work on page_pool and might fail.
Add a return code to it and handle it where needed.

Link: https://github.com/openwrt/openwrt/pull/23483
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-05-30 08:50:00 +02:00
Markus Stockhausen
0a80500fb0 realtek: eth: convert to scoped_guard
In the future there will be some error paths inside locking.
Make cleanup easier by converting the sections to scoped_guard.

Link: https://github.com/openwrt/openwrt/pull/23483
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-05-30 08:50:00 +02:00
Markus Stockhausen
c5bab7288c realtek: eth: improve error handling during probe
The error handling flow during probing has some shortcomings.

1. In case an error occurs after netif_napi_add() this must be
   cleaned up with a call to netif_napi_del().
2. If devm_register_netdev() fails not only NAPI must be cleaned
   up but also the phylink.

Add a cleanup section for the probe. Implement it generically
(checking for 0/NULL values) so it can be called any time when
encountering probe failures.

Link: https://github.com/openwrt/openwrt/pull/23483
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-05-30 08:50:00 +02:00
Lars Gierth
0a907daa80
realtek: rtl930x: add support for Hasivo F1100W-4SX-4XGT and variants
This commit adds support for the Hasivo F1100W-4SX-4XGT ethernet 10Gbase and PoE switch.
It also adds support for a whole matrix of variants of this device:

| Device              | Revision | RAM    | PoE | Console  |
|---------------------|----------|--------|-----|----------|
| F1100W-4SX-4XGT     | v1.03    | 256 MB | n/a | RJ45     |
| F1100W-4SX-4XGT     | v1.02    | 512 MB | n/a | RJ45     |
| F1100W-4SX-4XGT-SE  | v1.03    | 256 MB | n/a | internal |
| F1100W-4SX-4XGT-SE  | v1.02    | 512 MB | n/a | internal |
| F1100WP-4SX-4XGT    | v1.03    | 256 MB | yes | RJ45     |
| F1100WP-4SX-4XGT    | v1.02    | 512 MB | yes | RJ45     |
| F1100WP-4SX-4XGT-SE | v1.03    | 256 MB | yes | internal |
| F1100WP-4SX-4XGT-SE | v1.02    | 512 MB | yes | internal |

The devices are identical except for presence of the PoE daughter board,
RJ45 console port, and 256 or 512 MB RAM.

The non-512 MB image also works on the older 512 MB board revisions, but not vice versa.

Credit to @mensi @bevanweiss @markc1984

Hardware
--------

|          |                                                           |
|----------|-----------------------------------------------------------|
| SoC      | RTL9303 rev B                                             |
| RAM      | 256 MB Samsung K4B2G1646F DDR3L (board revision v1.03),   |
|          | or 512 MB unknown module (board revision v1.02 and older) |
| Flash    | 32 MB Macronix MX25L25645G SPI NOR,                       |
|          | 29 MiB usable by OpenWrt                                  |
| Ethernet | 4x SFP+ via SoC (10G/2.5G/1G),                            |
|          | 4x RJ45 via 4x RTL8261BE PHY (10G/5G/2.5G/1G/100M/10M)    |
| PoE      | only on WP variants                                       |
|          | 1x 802.3bt 90 W (port 5)                                  |
|          | 3x 802.3at 30 W (ports 6, 7, 8)                           |
|          | via daughter board with Hasivo HS104PTI controller        |
|          | PoE works but is unmanaged --> future work                |
| LEDs     | 1x system orange/green, 8x link green/red, 4x PoE orange  |
| Button   | Reset                                                     |
| Console  | RJ45 38400 bps 8n1, or pin holes on SE variants           |

Installing OpenWrt
------------------

Note: With vendor firmware 7.1.9, the bootloader's network profile is broken.
We need to select a different profile with port/phy overlap to make the TFTP
transfer work. Then only port 5 works in the OpenWrt initramfs, but all ports
work fine after flashing, when we don't need the profile trick anymore.

1. Attach to RJ45 serial console port using a cisco cable.
2. Attach your computer to Port 5 (the first RJ45 port).
3. Serve initramfs-kernel.bin on TFTP 192.168.1.111.
4. Power on the device.
5. Interrupt U-Boot by pressing `Ctrl+C`, then `Z`, then `H`, during 3 second countdown.
6. Run: `setenv boardmodel 'RTL9303_5x8261BE_2XGE_ZHIHUI' ; rtk network on`
7. Run: `tftpboot 0x84f00000 initramfs-kernel.bin ; bootm 0x84f00000`
8. Use `mtd dump` to make backups of all flash partitions.
9. Use SCP to copy `squashfs-sysupgrade.bin` to the device, then run `sysupgrade`.

Restoring factory firmware
--------------------------

OpenWrt uses the `RUNTIME` and `RUNTIME2` partitions as one combined partition.
To restore them from backups, boot from `initramfs-kernel.bin` just like during
the installation, then use `mtd write` to write your backups of the factory
`mtd5` and `mtd6` partitions.

Notes/Quirks
------------

- U-Boot interruption is obfuscated. Press `Ctrl+C`, then `Z`, then `H`,
  during the 3 second countdown.
- U-Boot rtk network profile is broken. Use the `RTL9303_5x8261BE_2XGE_ZHIHUI` profile
  instead, it makes at least port 5 work.
- MAC address is stored on the `RUNTIME` or `RUNTIME2` partitions, which are used by OpenWrt.
  Instead, we generate one random MAC address and store it in the U-Boot environment.
- PoE works but is unmanaged. The HS104 driver is worked on in
  https://github.com/openwrt/openwrt/pull/22245 and will work with ethtool and the
  kernel's new `pse-pd` subsystem.

Signed-off-by: Lars Gierth <larsg@systemli.org>
Link: https://github.com/openwrt/openwrt/pull/23020
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-05-28 22:10:00 +02:00
Markus Stockhausen
fc61e795ee realtek: mach: specify alignment topology
The kernel has two helper defines that guide about hardware
characteristics.

MIPS_L1_CACHE_SHIFT defines the cache line sizes (1<<x) of the
target. It defaults to 5 - so it is assumed that the device has
a cache line size of 32 bytes. This is not true for MIPS 4KEc
cores that are driving the RTL838x SOCs. These cores have 16
byte cache line sizes. Adapt the CONFIG properties for this
target to match the hardware.

ARCH_DMA_MINALIGN definies the alignment for memory allocations.
Other than its name suggests on MIPS devices that have non
coherent DMA kmalloc() respects this configuration. This ensures
that no normal memory is corrupted by DMA blocks that share the
same cache line.

The default for this is 128 bytes. And kernel states itself
"Total overkill for most systems but need as a safe default. Set
this one if any device in the system might do non-coherent DMA".

Realtek devices use non coherent DMA so they are affected by the
setting of ARCH_DMA_MINALIGN. Set this to cache line size for
all devices to reduce memory waste.

Link: https://github.com/openwrt/openwrt/pull/23492
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-05-28 21:02:24 +02:00
Jan-Henrik Bruhn
8e724fc3b3
realtek: add support for Linksys LGS328MPCv2
Hardware specification
----------------------

* RTL9301 SoC, 1 MIPS 34KEc core @ 800MHz
* 512MB DRAM
* 2MB NOR Flash
* 128MB NAND Flash
* 24 x 10/100/1000BASE-T ports with PoE+
* 4 x 10G SFP+ ports
* Power LED, Fault LED, PoE Max LED, LAN Mode LED, PoE Mode LED
* Reset button and LED Mode button on front panel
* LM63 Fan Controller
* UART (115200 8N1) via RJ45
* PSE: Nuvoton M0516LDE via I2C + 3x RTL8238B (not supported yet)

Installation using serial interface
-----------------------------------

1. Press "a" "c" "p" during message "Enter correct key to stop autoboot"
2. Start network "rtk network on"
3. Load image "tftpboot <TFTP IP>:openwrt-realtek-rtl930x_nand-linksys_lgs328mpc-v2-initramfs-kernel.bin"
4. Boot image "bootm"
5. Switch to first bootpartition "fw_setsys bootpartition 0"
6. Download sysupgrade "scp <IP>:openwrt-realtek-rtl930x_nand-linksys_lgs328mpc-v2-squashfs-sysupgrade.bin /tmp/."
7. Install sysupgrade "sysupgrade /tmp/openwrt-realtek-rtl930x_nand-linksys_lgs328mpc-v2-squashfs-sysupgrade.bin"

Installation using OEM webinterface
-----------------------------------

This is not possible because the OpenWrt NAND Flash layout is different
from the vendor layout. To be precise. Vendor uses:

- 64 MB vendor UBI root_data
- 32 MB vendor kernel+root 1 (~19 MB used)
- 32 MB vendor kernel+root 2 (~19 MB used)

OpenWrt uses:

- 64 MB vendor UBI (not touched)
- 10 MB OpenWrt kernel
- 22 MB Openwrt mtd-concat UBI
- 23 MB vendor kernel 2 (space reduced, vendor data unchanged)
- 09 MB OpenWrt mtd-concat UBI

Dual-boot with stock firmware using writable u-boot-env
-------------------------------------------------------

From stock to OpenWrt / primary image 1 (CLI as admin):
   - > boot system image1
   - > reboot

From OpenWrt to stock / boot image 2: (shell as root)
   - # fw_setsys bootpartition 1
   - # reboot

Debrick using serial interface
------------------------------

1. Press "a" "c" "p" during message "Enter correct key to stop autoboot"
2. Load vendor image with "upgrade runtime <TFTP IP>:LGS328xxxxx.imag"
3. switch to primary partition "setsys bootpartition 0"
4. safe config "savesys"

MAC Address Source
------------------

The MAC address for this device is coming from the u-boot-env ethaddr cell.

Further documentation
---------------------
See https://openwrt.org/toh/linksys/lgs352c

Signed-off-by: Jan-Henrik Bruhn <git@jhbruhn.de>
Link: https://github.com/openwrt/openwrt/pull/23466
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-05-26 16:10:07 +02:00
Jan-Henrik Bruhn
455d73619c
realtek: dts,build: create common Linksys LGS328x DTSI and image-recipe
This is in preparation for the addition of the LGS328MPC, which is
based on the LGS328C.

It also drops the unused UBINIZE_OPTS, as UBI is only used during runtime
of the firmware, not during build.

Signed-off-by: Jan-Henrik Bruhn <git@jhbruhn.de>
Link: https://github.com/openwrt/openwrt/pull/23466
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-05-26 16:10:06 +02:00
Rosen Penev
a302626ef4
realtek: kzalloc + kcalloc to kzalloc
Use a flexible array member to combine allocations.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/22651
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-05-26 10:30:40 +02:00
Jonas Jelonek
383c4469e4
realtek: pcs: rtl930x: force IP mode OFF in deactivate, unforce for MAC modes
Make deactivate fully restore the SerDes to an inert state at both the
MAC and IP layers. Previously deactivate only zeroed the MAC mode via
set_mode(OFF), which on the default branch only writes the MAC mode
register and leaves the IP mode register untouched. The IP mode register
then retained whatever the previous bring-up left behind (force=1 with
a stale mode value, or force=0 from boot defaults), making "deactivate"
not fully deactivate the SerDes.

Replace the set_mode(OFF) call with explicit set_mac_mode(OFF) plus
set_ip_mode(OFF). The latter writes force=1 with mode=OFF, pinning the
IP block to OFF until a subsequent bring-up takes a defined action.

This forced-OFF state would break MAC-driven modes (USXGMII / QSGMII /
XSGMII), which set only the MAC mode register and rely on the IP block
following along. To compensate, add an explicit unforce of the IP mode
force-bit (page 0x1f reg 0x09 bit 6) at the start of the MAC-mode branch
of rtpcs_930x_sds_set_mode. IP-mode bring-up via apply_ip_mode is
unaffected -- it re-asserts force=1 with the target mode value, which
overrides the deactivate force-OFF.

Net result: deactivate fully and explicitly deactivates the SerDes; each
set_mode path takes its own responsibility for the IP mode register
state. The previous asymmetric behaviour (set_mode default branch silently
not touching the IP register) is now explicit code rather than an
implicit accident-of-dispatch.

Verified on RTL930x hardware: SGMII, 2500BASE-X, 10GBASE-R, USXGMII-QX
and XSGMII all bring up correctly with link, traffic and iperf3 as
expected.

Link: https://github.com/openwrt/openwrt/pull/23513
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-05-26 08:38:00 +02:00
Jonas Jelonek
788745bae5
realtek: pcs: rtl930x: lift SerDes core power-cycle into {de,}activate
Move rtpcs_930x_sds_set_power() and rtpcs_930x_sds_rx_reset() out of
rtpcs_930x_sds_apply_ip_mode() and into rtpcs_930x_sds_{de,}activate().
After this, apply_ip_mode is pure IP-mode/CMU/state-machine programming
and the SerDes-core analog power is owned by the outer phase pair, the
same place that already owns the 1G/10G PHY block and fiber RX power.

Behavioural change: USXGMII / QSGMII / XSGMII modes did not previously
go through apply_ip_mode and therefore never had the SerDes-core power
gated on mode transitions. After this commit, every mode transition
power-cycles the SerDes core via the outer deactivate/activate.

For the SGMII / 1000BASE-X / 2500BASE-X / 10GBASE-R path the set of
register writes is unchanged; only the relative ordering vs. the
fiber/PHY power writes shifts: set_power(false) now precedes those
writes (was after), set_power(true) now follows them (was before).

Verified on RTL930x hardware: SGMII, 2500BASE-X, 10GBASE-R, USXGMII-QX
and XSGMII all come up with link, ping and iperf3 throughput as
expected.

Link: https://github.com/openwrt/openwrt/pull/23513
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-05-26 08:38:00 +02:00
Jonas Jelonek
26dc5f0cad
realtek: pcs: rtl931x: run set_mode before activate
Move rtpcs_931x_sds_set_mode(sds, hw_mode) ahead of
rtpcs_931x_sds_activate() in rtpcs_931x_setup_serdes(). The IP-block
mode registers latch with the SerDes powered down, so the mode can be
committed during the configure phase rather than after power-on.

This matches the phase order already used by 838x and 930x
(deactivate -> configure -> set_mode -> activate) and is a step toward
a unified bring-up sequence across variants.

Verified on RTL931x hardware: USXGMII, SGMII and 10GBASE-R modes all
come up, link is established, L2 forwarding works, and iperf3 reports
expected throughput.

Link: https://github.com/openwrt/openwrt/pull/23513
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-05-26 08:37:59 +02:00
Jonas Jelonek
fc0fc86e55
realtek: pcs: rtl930x: fold 1G/10G PHY power into {de,}activate
Move the 1G and 10G PHY block power-up writes (clear BMCR_PDOWN on pages
0x02 and 0x04) out of rtpcs_930x_phy_enable_10g_1g() and into
rtpcs_930x_sds_activate(), and add the mirror writes (set BMCR_PDOWN) to
rtpcs_930x_sds_deactivate(). Same for the fiber RX bit.

With 1G PHY / 10G PHY / fiber RX all now handled symmetrically, drop the
rtpcs_930x_phy_enable_10g_1g() helper. The remaining write it contained
(set medium = fiber on page 0x1f reg 11 bit 1) is unrelated to power
management, unconditionally applied, and to-be-inspected for non-fiber
modes. Move it inline into setup_serdes with a TODO comment; proper
mode-aware handling is out of scope for this commit.

Behavioural note: the 1G/10G PHY blocks and fiber RX are now
power-cycled on every mode transition. Previously they were only
powered up (never explicitly down) and the state persisted across
reconfigure. The new behaviour makes each setup_serdes a standalone
bring-up that does not rely on the prior state of these bits.

Link: https://github.com/openwrt/openwrt/pull/23513
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-05-26 08:37:59 +02:00
Jonas Jelonek
c2f129599e
realtek: pcs: introduce per-variant SerDes activate helpers
Mirror of the previous sds_deactivate commit: add rtpcs_{838x,931x}_sds_activate()
helpers that each wrap the variant-specific "bring the SerDes back to operational"
block-power call at the end of setup_serdes, and replace the inline call.

 - 838x: wraps rtpcs_838x_sds_power(sds, true)
 - 931x: wraps rtpcs_931x_sds_power(sds, true)

RTL839x and RTL930x are intentionally not given an activate helper in this
commit:

 - RTL839x calls rtpcs_839x_sds_reset() at the end of setup_serdes. That is
   a reset pulse whose internals (per-type 10G/5G analog sequences, internal
   REG3 0x7146 -> 0x7106 dance) are not yet fully characterized. Aliasing
   it as _activate would misrepresent the function.
 - RTL930x has no separate activation step: rtpcs_930x_sds_set_mode(sds,
   hw_mode) is what commits the new mode and is intended to be surfaced
   as its own "set mode" phase in a later commit rather than hidden inside
   a variant-specific _activate wrapper.

Both variants will be revisited when their respective phases are clarified.
This commit is a pure refactor, no behavioural change.

Link: https://github.com/openwrt/openwrt/pull/23513
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-05-26 08:37:59 +02:00
Jonas Jelonek
c484f93a0b
realtek: pcs: introduce per-variant SerDes deactivate helpers
Add rtpcs_{838x,930x,931x}_sds_deactivate() helpers that each encapsulate
the variant-specific "make SerDes inert before reconfigure" sequence, and
replace the inline calls at the start of each setup_serdes with a single
call to the new helper:

 - 838x: wraps rtpcs_838x_sds_power(sds, false)
 - 930x: wraps rtpcs_930x_sds_set_mode(sds, RTPCS_SDS_MODE_OFF)
 - 931x: rtpcs_931x_sds_power(sds, false) + rtpcs_931x_sds_set_mode(sds,
         RTPCS_SDS_MODE_OFF)

RTL839x has no deactivate step to factor out and is left unchanged.

This is a pure refactor: same register writes, same order, same return-
value handling at the call site. The helpers give each variant a named
hook for the deactivate phase and prepare for a subsequent commit that
promotes it to an rtpcs_sds_ops entry and hoists the call site into
rtpcs_pcs_config.

Link: https://github.com/openwrt/openwrt/pull/23513
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-05-26 08:37:59 +02:00
Jonas Jelonek
e4ed8e7fe7
realtek: add support for Ubiquiti UniFi USW Aggregation
Add support for the RTL9303-based Ubiquiti UniFi USW Aggregation, an
8-port 10G SFP+ aggregation switch.

Hardware
========

  - RTL9303 SoC
  - 256 MiB DDR
  - 16 MiB SPI-NOR flash
  - 8x 1G/10G SFP+ cages
  - Per-port LEDs: 1x white LED per SFP+ cage
  - Buttons: 1x Reset
  - Console: TTL 3.3V, 115200 8N1, internal unpopulated 4-hole THT
    footprint (the device must be opened to solder a header)
    - pinout (with the front panel facing you, left to right):
      VCC/unused, RX, TX, GND
  - Front touch display (see below)
  - Software chain:
    - U-Boot (Ubiquiti-flavoured)
    - UniFi OS (OpenWrt-based)

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

Single MAC address derived from the eeprom partition. Applied to all
switch ports.

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

The unit has a touch-capable front display, driven by a dedicated
STM32-based MCU connected to the host via UART. 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. The display is therefore
not supported beyond what the stock LCM firmware offers.

Disclaimer
==========

Stock uses a dual-bank layout (kernel0/kernel1, 7 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.

The stock firmware blob is RSA-signed and cannot be flashed via the
UniFi web UI. Installation has to be done from a root shell on the
running UniFi OS.

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

1. Enable SSH on the stock UniFi OS and log in as root.

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-aggregation-squashfs-sysupgrade.bin
   K0_BLOCKS=$((0x710000 / 0x10000))

   dd if="$IMG" of=/dev/mtdblock2 bs=64k count=$K0_BLOCKS conv=fsync
   if [ "$(wc -c < "$IMG")" -gt $((0x710000)) ]; 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.

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, re-run the installation
   procedure above (the dd block, with $IMG pointing at the image on
   /tmp).

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=US.rtl930x_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, write it to both kernel banks (since
the bootselect mechanism is not yet decoded, this guarantees U-Boot
picks the stock image regardless of bank):

   dd if=kernel0.uImage of=/dev/mtdblock2 bs=64k conv=fsync
   dd if=kernel0.uImage of=/dev/mtdblock3 bs=64k conv=fsync

Link: https://github.com/openwrt/openwrt/pull/23506
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-05-24 19:32:31 +02:00
Jan Hoffmann
b20068672b
kernel: realtek: replace RTL8226 MDI swap patch by upstream version
A version of this patch has been accepted upstream, so use it here.

Link: https://lore.kernel.org/netdev/177932162564.3801238.2549776951847746974.git-patchwork-notify@kernel.org/
Signed-off-by: Jan Hoffmann <jan@3e8.eu>
Link: https://github.com/openwrt/openwrt/pull/23493
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-05-23 17:25:59 +02:00
Jonas Jelonek
15593de376
realtek: pcs: derive SerDes link count from DT at probe time
Previously, sds->num_of_links was incremented from rtpcs_create() as
each DSA port bound its phylink_pcs. The count therefore relied on a
temporal contract (DSA must finish enumerating before pcs_config runs)
and on rtpcs_create() being the single chokepoint for all consumers.

Replace this with a probe-time scan of pcs-handle references in the
live OF tree: for every available consumer node carrying a pcs-handle
property pointing at one of our SerDes subnodes, bump that SerDes'
num_of_links. After the scan, the count is final regardless of when
or whether DSA later calls in.

To allow of_parse_phandle_with_args() to walk the property correctly,
add #pcs-cells = <0> to every serdes@N node in the 838x/839x/930x/931x
.dtsi files. A future cell-bearing form remains possible without
touching the scan.

Over-references (DT pointing more consumers at one SerDes than the
hardware can carry) are clamped at RTPCS_MAX_LINKS_PER_SDS and warned
about, but do not fail probe — the correctly-wired ports on that
SerDes still come up, and only the surplus reference is dropped.

The bounds check and the bare ++ in rtpcs_create() become redundant
under the scan-driven count and are removed.

This decouples num_of_links from DSA call ordering and is a prereq
for migrating to fwnode_pcs providers, where rtpcs_create() goes away
as the centralised counter.

Link: https://github.com/openwrt/openwrt/pull/23484
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-05-23 11:02:15 +02:00
Daniel Golle
8c264cf222 generic: 6.18: drop downstream RTL8261N driver
Now that the upstream RealTek PHY driver is patched to support also
the new 5G and 10G PHYs we can start to phase-out the messy downstream
driver.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2026-05-21 17:04:55 +01:00
Balázs Triszka
6369c9e5c7 generic: net: phy: realtek: add 5G and 10G PHY support
The functionality/support for 5G and 10G PHYs was extracted from the
realtek-phy driver and ported to the upstream Linux realtek PHY driver.
These PHY chips need a sequence of register writes (and similar operations)
for initialization. These sequences are provided as firmware files which
are interpreted/applied by a new register patch engine.

By switching to the upstream driver, it should be possible to get rid of a
large chunk of (from OpenWrt perspective) unmaintained code from Realtek.
The actual Linux phy-core infrastructure from Linux can be mostly used and
only the Realtek specific quirks need to be handled.

The files which need to be provided are depending on the PHY:

* rtl8261n.bin (package "rtl8261n-firmware" or "rtl8261n-lp-firmware")
  - RTL8251L 5Gbps PHY
  - RTL8261BE 10Gbps PHY
  - RTL8261N 10Gbps PHY
* rtl8264b.bin (package "rtl8264b-firmware")
  - RTL8254B 5Gbps PHY
  - RTL8264 10Gbps PHY
  - RTL8264B 10Gbps PHY

Files which are affected by this change (DEVICE_PACKAGES dependencies,
hwmon paths, default kernel configurations, refresh of patches, ...) are
updated at the same times.

Signed-off-by: Balázs Triszka <info@balika011.hu>
Co-authored-by: Semih Baskan <strst.gs@gmail.com>
Co-authored-by: Jonas Jelonek <jelonek.jonas@gmail.com>
Co-authored-by: Gilly1970 <gilroyscott@hotmail.com>
Co-authored-by: Aleksander Jan Bajkowski <olek2@wp.pl>
Co-authored-by: Carlo Szelinsky <github@szelinsky.de>
[sven: rebase, integrate suggestions from PR, add device packages, split]
Signed-off-by: Sven Eckelmann <sven@narfation.org>
[daniel: stripped to Linux 6.18 only, dropped unrelated changes]
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2026-05-21 17:04:55 +01:00
Markus Stockhausen
c27f9b3ba0 realtek: eth: rename netdev/ndev variables to dev
Right now the driver uses variable names netdev/ndev/dev to access
a net_device structure. Align this with most of the other upstream
drivers and convert everything to dev.

Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/23420
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-05-21 12:19:47 +02:00
Markus Stockhausen
d3577dfbf3 realtek: eth: get rid of struct device
In the network context there might be confusion between "struct netdev"
and "struct device". The driver should avoid variables of type device
and name "dev" where possible. Remove all variables that point to the
device and use pdev->dev instead. This is like other network drivers
do it.

While we are here modernize logging during probing. Remove messages
from helpers and log errors during probing with dev_err_probe().

Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/23420
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-05-21 12:19:47 +02:00
Markus Stockhausen
04433b4e75 realtek: eth: better error handling in init_mac()
The function init_mac() can produce errors for the RTL931x devices.
When this happens it throws a message but continues. That can
leave the hardware in a wrong state.

Cleanup the error handling. Remove all messages from the function
and simply return an error value. In the probe() consumer evaluate
this error and abort probing if needed. As there were no reported
issues in the past it is ok to drop the detailed messages and
aggregate them in a single one.

Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/23420
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-05-21 12:19:47 +02:00
Markus Stockhausen
a1a4b09076 realtek: eth: reorganize control structure setup
Early assign pdev and netdev to the control structure during probing.
This way it can be used at any time later.

Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/23420
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-05-21 12:19:47 +02:00
Markus Stockhausen
76e47b4421 realtek: mdio: convert to scoped_guard()
Upstream netdev does not like big guards. Especially
around debugging functions. Convert to scoped_guard()
and only lock the really needed code parts. This way
all debugging can run outside of the lock.

Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/23411
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-05-21 12:10:27 +02:00
Markus Stockhausen
b8fc512a05 realtek: mdio: convert to consistent a_to_b() helpers
Majority of kernel uses a_to_b(a) instead of b_from_a(a).
Convert to that to be consistent with all helpers in the
driver. Additionally drop inline function definitions.
Let the compiler decide what is best.

Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/23411
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-05-21 12:10:27 +02:00
Markus Stockhausen
57dbfa0a9c realtek: mdio: checkpatch & documentation cleanup
checkpatch is complaining. Fix that. Additionally adapt the
documentation and move it up to the beginning of the driver.

Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/23411
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-05-21 12:10:27 +02:00
Jonas Jelonek
c166c20cf6 realtek: add hog for PHY reset for XS1930-10 and -12HP
Add a GPIO hog for those two switches to avoid having a dangling GPIO
which might be pulled accidentally breaking all PHYs, and to have that
GPIO documented.

Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/23428
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-05-21 12:08:42 +02:00
Jonas Jelonek
8d9103a420 realtek: improve DTS readability for XS1930 switches
Improve the readability of the DTS files for XS1930 switches by mostly
making nodes with only a single property a one-liner. This wastes less
visual space and makes it more fluent to read.

Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/23428
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-05-21 12:08:42 +02:00
Jonas Jelonek
ce7a5037f3 realtek: make LED set config for XS1930 more generic
The led_set node was previously duplicated in the per-device DTS for
-10/-12HP and -12F, even though all three share the same Base-T LED
encoding. Move the shared led_set with the Base-T mapping into the
common DTSI as set 0, and have XS1930-12F append its SFP-port mapping
as led_set1 via a property override. Swap the led-set index on the
-12F ports accordingly so SFP ports use set 1 and the two Base-T
ports use set 0.

Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/23428
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-05-21 12:08:42 +02:00
Jonas Jelonek
50185c8708 realtek: add additional LED for XS1930-12HP
The -12HP variant has a dedicated red LED on GPIO 3 that lights up
when the PoE budget is exhausted. Add it as led_poe_max with
function = "poe-usage" so userspace can drive it from the PoE stack.

Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/23428
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-05-21 12:08:42 +02:00
Jonas Jelonek
9114f49446 realtek: fix LED function for XS1930 switches
The cloud and locator LEDs were declared with no function (cloud) or
with the generic LED_FUNCTION_INDICATOR (locator), which doesn't
match what the hardware actually exposes. Use the descriptive
function strings "cloud" and "locator" instead so the LEDs end up
with sensible names in sysfs.

Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/23428
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-05-21 12:08:42 +02:00
Jonas Jelonek
15ff65e522 realtek: fix SYS LED for XS1930-12HP
The XS1930-12HP model from Zyxel doesn't actually use the same GPIOs for
the SYS LED. This was assumed first but proved wrong now. Instead, the
green part of the SYS LED is on another GPIO and the red part of the SYS
LED is on GPIO 0 instead of the green part. Adjust that accordingly in
the device tree.

Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/23428
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-05-21 12:08:41 +02:00
Jonas Jelonek
d750f5f454 realtek: free restore button of XS1930 switches
The support addition for those switches defined the restore button as a
button to trigger a restart. However, those switches also have a reset
button which is wired to the SoC's reset line, causing a reset upon
pressing. Thus, using the restore button for basically the same purpose
doesn't make sense. Change the 'linux,code' property to 'BTN_0' to
assign no real function to that button, allowing it to be used for
different purposes.

Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/23428
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-05-21 12:08:41 +02:00
Jonas Jelonek
161a871edd realtek: wire up GPIO fan for Zyxel XS1930 switches
The switches from Zyxels XS1930 have one or two fans in the case. They
might be controlled in a limited fashion. There's a single GPIO which -
depending on the state - drives the fan in slow or fast mode. Wire that
up as a device tree node to be able to control that in userspace.

XS1930-10 and XS1930-12HP use the same GPIO while XS1930-12F moves that
to one of its GPIO expanders. Also add 'kmod-hwmon-gpiofan' for all
three devices to be selected by default.

Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/23428
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-05-21 12:08:41 +02:00