Support for Mikrotik RB3011UiAS-RM?

Yes checked, It is: a125ed0b31fb28b863ae2806f25fd37dba41474ae0f2baca0f73dce9387fba91
Here is the core dump made with breakpoint after driver was insmoded.

Yeah, I know that he means hAP ac2.
It does not have. brd files, but it has something similar.
It uses BDF aka board files, they are calibration specific to that vendors IPQ40xx based product line or even more specific to each board.
This is provided by QCA or their partners to individual vendors and are shipped in firmware and loaded by drivers, this is the reason for ipq-wifi package and the reason why ath10k firmware contains board-2.bin, it originally only contained BDFs for QCA reference design boards but now also contains other BDFs mostly for OpenWrt supported boards.
In all of QCA wisdom they provide BDFs for IPQ4019 for all with the BMI ID (16 for 2.4GHz and 17 for 5GHz), that is why qcom,ath10k-calibration-variant property was introduced to be able to differentiate between BDFs.

Each device also has traditional ART calibration shipped with it and its a difference between BDF and that specific device plus some other things like to indicate specific features like band steering or to include MAC address.
BMI ID is read from that ART calibration and without ART calibration ath10k will fail to probe and register the radio.
We dont see any BMI/BDF related error messages because board-2.bin included in OpenWrt has BMI IDs 16 and 17, but they are only for QCA reference boards.
And using wrong BDFs can cause low performance at best and unstable/crashy radios at worst.

Mikrotik ships BDFs inside one binary, its IPQ4019-otp.bin.
Driver has some clues, but its not too clear how they uncompress them.
Altough, it looks to be compressed somehow again as usual BDF size is 12064 and MikroTik shipped OTP file is only 4.6k

They have a SGMT magic which points to this:


It looks like its LZ compressed and they are feeding it directly into radio with bmi_transfer_lz function.
ath10k has some mention of LZ also, but I have not figured out how to use it

rbextract and hotplug scripts are in that same branch and like I said, without caldata being extracted ath10k would not even register the radio.

I hope this clears some stuff up

Log for WLAN stuff only:

Thanks for the detailed explanation. I'll dive into it later.

As for wireless. Something is off - that core file seems to be for a different wireless binary than the one with sha256sum a125.. - if you figure it out, let me know, that would help.

Anyhow, I think I found the offsets for whatever-you're-running:

0x000a6ab4:	bl	0x110f0
0x000a6b54:	bl	0x108d4
0x000a6b78:	bl	0x2efcc
0x000a6b7c:	ldrb	r3, [r4, #176]	; 0xb0

Those should hit..

Hm, I gotta check to see if I uploaded the correct file.
I did check hash and it matched one posted by you, only explanation is that I uploaded a old core dump.

@ius Here are core dumps for those offsets.
https://drive.google.com/drive/folders/1rteagdLDrQKPUzB_t66jMslIrI3WCM5L?usp=sharing

I have been looking at available info IPQ4019-otp.bin and it looks like its LZ77 compressed, but it also has some metadata in front.
For some reason upstream ath10k which actually support that kind of stuff wont load board.bin altough it recognizes the file format but it fails on uploading over CE on IPQ4019 radios.
This shell script pretty much describes how to make one of those compressed files, but not how to uncompress them.

mikrotik_brd_decrypt.py <input> <output>

Note: LFSR seed ('state') seems to differ between firmware versions. So this only works for the firmware you have right now.

I checked 6.44.x and 6.45.x, neither seems to match what you're running. Please check again.

25ceb924e3f0ad116bde445abb3e11af8b67f1842ad5ba56ed3e778ba0d4017b  wil6210-lhg-span2.8.brd
e8521e946aa78a5861cdb37b1b6fd030fce12fd80e4f9afe663bab9f025de576  dec.brd

Obviously can't test it, but it looks fine to me:

$ xxd dec.brd 
00000000: 0600 0000 3400 0000 3031 3236 0000 0000  ....4...0126....
00000010: 93aa 14d4 0100 0000 040e 0000 0000 0000  ................
1 Like

You were right, for some reason upgrade form 6.43.12 to 6.45.6 a couple of days ago failed.
Can you explain how to get LFSR seed for a specific firmware version?

I checked now and SHA256 sum in 6.45.6 I am now running is:

# sha256sum wireless 
a125ed0b31fb28b863ae2806f25fd37dba41474ae0f2baca0f73dce9387fba91  wireless

I tried used the board file and firmware generated by your script.
Headers are good, but it appears that checksum is not.
Errors:

wil_fw_verify: ERR[ FW ]checksum mismatch: calculated for 561160 bytes 0x23c6c79b != 0x25344813
ERR[ FW ]checksum mismatch: calculated for 3588 bytes 0x6b37878a != 0xd414aa93

If I disable returning an error on checksum board file will load but firmware wont.
So something is still off.

[  531.421411] wil6210 0000:01:00.0 wlan0: wil_reset: Use firmware <wil6210.fw> + board <wil6210.brd>
[  531.433344] wil6210 0000:01:00.0 wlan0: wil_fw_verify: ERR[ FW ]checksum mismatch: calculated for 561160 bytes 0x23c6c79b != 0x25344813
[  531.452333] wil6210 0000:01:00.0 wlan0: wil_fw_handle_record: ERR[ FW ]unknown record type: 100
[  531.452503] wil6210 0000:01:00.0 wlan0: wil_request_firmware: ERR[ FW ]Loading <wil6210.fw> failed, rc -22

Here is how the driver checks it:
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/drivers/net/wireless/ath/wil6210/fw_inc.c?h=v5.3.2#n105

Any clues on this?
Look like some minor tuning

For 6.45.6: state = 0x58cfa159

For that version the output for wil6210-lhg-span2.8.brd looks okay'ish, but the wil6210 header 0126 is no longer present. Crypto should be exactly the same though (in fact, I used this version's binary to recover the algorithm which works for 6.43.12). Beats me.


