Commit Graph
71619 Commits
Author SHA1 Message Date
Julius Bairaktaris 2bbb6cbac7 libbpf: update to 1.8.0
Release notes:
https://github.com/libbpf/libbpf/releases/tag/v1.8.0

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25725
Signed-off-by: Nick Hainke <vincent@systemli.org>
2026-10-11 09:49:28 +02:00
Yanase Yuki 9f2635e4b7 tools/expat: update to 2.9.0
Includes fixes for:
- CVE-2026-93990
- CVE-2026-102633
- CVE-2026-77214

Full changelog:
https://github.com/libexpat/libexpat/blob/R_2_9_0/expat/Changes

Signed-off-by: Yanase Yuki <dev@zpc.st>
Link: https://github.com/openwrt/openwrt/pull/25752
Signed-off-by: Nick Hainke <vincent@systemli.org>
2026-10-11 09:45:53 +02:00
Yanase Yuki 2904985666 jansson: update to 2.15.1
Full changelog:
https://github.com/akheron/jansson/blob/v2.15.1/CHANGES

Signed-off-by: Yanase Yuki <dev@zpc.st>
Link: https://github.com/openwrt/openwrt/pull/25772
Signed-off-by: Nick Hainke <vincent@systemli.org>
2026-10-11 09:45:10 +02:00
Yanase Yuki 1950d3dbfa libevent2: update to 2.1.13
This release includes fixes for:
- CVE-2026-63383
- CVE-2026-63384
- CVE-2026-63379
- CVE-2026-63382
- CVE-2026-63385
- CVE-2026-63388
- CVE-2026-63381
- CVE-2026-63387
- GHSA-5rgj-2c58-7jrc

Full changelog:
https://github.com/libevent/libevent/blob/release-2.1.13-stable/ChangeLog

Signed-off-by: Yanase Yuki <dev@zpc.st>
Link: https://github.com/openwrt/openwrt/pull/25773
Signed-off-by: Nick Hainke <vincent@systemli.org>
2026-10-11 09:44:22 +02:00
Yanase Yuki 64901feeea libjson-c: update to 0.19
This release includes fix for:
- CVE-2026-9146

No longer required patch:
- 002-cmake-version.patch

This commit also disable unused json_parse app build.

Full changelog:
https://github.com/json-c/json-c/blob/json-c-0.19-20260627/ChangeLog

Signed-off-by: Yanase Yuki <dev@zpc.st>
Link: https://github.com/openwrt/openwrt/pull/25774
Signed-off-by: Nick Hainke <vincent@systemli.org>
2026-10-11 09:43:40 +02:00
Shiji Yang ac46a4eafd uboot-tools: update to version 2026.10
Update to the latest release. Adjust the `PKG_BUILD_DIR` directory
pattern to align with upstream changes. Remove unused variable
`PKG_SOURCE_SUBDIR`. Out-of-sync server URLs have also been removed[1].

Manually rebased patch:
- 014-tools-fit_check_sign-no-decompress.patch[2]

[1] https://lore.kernel.org/u-boot/20261010142922.GI769217@bill-the-cat/
[2] https://git.u-boot-project.org/u-boot/u-boot/-/commit/79b6ee1a4b3ce9ca2db0429fc2e8dfb4110cd7e8

Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
Link: https://github.com/openwrt/openwrt/pull/25784
Signed-off-by: Nick Hainke <vincent@systemli.org>
2026-10-11 09:41:31 +02:00
Shiji Yang 24de657e0f tools/mkimage: update to version 2026.10
Update to the latest release. Adjust the `HOST_BUILD_DIR` directory
pattern to align with upstream changes. Out-of-sync server URLs have
also been removed[1].

[1] https://lore.kernel.org/u-boot/20261010142922.GI769217@bill-the-cat/

Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
Link: https://github.com/openwrt/openwrt/pull/25783
Signed-off-by: Nick Hainke <vincent@systemli.org>
2026-10-11 09:40:27 +02:00
Nick Hainke a000ba05a4 kernel: netsupport: add kmod-sched-dualpi2
Add the Dual Queue Coupled AQM (RFC 9332) queuing discipline, which
gives L4S traffic a low latency without starving classic traffic. It
is available since kernel 6.17, tc supports it already.

Link: https://github.com/openwrt/openwrt/pull/25779
Signed-off-by: Nick Hainke <vincent@systemli.org>
2026-10-11 09:36:43 +02:00
Nick Hainke 26ad76b186 kernel: netsupport: add kmod-sched-act-gate
Add the gate tc action (IEEE 802.1Qci), which passes or drops ingress
packets based on a time schedule. It is used for Time-Sensitive
Networking.

Link: https://github.com/openwrt/openwrt/pull/25777
Signed-off-by: Nick Hainke <vincent@systemli.org>
2026-10-11 09:29:58 +02:00
Nick Hainke 75db232e46 kernel: netsupport: add kmod-sched-etf
Add the Earliest TxTime First queuing discipline, which sends packets
at the time set with SO_TXTIME. It is used for Time-Sensitive
Networking, also together with taprio in txtime-assist mode.

Link: https://github.com/openwrt/openwrt/pull/25777
Signed-off-by: Nick Hainke <vincent@systemli.org>
2026-10-11 09:29:58 +02:00
Nick Hainke 08071e1036 kernel: netsupport: add kmod-sched-taprio
Add the Time Aware Priority (IEEE 802.1Qbv) queuing discipline, used
for Time-Sensitive Networking.

