GL.iNet Flint 3 exploration (GL-BE9300, IPQ5332)

Hello! I'm just an enthusiast that would like to see full OpenWrt support on the Flint 3 BE9300. I have recently bought it and if there is anything I can do or give to help, I'd be more than willing!

Quite frankly, if you have to ask, the answer is 'no'. It 'just' needs developers working on ipq957x, then ipq53xx, then the flint 3, if you aren't an experienced developer, the learning curve will be steep - and in either case it'll be months++ of work.

Is it conceivable or realistic, yes (as long as you're not married to the stupid display), but a conservative-optimistic time frame would be somewhere around 2 years (yes, motivated developers could shorten that, but I don't see those at the moment, there is very little activity on the ipq957x target and ipq53xx, which depends on ipq957x as a base, hasn't even been started yet; at the current pace, 2 years already is a pipe dream).

TL;DR

Mainline OpenWrt port of the GL.iNet Flint 3 (IPQ5332 + 2Γ— QCN6274) is now usable
as a wired router β€” LAN, WAN, DSA, VLANs all at line rate, clean procd boot, SSH.
The one hard blocker left is Wi‑Fi: ath12k can't bind because any PCIe
config-space access after boot stalls the AXI bus
. Looking for anyone who's
exercised IPQ5332 PCIe on real silicon.

What works (HW-verified)

  • eth0 / LAN via the RTL8372N switch as a DSA driver (written for this port):
    100% ping, 949 Mbit/s iperf3, bridge VLANs (tagged/untagged) validated.
  • eth1 / WAN (RTL8221B, USXGMII): link up at 2.5 Gbps, line rate.
  • VLANs: bridge vlan add/del honored by the chip's 4K table.
  • Boot: clean procd boot, dropbear/SSH up, no rdinit hacks.
  • 2Γ— QCN6274 enumerate on PCIe (Gen3 x2 link up, 17cb:1109).

The blocker: PCIe config-space access hangs post‑enumeration

modprobe ath12k hard-hangs the SoC (RCU stall, a CPU stuck in default_idle_call,
no oops). I instrumented the bind path with pr_emerg traces and narrowed it down
step by step:

ath12k INIT-STEP[A] calling pci_register_driver
BIND[1] pci_device_probe enter dev=0001:01:00.0
BIND[2] calling pci_assign_irq
ASSIGN[1] reading PCI_INTERRUPT_PIN      <-- last line printed
   (60 s later) rcu: INFO: rcu_sched detected stalls ...

So the hang is pci_read_config_byte(QCN, PCI_INTERRUPT_PIN) β€” a single PCIe
config-space read. It is not ath12k-specific: reading the root port's
current_link_speed (a DBI config read) hangs the same way. Config reads work
fine during boot enumeration (~t=1 s)
β€” the endpoint is enumerated β€” but any config
access afterward wedges the bus.

Ruled out

  • IOMMU/SMMU β€” CONFIG_IOMMU_SUPPORT off, no iommus on the node.
  • INTx/GIC mapping β€” dropping the DT interrupt-map didn't change it (the hang is
    the config read, before the map).
  • Clock gating β€” clk_summary shows gcc_pcie3x2_{axi_m,axi_s,ahb,rchng} enabled
    (held by pcie@18000000) and gcc_pcie3x2_pipe_clk running (250 MHz, from
    phy@4b1000). clk_ignore_unused pd_ignore_unused β†’ no change.
  • SMP/idle β€” nohz=off no change; maxcpus=1 can't be tested (breaks EDMA boot).

Setup

  • Kernel 6.12, OpenWrt qualcommbe/ipq53xx.
  • PCIe = upstream backports PCI: qcom: Add support for IPQ5332 +
    arm64: dts: qcom: ipq5332: Add PCIe related nodes, compatible = "qcom,pcie-ipq5332" β†’ cfg_2_9_0 (same config as ipq6018/ipq8074‑gen3/ipq9574).
  • Node has dbi/elbi/atu/parf/config regs, 7 clocks, 8 resets, pcie1_phy, msi-map
    to v2m. Looks complete and matches the upstream binding.

The question

Has anyone actually run IPQ5332 PCIe on real hardware? As far as I can tell no
upstream IPQ5332 board enables &pcie1
β€” the only &pcie1 users are ipq8074 /
ipq9574 / non‑IPQ SoCs. So this may be the first real exercise of the IPQ5332 PCIe
path, and I suspect a SoC-specific quirk in the controller bring-up that lets
enumeration succeed but leaves config TLPs unable to complete once the link goes
idle (ASPM/L1ss? a missing post-link reset/handshake? an atu/config window issue?).

