Commit Graph
70427 Commits
Author SHA1 Message Date
Markus Stockhausen ccde424785 realtek: dsa: move egress rate handling to SoC config
The RTL838x and RTL839x families use different mechanisms for reading
and configuring the port egress rate.

Add get_egress_rate and set_egress_rate callbacks to rtldsa_config and
use them from debugfs instead of selecting the implementation based on
priv->family_id.

Rename the existing functions to use the rtldsa_838x and rtldsa_839x
prefixes consistently with the other SoC-specific callbacks.

This removes another family_id dependency from the common debugfs
code and keeps the SoC-specific implementation selected through
rtldsa_config.

While we are here do some minor type cleanups:

- Change the value used by port_egress_rate_read() from int to u32
  and remove the negative value check. Both get_egress_rate callbacks
  return u32, so value can never be negative and the check could not
  report an error. The callbacks return 0 for an invalid port instead.
- Change the res size_t variable type to ssize_t. This fixes the dead
  comparison "res < 0".
- Remove the uninitialized read in rtldsa_839x_get_egress_rate()

Assisted-by: ChatGPT (OpenAI GPT-5.6 Sol)
Link: https://github.com/openwrt/openwrt/pull/24918
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-08-29 09:04:29 +02:00
Markus Stockhausen 08966754f1 realtek: dsa: move switch MAC trap register to SoC config
The RTL838x and RTL839x families use different registers to configure
the action for frames destined to the switch MAC.

Store the family-specific register in struct rtldsa_config and use it
directly during switch setup instead of selecting the register based
on priv->family_id.

This removes another family_id check from the common DSA code and
keeps the SoC-specific register selection in the corresponding
configuration.

Assisted-by: ChatGPT (OpenAI GPT-5.6 Sol)
Link: https://github.com/openwrt/openwrt/pull/24918
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-08-29 09:04:29 +02:00
Markus Stockhausen 29049ae59e realtek: dsa: describe L2 aging resolution in SoC config
Replace the RTL8380 family check in rtl83xx_get_l2aging() with a
high_res_l2_age capability in the SoC configuration.

RTL838x uses a 23-bit AGE_UNIT with a resolution of 204.8 ms, while
RTL839x and RTL93xx use a 21-bit AGE_UNIT with a resolution of 600 ms.

Set high_res_l2_age for RTL838x and use it to select the appropriate
AGE_UNIT mask and conversion. This removes another direct family_id
dependency from the common driver code without changing behavior.

Assisted-by: ChatGPT (OpenAI GPT-5.6 Sol)
Link: https://github.com/openwrt/openwrt/pull/24918
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-08-29 09:04:29 +02:00
Markus Stockhausen be26f2a9cf realtek: dsa: move statistics init to SoC config
Remove the family_id check from the common statistics initialization
path and move the RTL838x-specific statistics setup into the SoC
configuration.

Add a stat_init callback to struct rtldsa_config and provide an RTL838x
implementation for enabling the statistics counters. Families which do
not require additional setup leave the callback unset.

Rename rtldsa_83xx_init_stats() to rtldsa_init_stats() and use it from
both the 83xx and 93xx setup paths so statistics initialization is
handled consistently for all supported families.

This moves another SoC-specific decision out of the common driver code
and makes the configuration structure responsible for family-specific
behavior.

While we are here drop the TODO comment for RTL93xx. It is not known
if RTL93xx really needs initialization. With the new implementation
the function will be automatically called if it is added to the SoC
structure one day

Assisted-by: ChatGPT (OpenAI GPT-5.6 Sol)
Link: https://github.com/openwrt/openwrt/pull/24918
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-08-29 09:04:28 +02:00
Markus Stockhausen 2fb70bfb79 realtek: mdio: enable global polling flag for RTL839x
The RTL839x has a global polling enable bit. This is set by the
dsa driver and misses in the mdio driver. Before removing the
dsa logic move the setup where it belongs.

Link: https://github.com/openwrt/openwrt/pull/24918
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-08-29 09:04:28 +02:00
Rustam Adilov 6eb718ab30 realtek: mdio: add support for RTL9607C internal mdio bus
This commit adds support for internal mdio bus on RTL9607C SoC.
It is used to connect to 4 internal phys on the embedded switch.

Since there is an ongoing upstream work on porting mdio-realtek-otto
to mainline linux, make a separate rtl960x mdio driver for now. Once
it lands there should be no reason not to merge these two into one.

Add the otto prefix to the driver name to signify it and also that
rtl960x is a part of Realtek Otto family as the switch chips.

Most things were carved out of the main mdio-realtek-otto driver
except for multiple busses, port mapping, smi and such that are not
relevant to one single internal mdio bus of RTL9607C.

Co-developed-by: Michael Zavertkin <misha.zavertkin@mail.ru>
Signed-off-by: Michael Zavertkin <misha.zavertkin@mail.ru>
Signed-off-by: Rustam Adilov <adilov@tutamail.com>
Link: https://github.com/openwrt/openwrt/pull/24840
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-08-28 18:33:35 +02:00
Harshal Gohel 1ad2e78e6a realtek: dsa: trap EAPOL frames to the CPU on RTL93xx
EAPOL frames must not be forwarded to other ports. Trap them to the CPU so
that an 802.1X authenticator such as hostapd can handle them. RTL83xx
already does this via SPCL_TRAP_EAPOL_CTRL.

Signed-off-by: Harshal Gohel <hg@simonwunderlich.de>
Link: https://github.com/openwrt/openwrt/pull/21775
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-08-27 16:36:55 +02:00
Harshal Gohel 1ab4462d4f realtek: dsa: support BR_BCAST_FLOOD on RTL93xx
Broadcast flooding has its own port mask on RTL93xx, so offload it
separately instead of leaving it tied to BR_FLOOD.

Signed-off-by: Harshal Gohel <hg@simonwunderlich.de>
Link: https://github.com/openwrt/openwrt/pull/21775
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-08-27 16:36:55 +02:00
Harshal Gohel 93bcad00c2 realtek: dsa: support BR_PORT_LOCKED
A locked port only forwards frames whose source address has an FDB entry
pointing to that port. On this hardware that means trapping frames with an
unknown source address to the CPU, disabling automatic source address
learning and flushing the FDB when the port is locked. An authenticator
such as hostapd can then process EAPOL frames and add an FDB entry once a
supplicant is authorized.