Easiest way to recover the seed from the wireless binary is by using IDA or Ghidra, but it's not trivial. It's located in the crypto function, i.e. at offset 0x2f834 in 6.45.6. The only function referencing it has plenty of string references to be able to easily locate it in other versions...

Probably makes more sense to recover the seed based on some known plaintext in one of the .brd files it encrypts, as the state is only 32 bits.

1 Like

Thanks,
header missing is an issue as its really important for wil6210.
It contains a lot of important stuff, it even contains the CRC32 to which driver compares generated one.
Something is missing, but I believe that its extremely hard to reverse engineer solely based on decompiled binary.
I have been digging at v7-beta2 but Ghidra wont decompile a part of the binary where seed is

That weirdly does not also work under 6.46b44.
It also has seed in a similar function but it also generates unsuable files.
It also does not work in 6.44.2, well this is really weird.

Well, the seed is unchanged (0x58cfa159) for 6.46, so I assume it still decrypts fine.

Header missing is odd, but the decryption seems fine. I'm inclined to believe their driver just doesn't require it - although I haven't looked at it at all.

The CRC mismatch for the (old) version with header should be investigated further, though.

I'll need to find some time to look at hAP ac² first though..

Hm, you may actually be right.
In these cases without header, its 3516 B while with header its 3588 B which matches the upstream example.
Well, I gues we can easily calculate the CRC32 and use upstream header as template.
Its all on fixed sizes.

For now, I am using one from 6.43.12 with corrected CRC32 in the header, I dont think that their driver even checks the header.
Who knows what modifications they have made

1 Like