The Hellcreek switch driver depends on taprio, so disable it to avoid
a new config prompt.

Link: https://github.com/openwrt/openwrt/pull/25777
Signed-off-by: Nick Hainke <vincent@systemli.org>
2026-10-11 09:29:57 +02:00
Nick Hainke 63ebf08f1f kernel: netsupport: add kmod-sched-cbs
Add the Credit Based Shaper (IEEE 802.1Qav) queuing discipline, used
for Time-Sensitive Networking.

Link: https://github.com/openwrt/openwrt/pull/25777
Signed-off-by: Nick Hainke <vincent@systemli.org>
2026-10-11 09:29:57 +02:00
Nick Hainke 10837965af layerscape: armv8_64b: enable taprio and ENETC QoS offload
The Felix switch of the LS1028A is built in and depends on taprio
being built in or disabled. If taprio is built as a module, e.g. by
the upcoming kmod-sched-taprio, Felix can only be built as a module as
well and the switch is missing in the image.

Build taprio into the kernel, so that the switch stays built in and
Felix and ENETC can offload taprio, cbs and the gate action.

Link: https://github.com/openwrt/openwrt/pull/25777
Signed-off-by: Nick Hainke <vincent@systemli.org>
2026-10-11 09:29:57 +02:00
Nick Hainke 84802285f4 hostapd: pack hostapd-utils and wpa-cli in one variant only
hostapd-utils and wpa-cli use VARIANT:=*, so every variant packs them.
Since the variants are built in parallel, they write the same package
file and pkginfo files at the same time. This makes the build fail
randomly:

  Package hostapd-utils is missing dependencies for the following libraries:
  libgcc_s.so.1

Only pack them in the first selected variant that builds them.

Fixes: b029d56e0b ("hostapd: build the variants in parallel")
Link: https://github.com/openwrt/openwrt/pull/25796
Signed-off-by: Nick Hainke <vincent@systemli.org>
2026-10-11 09:26:39 +02:00
Rosen Penev af930e44d1 ath79: huawei,ap6010dn: fix PHY unit address
The PHY node is named ethernet-phy@18 while its reg is 0x4. Rename
it to ethernet-phy@4 so the unit address matches the reg, as the
AR8035 is strapped to MDIO address 4.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/25801
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-11 09:14:07 +02:00
Fil Dunsky d66966e480 uboot-mediatek: wl-wnt100x3: reduce ram speed to 1866 MT/s
The vendor BL2 of the Wavlink WL-WNT100X3 initializes DDR3 at
1866 MT/s:

  NOTICE:  BL2: v2.7(release):292bca1-dirty
  NOTICE:  DDR3 1866MHZ
  NOTICE:  EMI: Using DDR3 settings

while the plain spim-nand-ddr3 BL2 used by the ubootmod variant runs
DDR3 at the default 2133 MT/s, which is above what the vendor
qualified on this board.

Switch the ubootmod BL2 to the existing DDR3 1866 MT/s build, in line
with the vendor firmware.

Tested on WL-WNT100X3: BL2 reports the ddr3-1866 build, the memory
test passes, U-Boot and OpenWrt boot from UBI.

Fixes: d2fabb974c ("mediatek: add support for Wavlink WL-WNT100X3 ubootmod")
Signed-off-by: Fil Dunsky <filipp.dunsky@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/25763
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-11 09:06:01 +02:00
Rosen PenevandClaude Opus 5.5 68a4b32c70 bcm53xx: build qca8k as a module for Meraki MX65
qca8k was built into the kernel so the MX65's QCA8337 switches work in
failsafe. However, the QCA8337 PHY driver was not, so the internal PHYs
bound to genphy and missed the chip-specific setup in
qca83xx_config_init(), such as disabling EEE.

Switch to kmod-dsa-qca8k for the MX65 instead, which now pulls in
kmod-phy-qca83xx. Both are loaded in preinit, and the PHY driver loads
first, so failsafe keeps working and the PHYs get the right driver.
This also removes qca8k from the kernel of every other bcm53xx device.

Attach an extra patch sent upstream to use the internal MDIO, which no
longer supports generic PHY.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Rosen Penev <rosenp@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/25767
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-11 09:04:47 +02:00
Rosen PenevandClaude Opus 5.5 7f434d332a kernel: dsa-qca8k: depend on kmod-phy-qca83xx
The internal PHYs of the QCA8327/8334/8337 switches are handled by the
qca83xx PHY driver. Without it they silently fall back to genphy and
lose the chip-specific setup and fixups. Every device using
kmod-dsa-qca8k already pulls it in manually except the MikroTik
RB960PGS, which was missing it.

Add the dependency, like other DSA packages do with their PHY drivers,
and drop the now-redundant device package entries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Rosen Penev <rosenp@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/25767
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-11 09:04:47 +02:00
Shiji Yang 7782eaada2 u-boot: update PKG_BUILD_DIR for version 2026.10+
Starting with version 2026.10, the folder name inside the tarball
has changed: an additional `v` is prepended to the directory name.

Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
Link: https://github.com/openwrt/openwrt/pull/25778
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-11 08:55:47 +02:00
Rosen Penev 0b0825f9d9 ath79: dts: describe the AR8327s as switch devices
All of these AR8327s are claimed through the PHY ID by
ar8xxx_phy_probe(), which needs a plain ethernet-phy@0 node carrying
qca,ar8327-initvals, while a CPU port has to hang off a phandle to
that PHY. The switch nodes already in the tree take the other path:
ar8xxx_mdiodev_probe() claims them by compatible and the CPU port
runs off a fixed-link. Both end up with the same single swconfig
device and the same initvals.

