check your DM
For anyone curious:
You'll find IPQ5322 driver sources, firmware images, bootloaders etc. in the Cudy WR11000 GPL release (keyword: GPL_for_BE11000_20250120) with the obvious caveat that this is still QCOM IP, so lifting them straight up is not going to fly upstream.
qualcommbe targets was indeed moved to Kernel 6.18 in PR# 23908.
It probably will affect the entire list of PR submissions of all qualcommbe devices.
cool!
I've been waiting for this to happen, been checking the status now and then, so I could try building an image for a different qualcommbe device (yes, I know it was doable prior to this too, only harder).
I have a sysupgrade file that can be loaded from the original firmware and switches to openwrt (only ethernet is working in this version):
sysupgrade -n openwrt-gl-be9300.community-sysupgrade.bin
Then a normal sysupgrade can be used to upgrade to another version.
Nice β booting from the stock firmware via sysupgrade is exactly the UART-less path we were after.
When you say "only ethernet working" β which ports specifically, and at what speeds? I'm curious about:
- the 2.5G WAN β is it linking at 2.5G?
- the LAN ports β are all of them forwarding, or only some?
- and whether the 4th physical jack works for you. On my bench unit that one's dead in hardware, so if yours works it tells us it's my board rather than the port mapping.
(On WiFi: both radios come up with real clients on my tree, so if it's fully dead on yours we're probably just out of sync on the ath12k side β happy to point you at the patches.)
Lan2,3,4 works
WAN does not work, I do not see it detected (I see eth0, lan1-4 interfaces only).
This is my dmesg: https://pastebin.com/XCwRMBFd
If you could provide pointers related to ath12k enablement, please let me know.
Also I saw openwrt master is using 6.18 now, would that make the support easier ?
Thank you, could it work to the flin3? The link has the firmware. Thank you
Hiiii, I used this link from Uboot and it didn't work for me. Because It install glinet firmware ... Thank you for your help!
Hi @Ger
That image is a sysupgrade image β it has to be applied from a running system, it can't be flashed from U-Boot. When you load it in U-Boot recovery, U-Boot doesn't use it and falls back to the GL.iNet recovery, which reinstalls the stock GL firmware. That's why you ended up with GL.iNet firmware.
The way to install it:
- Boot the stock GL.iNet firmware (you already have it).
- Connect over SSH (ssh root@192.168.8.1). You have to set up root password first (via Web GUI).
- Copy the file to the router, e.g.:
ssh root@192.168.8.1 "cat > /tmp/sysupgrade.bin" < ~/openwrt-gl-be9300.community-sysupgrade.bin - Then on the router:
sysupgrade -n /tmp/sysupgrade.bin
One important tip: run it over an interactive SSH session (ssh -tt root@192.168.8.1) or from the LuCI System β Backup / Flash Firmware page. A plain non-interactive SSH command can silently drop the second stage and look like nothing happened.
Heads-up: in this build only Ethernet works (no Wi-Fi yet), as catalinii noted. Once it's installed you can sysupgrade normally to newer builds.
Hi @perceival, I took a look at your rtl8372n.c β nice work getting the chip ID + MDIO indirect access working. Here are some gaps I spotted that should be fixed before the driver is really usable:
1. Confirm DSA_TAG_PROTO_RTL8_4 protocol byte
tag_rtl8_4.c in mainline hardcodes Protocol = 0x04 in tag16[1] high byte β that's the RTL8365MB protocol byte. If RTL8372N/8373N uses a different value, rtl8_4_read_tag() will reject every RX frame with unknown realtek protocol and return -EPROTO, meaning RX is silently dead even if the chip is switching correctly.
You already have rtl8372n_capture_enable() enabled in probe β can you dump a raw frame at eth0 via AF_PACKET and check byte 3 of the tag against 0x04? If it differs, a new tagger is needed.
2. Missing port_change_mtu / port_max_mtu
Your README already documents this: "full-1500 frames are silently dropped on the CPU/Wi-Fi path". Without these callbacks DSA doesn't bump the conduit MTU to account for the 8-byte tag headroom. port_max_mtu should return ETH_DATA_LEN for user ports and ETH_DATA_LEN + RTL8_4_TAG_LEN for the CPU port. Straightforward to add.
3. port_bridge_join never sets *tx_fwd_offload = true
static int rtl8372n_port_bridge_join(struct dsa_switch *ds, int port,
struct dsa_bridge bridge,
bool *tx_fwd_offload, /* always left false */
struct netlink_ext_ack *extack)
{
dev_info(ds->dev, "port %d bridge_join (offload accepted)\n", port);
return 0;
}
Leaving tx_fwd_offload false tells the bridge that the switch can't hardware-forward between slave ports, so the bridge handles all inter-port traffic in software through the CPU. The RTL8372N does exactly the opposite β it switches in hardware β so this needs *tx_fwd_offload = true. The comment above the function explains why the callback exists but the value never gets set.
4. No FDB/MDB callbacks
.port_fdb_add // missing
.port_fdb_del // missing
.port_fdb_dump // missing
.port_mdb_add // missing
.port_mdb_del // missing
Without these, the Linux bridge can't push learned MACs into the switch's L2 LUT. The switch ends up flooding unknown unicast out all ports (or punting to CPU) instead of doing real hardware forwarding. You already have rtl8372n_l2_static_fdb_add() used in dsa_setup to pin the conduit MAC β just needs wiring up as a proper DSA callback.
5. No port_stp_state_set
You already have RTL8372N_REG_MSPT_STATE, RTL8372N_MSPT_FORWARDING, and the per-port macros defined. Without the callback, STP state changes from the bridge (DISABLED / BLOCKING / LEARNING / FORWARDING) are never pushed to the chip, so ports can get stuck or cause loops when interfaces go up/down.
Getting 1β5 sorted would make the driver correct at the DSA L2 layer. After that, the next step would be wiring up port_setup_tc / cls_flower callbacks on the switch side so the SoC's PPE/EDMA can actually bind flow offload entries for traffic going through the RTL8372N.
Thanks β genuinely useful pass, exactly the DSA-layer scrutiny the driver needed. Worked through it; status below.
(1) Tag protocol β checked, and good news: I captured three real LAN frames off eth0 via AF_PACKET with capture_enable on, and the Realtek tag byte is 0x04, sitting between SA and EtherType β matches tag_rtl8_4.c exactly. RTL8372N shares the RTL8365MB protocol byte, so no new tagger needed; RX decodes fine.
(2) MTU, (3) tx_fwd_offload, (5) STP β done (compile-clean on my 6.18 branch):
port_max_mtu/port_change_mtu: reportETH_DATA_LEN,+8(rtl8_4 tag) on the CPU port, so DSA bumps the conduit MTU and full-1500 frames stop dropping (I'd been papering over it with a hotplugip link set eth0 mtu 1600).tx_fwd_offload: now settrueinport_bridge_joinβ the chip forwards between user ports in hardware, so no more forcing software bridging through the CPU.port_stp_state_set: wired to theMSPT_STATEregister (disabled / blocking / learning / forwarding).
Getting there meant restoring the full driver first β my in-progress 6.18 rebase branch had it cut down to 3 callbacks. The one real 6.12β6.18 break was phylink: mac_link_up/mac_link_down moved out of dsa_switch_ops into a struct phylink_mac_ops (config-based), so I moved them there and wired ds->phylink_mac_ops. Everything else compiled as-is.
(4) FDB/MDB β deferring this one deliberately for now. port_fdb_add is a trivial wire onto the existing l2_static_fdb_add, but there's no l2 delete helper and port_fdb_dump needs full LUT iteration β new hardware LUT sequences I'd rather validate against the chip than write blind. I'll bring it in once the ethernet is up on 6.18.
Which is the one spot I'd genuinely welcome your eye, since you know the PPE side: on 6.18 the ethernet isn't fully up yet. qcom_ppe probe bails with:
nss_cc_ppe_clk_src: rcg didn't update its configuration
The uniphy PCS clocks are stuck at 12/24 MHz instead of switching to the high source, so the PPE clock can't leave the XO. Looks like the old PCS/uniphy source-select problem.
(Separately: the board was hard-resetting with an SBL NoC Error [0x6] until I traced it to clk_disable_unused gating a NoC-path clock β clk_ignore_unused clears that reset cleanly, and it's unrelated to the RCG.)
If you've got any IPQ5332 pointers on getting the uniphy port clocks to feed, that's the current gate.
cls_flower / flow-offload direction noted too β thanks!
Thank you for the clarification and for your work on bringing OpenWrt to the BE9300.
I have one technical question before proceeding with the installation. After flashing the community sysupgrade image from the stock GL.iNet firmware, does the device boot into a completely standard OpenWrt environment, replacing all GL.iNet customizations and the 4.8.4 web interface, or are any GL.iNet components/packages retained?
I'm mainly trying to understand whether this image performs a full migration from the GL.iNet firmware to upstream OpenWrt, or if it keeps part of the vendor software stack.
Thanks again for your help.
German
I checked the stock FDT properties against the multipd/ath12k code paths. Most stock QSDK/CNSS properties are probably noise for the current -12.
My view of what is a useful delta is only this:
q6v5_wcss: remoteproc@d100000 {
firmware-name = "IPQ5332/q6_fw0.mdt",
"IPQ5332/iu_fw.mdt";
};
q6_wcss_pd1: pd-1 {
firmware-name = "IPQ5332/q6_fw1.mdt";
};
q6_wcss_pd2: pd-2 {
firmware-name = "IPQ5332/q6_fw2.mdt";
status = "disabled";
};
q6_wcss_pd3: pd-3 {
firmware-name = "IPQ5332/q6_fw3.mdt";
status = "disabled";
};
My reasoning:
- Current DTS has PD1/PD2/PD3 all using q6_fw0.
- Qualcommβs public IPQ5332 multipd reference maps PD1/PD2/PD3 to q6_fw1/q6_fw2/q6_fw3.
- Public qcom_q6v5_mpd reads root firmware-name as an array and loads firmware[1+] with qcom_mdt_load_no_init(), so IU belongs as root firmware-name[1] in the mainline-style path.
- Public qcom_q6v5_mpd reads userPD child firmware from firmware-name only; I do not see it consuming stockβs iu_firmware property.
I would not lead with these stock properties for the current -12:
qcom,rproc_rpd
qcom,multipd_arch
qcom,userpd-subsys-name
qcom,board_id
qcom,bdf-addr
qcom,caldb-addr
qcom,caldb-size
qcom,tgt-mem-mode
qcom,offloaded_to_q6
PD child compatible strings
They are useful evidence of stock QSDK/CNSS behavior, but not fixes for the current mainline/OpenWrt remoteproc failure.
The only later useful ath12k side cleanup I see is changing the wifi node to the public binding style:
memory-region = <&q6_region>, <&m3_dump>, <&q6_caldb>, <&mlo_global_mem>;
memory-region-names = "q6-region", "m3-dump", "q6-caldb", "mlo-global-mem";
But I would test that separately after root Q6 gets past -12.
Hopefully this is useful for you.