Commit Graph
36832 Commits
Author SHA1 Message Date
Shine- GH 4e16c2ed8f realtek: rtl838x: add support for Netgear GS110TPv3
The Netgear GS110TPv3 is a 10-port gigabit managed switch with 8x RJ45
ports and 2x SFP cages. All 8x RJ45 ports are PoE+ capable.

This switch is similar to the already supported GS108Tv3 and GS110TPP
models and even shares its stock firmware with these two. SFP cage
configuration, on the other hand, is identical to the GS310TP.

SoC:         RTL8380M, 500MHz
RAM:         128MB DDR3
Flash:       32MB SPI-NOR
Ethernet:    8x 1GBE RJ45
             2x 1GBE SFP Cages
PoE:         8x PoE+ via Nuvoton controller, 55W total power budget
UART:        onboard, unpopulated (J1), 115200/8N1, 3.3V
LEDs:        1x dual color green/amber power LED, GPIO controlled
             1x amber PoE-Max and 8x green/amber PoE port LEDs
             - handled by PoE controller
             8x green/amber port status LEDs, unsupported in OpenWrt
             - handled by RTL8231 GPIO expander (see install instructions)
MAC address: base MAC from "ethaddr" U-Boot env variable, additional port
             MACs assigned incrementally.

Installation instructions:

1. Install OpenWrt initramfs firmware to the "Image1" firmware slot via
   vendor web GUI.
2. If not already so, set next startup firmware to "Image1" ("Activate"),
   then reboot.
3. After booting into OpenWrt initramfs firmware, access the device at IP
   192.168.1.1 and install the OpenWrt sysupgrade image.
4. Device automatically reboots once again into OpenWrt.
5. (Optional) To enable default port LED handling, change boot command by
   running in OpenWrt CLI: fw_setenv bootcmd "rtk network on; boota"
   Note: This may cause VLAN leaking during boot.

Back to stock:

1. Reset boot command to stock: "fw_setenv bootcmd boota"
2. Change to secondary firmware partition: "fw_setsys bootpartition 1"
3. Reboot. Device will now boot into stock firmware.
3. (Optional) Revert to stock firmware also for "Image1" firmware slot via
   vendor web GUI.

Signed-off-by: Shine- GH <4c.fce2@proton.me>
Link: https://github.com/openwrt/openwrt/pull/26006
Signed-off-by: Jonas Jelonek <jonas@jonasjelonek.de>
2026-10-19 21:31:27 +02:00
Kaloyan Naumov 46309f1396 realtek: add support for Horaco ZX-SWTGW2C48NS
Add support for the Horaco ZX-SWTGW2C48NS, also sold as the HRUI
HR-SWTGW2C48NS and the SODOLA SL-SWTGW2C48NS.

Hardware
--------
 * SoC: Realtek RTL9313
 * RAM: 512 MiB (2 x 256 MiB window, as in the DTS)
 * Flash: 32 MiB SPI NOR; U-Boot, two environment blocks, two stock
   configuration partitions (jffs, jffs2), the 28 MiB firmware partition
   (RUNTIME1) and a 1 MiB OEMINFO partition
 * Ethernet: 4 x 10GBASE-T (RTL8264B PHY), 8 x SFP+ (10GBASE-R)
 * Fan and temperature controller: ADT7476 on I2C
 * Console: internal UART header, 38400n8 in the kernel (U-Boot itself
   uses 115200). The exact location and pinout were not recorded.
 * Power: internal AC power supply
 * Buttons: reset
 * LEDs: per-port LEDs through the SoC LED controller; system LED

The ports are wired for three LEDs each, of which two are fitted, so the
LED set carries an unused first entry. The port LEDs also need the
controller in single-colour scan mode, set through realtek,led-mode; the
rtl931x driver reads that property since "realtek: rtl931x: set the LED
interface mode from realtek,led-mode". The system LED is taken off
hardware control and driven as a GPIO LED.

The SFP+ transmit pairs are polarity-inverted. The SFP LOS signals are
not wired to a known GPIO. The four copper PHYs need the rtl826x
firmware; without it their ports do not come up.

The fan is left to the ADT7476 closed loop. hwmon_fancontrol now has
one function for the ADT747x, shared with the PlasmaCloud ESX28/PSX28
(their values are unchanged), which finds the chip on whichever I2C bus
it sits. On this board it uses all three temperature channels, duty 40
(the stock idle speed; the fan is not stable lower) from 45 C up to
full duty at 71.67 C (the chip's range step nearest 70 C), keeps the fan
at duty 40 below 45 C, and sets the critical limit to 85 C.

MAC address layout
------------------
A single address is stored in the U-Boot environment (ethaddr) and is
read through nvmem for ethernet0, which is also the label MAC. It is
applied to all ports, as the stock firmware does.

Installation
------------
The bootloader and the stock updater require the Realtek SDK uImage
magic 0x83800000, which factory.bin carries. Upload the factory image
through the stock web UI's manual firmware upgrade page (its TFTP-client
upgrade accepts the same image), then reboot from Diagnostics > Reboot:
the stock firmware does not reboot by itself. Only the RUNTIME1
partition is written; U-Boot, its environment and OEMINFO are kept.

Later upgrades use the sysupgrade image.

To return to stock, run "sysupgrade -F -n" with a vendor image. -F is
needed because a vendor image carries no OpenWrt metadata; it also
skips every image check, so first confirm the image starts with the
uImage magic 0x83800000 (for example with "hexdump -C -n 4").