Add an enable_l2_new_sa_fwd() callback for the per-port NEW_SA_FWD action
and advertise BR_PORT_LOCKED only where it is implemented, which is RTL9300
and RTL9310.

Source address learning now also follows BR_LEARNING, so unlocking a port
restores the state the bridge asked for and a port leaving a bridge stops
learning.

To lock or unlock a port:

  bridge link set dev lan1 locked on
  bridge link set dev lan1 locked off

To add or delete an authorized entry:

  bridge fdb add 12:34:56:78:90:ab dev lan1 vlan 1 master extern_learn
  bridge fdb del 12:34:56:78:90:ab dev lan1 vlan 1 master

Signed-off-by: Harshal Gohel <hg@simonwunderlich.de>
Link: https://github.com/openwrt/openwrt/pull/21775
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-08-27 16:36:55 +02:00
Harshal Gohel a15db9f75b realtek: dsa: cache bridge port flags
port_bridge_flags() may be called with a single flag or with several at
once, and only the flags in flags.mask are valid. Cache the current set per
port so the callbacks can be programmed from the complete state instead of
from whatever a single call happened to carry.

The cache is cleared in port_bridge_join().

Signed-off-by: Harshal Gohel <hg@simonwunderlich.de>
Link: https://github.com/openwrt/openwrt/pull/21775
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-08-27 16:36:55 +02:00
Harshal Gohel bfa4bbfd37 realtek: dsa: support multiple flood_type with enable_flood()
enable_flood() took a bool, which can only select between forwarding and
dropping. The hardware supports more actions per port and the upcoming
BR_PORT_LOCKED support needs trap-to-CPU, so replace the bool with an enum
matching the hardware encoding of the L2 learning constraint action field.

On RTL93xx also program the unknown unicast flood port mask, which is what
BR_FLOOD actually controls.

No functional change for RTL83xx, where the field is only two bits wide.

Signed-off-by: Harshal Gohel <hg@simonwunderlich.de>
Link: https://github.com/openwrt/openwrt/pull/21775
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-08-27 16:36:55 +02:00
Harshal Gohel 4f7269c4db realtek: dsa: fix inverted fast_age() availability check
The check guarding the r->fast_age() call was inverted: the callback was
only invoked when it was *not* implemented, and skipped when it was. All
four families provide .fast_age, so this was a noop.

Return early when the callback is missing and take the register lock only
around the actual call, matching rtldsa_port_vlan_fast_age() right below.

Fixes: f3743850bf ("realtek: dsa: switch RTL93xx to new fast_age()")
Signed-off-by: Harshal Gohel <hg@simonwunderlich.de>
Link: https://github.com/openwrt/openwrt/pull/21775
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-08-27 16:36:55 +02:00
Markus Stockhausen 025d7b0dda realtek: eth: stop TX queues before teardown
Stop all TX queues at the beginning of rteth_stop() before shutting
down phylink, hardware and NAPI.

This prevents new packets from entering the transmit path while the
device is being stopped and its TX and RX resources are being released.

Assisted-by: ChatGPT (OpenAI GPT-5.6 Sol)
Link: https://github.com/openwrt/openwrt/pull/24874
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-08-27 16:35:20 +02:00
Markus Stockhausen d108030728 realtek: eth: validate DSA trailer length
Check that the skb is large enough to contain the DSA trailer before
accessing it in rteth_get_dsa_port().

Without the check, packets shorter than four bytes could result in an
out-of-bounds access when looking for the RTL Otto trailer.

Return -ENOENT when no valid DSA trailer is present.

Assisted-by: ChatGPT (OpenAI GPT-5.6 Sol)
Link: https://github.com/openwrt/openwrt/pull/24874
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-08-27 16:35:20 +02:00
Markus Stockhausen 45924e925b realtek: eth: compact OF device match table
Use the common single-line style for the simple
entries in the OF device match table.

This makes the table more compact while preserving
the existing compatible strings and associated
configuration data.

No functional change intended.

Assisted-by: ChatGPT (OpenAI GPT-5.6 Sol)
Link: https://github.com/openwrt/openwrt/pull/24874
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-08-27 16:35:20 +02:00
Markus Stockhausen 81f18cf54c realtek: eth: check DMA ring allocations
The return values of the coherent DMA allocations for the
RX and TX ring data are currently not checked.

A failed allocation would leave either rx_data or tx_data
NULL and cause a NULL pointer dereference when the driver
later initializes or accesses the DMA rings.

Check both allocations during probe and return -ENOMEM with
an appropriate error message on failure.

Assisted-by: ChatGPT (OpenAI GPT-5.6 Sol)
Link: https://github.com/openwrt/openwrt/pull/24874
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-08-27 16:35:20 +02:00
Markus Stockhausen 945471dc7b realtek: eth: use local RX ring info in receive path
rteth_hw_receive() repeatedly accesses the RX ring state
through ctrl->rx_info[ring].

Introduce a local rx_info pointer for the selected ring and
use it throughout the receive path. This reduces repeated
array indexing and makes the relationship between the NAPI
instance and its per-ring state clearer.

No functional change intended.

Assisted-by: ChatGPT (OpenAI GPT-5.6 Sol)
Link: https://github.com/openwrt/openwrt/pull/24874
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-08-27 16:35:20 +02:00
Markus Stockhausen d595cba135 realtek: eth: remove unnecessary MAC address locking
rteth_set_mac_hw() uses the general driver spinlock
while programming the MAC address registers.

These registers are not accessed by the interrupt or
data paths, and MAC address changes are already serialized
by the netdevice control path. During probe, the function
is called before the netdevice is registered.

Remove the unnecessary spinlock from rteth_set_mac_hw().

Assisted-by: ChatGPT (OpenAI GPT-5.6 Sol)
Link: https://github.com/openwrt/openwrt/pull/24874
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-08-27 16:35:20 +02:00
Markus Stockhausen 155ffbfad8 realtek: eth: remove unnecessary MTU change locking
The TX timeout recovery is now performed from a workqueue
under RTNL, which serializes it against MTU changes.

