Adding OpenWrt support for Xiaomi AX3600

yeah but are they just using the DTS to select the board data file or is that data also sent via QMI to the radio

Its most likely just for the driver to be able to pick the correct board file.
ath11k just fetches the info from QMI, I dont think that it can write the board-id, fw version etc via QMI.
It does not need to anyway, it just parses that to be able to match the board file.

Yeah that's how I originally understood it. I provided the legacy bwwlan.b292 via the legacy / API 1 loading within ath11k

I just copied bwwlan.b292 to bdwlan.bin and removed board-2.bin (forced it to load the data using the API 1 method). However the results where the same as what you have now.

I guess at this point only ath11k maintainers can help :frowning:

1 Like

Yeah, did the same.
No luck even with the correct board file, so I am guessing that Xiaomi is doing some nasty business before starting the radios.

True, it could be that there is some issue in general that qsdk board files dont work correctly with ath11k (forcing some kind of fallback mode). Without another device its hard to know.

The AX3600 so far has worked like a qcom dev platform (no strange hacks needed) so its a bit surprising that wifi is where the issues start :confused:

I actually would not be surprised as AX3600 is one of the earliest IPQ807x boards, you can see it by the rather old QSDK version meaning that it has been in development for a while, so I would bet that Qualcomm had some bugs in the drivers and tooling for sure that Xiaomi worked around and was then too lazy to update to new QSDK.

1 Like

Maybe, but someone had a generic pore QSDK build (very early in this thread) that had no extras from Xiaomi (thats known as the PCIE bus was broken).

As at the very least this device did work with plain QSDK in the past.


Its a question whether it fully worked, I might build a QSDK11.2 to check whenever I have some time.

1 Like

It worked in terms of the main radio could enable most of the stock VHT modes (There was some DFS selection issues for the restricted channels)

1 Like

DFS issues are most likely due to wrong board data as its gonna fallback to 0xFF or 255 if QMI does not return one.

Humm, not sure that VHT would work at all in that case ? it definably worked on VHT80 and 160 after some messing with the regions / channels

It most likely would as board file should not mess with that, it should set the radio limits it can do and most vendors have these per region so they limit the channels that way.

1 Like

Ahh fair enough, maybe its always been an issue.

Its probably still worth asking on the ath11k mailing list (maybe even with our board file from stock) at the very least they should indicate if its a known issue or not :confused:

1 Like

Yeah, I hope to have some time this evening to write one

1 Like

I aquired a Redmi AX6 (almost identical to the AX3600)
As soon it gets delivered, I'm trying to gain serial access (there should be an unpopulated header)

And if thats successful, i can check if ath11k is working or not....

AFAIK newer Xiaomi routers comes with read-only serial access by default, so you would need to exploit it and obtain ssh access first.

Here's a guide (in Chinese, credits to @yyjdelete on

Yes that's right, and at the moment there is no exploit to enable ssh on the AX6.

Whoops, there was one linked in my previous post.

It's kinda onerous and requires another router, though. All credits go to @yyjdelete on

Basic steps:

  • DIsable DHCP on the other router, and set the gateway IP to
  • create /usr/lib/lua/luci/controller/admin/xqsystem.lua with the following content (if running OpenWRT):
module("luci.controller.admin.xqsystem", package.seeall)

function index()
    local page   = node("api")  = firstchild()
    page.title   = ("")
    page.order   = 100
    page.index = true
    page   = node("api","xqsystem")  = firstchild()
    page.title   = ("")
    page.order   = 100
    page.index = true
    entry({"api", "xqsystem", "token"}, call("getToken"), (""), 103, 0x08)

local LuciHttp = require("luci.http")

function getToken()
    local result = {}
    result["code"] = 0
    result["token"] = "; nvram set ssh_en=1; nvram commit; sed -i 's/channel=.*/channel=\"debug\"/g' /etc/init.d/dropbear; /etc/init.d/dropbear start;"
  • if not running OpenWRT, make sure returns
{"code":0,"token":"; nvram set ssh_en=1; nvram commit; sed -i 's/channel=.*/channel=\"debug\"/g' /etc/init.d/dropbear; /etc/init.d/dropbear start;"}

(the backslash can be escaped, and the order of the keys doesn't matter)

  • on the AX6, browse to;stok=<STOK>/api/misystem/extendwifi_connect?ssid={the ssid of the other router}&password={the WPA passphrase of the other router} (sans brackets)
    • it should return with code 0 after a while
  • then browse to;stok=<STOK>/api/xqsystem/oneclick_get_remote_token?username=xxx&password=xxx&nonce=xxx
    • you can leave the fields username, password, and nonce as is, or change them to any non-empty value
    • if accessing requires authentication, try entering the username/password in the respective fields
    • It should also return with code 0
  • SSH should be enabled now. If AX6's Wi-Fi is down, reboot the router.

If you don't have another router with shell access (unlikely for users here), you can try running hostapd and a server (that serves the content at the specified URL) like I did :slight_smile:

My AX6 returned 504 for the first few attempts on the extendwifi_connect step, but it eventually connected to my soft AP.

Thanks for the guide. Do you have serial access to the AX6?