Switch the remaining boards over to that second form, i.e. an
ethernet-switch@10 with compatible = "qca,ar8327" and reg = <0x10>.
0x10 is the first register of the AR8327 window, 0x18 being the page
select register, so that is the address to probe at. Where the phy-mode
only lived on the PHY node, move it to the MAC that took over the
link.

For zyxel,nbg6x16, wd,mynet-n750, and comfast,cf-wr650ac, fix the address
from 1f to 10. The former is for built-in 100Mbps switches. The mdio1
stuff is also irrelevant. Both ethernet interfaces are part of the switch.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/25467
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-11 08:54:31 +02:00
Rosen Penev 1724bdced2 ath79: dts: describe the AR8236s as switch devices
These external AR8236s were copied from the builtin-switch pattern
(switch0@1f). QCA9558 has no builtin switch; AR8236 register access
starts at MDIO 0x10.

Use ethernet-switch@10 with compatible = "qca,ar8236" and reg = <0x10>,
matching the other external QCA switches.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/25467
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-11 08:54:31 +02:00
Quinn O'Shea 7f31e15de4 realtek: dsa: map DSA LAG ids to zero-based trunk groups
DSA numbers LAGs from 1 to num_lag_ids. The driver uses the id as it is
to index its LAG arrays and as the hardware trunk group, both of which
start at 0. Group 0 is therefore never used and the last id is refused,
so one LAG fewer than the switch supports can be offloaded.

Accept ids from 1 to num_lag_ids and subtract one where the id becomes
a group.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Quinn O'Shea <qoshea@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/25792
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-10-11 08:54:06 +02:00
Quinn O'Shea 2433508b51 realtek: dsa: report a failed LAG leave
port_lag_leave returns 0 whatever happened, and it clears the port from
the driver's LAG masks before it asks the hardware to release it. When
the release fails, DSA is told that it worked and the driver no longer
counts the port as a LAG member while the hardware still does.

Release the port in hardware first, update the masks only when that
succeeded, and return the error, which DSA then logs.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Quinn O'Shea <qoshea@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/25792
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-10-11 08:54:06 +02:00
Quinn O'Shea 8509328d1a realtek: dsa: track the primary port of a LAG
The first member of a LAG becomes its primary port when lag_primary[]
holds -1, but the array comes zero-filled from devm_kzalloc() and is
never set to -1. Every member is therefore marked non-primary, and the
FDB and MDB code of the RTL83xx skips non-primary ports.

The leave path is wrong as well: it elects a new primary whenever any
member leaves, uses fls64(), which is one-based, as a port number, and
keeps the old primary when the last member leaves, so the next LAG with
that id starts without one.

Set every slot to -1 at probe, record the primary only after the
hardware join succeeded, and on leave elect a new primary only when the
primary itself leaves: the lowest remaining member, or -1 when the LAG
is empty.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Quinn O'Shea <qoshea@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/25792
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-10-11 08:54:06 +02:00
Quinn O'Shea c39546671e realtek: dsa: take the LAG id from the notifier
port_lag_leave looks the LAG up with dsa_lag_id(). DSA drops its
reference on the LAG before it notifies the switch, so when the last
port leaves, the LAG is already unmapped and the lookup returns -ENODEV.

Without this change, the leave is rejected as "LAG -19 invalid" and the
port stays a member of the hardware trunk. Addresses learned on it
afterwards are stored as trunk entries and frames for them are no
longer delivered, and the port cannot join a LAG again.

DSA passes the id in the notifier for exactly this reason. Use it in
port_lag_leave, and in port_lag_join for symmetry, and drop the check
for a return value dsa_lag_id() never had.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Quinn O'Shea <qoshea@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/25792
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-10-11 08:54:06 +02:00
Markus Stockhausen 60391538c7 realtek: dsa: standardize TC function prefixes
TC functions currently use a mix of rtl83xx_ and rtldsa_ prefixes.
Use otto_tc_ for generic functions and otto_tc_930x_ or otto_tc_931x_
for device-specific functions to make TC module ownership explicit.

Remove redundant tc components from the remaining function names.
Update all declarations, call sites, callback assignments and
function references in comments accordingly.

Assisted-by: ChatGPT (OpenAI GPT-6 Astra)
Link: https://github.com/openwrt/openwrt/pull/25790
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-10-11 08:48:03 +02:00
Harm Kroon 385021509d realtek: fix race condition in rtl8214fc_media_set
There is a similar race condition in rtl8214fc_media_set() as in
rtl8214fc_power_set(). It changes the base PHY's page registers in
separate MDIO bus lock sections, so another port can see the internal
page in between and restore it.

This fix holds the MDIO bus lock for the whole page-select sequence in
rtl8214fc_media_set().