The driver no longer needs to use its spinlock to prevent
the timeout recovery from reprogramming the packet length
and RX ring limits concurrently with ndo_change_mtu().

Remove the spinlock from rteth_change_mtu() and update the
corresponding comment.

Assisted-by: ChatGPT (OpenAI GPT-5.6 Sol)
Link: https://github.com/openwrt/openwrt/pull/24874
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-08-27 16:35:20 +02:00
Markus Stockhausen 85c0429b27 realtek: net: move TX timeout recovery to workqueue
The TX timeout handler currently performs the complete device
recovery while holding a spinlock. The recovery path stops and
resets the hardware, frees and reallocates DMA buffers, and
reinitializes the rings. Some of these operations may take a
considerable amount of time and should not be performed while
holding a spinlock with interrupts disabled.

Move the recovery into a workqueue so it runs in process
context. Stop all TX queues immediately when a timeout is
detected to prevent new packets from entering the transmit
path while recovery is pending.

Serialize the recovery with RTNL and reuse the regular device
stop and open paths instead of duplicating the hardware
teardown and initialization sequence in the timeout handler.

Cancel pending timeout recovery work during device removal
after unregistering the netdev, ensuring that no recovery
work remains before the driver's resources are released.

This also removes the need for the general driver spinlock
to serialize TX timeout recovery against operations performed
under RTNL, such as MTU changes.

Assisted-by: ChatGPT (OpenAI GPT-5.6 Sol)
Link: https://github.com/openwrt/openwrt/pull/24874
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-08-27 16:35:20 +02:00
Markus Stockhausen 540666c57a realtek: eth: guard repeated NAPI disable
Track the NAPI state explicitly to avoid calling napi_disable() more
than once without an intervening napi_enable().

A repeated rteth_stop() may otherwise attempt to disable an already
disabled NAPI instance, which is not supported and may block.

Set the flag after enabling all RX NAPI instances in rteth_open() and
clear it before disabling them in rteth_stop().

This makes the NAPI handling safe for repeated sequential calls to
rteth_stop().

Assisted-by: ChatGPT (OpenAI GPT-5.6 Sol)
Link: https://github.com/openwrt/openwrt/pull/24874
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-08-27 16:35:20 +02:00
Tanner Lane 7f03bc02b0 realtek: add support for MokerLink 10GT080M
The MokerLink 10GT080M is a 12-port managed switch based on the
Realtek RTL9313 SoC.

Specifications:
- SoC: Realtek RTL9313
- RAM: 512 MB
- Flash: 32 MB SPI NOR
- Ethernet: 8x 10GBASE-T (RTL8261BE), 4x SFP+ (10G)
- LEDs: 1x green system status (GPIO), per-port link/activity via
  the SoC LED engine
- Buttons: 1x reset
- Power: 100-240 V AC, 50/60 Hz, up to 60 W
- UART: 115200 8N1 on the front-panel RJ45 console port

Working: switching on the copper and SFP+ ports, SFP hotplug and
EEPROM access, copper and SFP+ port LEDs, system status LED, reset
button, PHY temperature monitoring, sysupgrade, and the persistent
JFFS2 overlay.

Installation:
Netboot the initramfs image over TFTP, then run sysupgrade from OpenWrt.
Connect to the serial console and press Escape during the one-second
U-Boot countdown. Configure the network parameters for the local TFTP
server, then initialize the switch and boot the image:

  RTL9310# setenv ipaddr 192.168.1.250
  RTL9310# setenv serverip 192.168.1.156
  RTL9310# setenv netmask 255.255.255.0
  RTL9310# rtk network on
  RTL9310# rtk 10g 54 dac300cm
  RTL9310# tftpboot 0x84f00000 openwrt-...-initramfs-kernel.bin
  RTL9310# bootm 0x84f00000

Port 54 is front-panel SFP+ port 12. Select the matching U-Boot media
mode when using a transceiver or a different DAC length. Once OpenWrt
has booted, copy the sysupgrade image to the device and install it with
sysupgrade.

The OpenWrt firmware partition replaces the stock RUNTIME1 partition.
The stock RUNTIME2 partition remains read-only and can be booted with
"boota 1" from U-Boot for recovery.

MAC addresses:
The base MAC comes from the U-Boot environment variable "ethaddr" in
the u-boot-env partition. Per-port LAN MACs are derived sequentially.

Signed-off-by: Tanner Lane <tannerln7@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/24905
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-08-27 16:34:17 +02:00
Shiji Yang a865bd92e2 kernel: bump 6.12 to 6.12.105
Changelog: https://cdn.kernel.org/pub/linux/kernel/v6.x/ChangeLog-6.12.105

All patches are automatically refreshed.

Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
Link: https://github.com/openwrt/openwrt/pull/24808
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
2026-08-27 02:06:32 +02:00
Shiji Yang bbddea7603 kernel: bump 6.12 to 6.12.104
Changelog: https://cdn.kernel.org/pub/linux/kernel/v6.x/ChangeLog-6.12.104

Upstream merged patches:
- bcm53xx/patches-6.12/353-ARM-dts-bcm-ns-fix-PCIe-controller-2-second-interrup.patch[1]
- generic/backport-6.12/429-01-v6.18-mtd-spinand-fix-direct-mapping-creation-sizes.patch[2]
- generic/backport-6.12/429-02-v6.18-mtd-spinand-try-a-regular-dirmap-if-creating-a-di.patch[3]
- generic/backport-6.12/429-03-v6.18-mtd-spinand-repeat-reading-in-regular-mode-if-con.patch[4]

Manually rebased patches:
- generic/pending-6.12/804-nvmem-core-support-mac-base-fixed-layout-cells.patch[5]
- generic/pending-6.12/809-01-nvmem-core-generalize-mac-base-cells-handling.patch[5]