Pointers I'd love: a known-good IPQ5332 PCIe DT/bring-up reference (vendor QSDK or
otherwise), or anyone who's seen "enumerates then config-access stalls" on a DWC/qcom
controller.

Repo (full patch series + DTS + RTL8372N DSA driver):

Request the QSDK tarball from gl.inet ?

Maybe take a look at this pr (even though it's in draft):

Quick follow-up β€” dug into the vendor side and found the concrete difference (and it lines up with @frollic's QSDK pointer).

I pulled the device's own DT (/proc/device-tree off the vendor firmware). The vendor qti,pcie-ipq5332 node has a 6th reg region mainline doesn't:

reg-names = "dbi", "elbi", "atu", "parf", "config", "system_noc";
            system_noc @ 0x0059c210 (4 bytes)
axi-halt-val = <0x1e>;

ipq6018/ipq8074/ipq9574 (all cfg_2_9_0, all working) have only the first 5 regs and handle the equivalent inside PARF β€” so system_noc is IPQ5332-specific. The vendor driver evidently uses it to manage the PCIe master's AXI-halt on the SoC system NoC, which fits exactly: config TLPs work during enumeration but stall the AXI bus once the link goes idle afterwards.

I added the reg + an axi-halt-val write in qcom_pcie_post_init_2_9_0. The write fires (confirmed at boot) β€” but config access still stalls identically. So a one-shot write at post-init isn't enough.

Questions for anyone with the QSDK pcie-qcom source: is axi-halt-val a full value or a read-modify-write bitmask? Is it written once or managed across link-up/down? Is the real trigger the link dropping to L1ss after enumeration?

Patch + full series: https://github.com/perceival/openwrt-flint3

Solved it β€” and thanks @LS3434, PR #23161 was the key pointer.

The whole config-access stall was a missing interconnects (NoC) declaration on the
PCIe node. Mainline pcie-qcom.c (qcom_pcie_icc_init) does
devm_of_icc_get(dev, "pcie-mem") + devm_of_icc_get(dev, "cpu-pcie") and icc_set_bw()
on them. With no DT property those paths are NULL, so the CPU↔PCIe fabric path
(cpu-pcie) never gets bandwidth
β€” config TLPs work during enumeration but stall the
AXI/NoC once the link goes idle (e.g. when ath12k reads the QCN's config space). The
vendor qti,pcie-ipq5332 driver's manual system_noc/axi-halt poke is just the
downstream equivalent of this.

The 3-line fix on pcie@18000000:

interconnects = <&gcc MASTER_SNOC_PCIE3_2_M &gcc SLAVE_SNOC_PCIE3_2_M>,
                <&gcc MASTER_ANOC_PCIE3_2_S &gcc SLAVE_ANOC_PCIE3_2_S>;
interconnect-names = "pcie-mem", "cpu-pcie";

(All the icc IDs + gcc mappings were already present; the node just didn't declare them.
This matches the upstream v6.16 ipq5332 PCIe node in PR #23161.)

Result: modprobe ath12k now completes β€” chip_id read, firmware loaded
(WLAN.WBE.1.6), and both radios register (phy0 + phy1, 5 GHz + 6 GHz, WiFi 7).
Stable, no crash on load (we're on fw 1.6, no crash so far β€” will watch under load given
the 1.4.1 note).

Next step: bring up an actual AP / test under load, then look at adopting the rest of the
v6.16 PCIe node (DWC MSI, the mhi reg) to align with PR #23161.

Repo updated: https://github.com/perceival/openwrt-flint3

Well, i'm glad i could be of some help :slight_smile:

FYI. Here is a working build for the GL-BE6500 Flint 3e: https://forum.gl-inet.com/t/gl-be6500-latest-firmware-release-openwrt-25-12-qsdk-6-6-kernel/68750

Same HW base as Flint 3. Maybe this effort for Flint 3e can help yours.

Unless both units use the same image, not much.

@Rovasteen thanks for the pointer β€” I dug through the wlan-ap tree.

For context on @frollic's point: I'm targeting mainline OpenWrt (kernel 6.12, DSA, upstream ath12k), so the BE6500's QSDK 6.6 image isn't usable directly β€” agreed there. But I went looking at the source for anything portable. Findings:

Useful as reference in feeds/qca-wifi-7/ipq53xx/:

  • A vendor Realtek multi-gig PHY suite (drivers/net/phy/rtk/ β€” rtl8221d.c, rtk_phylib_rtl826xb.c, conf_rtl8264b.c). Same PHY family as my WAN RTL8221B β€” handy for 2.5G register sequences, though it's wrapped in its own rtk_osal SDK layer.
  • ath12k IPQ5332 firmware + regulatory data, which may explain a 5 GHz quirk I just hit (the radio is self-managed-regulatory and only permits DFS channels here).

Not there, unfortunately: no RTL8372N switch driver (that's my current bottleneck for the 2.5G LAN-side link), and no GL board DTS β€” those are GL-specific, layered on top of wlan-ap rather than in the public TIP tree. The readable RTL8372N driver would be in GL.iNet's GPL kernel-source release for the Flint 3 / 3e, so that's what I'll chase for the switch side.

While I'm here β€” a milestone update since post #27: Wi-Fi is now fully working on mainline. After adding the missing PCIe interconnects (NoC) property, ath12k probes both QCN6274 radios, and I've had real clients associate end-to-end β€” SAE auth + DHCP, on 5 GHz (DFS ch100) and 6 GHz simultaneously. So the BE9300 now does wired + dual-band Wi-Fi 7 on stock OpenWrt; remaining gaps are the RTL8372N 2.5G-port negotiation and cleanup of the debug patches.

I hope it's not the same as for the GL-MT5000, where the code for the switch chip isn't FOSSed - https://github.com/openwrt/openwrt/pull/21728#discussion_r2763097041.

How's the WiFi throughput?

This repository contains a driver for RTL8372N , but it's a swconfig driver. This driver originates from the repository https://github.com/RuijieNetworksCommunity/rtl837x-gsw-driver. I also wrote a DSA driver based on this repository with LLM support [https://github.com/JiaY-shi/rtl837x-dsa-driver], and it works after simple testing.

@shi05275 β€” thank you for this, and for pointing at the RuijieNetworksCommunity RTL8372N repo; that reference was genuinely useful. And great timing: I've been on a parallel mainline port and also ended up writing a DSA driver for the RTL8372N (also LLM-assisted, for what it's worth) β€” so we've independently converged on the same approach. Two implementations is honestly the best thing that could happen for getting this chip into mainline DSA; I'd love to compare and merge the best of both.

Where my tree is right now (qualcommbe/ipq53xx, kernel 6.12) β€” it's been running as my live home AP for days:

  • WiFi 7 on 5 & 6 GHz (ath12k, the 2Γ— QCN9274/PCIe), FT-SAE + dawn roaming in a multi-AP setup. (The one non-obvious blocker: the PCIe node was missing its interconnects ICC path β€” without it any post-enum config-space access wedged the AXI bus and ath12k never probed. 3-line DT fix.) MLO is masked β†’ two independent wiphys.
  • RTL8372N as DSA β€” probe (chip 0x8372 via MDIO-indirect), DSA reg, RTL8_4 CPU tag, VLAN add/del/filtering + FDB, and the Qualcomm PPE/EDMA RX+TX path at line rate.
  • 2.5G copper (CPU↔switch 10GBASE-R, PCS skip-reconfig), 2.5G WAN, eMMC f2fs persistence.

Since yours "works after simple testing," a few deeper gotchas I hit pushing it to a 24/7 AP, in case they save you time:

  • conduit MTU vs vlan-aware bridge: DSA sizes the CPU conduit for the 8-byte CPU tag but not the 4-byte 802.1Q tag β†’ full-1500 frames silently dropped on the CPU/WiFi path (pings/DNS fine, TCP/SSH stall). Bump the conduit MTU.
  • VLAN IVL/FID: the VLAN-1 4K entry needs fid_msti=1 / ivl_svl=1 or lookups miss the FID bucket and unicast never reaches the CPU.
  • EDMA: index-based opaque (not the pointer-in-descriptor), and gate the LIN/SCATTER prefetch on work_to_do or it over-consumes one skb per NAPI poll.
  • Port map: the 4 LAN jacks are chip ports 5,6,7,8 (LAN4 = port 8); port 4 is a 1G secondary CPU/trunk, not a jack β€” easy to mis-declare in the DT (I did, and just fixed it).

Still open (where help/pointers are very welcome): the 2.4 GHz on-SoC radio β€” needs the Q6/WCSS root-PD remoteproc (the unmerged "WCSS secure PIL" series; the older multi-PD approach was dropped) + ATH12K_AHB (already merged upstream, just disabled) + IPQ5332 firmware (not in upstream linux-firmware). Plus 6 GHz downlink TX polish and a WAN-on-trunk boot stall.

Happy to share patches, the DT, and the full debugging trail β€” and keen to line our two DSA drivers up side by side and push toward a mainline submission. Thanks again for sharing your work. :folded_hands:

To @all:

If it feels worthwhile, you can buy me a coffee β€” well, really a second Flint 3 to dev on β€” here: https://ko-fi.com/perceival. No pressure though; testers and pointers help just as much.

Big update on the last remaining radio. Quick recap of where the port stands, then the 2.4 GHz story.

Already working (deployed as a live home AP): LAN (RTL8372N via a custom DSA driver + EDMA/PPE, 949 Mbit/s), WAN (RTL8221B, 2.5 Gbps), DSA VLANs, and both QCN6274 PCIe radios on 5 + 6 GHz (real clients, SAE + DHCP, 802.11r + dawn). The one gap has always been the 2.4 GHz radio, which on the IPQ5332 is on-SoC β€” it runs on the Q6/WCSS Hexagon, not on a PCIe card.

That was the "hard, maybe-not-this-year" blocker. It moved a lot this week.

What got done

  • Firmware β€” the big surprise: I didn't need to beg QCA/GL for it. The stock q6_fw0/q6_fw1/iu_fw/m3/board images were sitting in the device's own WIFIFW partition (a squashfs β€” 7z x it). Extracted and staged into the image.
  • Multipd Q6 remoteproc β€” ported the qcom,ipq5332-q6-mpd driver + the qcom_scm metadata/msa/MPD patches from the qualcommax target (originally Manikanta Mylavarapu's multipd series + George Moussalem's IPQ5018-wifi v6 series) into qualcommbe/6.12. 11 patches; compiles clean.
  • ath12k AHB β€” ahb.c in the 6.18 backports needed two fixups to build against our tasklet-based CE-irq core + the 6.12 qcom_mdt_load_no_init signature. One patch.
  • Device tree β€” authored remoteproc@d100000 (q6-mpd + 3 PDs), wcss-smp2p, and wifi@c000000 (qcom,ipq5332-wifi, 56 IRQs), decoding every value out of the vendor DT.

On hardware, it gets almost all the way

qcom-q6-mpd d100000.remoteproc is available
qcom-q6-mpd d100000.remoteproc: pd-1/pd-2/pd-3 node found     -> remoteproc0/1/2/3
ath12k_ahb c000000.wifi: Hardware name: ipq5332 hw1.0
remoteproc0: Booting fw image IPQ5332/q6_fw0.mdt, size 11812
qcom-q6-mpd d100000.remoteproc: wcss_reset failed
remoteproc0: can't start rproc d100000.remoteproc: -22
ath12k_ahb c000000.wifi: failed to boot the remote processor Q6 (-22)

So the multipd driver binds, ath12k recognizes the radio, the Q6 firmware loads β€” and the only failure is the final qcom_scm_pas_auth_and_reset(pasid=0xD): TrustZone rejects the PAS authenticate-and-reset with ret=-22 (a0 β†’ -EINVAL), res[0]=-32.

What I've ruled out (with on-device debug logging)

  • V1/V2 metadata β€” PAS_INIT_IMAGE_V2 (cmd 0x1a) is selected and runs (V2_avail=1). Not it.
  • Metadata-context lifetime β€” kept the metadata buffer alive through auth (pas_init + retained ctx + release after auth); init returns 0, auth still -22/-32. Not it.
  • memory-region β€” vendor uses wcnss@4a900000, which is what I wire.
  • init_image + mem_setup + the segment load all succeed; the failure is purely the auth step.

Notably, the stock vendor OS boots this exact q6_fw0.mdt on this exact TZ/fuses and 2.4 GHz works β€” so firmware+TZ+fuses is a known-good combo. Secure boot here is fuse-unblown. So either the QSDK does a pre-auth step the mainline path drops (MSA-lock ordering, a region/secure-assign), or there's a non-PAS load path on non-secure parts.

Ask

Has anyone brought up the IPQ5332 (or IPQ9574) Q6 via the multipd/secure-PIL path on a fuse-unblown board and hit pas_auth_and_reset returning -22? I've reached out to the upstream authors too. Any pointer on what res[0]=-32 means at the PAS boundary, or what step the QSDK does between init_image and auth, would save a lot of guessing.

Everything else is done β€” this is genuinely the last mile of the last radio.

Excellent work so far perceival. Sent you a ko-fi.

Not sure if you saw, but the GL-iNet guys are looking to help you out:

Really well done. GL.iNet does look interested to support this effort.

Hi,

This is Will Qiu from the GL.iNet Technical Support Team.

Thank you for your contributions and efforts toward supporting the BE9300 on native OpenWrt.

Regarding the RTL8372N driver, since Realtek has not open-sourced it yet, there is unfortunately not much we can do to help directly. However, we are actively encouraging them to move this forward.

We noticed that you have already contacted us by email regarding this matter & DTS. We will review it and get back to you shortly.


If there is anything else we can assist with, please feel free to let us know.

Once again, thank you for your work and contributions.

Looks like OpenWRT is gaining more support for the Qualcomm environment