Assisted-by: Claude:claude-opus-5
Assisted-by: Claude:claude-fable-5
Assisted-by: Claude:claude-sonnet-5-5
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Kaloyan Naumov <knaumov@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/25575
Signed-off-by: Jonas Jelonek <jonas@jonasjelonek.de>
2026-10-19 19:54:08 +02:00
Markus Stockhausen a32de27382 realtek: dsa: standardize QoS function names
Rename all QoS functions, including static helpers, to use the
otto_qos_ prefix. Use otto_qos_<family>_ for chip-specific functions
and otto_qos_83xx_ for the shared RTL83xx helper.

Update header declarations, internal calls and per-chip function
tables to match the new names.

No functional changes intended.

Assisted-by: ChatGPT (OpenAI GPT-6 Astra)
Link: https://github.com/openwrt/openwrt/pull/25974
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-10-19 18:33:12 +02:00
Gennaro Cimmino 35c2081044 realtek: dsa: rtl839x: offload 802.1ad bridges
RTL839x refuses 802.1ad bridges, although it has the provider port
blocks RTL930x uses for them (cypress SDK): a TPID pool, outer TPID
compare masks per port, an outer/inner forwarding bit per port and the
tag status with its keep bits. A port that joins an 802.1ad bridge now
parses S-TAGs (pool entry 0, 0x88a8), switches on the outer VID, sends
the outer tag of the VLAN table and keeps the customer's tag on ingress
and egress. Leaving the bridge restores the 802.1Q state.

Nothing is set up at boot, unlike on RTL930x. The TPID pool, the inner
compare masks and the egress TPID indexes keep their values after boot,
which the vendor SDK does not program either; HPE 1920-48G reads
0x88a8/0x8100 in all four pool entries and index 0. The CPU port needs
no outer compare: frames it sends with an S-TAG leave a provider port
with that tag.

HPE 1920-48G (RTL8393), lan48 and lan47 in an 802.1ad bridge, a host
behind lan48 with an 802.1ad VLAN 200 interface, the switch address on
VLAN 200: 8 of 8 pings get a reply that leaves lan48 with an outer
0x88a8 tag, VID 200; with an 802.1Q tag none does. The host's ARP in
S-VLAN 200 leaves lan47, with the S-TAG, only once lan47 is in VLAN 200,
and a C-TAG 10 inside it stays (without the egress keep on lan47 it is
stripped); the host's untagged ARP does not leave lan47. Changing the
bridge to 802.1Q is refused, and after leaving the registers read as
before the join. Not tested: traffic at line rate, a port untagged in
an S-VLAN.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Gennaro Cimmino <gcimmino@rayonra.net>
Link: https://github.com/openwrt/openwrt/pull/25992
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-10-19 18:29:19 +02:00
Gennaro Cimmino 8e5b068481 realtek: dsa: rtl839x: fix the VLAN_PORT_FWD bit of a port
otto_vlan_839x_port_forward_on_inner() addresses VLAN_PORT_FWD with the
big-endian port accessor, which puts ports 0 to 31 in the second word.
The register holds one bit per port, port p at bit p % 32 of word p / 32
(VLAN_PORT_FWD in the cypress register list of the vendor SDK, which
addresses such arrays in ascending word order), so the little-endian
accessor is the right one.

So far the function only clears bits, at setup for every port but the
CPU port. With the fix the loop clears ports 20 to 31 too and no longer
clears the CPU port's bit; on HPE 1920-48G both words read 0 after boot
with and without this change. The 802.1ad provider port role needs to
set a port's bit.

HPE 1920-48G (RTL8393), lan48 (port 47) as an 802.1ad provider port on
a test build of that role: with its bit at 0x27B0 bit 15 the S-VLAN
stays off lan47; moved by hand to 0x27AC bit 15, where this function
wrote it, lan48 forwards on the inner VID and the frames leak out of
lan47.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Gennaro Cimmino <gcimmino@rayonra.net>
Link: https://github.com/openwrt/openwrt/pull/25992
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-10-19 18:29:19 +02:00
Gennaro Cimmino e4c5f850ee realtek: dsa: drop untagged frames of ports without PVID
Every port is a member of VID 0, so that the frames the CPU sends with
its PVID 0 reach the ports with untagged VLANs. A port without PVID
keeps PVID 0 too, so in a VLAN-filtering bridge its untagged and
priority tagged frames land in VID 0 and are flooded to the other ports
of the bridge, tagged VID 0, where the bridge would drop them.

The acceptable frame type of a port tells the two apart (one bit each
for inner and outer, tagged and untagged frames; vendor SDK). While a
port without PVID is in a VLAN-filtering bridge, it accepts only tagged
frames, outer tagged ones as an 802.1ad port; standalone ports, which
can have VLAN filtering on, and every other state accept all. The
driver tracks the bridge membership itself, since DSA rolls back a
failed join through port_bridge_leave() before it clears dp->bridge.
VID 0 and the CPU path stay as they are. The register has this layout
on all four families; only RTL839x sets its address here, the others
keep their behaviour until tested.

HPE 1920-48G (RTL8393), lan48 a UCI trunk with VLAN 3 and 7 tagged,
lan47 an access port in VLAN 1: untagged and priority tagged ARP from
the host behind lan48 left lan47 tagged VID 0, 3 of 3 each; now none
does. STP, LLDP, LACP and EAPOL frames on lan48 still reach the CPU,
5 of 5 each, and VLAN 3 tagged frames pass. With a PVID on lan48 again,
and in a bridge without VLAN filtering, the ARP leaves lan47 untagged;
as standalone ports both accept all frames again.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Gennaro Cimmino <gcimmino@rayonra.net>
Link: https://github.com/openwrt/openwrt/pull/25992
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-10-19 18:29:19 +02:00
Alan Gao 14423144a5 qualcommax: ipq50xx: fix Wallys DR5018S Wi-Fi
The DR5018S uses the integrated IPQ5018 radio and two QCN6122 radios.
Move its calibration handlers to the matching IPQ5018 and QCN6122
firmware cases and use the corresponding ART blocks.