I tried copying the 72 first bytes from a "vanilla" brd and corrected the CRC and this is the error I got. Any ideas? We are trying to get the brd from a wAP 60Gx3 AP (https://mikrotik.com/product/wap_60gx3_ap) and at the moment we are successful. The brd file is from 6.46.4 and I can confirm that the seed is 0x58cfa159 but the headers are missing.

[194704.810380] wil6210 0000:01:00.0 wlan0: wil_get_bl_info: Boot Loader struct v2: MAC = b8:69:f4:d5:7a:22 RF = 0x0000 (status 0x0000) bband = 0x00000000
[194704.810788] wil6210 0000:01:00.0 wlan0: wil_get_bl_info: Boot Loader build 255.255.0.7253
[194704.823628] wil6210 0000:01:00.0 wlan0: wil_set_oob_mode: oob_mode to 0
[194704.831237] wil6210 0000:01:00.0 wlan0: wil_reset: Use firmware <wil6210.fw> + board <wil6210.brd>
[194704.871036] wil6210 0000:01:00.0 wlan0: wil_fw_verify: ERR[ FW ]checksum mismatch: calculated for 3588 bytes 0xd7247813 != 0xeb5c4046
[195145.374374] wil6210 0000:01:00.0 wlan0: _wil6210_disconnect: bssid= (null), reason=3, ev-
[195145.420367] wil6210 0000:01:00.0 wlan0: wil_get_bl_info: Boot Loader struct v2: MAC = b8:69:f4:d5:7a:22 RF = 0x0000 (status 0x0000) bband = 0x00000000
[195145.420780] wil6210 0000:01:00.0 wlan0: wil_get_bl_info: Boot Loader build 255.255.0.7253
[195145.433512] wil6210 0000:01:00.0 wlan0: wil_set_oob_mode: oob_mode to 0
[195145.441229] wil6210 0000:01:00.0 wlan0: wil_reset: Use firmware <wil6210.fw> + board <wil6210.brd>
[195145.483901] wil6210 0000:01:00.0 wlan0: wil6210_irq_misc: Firmware error detected, assert codes FW 0x00001368, UCODE 0x00000000
[195145.769436] wil6210 0000:01:00.0 wlan0: wil_fw_core_dump: fw core dumped, size 823296 bytes
[195145.769494] wil6210 0000:01:00.0 wlan0: wil_notify_fw_error: Notify about firmware error
[195145.777131] wil6210 0000:01:00.0 wlan0: wil_fw_error_worker: No recovery - interface is down
[195147.530136] wil6210 0000:01:00.0 wlan0: wil_wait_for_fw_ready: Firmware not ready

Did you also change the FW?

I tried with the firmware that comes with 6.46.4 and with the firmware that works for the wAP 60G https://github.com/IMDEANetworksWNG/Mikrotik-researcher-tools/tree/master/files/lib/firmware and neither worked.

With the firmware from 6.46.4 I got:

[194704.810380] wil6210 0000:01:00.0 wlan0: wil_get_bl_info: Boot Loader struct v2: MAC = b8:69:f4:d5:7a:22 RF = 0x0000 (status 0x0000) bband = 0x00000000
[194704.810788] wil6210 0000:01:00.0 wlan0: wil_get_bl_info: Boot Loader build 255.255.0.7253
[194704.823628] wil6210 0000:01:00.0 wlan0: wil_set_oob_mode: oob_mode to 0
[194704.831237] wil6210 0000:01:00.0 wlan0: wil_reset: Use firmware <wil6210.fw> + board <wil6210.brd>
[194704.871036] wil6210 0000:01:00.0 wlan0: wil_fw_verify: ERR[ FW ]checksum mismatch: calculated for 3588 bytes 0xd7247813 != 0xeb5c4046
[195145.374374] wil6210 0000:01:00.0 wlan0: _wil6210_disconnect: bssid= (null), reason=3, ev-
[195145.420367] wil6210 0000:01:00.0 wlan0: wil_get_bl_info: Boot Loader struct v2: MAC = b8:69:f4:d5:7a:22 RF = 0x0000 (status 0x0000) bband = 0x00000000
[195145.420780] wil6210 0000:01:00.0 wlan0: wil_get_bl_info: Boot Loader build 255.255.0.7253
[195145.433512] wil6210 0000:01:00.0 wlan0: wil_set_oob_mode: oob_mode to 0
[195145.441229] wil6210 0000:01:00.0 wlan0: wil_reset: Use firmware <wil6210.fw> + board <wil6210.brd>
[195145.483901] wil6210 0000:01:00.0 wlan0: wil6210_irq_misc: Firmware error detected, assert codes FW 0x00001368, UCODE 0x00000000
[195145.769436] wil6210 0000:01:00.0 wlan0: wil_fw_core_dump: fw core dumped, size 823296 bytes
[195145.769494] wil6210 0000:01:00.0 wlan0: wil_notify_fw_error: Notify about firmware error
[195145.777131] wil6210 0000:01:00.0 wlan0: wil_fw_error_worker: No recovery - interface is down
[195147.530136] wil6210 0000:01:00.0 wlan0: wil_wait_for_fw_ready: Firmware not ready

And with the firmware that works on wAP 60G:

root@OpenWrt:/lib/firmware# ifconfig wlan0 up
ifconfig: SIOCSIFFLAGS: Invalid argument

And dmesg outputs:

[195400.254260] wil6210 0000:01:00.0 wlan0: _wil6210_disconnect: bssid= (null), reason=3, ev-
[195400.300447] wil6210 0000:01:00.0 wlan0: wil_get_bl_info: Boot Loader struct v2: MAC = b8:69:f4:d5:7a:22 RF = 0x0000 (status 0x0000) bband = 0x00000000
[195400.300856] wil6210 0000:01:00.0 wlan0: wil_get_bl_info: Boot Loader build 255.255.0.7253
[195400.313497] wil6210 0000:01:00.0 wlan0: wil_set_oob_mode: oob_mode to 0
[195400.321320] wil6210 0000:01:00.0 wlan0: wil_reset: Use firmware <wil6210.fw> + board <wil6210.brd>
[195400.346609] wil6210 0000:01:00.0 wlan0: wil_fw_verify: ERR[ FW ]checksum mismatch: calculated for 561252 bytes 0xcc9438cd != 0xc6a20f01

Which is a checksum for a file I cannot find.

You can use the firmware from ROS, its patched and much newer.
The one from linux-firmware worked for me

I'm not sure I follow, ROS is Router OS isn't it? Or by any chance you mean the Robot OS? Also do I need to decrypt the brd and add the headers for that firmware?

And last question, are you aware of any effort in reverse engineering the wil6210.fw? I myself have done some attempts but without much success.

Thanks!

Its RouterOS, you cant use the firmware file from it.
Mikrotik has a newer and patched firmware and it cant be used with the upstream driver.
Use the one from linux-firmware.

Board file however can be used if the header is patched.

Dont even attempt to reverse engineer it, its way too complex and does anything RF related like in ath10k etc

BTW, I have a RB3011UiAS-RM, I'd like to run OpenWrt on it and ready to help with the support as soon as I'll replace it with another router.

We also found that the hardware version of the wil6210 is different in the wAP x3 than in the wAP:

root@OpenWrt:~# cat /sys/kernel/debug/ieee80211/phy0/wil6210/hw_version 
0x00000002

In the wAP it is 0x00000001 as well as in the Talon AD7200. Do you know anything about this?

Hm, it looks like a never revision.
Driver should tell you which model it is in the bootlog.