Signed-off-by: Harm Kroon <hhhkroon@hotmail.com>
Link: https://github.com/openwrt/openwrt/pull/25766
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-10-11 08:47:05 +02:00
Harm Kroon 9ae0837c58 realtek: fix race condition in rtl8214fc_power_set
There is a race condition in rtl8214fc_power_set(). It reads the
extended page register (reg 30) with __phy_read() without the MDIO bus
lock. Port 0 of the RTL8214FC is the base PHY. The other ports
poll __rtl8214fc_media_is_fibre(), which sets the base PHY's reg 30 to 8
(INTERNAL) for a short time. If port 0 reads in that window, it
"restores" page 8 and stays there. Its standard registers then point to
the internal page, so no link is seen. Every later power cycle reads 8
and writes 8 again.

This fix holds the MDIO bus lock for the whole page-select sequence in
rtl8214fc_power_set().

Signed-off-by: Harm Kroon <hhhkroon@hotmail.com>
Link: https://github.com/openwrt/openwrt/pull/25766
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-10-11 08:47:05 +02:00
Gennaro Cimmino baf6e5319b realtek: pie: rtl839x: place the log index at bit 6
A PIE rule on RTL839x counts the packets it matches into the counter
named by its LOG_IDX field, bits 80:70 of the entry (Realtek GPL SDK,
rtk_cypress_tableField_list.c), which are bits 16:6 of r[14]. The
writer puts the index at bits 14:4, so the hardware reads it divided
by four, and bit 0 of the index lands in MIR_IDX.
The reader shifts the same way, so the route dump in debugfs reads the
counter the driver allocated rather than the one the hardware fills.

Write and read the index at bit 6.

Tested on an HPE 1920-48G (RTL8393) with two offloaded routes, which
got packet counters 0 and 1, and 8 echo requests through one route at
a time. Before, the requests through the second route added 8 to the
first route's counter and nothing to its own. After, each route's
counter grew by 8 for its own requests and stayed put for the other's.
Counters above 1 were not exercised.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Gennaro Cimmino <gcimmino@rayonra.net>
Link: https://github.com/openwrt/openwrt/pull/25795
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-10-10 21:36:10 +02:00
Gennaro Cimmino 1583716e42 realtek: l3: rtl839x: trap packets whose TTL runs out
What an RTL839x does with a routed IPv4 packet whose TTL runs out is
set by the IP4_TTL_EXECEED field of ROUTING_EXCPT_CTRL, and nothing in
the driver writes that register. On main, #25768 found that an echo
request with TTL 1 through an offloaded route got no Time Exceeded
from the switch, and nothing reached the gateway either.

Set the field to trap, so that the CPU gets the packet and the kernel
answers it as it would on a route it forwards itself. The encoding,
0 drop, 1 forward, 2 trap, is the one of the Realtek GPL SDK
(dal_cypress_trap.c). The other fields of the register keep their
value.

Tested on an HPE 1920-48G (RTL8393), with 10.99.1.0/24 offloaded
through a gateway behind the client's own port and 8 echo requests
with TTL 1 per case, in one boot. With the field at 2, the client got
7 Time Exceeded replies, consistent with the kernel's ICMP rate limit,
and none of the requests reached the gateway. With the field forced
to 0 through devmem, the client got no reply and nothing reached the
gateway, the symptom #25768 reported on main. Echo requests with the
default TTL still reached the gateway 8/8, TTL 63, with IPv4
forwarding off.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Gennaro Cimmino <gcimmino@rayonra.net>
Link: https://github.com/openwrt/openwrt/pull/25794
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-10-10 21:35:17 +02:00
Gennaro Cimmino eb51d41b12 realtek: dsa: let the FDB dump walk reschedule
rtldsa_port_fdb_dump() calls cond_resched() every 64 rows, but at the
end of the loop, after the "continue" that skips each row that is not
a valid unicast entry. So it only reschedules when such a 64th row
happens to hold a valid unicast entry.

DSA calls the function once per port. On the 52-port HPE 1920-48G
(RTL8393) a full "bridge fdb show" walks the 16384 rows 52 times:
96 ms per port, 5.0 s in all. With PREEMPT_NONE no other task runs
on that CPU meanwhile. When the kernel's watchdog worker, which
toggles the board's external PT7A7514, waits on that CPU, it misses
its pings and the board resets during the dump, without any console
output.

Move cond_resched() to the top of the loop, as the L3 debugfs dumps
already do, so it runs every 64 rows whatever the row holds.

Tested on the HPE 1920-48G under ping load, with full dumps. Without
this change and the dump pinned to CPU0, 20 of 20 dumps completed
with the watchdog worker on CPU1; moved to CPU0 in the same boot, the
board reset on the first dump. With this change, 20 of 20 completed
with both on CPU0, 20 of 20 with CPU1 kept busy and 20 of 20 with
nothing pinned. Across those 60 dumps no two toggles of the watchdog
GPIO were more than 0.51 s apart. Not tested on other families.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Gennaro Cimmino <gcimmino@rayonra.net>
Link: https://github.com/openwrt/openwrt/pull/25787
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-10-10 18:57:18 +02:00
Quinn O'Shea 7c8ca38c76 realtek: dsa: report multicast and broadcast frame counts
The port counters hold the multicast and broadcast frame counts, and
the frame totals are already built from them, but the fields that
report them on their own are never assigned. ethtool leaves the
multicast and broadcast members of the standard MAC statistics out, and
the multicast member of the link statistics reads zero.