The ART blocks already contain the radio MAC addresses; remove the
redundant read-and-write operations.

Extend q6_region to cover the BDF and M3 dump addresses used by the
second QCN6122. Without this, its BDF address lies outside the reserved
WCSS region and the 6 GHz radio fails with "qmi ioremap error for
bdf_addr".

Tested on a Wallys DR5018S: all three radios register with their ART
MAC addresses and continue working after reboot.

Signed-off-by: Alan Gao <1226010136@qq.com>
Link: https://github.com/openwrt/openwrt/pull/25950
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-19 14:36:25 +02:00
Daniel Golle 231074c38b x86: 64, generic: set the fbdev drivers off
Without CONFIG_FB in the subtarget configs, kmod-fb builds FB as a
module, which makes XEN_FBDEV_FRONTEND and FB_HYPERV visible with no
value in any config. A non-interactive kernel build then stops at the
syncconfig prompt for XEN_FBDEV_FRONTEND, which defaults to m on these
subtargets because XEN is enabled.

Set both drivers off: simpledrm, hyperv_drm and the hvc console cover
the display of these guests.

Fixes: b091137d79 ("x86: 64, generic: replace fbdev with simpledrm")
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2026-10-19 12:16:38 +01:00
Daniel Golle 93c11db78a armsr: drop the kernel virtual terminal
The kernel virtual terminal serves a framebuffer or VGA text console and
the console hotkeys in drivers/tty/vt/keyboard.c: Alt+Fn and Ctrl+Alt+Fn
switching, Ctrl+Alt+Del, SAK and the show-state keys. With fbdev gone
there is no console on it, while the hotkeys stay live on any attached
keyboard, which on an appliance means an unauthenticated reboot.

Drop CONFIG_VT and the symbols that depend on it. The serial console and
/dev/console are untouched, and a userspace terminal such as kmscon needs
no VT: it falls back to its fake VT backend and reads input from evdev.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2026-10-19 12:15:51 +01:00
Wojciech Zwolinski bf5c535c42 qualcommax: ipq50xx: add support for ZTE T5400
Add support for the ZTE T5400, based on the Qualcomm IPQ5018.

Specifications:
- Qualcomm IPQ5018 SoC, 2x ARM Cortex-A53
- 512 MiB RAM
- 256 MiB SPI-NAND (Winbond W25N02JWZEIF)
- integrated IPQ5018 2.4 GHz 802.11ax radio, 2x2
- Qualcomm QCN9024 5 GHz 802.11ax radio, 4x4, PCIe Gen2 x2,
  exposed to ath11k under the QCN9074 hw1.0 profile
- QCA8337 switch providing 3x LAN ports, with an SGMII uplink via
  GMAC1/UNIPHY0 and CPU port 6
- IPQ5018 internal GEPHY providing the fourth RJ45 Ethernet port,
  configured as WAN, via GMAC0
- reset and WPS buttons
- red and white status LEDs
- USB2 + USB3 Type-C port (not enabled)
- 12 V / 2.0 A (24 W) DC power input

UART:

The UART pads are on the component side near the SoC/RAM shield.
With the Ethernet ports at the bottom and antenna connectors on the
left, the pads are at the upper-right edge of the shield area. They
are not labelled on the PCB. Access requires removing the shield
cover.

With the board oriented as above:

  upper signal pad: router TX
  lower signal pad: router RX

The UART uses 1.8 V logic, 115200 8N1, without flow control.

  router TX -> adapter RXD
  router RX <- adapter TXD

No dedicated UART ground pad was identified next to the TX/RX pads.
The shield is connected to ground and can be used for adapter GND.
Other board points can be verified as ground by checking continuity
against the shield.

Ethernet and MAC addresses:

Stock firmware derives interface addresses from a single factory base
MAC stored in the "mac" NAND partition by adjusting only the fourth
octet (mac[3]) by a per-interface constant.

This is intentionally not reproduced bit-for-bit. The port uses the
generic "mac-base" nvmem layout already used by other devices in-tree,
which matches stock except when an offset causes the fourth octet to
cross a boundary.

- label / br-lan (LAN):       factory MAC, unmodified
- eth0 / GMAC0 (WAN):         factory MAC, mac[3] - 2
- eth1 / GMAC1 (LAN conduit): factory MAC, mac[3] - 1
- integrated 2.4 GHz radio:   factory MAC, unmodified
- external 5 GHz radio:       factory MAC, mac[3] + 10

The generic mac-base layout performs normal 48-bit arithmetic on the
whole address, while stock firmware wraps the fourth octet
independently. The results can therefore differ when the affected
octet crosses a 0x00 or 0xff boundary.

Replicating the stock fourth-octet-only arithmetic exactly would
require device-specific handling for this edge case.

The tested unit does not hit the edge case, so all derived addresses
match stock and remain unique. It is not known from a single unit how
often such a boundary case occurs across production T5400 devices.

Flash layout:

On the tested unit, OpenWrt is installed entirely in the existing
60 MiB "rootfs" partition, exposed as mtd17. The second stock
slot, "rootfs_1", is exposed as mtd18 and remains untouched.

The stock U-Boot boot chain is left unmodified. Its bootcmd=bootipq
boots the OpenWrt UBI from mtd17 using FIT config@mp03.1. No
persistent U-Boot environment, MIBIB or BOOTCONFIG changes are
required.

Flashing instructions:

Connect a TFTP host to physical RJ45 port 4 (GMAC0/eth0).
For the procedure below, configure the router as 192.168.0.1 and
the TFTP host as 192.168.0.22.