All other patches are automatically refreshed.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v6.12.104&id=65f3f2ed15a87d950a23deef32b4ad6c4036a459
[2] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v6.12.104&id=f7d35b6043dcc38d2559822f755f9a25b2a6bc15
[3] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v6.12.104&id=e2b420e755e243a432a1c4a6184215fa24d6c799
[4] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v6.12.104&id=f1a4b9db4830bc9648afc6b96311380a807a30ae
[5] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v6.12.104&id=751cc15343161267cca89aa31a6da4a79ea1f8f0
Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
Link: https://github.com/openwrt/openwrt/pull/24808
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
2026-08-27 02:06:32 +02:00
Hauke Mehrtens ed545519ee bmips: enet: handle EPROBE_DEFER for the MAC address
Both bmips ethernet drivers call of_get_mac_address() and throw the
return value away. They then decide from the contents of an
uninitialised stack buffer whether a MAC address was found, and fall
back to eth_hw_addr_random() when it does not look valid. An
-EPROBE_DEFER is therefore turned into a random MAC address instead of
into a retry.

This did not matter while fixed-layout NVMEM cells were parsed
synchronously by the NVMEM core. Linux 6.12.104 picks up 751cc1534316
("nvmem: layouts: Add fixed-layout driver"), which drops the
"fixed-layout" entry from of_nvmem_layout_skip_table and turns it into
an ordinary NVMEM layout bus driver: nvmem_register() now only creates
the layout device and sets nvmem->layout, and the cells show up later,
when fixed_layout_probe() runs. Until then
nvmem_layout_module_get_optional() sees no bound driver and
of_nvmem_cell_get() returns -EPROBE_DEFER.

That window is hit on every boot rather than occasionally, because it
is link order and not a race. nvmem_init() is a subsys_initcall, but
the layout driver is a device_initcall and drivers/Makefile places
nvmem/ after both mtd/ and net/. The flash therefore registers its
NVMEM device first, the ethernet driver probes next and defers, and
only afterwards does the fixed-layout driver bind and add the cells.