Assign them from the counters that are already collected.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Quinn O'Shea <qoshea@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/25756
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-10-10 17:12:45 +02:00
Gennaro Cimmino 5d9fa15647 realtek: eth: drop the RTL839x L2 notification code
On RTL839x the ethernet driver turns on the L2 notification engine and
passes its learn and age events to the bridge. It reports them against
the conduit, which is not a bridge port, so br_switchdev_event() drops
every one of them. Nothing else reads them. RTL838x, RTL930x and
RTL931x run without this code.

Drop the notification setup, its interrupt handling and ring, and the
NIC reset code that preserved them. The vendor SDK defines no
interrupt in the mask bits this code also set on the other families:
bits 20-22 of DMA_IF_INTR_MSK on RTL838x, bits 4-6 of
DMA_IF_INTR_TX_DONE_MSK on RTL930x and RTL931x.

Tested on an HPE 1920-48G (RTL8393):
- after boot, L2_NOTIFICATION_CTRL reads 0x00001002 (engine off) and
  DMA_IF_INTR_MSK has none of bits 20-22 set;
- the switch still learns the hosts behind its ports;
- a route offloaded with IPv4 forwarding off still delivers 8 of 8
  echoes.

This does not stop the resets on a full bridge fdb show on that switch:
they happen with or without this code.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Gennaro Cimmino <gcimmino@rayonra.net>
Link: https://github.com/openwrt/openwrt/pull/25776
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-10-10 16:40:42 +02:00
Gennaro Cimmino 884ab21a3a realtek: l3: add a route dump to debugfs for RTL839x
An RTL839x has no L3 tables to dump. It routes through PIE rules that
match the destination prefix and forward to the L2 entry of the
gateway, and that entry names the ROUTING table row holding the gateway
MAC. Add realtek_otto_l3/routes for it: it walks the PIE rules and
shows each routing one with its L2 entry, its ROUTING row and its
packet counter.

The setup of the debugfs directory moves into a helper that both
families share.

Tested on an HPE 1920-48G (RTL8393) with 10.99.0.0/16 via one host
and 10.99.5.0/24 via another:
- both rows show the gateway's MAC in the L2 entry and in the ROUTING
  row, on the port that host is behind;
- 8 echoes into each prefix raise the counter of the rule that matched
  by 8;
- the counters show the /16 rule, installed first, matching 10.99.5.x
  as well, and captures saw all 8 of those echoes at the /16 gateway;
- after deleting the /24 route, only the /16 row is left.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Gennaro Cimmino <gcimmino@rayonra.net>
Link: https://github.com/openwrt/openwrt/pull/25775
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-10-10 16:33:55 +02:00
Gennaro Cimmino 86cc0a4188 realtek: pie: rtl839x: read rules back as they are written
rtl839x_pie_rule_read() does not read back what rtl839x_pie_rule_write()
writes:
- it takes the forward action, and the drop, from r[14], while the
  writer puts them in the low bits of r[13];
- it never reads the forward and log data;
- it reads the masks of the templated fields word aligned, while the
  writer puts them 8 bits up;
- it puts the two halves of the destination address in the wrong
  order and builds the mask from the address.

Read all of these back from where the writer puts them. The hardware
follows the writer: the routes it programs on an HPE 1920-48G (RTL8393)
forward to their next hop.

Nothing reads a PIE rule back on RTL839x yet, so this changes no
behaviour. The RTL839x L3 debugfs added next uses it.

Checked on that switch through the debugfs dump of the next commit:
- the rules of 10.99.0.0/16 and 10.99.5.0/24 read back as these
  prefixes, with the L2 index of their gateway;
- their raw words hold forward action 6 in the low bits of r[13];
- their masks sit 8 bits up, as written.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Gennaro Cimmino <gcimmino@rayonra.net>
Link: https://github.com/openwrt/openwrt/pull/25775
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-10-10 16:33:55 +02:00
Paul Spooren 936617ab59 tfa-layerscape: pad the byte swapped PBL with zeros
The firmware images of Layerscape boards booting from QSPI, e.g. the
LS1046A-FRWY, differ between builds in 4 bytes at the end of the PBL:

  -00009e80: 019f 1e98 0000 0000 0000 0000 0000 0000
  +00009e80: e10f e4a8 0000 0000 0000 0000 0000 0000

byte_swap pads the PBL to a multiple of 8 bytes from a 4 byte variable,
so fwrite() reads up to 4 bytes of the stack past it, and an aligned
PBL always gets 8 bytes appended, 4 of them random.

Add a patch that pads with an 8 byte buffer of zeros. The output keeps
its length and layout: for an aligned input only the 4 former random
bytes become zeros, an unaligned input gives the same output as before.

Link: https://github.com/openwrt/openwrt/pull/25720
Signed-off-by: Paul Spooren <mail@aparcar.org>
2026-10-10 13:04:55 +02:00
Paul Spooren b71d03a79c openssl: probe the cross compiler regardless of the host CC
libopenssl3 differs between builds depending on the environment of the
build host, e.g. in the images of the Turris Omnia:

  -compiler: arm-openwrt-linux-muslgnueabi-gcc -fPIC -pthread -Os ...
  +compiler: arm-openwrt-linux-muslgnueabi-gcc -fPIC -pthread -Wa,--noexecstack -Os ...
  -  GNU_STACK ... RWE 0x10
  +  GNU_STACK ... RW  0x10