The stock U-Boot autoboot delay is one second. Interrupt autoboot over
UART to reach the IPQ5018# prompt.

Use the following transient network settings:

  setenv serverip 192.168.0.22
  setenv ipaddr 192.168.0.1

Stock backup:

Before the first persistent write, both stock rootfs slots can be
exported directly from stock U-Boot:

  nand read 0x44000000 0x00a60000 0x03c00000
  tftpput 0x44000000 0x03c00000 192.168.0.22:zte-t5400-mtd17-rootfs.bin

  nand read 0x44000000 0x04660000 0x03c00000
  tftpput 0x44000000 0x03c00000 192.168.0.22:zte-t5400-mtd18-rootfs_1.bin

The saved mtd17 image provides the tested stock recovery path.

Boot the OpenWrt initramfs image over TFTP:

  tftpboot 0x44000000 openwrt-qualcommax-ipq50xx-zte_t5400-initramfs-uImage.itb
  bootm 0x44000000

The initramfs runs entirely from RAM and does not modify NAND by
itself.

Transfer the following factory image to /tmp on the running
OpenWrt initramfs system:

  openwrt-qualcommax-ipq50xx-zte_t5400-squashfs-factory.ubi

Verify that /dev/mtd17 is the "rootfs" partition before writing
the image.

Then write mtd17:

  ubiformat /dev/mtd17 -y \
    -f /tmp/openwrt-qualcommax-ipq50xx-zte_t5400-squashfs-factory.ubi

Power-cycle the router after the write completes. The unchanged stock
bootipq path then boots OpenWrt from mtd17.

Subsequent upgrades use the normal OpenWrt NAND sysupgrade path with:

  openwrt-qualcommax-ipq50xx-zte_t5400-squashfs-sysupgrade.bin

Normal installation and upgrade leave mtd18, ART, the MAC partition,
MIBIB, BOOTCONFIG and bootloader partitions unchanged.

Testing:

Tested on real hardware:
- initramfs boot over UART/TFTP
- factory installation and persistent cold boot
- clean and configuration-preserving sysupgrade
- all four Ethernet ports with routed iperf3 traffic
- both Wi-Fi radios in AP mode and with routed iperf3 traffic
- LEDs and reset/WPS buttons
- restoration of the saved stock mtd17 image and vendor-kernel boot,
  followed by a clean OpenWrt reinstall

Signed-off-by: Wojciech Zwolinski <wojciech.zwolinski0@gmail.com>
2026-10-19 12:59:44 +02:00
Jonas Jelonek 913daed791 realtek: pcs: rtl930x: refine RX calibration diagnostics
Add debug-level tracing for calibration requests, readiness polling,
attempts and results, retries, coefficient refinement and mode-change
invalidation. Record symbol-error samples, attempt duration and mutex
wait time to diagnose acquisition and scheduling issues.

Demote per-attempt link and error-count failures to debug level since
later attempts can recover. Include measured counts, thresholds, mode
and attempt context, sharing named XSGMII limits between checks and
messages. Retain warnings for exhausted attempts and errors for failed
register accesses.

Assisted-By: ChatGPT (OpenAI GPT-6.1 Sol)
Link: https://github.com/openwrt/openwrt/pull/25882
Signed-off-by: Jonas Jelonek <jonas@jonasjelonek.de>
2026-10-19 09:35:04 +02:00
Jonas Jelonek 27d97aa507 realtek: pcs: rtl930x: limit clock-ready polling to 10G SerDes
The clock-ready debug readback is used by the SDK's 10G SerDes setup
sequence. Restrict polling to 10G-type SerDes while retaining the
existing exclusion for OFF mode.

This avoids applying the check to the 5G QSGMII SerDes 0 and 1, which can
report clock synchronization failures despite working links.

Assisted-By: ChatGPT (OpenAI GPT-6.1 Sol)
Link: https://github.com/openwrt/openwrt/pull/25882
Signed-off-by: Jonas Jelonek <jonas@jonasjelonek.de>
2026-10-19 09:35:04 +02:00
Jonas Jelonek 29a7121781 realtek: pcs: rtl930x: retry RX calibration across worker runs
Store the calibration attempt count per SerDes and execute one full
attempt per worker invocation. Requeue failed attempts after one second,
up to a total of three attempts, checking RX readiness on each run.

Reset the count when arming a new configuration. Readiness polling does
not consume attempts, and success or exhaustion finishes the request.

Assisted-By: ChatGPT (OpenAI GPT-6.1 Sol)
Link: https://github.com/openwrt/openwrt/pull/25882
Signed-off-by: Jonas Jelonek <jonas@jonasjelonek.de>
2026-10-19 09:35:04 +02:00
Jonas Jelonek a3594cc459 realtek: pcs: rtl930x: require RX link for calibration success
Zero symbol errors can also be observed without an established receive
link. Require physical RX link-up after the error measurement window
before accepting a calibration attempt.

Reuse the 10G receive-link indication for 10GBase-R and USXGMII. For
XSGMII, require the full link-status bitmap on both backing digital
SerDes, accounting for the logical-to-physical mapping.

Assisted-By: ChatGPT (OpenAI GPT-6.1 Sol)
Link: https://github.com/openwrt/openwrt/pull/25882
Signed-off-by: Jonas Jelonek <jonas@jonasjelonek.de>
2026-10-19 09:35:04 +02:00
Jonas Jelonek 703bffe6b6 realtek: pcs: rtl930x: defer RX calibration until the receiver is ready
Apply the RX baseline in post-config and arm delayed work per SerDes.
Wait for RX_IDLE to deassert before running the full calibration
sequence, retaining initialization on each of up to three attempts.