28 bmips boards take their MAC address from a "fixed-layout" node and
bmips has no base-files fallback, so all of them would come up with a
random MAC address that changes on every boot. Propagate -EPROBE_DEFER
so that the probe is retried once the cell exists, the same way this
was already fixed for lantiq in 50e7e5c80d ("lantiq: xrx200: handle
EPROBE_DEFER for MAC address").

Fixes: 91a52f22a1 ("treewide: backport support for nvmem on non platform devices")
Fixes: 1c552eb44d ("bmips: add basic BCM6358 ethernet support")
Assisted-by: Claude:claude-opus-5
Link: https://github.com/openwrt/openwrt/pull/24808
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
2026-08-27 02:06:08 +02:00
Julius Bairaktaris 63605e5a9f qualcommax: use the upstream fix for the optional wcss_q6_bcr_reset
The wcss_q6_bcr_reset reset is not present in the IPQ8074 or IPQ6018
device trees, so devm_reset_control_get_exclusive() returns an error and
takes q6v5_wcss_probe() down with it. Patch 0116 works around this by
adding a per-SoC bcr_reset_required flag to struct wcss_data and skipping
the acquisition when the flag is false.

Linux 6.19 fixed the same problem upstream in commit 641092c1bc1b
("remoteproc: qcom_q6v5_wcss: use optional reset for wcss_q6_bcr_reset"),
by switching to devm_reset_control_get_optional_exclusive(), which returns
NULL instead of an error when the reset is absent from DT. That covers
everything the flag did, without carrying per-SoC data for it.

Replace 0116 with a backport of the upstream commit, and drop the now-dead
.bcr_reset_required initialiser from 0136, where it is an added line, and
from the context of 0905 and 0910. 0119 and 0908 are refresh-only.

Behaviour is unchanged on every affected SoC. Before and after,
wcss_q6_bcr_reset ends up NULL on IPQ8074 and IPQ6018, and its only
consumer, reset_control_deassert() in q6v5_wcss_qcs404_power_on(), is
never reached there, because that path runs only through the QCS404 ops,
and is a no-op on NULL in any case. QCS404 declares the reset in DT, so
the optional getter still finds it there.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/24433
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-08-26 22:25:10 +02:00
Robert Marko eb7a45bc8f qualcommax: refresh SSR patch
I forgot to refresh the SSR fix before pushing, so refresh it.

Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-08-26 13:23:24 +02:00
Robert Marko 1bf6bd8017 qualcommax: fix IPQ6018 WCSS SSR name
The Linux 6.18 patch refresh moved the IPQ6018 SSR-name workaround's
second hunk to the IPQ8074 data. As a result, IPQ8074 used "wcnss"
while IPQ6018 retained the invalid "q6wcss" name.

Stopping WCSS sends this name to RPM. On IPQ6018, "q6wcss" causes a
watchdog reset, and the following warm boot hangs in SBL1 during
Pre_DDR_clock_init.

Restore IPQ8074's original name and assign "wcnss" to IPQ6018 as the
workaround intended.

Fixes: 97f8b0878d ("qualcommax: 6.18: update patches")
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-08-26 13:16:23 +02:00
Stanislaw Pal 86b584bd09 qualcommax: fix SoC hang after the CMN PLL probe on IPQ5018
The ipq-cmn-pll driver enables the GCC AHB & SYS clocks of the CMN block
through a runtime PM reference taken in probe, registers its clocks and
then drops the reference again, so pm_clk gates both clocks a few
milliseconds after probe returns.

IPQ5018 does not survive that gate. Boards die silently within
milliseconds of the CMN PLL probe, before userspace exists and with no
consumer of the PLL outputs active; depending on the binary layout this
ranges from an occasional hang to a fully reproducible boot loop. The
current snapshot images for the GL.iNet GL-B3000 boot loop for this
reason - booting the very same image with
initcall_blacklist=ipq_cmn_pll_clk_driver_init gets the board up, and so
does this patch, which is how it was isolated.

Hold a devres-managed runtime PM reference so the bus clocks stay
enabled while the driver is bound.

The mechanism has since been isolated across three boards from three
vendors (Archer AX55 v1, GL-B3000, Cudy P5): the asynchronous gate
lands amid early-boot bus activity and hangs the SoC, while gating the
same clocks on an idle, booted system is harmless. On the Cudy P5
stretching the end of probe by ~15 ms avoids the hang; on the GL-B3000
neither 15 ms nor 2 s helps (8 of 8 boots die each), so a delay is a
diagnostic, not a workaround - holding the reference is the only
arrangement that boots deterministically on all three boards.

Submitted upstream (v4, with these findings):
https://lore.kernel.org/linux-clk/20260813093351.178419-1-kuncy7@gmail.com/

Signed-off-by: Stanislaw Pal <kuncy7@gmail.com>
Tested-by: Georg Seema <georgseema@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/24653
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-08-26 11:17:25 +02:00
Julius Bairaktaris 6c12b87ffc qualcommax: qca_ppe: report hardware MIB counters in port statistics
The PPE forwards traffic between its ports in hardware, so frames that are
bridged from one port to another never reach the host. The per-port
software counters only ever account for the frames that were punted to the
CPU, and the interface statistics consequently under-report bridged traffic
by several orders of magnitude: transferring 1.10 GB between two ports of
the same bridge on an IPQ8074 board leaves the receiving port reporting
2724 transmitted bytes. Routed traffic crosses the host on its way between
the two ports and is counted correctly, which is why this mostly goes
unnoticed.

Every frame does cross the port's MAC, which maintains its own MIB
counters, and the driver already reads those for ethtool -S. Report them
through get_stats64 as well, so that the interface counters reflect what
actually crossed the wire, no matter which engine forwarded it. mt7530 and
ar9331 report their port statistics from the hardware the same way, as do
the ssdk and nss-dp vendor drivers for this hardware.

A port is not bound to one MAC. Ports 5 and above drive either the GMAC the
port number names or an XGMAC, and whichever block is idle reads back zero,
so one MIB address per counter answers with zeroes for half the mux
positions. Each row of the table therefore carries its counter twice, as
the GMAC expresses it and as the XGMAC MMC block does, because the two
disagree on address and on width: the GMAC keeps most counters in a single
32-bit register and the XGMAC in a low/high pair. Where the XGMAC has no
equivalent the row carries offset 0 and the counter reads zero, which is
the honest answer for the collision counters, the alignment errors and the
bad receive byte count - the XGMAC is full duplex and exposes only a
good+bad octet total, and deriving a bad count by subtracting the good one
would invent a counter the hardware does not keep. Two names shift meaning
on such a port: the XGMAC lumps 1519-and-up into its 1024-to-max bin, so
rx_1024_1518byte and tx_1024_1518byte hold the whole 1024-to-max range
there and the 1519_maxbyte pair reads zero.

Both MIBs are free running and the GMAC keeps most of its counters in 32
bits, so the register value is not what rtnl_link_stats64 has to present: a
port at line rate with minimum-sized frames wraps a packet counter in under
49 minutes at 1G and in under five at 10G, and a total taken straight from
the register steps backwards there. Each port therefore keeps a 64-bit
total per counter alongside the raw value that total was last brought up to
date from, and a fold adds the difference in at the width of the register
it came from. get_stats64 and ethtool -S both fold before they answer, so
neither lags the hardware and the two agree, and a delayed work folds every
user port every 30 seconds so that a counter nothing reads cannot wrap
twice unobserved.

A difference is only meaningful across a counter that kept running, so two
things take a baseline instead of a difference, and both take it at the
moment the counter they read stops being the one the total was built from.
qca_ppe_mac_config() asserts the port reset, which zeroes the MIB that port
owns: the counters are banked before the reset, the rebase is held across
it so that a fold arriving from another CPU cannot consume it while the
counters are still running, and the baseline is taken from the cleared MIB
as soon as the reset is released, while the MAC is still stopped. Deferring
it to the periodic fold instead would discard everything the port counted
from link-up. Left unguarded the reset lands every 32-bit counter on 2^32
plus its true value and every 64-bit one back on zero, which is what the
difference against a stale baseline comes to in each width.

A port muxed to its XGMAC likewise starts reading a second MAC's counters,
which advance independently of the first. qca_ppe_mac_link_up() banks what
the MAC the port is leaving counted, changes the bank under mib_lock, and
baselines the one it arrives on in the same critical section, so that the
change costs neither the tail of the old MAC's counting nor the head of the
new one's.

The MIB block is reached through an MMIO regmap, whose accesses are
spinlock protected and therefore safe in the atomic callers of
ndo_get_stats64 - dev_get_stats() is reachable under a spinlock from
bond_get_stats(). Every site takes mib_lock with softirqs disabled, so the
lock has one acquisition mode rather than two. The two halves of a 64-bit
counter are read in separate statements so that the order is not left to
the compiler, low half first,
which is the order the reference ssdk driver uses for them
(adpt_hppe_get_mib_info(), adpt/hppe/adpt_hppe_mib.c,
NHSS.QSDK.14.0.r8-00026-O). Nothing added here consumes the counters it
reads: setup writes PPE_MIB_EN without PPE_MIB_RD_CLR, and MMC_CONTROL's
reset value leaves RSTONRD clear.

The XGMAC arm is inspection-only: there is no XGMAC port on the bench. The
GMAC arm is what the board's copper ports exercise.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/24229
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-08-25 14:34:15 +02:00
Alexander Astrovsky a3357c90be wifi-scripts: mac80211: fix 6 GHz 40 MHz channel configuration for non-AP modes
In `iw_htmode()`, 40 MHz modes (HE40/EHT40) on the 6 GHz band fell through
to the 5 GHz HT40+/HT40- calculation. Since 802.11n HT modes do not exist
in 6 GHz, `iw` commands like `iw dev <ifname> set freq <freq> HT40+` fail
in cfg80211 with `-EINVAL` (`invalid channel definition`).
Fix this by adding 6 GHz band handling in `iw_htmode()` to calculate and
return the 40 MHz center frequency (`40 <center_freq>`).

Signed-off-by: Alexander Astrovsky <astrouski@google.com>
Link: https://github.com/openwrt/openwrt/pull/24876
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-08-24 19:48:10 +02:00
Balsam CHIHI 05d2d5626d qualcommbe: fix 1000BASE-X SFP support on IPQ9574
Update the existing 0342-net-qualcomm-Update-IPQ9574-PPE-driver.patch
to fix an oversight in the out-of-tree qcom_ppe driver where
PHY_INTERFACE_MODE_1000BASEX was missing from the MAC speed clock rate
configuration switch statement.

Without this fix, inserting a 1G fiber SFP module into the 10G MAC throws
an -EOPNOTSUPP (-95) error during phylink negotiation, preventing the link
from coming up. Routing 1000BASE-X to the GMII clock helper restores native
1G SFP module hot-swapping on IPQ9574 boards like the 8devices Kiwi-DVK.

Signed-off-by: Balsam CHIHI <balsam.chihi@moment.tech>
2026-08-24 19:38:49 +02:00
Chuanhong Guo 7f6895da27 siflower: switch to kernel 6.18 and drop 6.12
The only two boards supported in this target are tested with 6.18
and they both work fine.
Switch to 6.18 directly without going through a testing phase.

Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
2026-08-24 23:02:39 +08:00
Chuanhong Guo 46da9cc91b siflower: fix drivers for kernel 6.18
Update drivers for 6.18.

For SF19:
1. update the GPIO set callback to return status and use the restored
   platform driver remove callback.
2. drop the obsolete PCS-ignore flag. Linux 6.18 removed the broken
   legacy PCS ethtool and carrier handling, making phylink
   authoritative unconditionally.

For SF21:
1. update the PCIe and XPCS remove callbacks
2. pass the new negotiation mode argument to the PCS state callback
3. replace the now-private init_dummy_netdev() helper with an allocated
   dummy netdev.
4. Track initialized NAPI contexts so probe failures and device removal
   release only valid resources.

Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
2026-08-24 23:02:39 +08:00
Chuanhong Guo e4ef66738c siflower: refresh kernel 6.18 configurations
refresh kconfig for both subtargets and disable a few new riscv
vendor extensions unrelated to this board.

Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
2026-08-24 23:02:39 +08:00
Chuanhong Guo d5f689e2cb siflower: refresh kernel 6.18 patches
all patches refreshed without conflicts.

Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
2026-08-24 23:02:39 +08:00
Chuanhong Guo 16caec1f66 siflower: restore files for v6.12
This is an automatically generated commit which aids following Kernel patch
history, as git will see the move and copy as a rename thus defeating the
purpose.

For the original discussion see:
https://lists.openwrt.org/pipermail/openwrt-devel/2023-October/041673.html

Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
2026-08-24 23:02:39 +08:00
Chuanhong Guo f93de5b0e2 siflower: create files for v6.18 (from v6.12)
This is an automatically generated commit.

When doing `git bisect`, consider `git bisect --skip`.

Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
2026-08-24 23:02:39 +08:00
Robert Marko 8df271d134 microchipsw: use MMC patches pending upstream
Instead of the whole series from Microchips UNG kernel, use the simple
upstream pending support.

Update the Tactical 1000 DTS with driver changes.

There is no HS200 support in the SoC controller.

Signed-off-by: Robert Marko <robert.marko@sartura.hr>
2026-08-24 14:17:44 +02:00
Andrew LaMarcheandFrank Wunderlich 554b5dcc51 mediatek: add support for BananaPi BPi-R4 Pro 8X
The BPi-R4 Pro 8X is a Wi-Fi 7 router board based on the MT7988A SoC.

Specification
-------------

- SoC:		Mediatek MT7988A (4x Cortex-A73 @1.8GHz)
- RAM:		8GB DDR4
- Flash: 	256MB SPI-NAND, 8GB eMMC, microSD Slot
- Switch:	MT7988A built-in switch, MxL86252C
- PHYs:		2x AS21010P
- Ports:	9 ports, 7 usable simultaneously
	* 1x 1G RJ45 LAN
	* 4x 2.5G RJ45 LAN
	* 1x 10G RJ45/SFP Combo
	* 1x 10G RJ45/SFP Combo
- Buttons:	Reset, WPS
- LEDs:		Power
- USB:		On-board VIA VL822 USB3.2/USB2.0 hub
	* 1x USB-A 2.0 connector
	* 1x USB-A 3.2 connector
	* 3x NGFF-KEYB
- PCIe:
	* 2x mini-PCIe slots with PCIe 3.0 2-lane interface
	* 2x M.2 M-Key slots with PCIe 3.0 1-lane interface (switchable
	  PCIe signal with M.2 B-Key)
- Debug:	USB Type-C console port
- Power:	USB Type-C PD 20V or DC barrel connector

Note: This device comes without a MAC address programmed from the
factory. The randomly generated MAC is stored in the U-Boot env on first
boot and used persistently afterwards.

Installation
------------

Uncompress *sdcard.img.gz and write to microSD card, eg. using 'dd'. Use
bootloader menu on the serial console to install SPI-NAND once installed
to SPI-NAND you can used the bootloader menu to install to eMMC. See
instructions for BananaPi R4 for details.

Co-authored-by: Frank Wunderlich <frank-w@public-files.de>
Signed-off-by: Andrew LaMarche <andrewjlamarche@gmail.com>
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2026-08-24 13:00:51 +01:00
Andrew LaMarcheandFrank Wunderlich 3aa068ac71 uboot-mediatek: add support for BananaPi BPi-R4 Pro 8X
The BPi R4 Pro 8X can boot from microSD, SPI-NAND and eMMC. Add support
for each storage option.

Co-authored-by: Frank Wunderlich <frank-w@public-files.de>
Signed-off-by: Andrew LaMarche <andrewjlamarche@gmail.com>
2026-08-24 13:00:51 +01:00
Julius Bairaktaris 3052766a83 qualcommax: qca_ppe: take both XLT indices before programming a VLAN
qca_ppe_port_vlan_add() allocates two XLT indices. The first is taken
before anything is written, and its failure path drops the port from the
entry again. The second, for the pvid rule, is taken from the middle of
the function: by then entry->ports carries the port, the membership XLT
rule and the egress tag mode are programmed, PPE_PORT_DEF_CVID has been
rewritten, priv->port_pvid[port] has been overwritten and the port is in
entry->pvid_ports. Its -ENOSPC return leaves all of that behind.

Nothing undoes it. DSA returns the driver error straight out of
dsa_port_do_vlan_add(), and the bridge does not add the VLAN to the port
on that path either, so no port_vlan_del() follows. The port keeps a
pvid in hardware that the driver's own state does not describe, and the
early return also skips ppe_vlan_members_update(), so the membership XLT
rule classifies the port's tagged frames into a VSI whose member mask
still excludes it.

Take both indices up front, before the first register write and before
the port joins entry->ports. Nothing is programmed until every resource
the call needs is in hand, so there is nothing to unwind: the failure
path only has to release an entry this call allocated, which is the one
that still has no members. In particular nothing has to remember the
pvid the port held before. That last part is not a detail an undo could
have got right cheaply: moving a pvid from one VLAN to another is a
single port_vlan_add() on the new VLAN (__vlan_add_pvid() just moves
vg->pvid), so restoring 0 would have left a port that had a working
pvid with none at all.

Deferring the entry->ports update is what makes one failure path serve
both allocations. The first can only fail on a fresh entry, so dropping
the port again was exact there; the pvid one cannot - xlt_pvid_idx is -1
for any VLAN that has no pvid port yet, including one with several
tagged members, and the bridge re-notifies an existing VLAN when its
flags change.

Not reachable today: PPE_VSI_MAX * 2 == PPE_XLT_TBL_NUM, so any
arrangement that exhausts the XLT pool has already given every entry its
pvid index and the second allocation never fails. That is an accident of
two constants rather than an invariant - raising PPE_VSI_MAX without
raising PPE_XLT_TBL_NUM opens it.

Fixes: 142104bb90 ("qualcommax: add PPE driver")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/24535
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-08-24 10:04:30 +02:00
Julius Bairaktaris dc4a7a1ff0 qualcommax: pcs: qca-uniphy: configure the UNIPHY instance once per mode
qca_uniphy_pcs_config_mode() runs the instance-wide UNIPHY initialization
- analog PLL reset, MODE_CTRL update, UNIPHY soft reset and calibration -
on every phylink pcs_config call, i.e. once per port. On a multi-channel
instance (PSGMII: five channels behind one SerDes) a cold boot executes
this sequence up to five times within ~2 seconds (preinit plus one netifd
ifup per port), and each run tears down the channels that already synced.
Whether every QCA8075-side SerDes lane re-locks against the re-calibrated
UNIPHY is timing luck: roughly one boot in three left one port (whichever
lost the race) with link up and working TX but a dead receive path - the
GMAC receives almost nothing (2 frames total, zero rx errors), ARP stays
INCOMPLETE, and only an admin down/up of the port (or a reboot) recovers
it. An autoneg restart or a cable replug does not, since carrier-only
cycles never touch the PCS.

This is a plain host-stack failure: it reproduces on a stock qualcommax
image with no offload driver loaded.

The vendor driver never re-runs this sequence: the SSDK configures the
UNIPHY mode once (__adpt_hppe_uniphy_psgmii_mode_set) and per-port
operations only touch channel state afterwards.

Record the configured interface mode in struct qca_uniphy (the member
already existed, unused) and skip the instance-wide sequence when
pcs_config is called again for the same mode; the per-channel IPQ5018
force-mode handling still runs on every call. A genuine mode change
re-runs the full sequence. This also removes ~1.5 s of redundant reset
sleeps from every boot.

The cached mode needs a lock of its own. phylink serializes pcs_config
per netdev, so on a multi-channel instance two ports can enter the
function concurrently, both find the cache empty and both run the
sequence - the very thing being removed here, and now with one channel
resetting the instance while the other polls calibration. Serialize the
test and the sequence on a per-instance mutex, and clear the cache before
the sequence so a bail-out cannot leave a mode recorded that the hardware
does not have.

The sequence disables the calling channel's TX and RX clocks and
re-enables them at its end, so a calibration timeout leaves them off.
Until now the next pcs_config call re-ran the sequence and restored them,
tripping clk_core_disable()'s "already disabled" WARN on the way. With an
unchanged mode now skipping the sequence, a channel whose calibration
timed out while another channel of the instance succeeded would keep them
off until a genuine mode change, so the bail-out re-enables them itself.
The pair moves as a bulk, which unwinds a partial enable, and a flag per
channel records whether the driver left it on, so a clock that will not
enable cannot make the next call disable an already disabled one. The
mode is cached after the last step of the sequence, so that any failure
below the invalidation - a clock, the XPCS reset release, the reference
clock - leaves the next call running the sequence again rather than
skipping it.

Validated on a Xiaomi AX3600 (IPQ8074, four QCA8075 PSGMII ports, kernel
6.18): the failure reproduced within 3 boots before the change; with it,
three boots each came up with a single instance configuration, RX and TX
counters moving on every port, and no clock warning in dmesg. Forcing one
port through 1000, 100 and 10 Mbps left the other channels' registers
untouched and traffic flowing at each step. The calibration bail-out and
the XPCS paths are not reachable on this board and were not exercised.

The reset operations the sequence runs are checked with everything else that
can fail ahead of the cache, so a mode is never recorded for an instance whose
reset did not take: a stale CALIBRATION_DONE would otherwise let the poll pass
and the cache would then skip the sequence for good. The two after the clock
disable share the calibration timeout's clock restore. No in-tree consumer can
reach the new branches - every UNIPHY reset comes from &gcc, whose
qcom_reset_set_assert() discards the regmap return and always reports success -
so this makes the invariant hold by construction rather than by which provider
is wired up.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/24186
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-08-24 10:01:19 +02:00
Julius Bairaktaris 358ee77e16 qualcommax: pcs: qca-uniphy: set MAC mode for PSGMII and QSGMII
The QCA8075 LAN/WAN ports on IPQ807x run through the UNIPHY PSGMII
rate-adaptation adapter, which carries 10 and 100 Mbps over the fixed
PSGMII line rate by code-group (de-)replication. Which sub-gigabit datapath
the adapter uses is selected by the MODE_CTRL_25M field of UNIPHY_MODE_CTRL,
which must stay at its MAC reset value for the SGMII family of modes.

The SGMII and 2500BASEX cases already program MODE_CTRL_25M=MAC, but the
PSGMII and QSGMII cases did not, while the shared MODE_CTRL write mask clears
the field. Both therefore ran with MODE_CTRL_25M=0, mis-configuring the
sub-gigabit adapter: every 10 and 100 Mbps frame was mis-sampled and dropped
on RX, while 1000 Mbps (which uses the full-rate datapath) was unaffected.

Program MODE_CTRL_25M=MAC for PSGMII and QSGMII, matching the SGMII/2500BASEX
cases and the value the QCA SSDK leaves in place. 10, 100 and 1000 Mbps RX all
work on an AX3600 (QCA8075, PSGMII). QSGMII is the only other SGMII-family mode
in this switch and is cleared by the same mask, so it had the same defect by
construction, but no QSGMII board was available to confirm the symptom on
hardware.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/24186
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-08-24 10:01:19 +02:00
Julius Bairaktaris e616833278 qualcommax: pcs: qca-uniphy: take a channel's clock pair as a bulk
pcs_enable() enables a channel's RX clock and then its TX clock, and
returns as soon as one of them fails - leaving the other one enabled.
Nothing rebalances that: the next call enables the survivor a second
time, and the pair never lines up again. pcs_disable() has the mirror
shape without the checks.

The two are adjacent entries of the bulk array the driver already holds,
so clk_bulk_enable() takes them in one call and unwinds what it enabled
when one fails - the property the open-coded pair is missing.

That leaves the other half of the same imbalance: phylink discards what
pcs_enable() returns and calls pcs_disable() either way, so a channel
whose clocks would not enable still gets a reference dropped that was
never taken, underflowing the enable count. Record per channel whether
the driver left the pair on, and disable only what it enabled.

Not exercised on hardware: both call sites are IPQ5018-only and the
board here is an IPQ8074, where the driver leaves the port clocks to the
configuration sequence.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/24186
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-08-24 10:01:19 +02:00
Daniel Golle f0204d78e1 generic: 6.18: sync MxL862xx DSA switch driver
Support for the SerDes ports has been merged upstream, firmware
update support has gained several robustness and recovery features.
Trapping of link-local traffic has also been improved and now allows
multicast snooping to work as expected.
Add more sophisticated ready-state assessment to avoid racing of the
driver with the firmware applying the initial default configuration.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2026-08-23 23:00:01 +01:00
Andrew LaMarche 3d902d07a9 qualcommbe: remove source-only
Drop source-only from qualcommbe target as we have some supported
devices now.

Signed-off-by: Andrew LaMarche <andrewjlamarche@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/21586
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-08-23 18:07:01 +02:00
Andrew LaMarcheandKenneth Kasilag 31c49dd076 qualcommbe: add support for Askey SBE1V1K
This commit adds support for Askey SBE1V1K.

Device specification
--------------------
SoC:		Qualcomm IPQ9570
RAM:		Micron (2GB)
Flash:		8GB eMMC
Ethernet:	1x 10G RTL8261BE
		1x 2.5G QCA8081
		2x 1G QCA8075
Wi-Fi:		QCN6214 2.4GHz 4x4
		QCN6274 5GHz 4x4
		QCN6274 6GHz 4x4
LEDs:		1 LED, power/status
Buttons:	1 reset
USB ports:	none
Bootloader:	U-Boot 1.0.9 [spf12.2_CSU2] (Jun 28 2024 - 17:47:10 +0000)

Installation (serial required):

**NOTE** This procedure requires glitching the eMMC. It is very possible
that you may damage or corrupt your bootloader in doing so. Proceed with
caution, and always make a full eMMC backup!

**NOTE** If the bootloader has trouble accessing eMMC due to glitching it, any
U-Boot env updates are written directly to the start of flash, overwriting
the bootloader. For this reason, it is strongly NOT recommended to make any
persistent U-Boot env changes from U-Boot itself; do this in Linux.

- Open the chasis and connect to the serial port.
- While booting, short eMMC CLK to UART VCC during FIT image load to enter
  U-Boot.
- setenv ipaddr 192.168.1.1
- setenv serverip 192.168.1.2
**NOTE** DO NOT SAVE THE ENV
- Set your PC IP address to 192.168.1.2 and host the initramfs on a tftp
  server.
- tftpboot 0x44000000 initramfs.itb
- bootm 0x44000000
If you get an error and it reboots, try loading to 0x80000000.

In the initramfs:
- fw_setenv bootargs 'console=ttyMSM0,115200n8 rootwait root=/dev/mmcblk0p27'
- fw_setenv bootcmd 'echo "Hit ctrl+c for shell..."; if sleep 3; then run do_boot; else do_nothing; fi;'
- fw_setenv do_boot 'mmc read 0x44000000 0x00014022 0x3800; bootm 0x44000000'
- Install a sysupgrade

U-Boot hardcodes the bootargs to reset on each boot, which is why it is
necessary for the bootcmd to override them. Thankfully, the vendor did
not bother to secure U-Boot any further. As long as the vendor software
does not boot, the U-Boot env will stay. If a vendor image boots, the
U-Boot env will revert to default. The vendor U-Boot also ignores
bootdelay, which is why we add a dummy sleep to allow the user time to
drop into a shell without needing to glitch any more.

Co-authored-by: Kenneth Kasilag <kenneth@kasilag.me>
Signed-off-by: Andrew LaMarche <andrewjlamarche@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/21586
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-08-23 18:07:01 +02:00
Andrew LaMarche f1c1d8b76d qualcommbe: enable CONFIG_NVMEM_BLOCK
Enable CONFIG_NVMEM_BLOCK to support block devices in dts, used for
reading nvmem.

Signed-off-by: Andrew LaMarche <andrewjlamarche@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/21586
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-08-23 18:07:01 +02:00
Robert Marko 7628d11ca5 ipq-wifi: update to Git HEAD (2026-08-23)
0c67bbcca45f qnc9274: add Askey SBE1V1K BDF + regdb

Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-08-23 18:04:56 +02:00