Configure probes whether the assembler supports --noexecstack by running
$CROSS_COMPILE$CC, with CC taken from the environment. A host which sets
CC to select its compiler, e.g. CC=gcc-13, makes it run
arm-openwrt-linux-muslgnueabi-gcc-13, which does not exist, so the flag
is silently dropped and libcrypto ends up with an executable stack.

Pass CC=gcc to Configure, so that it always probes the cross compiler.
With CC=gcc-13 in the environment, the configuration now gets
-Wa,--noexecstack like a build without CC set.

Link: https://github.com/openwrt/openwrt/pull/25719
Signed-off-by: Paul Spooren <mail@aparcar.org>
2026-10-10 13:04:30 +02:00
Julius Bairaktaris 53ec2d05a4 qualcommax: qca_ppe: add 10 and 100 Mbps half duplex
The ports list only full duplex in their MAC capabilities, so the PHY
advertises no half-duplex mode. A link partner with autonegotiation off
is found by parallel detection, which resolves to half duplex, and the
port does not link.

Add MAC_10HD and MAC_100HD to ports 1-6. The GMAC programs half duplex;
USXGMII runs on the XGMAC, which has no duplex setting, so
mac_get_caps() removes both modes for that interface.

On a Xiaomi AX3600 (QCA8075) with the partner forced to 10 or 100 Mbps,
the port stays down before the change and links at half duplex after
it, 3/3 runs each.

Closes: https://github.com/openwrt/openwrt/issues/25657
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25750
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-09 23:04:41 +02:00
Julius Bairaktaris ee6860ee0f qualcommax: pcs: qca-uniphy: clear the mode select for SGMII on UNIPHY0
On the PSGMII instance (UNIPHY0 on IPQ8074 and IPQ6018), SGMII and
1000BASE-X run with every mode select bit of UNIPHY_MODE_CTRL clear, as
qca-ssdk's __adpt_hppe_uniphy_sgmii_mode_set() programs it. The driver
sets UNIPHY_SGMII_MODE there instead, and the Zyxel NWA110AX, whose
AR8033 sits on UNIPHY0 channel 0, transmits nothing.

Leave the mode select clear on the instance with a clock pair per
channel, and report 125 MHz for that setting in the clock recalc.
Writing 0x20 or 0x21 to the register on the NWA110AX restores TX.

Closes: https://github.com/openwrt/openwrt/issues/25657
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25750
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-09 23:04:41 +02:00
Gennaro Cimmino c09cb2f80f realtek: dsa: rtl839x: add a port to its own isolation mask
The RTL839x applies a port's isolation mask to every frame that came in
on it, routed ones included. The driver leaves the port out of its own
mask, so a route offloaded through a gateway behind the port a packet
came in on, such as routing between two VLANs of one trunk, drops
everything: the kernel shows the route as offloaded, and the drop
counter PORT_ISOLATION counts each packet.