Serialize the worker with PCS configuration, invalidate pending requests
on mode changes, and drain the work through a managed cleanup action on
probe failure or device removal.

Assisted-By: ChatGPT (OpenAI GPT-6.1 Sol)
Link: https://github.com/openwrt/openwrt/pull/25882
Signed-off-by: Jonas Jelonek <jonas@jonasjelonek.de>
2026-10-19 09:35:04 +02:00
Erik Larsson c2c3e8ab6b realtek: add support for XikeStor SKS8300-12x V2
The XikeStor SKS8300-12x V2 is a managed switch based
on RTL9313 with 12 SFP+ ports.

Device specification:
- SoC: Realtek RTL9313
- RAM: 256MiB
- Flash: 32MiB Macronix SPI NOR
- Ethernet: 12x SFP+ cages
- Button: hard reset
- System LED: GPIO 0
- Bootloader: U-Boot 2011.12.(3.6_CURRENT)
- Vendor board model: RTL9313_12XGE
- UART: Cisco style RJ45 port on the front.
  - Settings: 115200n8
- Power: 100-240 VAC 50/60 Hz C13/C14
- Monitoring: LM75
- Fan controller: Maxim 6651

Notes:
The MAC address can be extracted from the jffs2
partition in the file factoryData at offset 0x80.
As the jffs and jffs2 partitions are formatted
with 4K erase sectors this requires the kernel to be
configured with CONFIG_MTD_SPI_NOR_USE_4K_SECTORS or
dumping it with jefferson.

The switch has a RTL8231 connected to it via SMI
which seem to control the port LEDs.
"rtk network on" initializes the RTL8231 so the LED
works but can't be controlled via OpenWrt.

Booting the initramfs image:
1. Connect to the serial port, power on the device and press Esc
   before autoboot starts to get to the u-boot CLI.
2. Run "rtk network on".
3. Boot the initramfs image.
   Via YMODEM:
     Run "loady 0x82000000".
     And then "bootm 0x82000000".
   Via TFTP:
     Connect a SFP module or a DAC to port 1.
     Run "rtk 10g 0 fiber1g".
     If using a DAC replace fiber1g with the correct type.
     The default TFTP server IP is 192.168.1.111.
     Run "tftpboot 0x82000000 <image name>".
     Where "<image name>" is the name of the initramfs image.
     And then run "bootm 0x82000000".

Installation:
After booting the initramfs image transfer the sysupgrade
to the device and run sysupgrade <path to sysupgrade image>.
Set the bootcmd u-boot variable to "rtk network on ; boota"
and save the variable and reset the switch.

Signed-off-by: Erik Larsson <who+github@cnackers.org>
Link: https://github.com/openwrt/openwrt/pull/25782
Signed-off-by: Jonas Jelonek <jonas@jonasjelonek.de>
2026-10-18 19:43:28 +02:00
Shine- GH 4d1eb955da realtek: rtl838x: enable SFP cages for Netgear GS310TP
This enables the two SFP cages for the Netgear GS310TP switch. The
GPIO numbers used have been harvested from the stock firmware's
"show tech-support" command.

Tested on real hardware with various optical and RJ45 transceivers.

Signed-off-by: Shine- GH <4c.fce2@proton.me>
Link: https://github.com/openwrt/openwrt/pull/25987
Signed-off-by: Jonas Jelonek <jonas@jonasjelonek.de>
2026-10-18 19:36:33 +02:00
Leonard Anderweit 8dcdd8fa0e qualcommax: ipq50xx: add AVM FRITZ!Box 4050
Add support for AVM FRITZ!Box 4050, an IPQ5018 based WiFi 6 router.

Hardware
--------
SOC	: Qualcomm IPQ5018 2x A53
RAM	: 512MiB DDR3L Winbond W634GU6QB-11
Flash	: 128MiB Winbond W25N01GWZEIG
ETH	: 4x GbE
Switch	: Qualcomm QCA8337
WiFi	: IPQ5018, QCN6102
USB	: 1x USB 2.0
Buttons	: WLAN, DECT, WPS
LEDs	: Power, WLAN, DECT, WPS, Info green, Info red
DECT	: DCX81AC0CFAE3FNC
Power	: DC 12V 1.5A

UART
----
4 holes, vcc is square
gnd - rx - tx - vcc
3.3v

Installation
------------
1. Download scripts/flashing/eva_ramboot.py, initramfs image and sysupgrade.bin
2. Connect to lan1 and set host ip to 192.168.178.2
3. Power the device and run
   `./eva_ramboot.py --ramsize 0x20000000 --ramstart 0x40000000 192.168.178.1 <initramfs image>`
   when only the 'Power' led blinks
4. Set host ip to 192.168.1.2 and connect to LuCi on 192.168.1.1
5. Sysupgrade in LuCi

Revert to OEM firmware
----------------------
Follow the OEM guide: https://fritz.com/en/pages/recover
The recovery process also works on Linux using Wine.

MAC Addresses
-------------
WAN	: D4:24:DD:XX:XX:FF
LAN	: D4:24:DD:XX:XX:02 (label mac)
2.4GHz	: D4:24:DD:XX:XX:04
5GHz	: D4:24:DD:XX:XX:05

Not Supported
-------------
DECT
analog phone port

Signed-off-by: Leonard Anderweit <leonard.anderweit@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/25056
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-18 13:14:19 +02:00
Leonard Anderweit dc52eb7a2a qualcommax: add spidelay patch
Copy the spidelay patch from
target/linux/bcm27xx/patches-6.18/0314-spi-spi-gpio-Implement-spidelay-when-requested-bit-r.patch
to be able to reduce the frequency of spi-gpio.