Keep the port in its own mask, as the GPL SDK does at init
(_dal_cypress_port_init_config() sets every port's mask to all ports).
A broadcast is still not sent back out of the port it came in on. Only
RTL839x changes; the other families keep their masks as they are.

Tested on an HPE 1920-48G (RTL8393), with 10.99.1.0/24 routed from VLAN
7 to a gateway on VLAN 3, both behind lan48. On main, 0/8 echo requests
reached the gateway, even with IPv4 forwarding on in the kernel. With
this change and forwarding off, so that only the hardware path delivers,
8/8 arrived, TTL 63, from the switch MAC. Routing to a gateway behind
lan47 still delivers 8/8. Two bursts of 50 broadcasts entering lan48
added nothing to its tx_BroadcastPkts, while the same entering lan47
added 50 and 53.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Gennaro Cimmino <gcimmino@rayonra.net>
Link: https://github.com/openwrt/openwrt/pull/25764
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-10-09 22:40:46 +02:00
Gennaro Cimmino 9b2d17a1b6 realtek: l3: rtl839x: route with the switch's own MAC
otto_l3_839x_setup_port_macs() fills the RTL839x routing source MAC
table with the switch MAC plus one, plus two and so on, a leftover
marked "BUG: VRRP for testing". A route only ever names entry 0, since
switch_mac_id is never set, so every frame the switch routes in
hardware leaves with the switch MAC plus one, a MAC that no interface
of the switch has.

Write the switch MAC as it is. That is what the GPL SDK puts in entry 0
when it sets the switch MAC (dal_cypress_switch_mgmtMacAddr_set(),
"Patch: Set router mac entry 0").

Tested on an HPE 1920-48G (RTL8393), with 10.99.1.0/24 routed between
VLAN 7 on lan48 and a gateway on VLAN 3 on lan47, and IPv4 forwarding
off in the kernel so that only the hardware path delivers. On main, 8/8
echo requests reached the gateway with the switch MAC plus one in the
last byte as their source. With this change, 8/8 arrived with the switch
MAC.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Gennaro Cimmino <gcimmino@rayonra.net>
Link: https://github.com/openwrt/openwrt/pull/25759
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-10-09 22:15:57 +02:00
Felix Fietkau ae9276426c ucode: rtnl: return true on acknowledged requests without data
Fixes error handling issues on requests

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-10-09 20:46:24 +02:00
Quinn O'Shea 83e12ff35f realtek: rtl930x: add support for Lianguo LG-SWTGW3C8F
The Lianguo LG-SWTGW3C8F is an eight-port SFP+ managed switch based on
the Realtek RTL9303. It is the same vendor board as the Horaco
ZX-SWTGW2C8F and the GoodTop GT-SWTXG8FM (boardmodel RTL9303_8XGE in
the U-Boot environment) and uses the Horaco device tree unchanged.

Device specification:
- SoC: Realtek RTL9303
- RAM: 128 MiB DDR3, Winbond W631GG6KB-12
- Flash: 16 MiB SPI NOR, Winbond W25Q128
- Ethernet: 8x SFP+ cages
- Button: reset, GPIO 5 active-low
- System LED: GPIO 0
- Console: RJ45 RS-232 port, 115200 8N1
- Power input: 12 V DC
- Bootloader: Realtek U-Boot 2011.12 (1.0.0.2)
- Vendor firmware: KT-NOS 1.1.1.30
- Vendor board model: RTL9303_8XGE

The flash layout is the Horaco's. The MAC address is read from ethaddr
in BDINFO through NVMEM. The vendor firmware and bootloader use the
uImage magic 0x83800000, like the Horaco.

Installation from the vendor web interface:
1. Open Management -> Firmware -> Manual Upgrade.
2. Select the action Upgrade and the method HTTP.
3. Upload the squashfs-factory.bix image.
4. Wait for "Upgrade Image Done", then reboot the switch.

Installation over the serial console:
1. Put the initramfs-kernel.bin image on a TFTP server that is reached
   through one of the SFP+ cages. The cages are switch ports 0, 8, 16,
   20, 24, 25, 26 and 27; the commands below use the eighth one.
2. Stop the bootloader with ESC at the autoboot prompt and enter:
     rtk network on
     rtk ext-devInit 0
     rtk 10g 27 fiber10g
     setenv ipaddr <address of the switch>
     setenv serverip <address of the TFTP server>
     tftpboot 0x84f00000 <name of the initramfs image>
     bootm 0x84f00000
3. Write the squashfs-sysupgrade.bin image with sysupgrade from the
   running system.

Return to the vendor firmware: with a backup of the 12 MiB firmware
partition taken before OpenWrt was installed, copy it to
/tmp/RUNTIME.bin under OpenWrt and write it back:

  mtd -f write /tmp/RUNTIME.bin firmware
  mtd verify /tmp/RUNTIME.bin firmware

Tested on hardware: both installation routes, sysupgrade, the return
to the vendor firmware, the MAC address, a 10G link over a DAC in each
of the eight cages and a 1G link over fibre, each with its port LED
(blue at 10G, green at 1G), the system LED and the reset button. With
an SR module and no fibre the port reports loss of signal, and the
laser goes off when the port is set down. A 2.5G link over fibre came
up as well, with a local SFP quirk for the module that is not part of
this change.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Quinn O'Shea <qoshea@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/25715
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-10-09 19:34:23 +02:00
Markus Stockhausen fe25904cd1 realtek: dsa: unify LAG function naming
LAG helpers use inconsistent prefixes and placement of the lag component.

Use otto_lag_ for generic functions and otto_lag_<family>_ for device
and family helpers, retaining 83xx and 93xx for shared implementations.
Remove redundant lag components so each function name contains lag once.

Update all declarations, call sites, callback assignments and the
outdated function reference in a comment.

No functional changes intended.

Assisted-by: ChatGPT (OpenAI GPT-6 Astra)
Link: https://github.com/openwrt/openwrt/pull/25755
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-10-09 19:28:58 +02:00
Gennaro Cimmino 0ef832f34e realtek: l3: trap main routes inside a local IPv6 prefix
With more than one IPv6 table, the kernel also looks the local table up
before main, so a local IPv6 prefix (AnyIP: ip -6 route add local ...
table local) takes the destinations of a longer main route inside it.
The switch matches the longest prefix and forwards them. Commit
bf54d898c7 ("realtek: l3: trap main routes inside a local prefix") made
such a route trap for IPv4 only.

otto_l3_local_covers() now looks at local prefixes of both families. So
that a local prefix that comes or goes is seen for IPv6 too,
otto_l3_route_inside(), otto_l3_gw_seen() and
otto_l3_local_prefix_check() take the struct fib_notifier_info both
notifier infos start with, and tell the family from it. The IPv6 FIB
work calls otto_l3_local_prefix_check() after an add or a delete, and
the check no longer skips a prefix of length zero: otto_l3_fib_trap_v6()
gives a local ::/0 a row, which otto_l3_local_covers() counts as
covering every main route. An IPv4 local default route gets no row from
otto_l3_fib_trap_v4(), so for it the check only resolves the gateways
again and every route stays as it was. Without IPV6_MULTIPLE_TABLES the
local routes are in main, where the kernel matches the longest prefix
as the switch does, and they are not taken for local ones. Otherwise
IPv4 behaves as before.

Tested on a Hasivo S1100W-8XGT-SE (RTL9303), with 2001:db8:1:0:1::/80
via a gateway on switch.3 and echo requests to eight addresses inside
it captured at the gateway. With ip -6 route add local 2001:db8:1::/64
dev lo table local, main kept the row forwarding and all 8/8 reached the
gateway, whether the local prefix came before or after the route. With
this change the row traps and 0/8 reach it, in both orders. Without the
local prefix both forward 8/8. The same run of the IPv4 case traps on
both, as before. That run predates the zero-length part. In a run of
the final change, a local ::/0 made the row trap with 0/8 reaching the
gateway, and once it went the row forwarded 8/8 again.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Gennaro Cimmino <gcimmino@rayonra.net>
Link: https://github.com/openwrt/openwrt/pull/25753
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-10-09 15:59:08 +02:00
Gennaro Cimmino e4974473db realtek: l3: move routes to the new MAC of their device
A route's egress interface carries the source MAC that routed frames go
out with, taken from the route's device when the route is added. When
the device then takes a new MAC, NETDEV_CHANGEADDR updates the router
MAC table, but the routes already through it keep their interface, and
hardware-forwarded frames keep leaving with the old source MAC. That
breaks anything that filters on it.

On NETDEV_CHANGEADDR, give every route out of the device the new MAC.
An egress interface that only routes out of the device takes it in
place, which needs no free interface. Otherwise the route moves to an
interface with the new MAC, through the same refcount, and the next hop
it has programmed is pointed at it before the old interface is let go;
if no interface is left, the log says once that they keep the old MAC.
This runs on the queue that the neighbour work runs on, since that work
writes the same next hops, and under RTNL, as the FIB work does. A
device left with no valid MAC (a bridge with no port) keeps its routes
as they are until it gets one back. Only a family with a router MAC
table has the notifier.

Tested on a Hasivo S1100W-8XGT-SE (RTL9303): with 10.99.87.0/24
forwarding through switch.3, switch.3 took a new MAC. On main the routed
echo requests kept arriving with the old source MAC (8/8); with this
change they came with the new one (8/8).

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Gennaro Cimmino <gcimmino@rayonra.net>
Link: https://github.com/openwrt/openwrt/pull/25739
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-10-09 14:01:05 +02:00
Gennaro Cimmino ba306e22a6 realtek: l3: move otto_l3_netdev_notifier() down
Move the netdevice notifier below the egress interface helpers, so that
the next commit can call them from it without a forward declaration.
This is a pure move, with no functional change.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Gennaro Cimmino <gcimmino@rayonra.net>
Link: https://github.com/openwrt/openwrt/pull/25739
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-10-09 14:01:05 +02:00
Gennaro Cimmino 31c2a5e405 realtek: l3: leave a prefix route alone once rows are stale
A row move that fails partway, or a lookup that times out, leaves the
prefix rows no longer where the route list says, which prefix_rows_stale
records. Placing stops there, but a route that already has a row is
still written there when a neighbour update, a trap or the policy rules
change it, and that row may hold another route by now: the write
replaces a live route.

Once the rows are stale, a prefix route whose row no longer reads back
as it, checked with otto_l3_route_is_at(), is left as it is: both what
it says and its row. otto_l3_route_update_hw() and
otto_l3_route_trap_hw() pass it by, and so does otto_l3_rules_check()
when it suspends forwarding, so nothing is written over the other
route; resuming only asks for the gateway, and the update that follows
goes through otto_l3_route_update_hw(). A route whose row still reads
back as it is updated as before, route and row together, so its removal
still finds it. The two messages that mark the rows stale say "no
prefix route will be placed again" instead of "no route": host routes
still are. Nothing changes while the rows are not stale.

Compile-tested for rtl930x, rtl838x and rtl839x. The stale state needs a
table engine timeout, which was not reproduced, so this path was not
exercised on hardware. An earlier form of this change, which left every
placed prefix route alone, passed the route offload regression run for
the earlier L3 changes (46/46) on an RTL9303 build carrying the other
fixes from issue 25731.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Gennaro Cimmino <gcimmino@rayonra.net>
Link: https://github.com/openwrt/openwrt/pull/25738
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-10-09 13:03:18 +02:00
Gennaro Cimmino 76e9e7ef2a realtek: l3: match a route's row whatever its action
otto_l3_route_is_at() decides whether a row still holds a route, and
among other fields it compares the row's action with the route's. The
action is what the route last asked for, not what tells the row apart:
when a write of the route does not land, such as a table write that
times out after the route already says trap or forward, the row keeps
the old action and is taken for another route. Removing the route then
logs "row %d holds another route" and leaves the row valid in hardware.

The next hop index already tells two routes for one destination apart.
A route that forwards carries its own id; two routes share one only
when neither gateway has resolved, and then both trap. Drop the action
from the comparison.

Compile-tested for rtl930x, rtl838x and rtl839x. A write that does not
land needs a table engine timeout, which was not reproduced. Where the
write lands, the row's action and the route's are the same, so nothing
changes there.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Gennaro Cimmino <gcimmino@rayonra.net>
Link: https://github.com/openwrt/openwrt/pull/25738
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-10-09 13:03:18 +02:00
Gennaro Cimmino aa017eb1c4 realtek: l3: move otto_l3_route_is_at() up
Move otto_l3_route_is_at() above the code that writes routes, so that
the next commit can use it there without a forward declaration. This is
a pure move, with no functional change.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Gennaro Cimmino <gcimmino@rayonra.net>
Link: https://github.com/openwrt/openwrt/pull/25738
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-10-09 13:03:17 +02:00