Signed-off-by: Leonard Anderweit <leonard.anderweit@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/25056
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-18 13:14:19 +02:00
Julius Bairaktaris 7724018064 qualcommax: qca_ppe: do not classify host frames into a bridge VLAN
The ingress VLAN rule of a filtering bridge VLAN keyed the CPU port as
well, so every frame the host sent with that VID was classified into the
VLAN's VSI, also when it was addressed to a port outside the bridge. A
standalone port, or the conduit of a QCA8337 behind the PPE, then dropped
it. On the RT-AX89X a VLAN-aware bridge of lan3 and 10g-copper with PVID
10 passed no traffic towards lan3.

The host sends each frame already formatted for the port it names, so
leave the CPU port out of the rule and keep it in the VSI's members.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25700
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-18 12:50:09 +02:00
Julius Bairaktaris 4d37c515e7 qualcommax: qca_edma: add ethtool DMA reset
The EDMA block has a reset line of its own, but the driver asserts it
only at probe and when it rebuilds the rings. qca_edma is built in and
the switch sits on the conduit, so a reboot is the only other way back
to the engine's power-on state. Implement the ethtool reset op for
ETH_RESET_DMA with the rebuild ring resizing already uses.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25700
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-18 12:50:09 +02:00
Julius Bairaktaris 9aac12f7b1 qualcommax: qca_ppe: warn when the setup FDB flush times out
qca_ppe_setup() discards what ppe_fdb_flush() returns, so a flush that
never completes leaves the entries left behind by the boot loader in
place without a trace. Warn when it times out.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25700
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-18 12:50:09 +02:00
Julius Bairaktaris 7f5630527a qualcommax: qca_edma: mask the misc interrupt once it has fired
edma_misc_irq_handle() reads MISC_INT_STAT and returns without clearing
the condition, so a condition that persists keeps the interrupt asserted
and the handler runs back to back. Mask the misc interrupt on the first
report, as qca-nss-dp does in edma_handle_misc_irq(). edma_hw_init()
unmasks it again.

Fixes: bdb0b722b7 ("qualcommax: add EDMA driver")
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25700
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-18 12:50:08 +02:00
Julius Bairaktaris 23d81764e3 qualcommax: qca_edma: clear only the TX interrupt masks that exist
edma_irq_disable_all() clears a TX interrupt mask for every TX
descriptor ring, but the TX interrupt registers come one per completion
ring. IPQ807x has eight completion rings, so indices 8 to 23 land in the
RXFILL block and zero the producer index and the interrupt mask of fill
rings 0 to 7. Bound the loop by the completion ring.

Fixes: bdb0b722b7 ("qualcommax: add EDMA driver")
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25700
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-18 12:50:08 +02:00
Julius Bairaktaris 3218bba2d2 qualcommax: qca_ppe: count the CPU port's queues in ethtool -S
The CPU port reports the MAC counters of a MAC it does not have, all
zero, and none of its queue counters. Report its unicast and multicast
queue counters instead, as for the user ports.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25700
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-18 12:50:08 +02:00
Julius Bairaktaris 06a80616a7 qualcommax: qca_ppe: offload gred
The queue manager has a WRED threshold pair per colour on every unicast
queue, but only a colour-blind red is offloaded. Offload gred in WRED
mode on the same queues a red takes: DP 0 sets the queue limit and the
green thresholds, DP 1 and 2 the yellow and red ones below it, and the
queue turns colour aware; ECN and per-VQ averaging are refused. On
IPQ8074, two uploads under the 165 Mbit/s WAN shaper, one marked yellow,
ran at 14/47/6 and 140/71/146 Mbit/s with only yellow dropped
(572/343/162), against 110/135/80 and 43/25/82 under a colour-blind red.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25700
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-18 12:50:08 +02:00
Julius Bairaktaris fa41f4d99a qualcommax: qca_ppe: set the drop precedence from a flower classid
An ingress flower classid sets skb->tc_index, which gred reads as the
drop precedence, but the driver ignores the classid and offloads the
rule without it. Map classid :0 to :2 to the ACL action's internal drop
precedence, green, yellow or red, and refuse any other classid.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25700
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-18 12:50:08 +02:00
Julius Bairaktaris ae6592dc6a qualcommax: qca_ppe: count queue drops in tx_dropped
A port's egress queues drop frames that tx_dropped never shows: the
counter it folds sits ahead of the queues. Add the drops of the port's
unicast and multicast queues to tx_dropped, folded like the others. On
IPQ8074 a port shaped to 20 Mbit/s under a download reports the same
drops in tx_dropped as its queues do in ethtool -S (618, 539 and 503).

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25700
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-18 12:50:08 +02:00
Julius Bairaktaris ef958a1767 qualcommax: qca_ppe: keep the VLAN tag on frames to the CPU
VSI_TAG_EN in PORT_EG_VLAN is set out of reset, so every port takes its
egress tag mode from the per-VSI table instead of its own. On the CPU
port this strips the C-tag of a frame that enters a VLAN-unaware bridge
port tagged, and a VLAN upper of the bridge never receives it. Clear the
bit on every port at setup; a VLAN-filtering port sets it again.

Fixes: 142104bb90 ("qualcommax: add PPE driver")
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25700
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-18 12:50:08 +02:00
Julius Bairaktaris da09ab3c20 qualcommax: qca_edma: add TX VLAN offload
The TX preheader can carry a C-tag or S-tag for the switch to insert,
but the driver makes the stack push every tag into the frame. Add
NETIF_F_HW_VLAN_CTAG_TX and NETIF_F_HW_VLAN_STAG_TX: the tag is flagged
in pre2, its TCI written to pre3 and the insertion commanded in pre4.
They are in vlan_features, so the DSA user ports and their VLAN uppers
hand their tag to the conduit out of band. The switch inserts a C-tag
behind an S-tag already in the frame and drops a tag of the type the
frame starts with, so for those frames the stack still pushes the tag.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25700
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-18 12:50:08 +02:00
Julius Bairaktaris 2fe319438f qualcommax: qca_edma: add RX VLAN offload
The receive ring can strip the C-tag of a frame and report it in the
preheader, but the driver leaves every tag for the stack to pull. Add
NETIF_F_HW_VLAN_CTAG_RX: the ring strips the outer C-tag and the driver
hands it up out of band. A C-tag below an S-tag is not stripped and
stays in the frame.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25700
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-18 12:50:08 +02:00
Julius Bairaktaris 89ac01dc9b qualcommax: qca_edma: add NETIF_F_FRAGLIST support
A GRO aggregate that outgrows MAX_SKB_FRAGS keeps its further segments
on a frag_list, and without NETIF_F_FRAGLIST the stack segments it
before it reaches the conduit. Write the heads and fragments of the
frag_list skbs to descriptors like any other fragment. An aggregate
that needs more than 32 descriptors is segmented in software by
ndo_features_check rather than linearised.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25700
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-18 12:50:08 +02:00
Julius Bairaktaris 812890612e qualcommax: qca_ppe: put a port back on VSI 0 when it leaves a bridge
port_bridge_leave() marks the port's VSI invalid, and a port without a
valid VSI drops every frame it receives, so a port taken out of a bridge
stops receiving until the next probe. Program VSI 0, which carries the
standalone ports, as probe does.

Fixes: 142104bb90 ("qualcommax: add PPE driver")
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25700
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-18 12:50:08 +02:00
Julius Bairaktaris 5b835fbcd8 qualcommax: qca_ppe: add devlink sb port pool and tc pool bind
devlink shows the shared buffer's pools but no port's share of them. A
switch port's ingress is one buffer manager port, port + 7 as qca-ssdk's
PHY_PORT_TO_BM_PORT() has it, so its single ingress class binds to that
port's buffer group and its threshold is the dynamic weight. The egress
classes are the port's unicast queues and report their admission group and
weight, and moving them is refused because the driver assigns the queue
groups. Occupancy is read from the buffer and queue counters at each
snapshot; they report only the current value, so the maximum is the
largest value a snapshot has seen.

On IPQ8074 a port threshold changes only the weight of that BM port's
entry, the neighbouring port's entry stays intact, an egress bind is
refused, and a port shaped to 50 Mbit/s with a 200000-byte limit reports
87040 bytes occupied in its egress pool under load.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25700
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-18 12:50:08 +02:00
Julius Bairaktaris 4ca73a4695 qualcommax: qca_ppe: offload ets DRR bands
An ets with DRR bands is either refused or, with equal quanta, run as
strict bands while it reports offloaded. With a strict top band, DRR lower
bands now move the middle band's queues to a spare L1 node of the port at
the bottom band's priority, and the two nodes share the port's DRR list
with weights scaled from the quanta. Weighting the queues instead would
split a band's share by how many of its hash queues are busy, and a DRR top
band is refused, because its node also carries multicast.

Measured on IPQ8074, n=3: quanta 3000:1000 give 69 and 18-21 Mbit/s, and
1500:1500 about 1:1.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25700
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-18 12:50:08 +02:00
Julius Bairaktaris 17fd68c109 qualcommax: qca_ppe: offload mqprio min_rate
mqprio's min_rate is refused, although every scheduler node has a committed
and an excess token bucket. A class's min_rate now goes in the committed
bucket and the difference up to max_rate in the excess one, a floor without
a max_rate leaves the excess unmetered, and both buckets share one token
unit chosen for the faster of the two. The port serves committed traffic
ahead of excess, so when any class has a floor, a class without one sends
only as excess: its committed bucket is armed empty and its max_rate goes
in the excess one.

Measured on IPQ8074 on a 100 Mbit/s port, n=3: a class with a 60 Mbit/s
floor against a strict top class carries 52-53 Mbit/s of TCP goodput, and 0
without the floor.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25700
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-18 12:50:08 +02:00
Julius Bairaktaris da6e886853 qualcommax: qca_ppe: offload the red qdisc
The queue manager has WRED on every unicast queue, and nothing programs it.
A red at the root or under a root tbf now covers the port's unicast queues,
one under a band of an offloaded ets or prio covers that band's queues, and
its stats and xstats come from those queues' counters, which also give a
tbf under the top band its stats. Its max becomes a static queue limit and
its min the gap below it where early drop starts, in 256-byte buffers and
colour blind, and ECN marking is refused because the queue manager only
drops. The drop probability is fixed in hardware, so the probability is
ignored with a one-time notice: measured on IPQ8074 with a 50 Mbit/s tbf
and red min 30000 max 90000, under UDP at 1.6, 2.4 and 4 times the rate
(n=3 each), the early-drop probability reaches about 0.66 at max.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25700
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-18 12:50:08 +02:00
Julius Bairaktaris 7ed28a5b6b qualcommax: qca_ppe: offload tbf under the top ets/prio band
Only a root tbf is offloaded, and TC_ETS_GRAFT and TC_PRIO_GRAFT are
refused, so a rate on one band of an offloaded ets or prio stays in
software. A tbf on the top band now programs that band's L1 node shaper,
which also carries the port's multicast queues and sparse list. The lower
two bands share one L1 node and are four L0 queues each, so no single
bucket meters one of them, and a tbf there is refused.

Measured on IPQ8074 on a 100 Mbit/s port, n=3: a 20 Mbit/s tbf on the top
band holds it to 18 Mbit/s, against 94 Mbit/s without the tbf.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25700
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-18 12:50:08 +02:00
Julius Bairaktaris dae98fe7f5 qualcommax: qca_ppe: add per-queue and per-colour ethtool -S counters
ethtool -S reports only the MAC MIB, while the per-queue transmit counters,
the per-colour queue drop counters, the buffer manager drop counters and
the port meter colour counters are read only by debugfs. Each user port now
lists its own unicast and multicast queues, its buffer manager port and its
meter. The packet counts are 32 bits and the byte counts 40, so they are
folded with the MIB to survive a wrap.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25700
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-18 12:50:08 +02:00
Julius Bairaktaris 7e2ad821fa qualcommax: qca_ppe: report rx_dropped and tx_dropped in get_stats64
The port receiver's drop counter and the port's egress drop counter are
read only by debugfs, so `ip -s link` shows no drops for a port. Both are
32-bit packet counters outside the MAC, so they are folded with the MIB
counters to survive a wrap, and unlike the MAC MIB a port reset does not
clear them.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25700
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-18 12:50:08 +02:00
Julius Bairaktaris f89340fa5f qualcommax: qca_ppe: offload FLOW_ACTION_RX_QUEUE_MAPPING
tc reaches the classifier's queue action only through ethtool n-tuple.
Accept skbedit queue_mapping with skip_sw, as ice does, by redirecting the
frame to the CPU port and selecting that queue among the CPU port's twelve
unicast queues.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25700
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-18 12:50:08 +02:00
Julius Bairaktaris 167b1d8d1d qualcommax: qca_ppe: match ARP sender and target IP
The IPv4 address rule types carry an L3 packet type, one value of which is
ARP, but FLOW_DISSECTOR_KEY_ARP is refused. Match flower's arp_sip and
arp_tip in the source and destination address of those rule types with the
packet type set to ARP. Opcode and hardware addresses stay refused.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25700
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-18 12:50:08 +02:00
Julius Bairaktaris b213b14de6 qualcommax: qca_ppe: match ethtool user-def data in UDF windows
The parser extracts four 16-bit user-defined fields per packet class at a
configurable offset from the L2, L3 or L4 header, and two ACL rule types
compare them, but nothing programs them. Match the ethtool n-tuple user-def
field there. It is laid out as i40e does, the word in bits 15:0 and the
byte offset in bits 31:16, with the header in bits 33:32. The windows are
shared by all rules of a class and refcounted.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25700
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-18 12:50:08 +02:00
Julius Bairaktaris 222e61fdf7 qualcommax: qca_ppe: match IP keys inside a PPPoE session
A flower filter with ppp_proto is refused, so no rule can match the
addresses or ports of traffic inside a PPPoE session. For ppp_proto ip or
ipv6, flower sets n_proto to the IP ethertype, which the classifier matches
with the IPv6 bit of the IP misc rule type and not with the ethertype field
the session match uses. Accept those two and keep refusing every other
ppp_proto.

On IPQ8074 a filter on an address inside a session matches its packets and
none of the control.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25700
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-18 12:50:08 +02:00
Julius Bairaktaris c9a39ff6a0 qualcommax: qca_ppe: match the VLAN DEI bit
ethtool's vlan_tci mask hands the DEI bit to the driver, which ignores it,
so an n-tuple rule naming DEI matches either value. The VLAN rule type
compares the C-tag DEI in bit 19 of its first word; match it there.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25700
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-18 12:50:08 +02:00
Julius Bairaktaris 757aab1037 qualcommax: qca_ppe: match IP TTL and hop limit of 0, 1 or 255
The IP misc rule type encodes the IPv4 TTL and IPv6 hop limit in two bits
as 0, 1, 255 or any other value. Offload a flower ip_ttl match on one of
those three values with a full mask and keep refusing every other TTL
match.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25700
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-18 12:50:08 +02:00
Julius Bairaktaris ac95cc8fee qualcommax: qca_ppe: match FLOW_DIS_FIRST_FRAG
The IP misc rule type has a first-fragment bit next to the fragment bit,
but flower's firstfrag flag is refused. Map FLOW_DIS_FIRST_FRAG to it.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25700
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-18 12:50:08 +02:00
Julius Bairaktaris ec172b8391 qualcommax: qca_ppe: offload packet-rate police
Both the ACL meter and the port meter have a meter unit bit that makes them
count frames instead of bytes, but the driver refuses rate_pkt_ps. Program
a packet rate in that mode. In packet mode a frame costs 128 times the
tokens a byte costs in byte mode at every token unit, as in the rate tables
of qca-ssdk adpt_hppe_policer.c, so the existing byte rate helper serves
both.

Measured on IPQ8074 at 4100 packets/s, n=3 at each of two frame sizes: an
ACL police passes 4100-4110 packets/s, and a packet-rate port police holds
its rate in the same test.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25700
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-18 12:50:08 +02:00
Julius Bairaktaris f92180d67b qualcommax: qca_ppe: accept FLOW_ACTION_CSUM after a DSCP rewrite
A pedit of the IPv4 DSCP needs "action csum iph" to be correct in software,
and the classifier refuses the csum action, so the rewrite cannot be
offloaded as tc users write it. Accept csum when it updates only the IPv4
header checksum and the rule also rewrites the DSCP, which the egress
editor does with the checksum fixed up.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25700
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-18 12:50:08 +02:00
Julius Bairaktaris c072765405 qualcommax: qca_ppe: add cls_flower_stats
An offloaded flower filter reports no packets, because the ACL hit counters
are read only by debugfs. Add .cls_flower_stats: sum the hit counters of
every entry the rule occupies and report the red count of its meter as
drops. Both are cleared when the entry or meter is freed, so the next rule
starts at zero, and filters that ask for a hw_stats type other than
immediate are refused.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/25700
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-10-18 12:50:08 +02:00