Acer Predator W6 with OpenWrt

We won't be able to fix the strapping pins (if it's actually that) but we sure could fix the null pointer dereference... I am happy to test - after all, I can reproduce it quite reliably :stuck_out_tongue:

Wow, you've found the bad apple.

I am still trying to understand the relevant mt76 code. We're getting a bit off topic, but do you agree that the (null pointer) bug can be found in file tx.c between lines 239 and 296 or in the functions (with no exported symbol – which would be seen in the logs) called in these lines?

__mt76_tx_complete_skb (tx.c line 239) is called by
mt76_txq_schedule_pending_wcid (tx.c lines 600/633) called by
mt76_txq_schedule_pending (tx.c lines 644/646/666) called by
mt76_txq_schedule_all (tx.c lines 683/688) called by
mt7915_mac_restart (mt7915/mac.c lines 1308/1341/1343) called by
mt7915_mac_full_reset (mt7915/mac.c lines 1433/1456) called by
mt7915_mac_reset_work (mt7915/mac.c lines 1486/1508).

I doubt source code line numbers can be printed in the debug logs but we see the binary offset in the program counter.

It would be difficult to hunt down the bug without a disassembler and without a runtime debugging environment, but if you are happy to test, maybe you want to add debug infos to the code of __mt76_tx_complete_skb?

I am not so sure about __mt76_tx_complete_skb. Initially I thought so too but the offset doesn't make any sense. I can disassemble the kernel module just fine in gdb. The interleaving with source code (disas/m/disas/s) seems a bit broken - at least where it actually counts - but that simply might be because it's in an inline function from list.h.

The interesting part is that the address of __mt76_tx_complete_skb+0x56c is actually outside of that function, which ends at +632 (NB: gdb prints it as decimal, that's 0x278).

p/x __mt76_tx_complete_skb+0x56c
0x8c6c

disas/s 0x8c6c then gives us...

568	static inline void list_splice_init(struct list_head *list,
569					    struct list_head *head)
570	{
571		if (!list_empty(list)) {
   0x0000000000008c5c <+124>:	ldr	x3, [sp, #104]
   0x0000000000008c60 <+128>:	cmp	x3, x0
   0x0000000000008c64 <+132>:	b.eq	0x8c88 <mt76_txq_schedule_pending+168>  // b.none

572			__list_splice(list, head, head->next);
   0x0000000000008c68 <+136>:	ldp	x2, x1, [x22, #48]

530		first->prev = prev;
   0x0000000000008c6c <+140>:	str	x28, [x2, #8]

When I compare this to the output of disas/m 0x8c6c....

disas/m 0x8c6c
Dump of assembler code for function mt76_txq_schedule_pending:
646	
   0x0000000000008be0 <+0>:	stp	x29, x30, [sp, #-128]!
   0x0000000000008be4 <+4>:	mov	x29, sp
   0x0000000000008be8 <+8>:	stp	x21, x22, [sp, #32]
   0x0000000000008bec <+12>:	mov	x22, x0
   0x0000000000008bf4 <+20>:	stp	x27, x28, [sp, #80]

647			spin_unlock(&phy->tx_lock);
   0x0000000000008bfc <+28>:	add	x28, sp, #0x70
   0x0000000000008c00 <+32>:	stp	x0, x28, [sp, #104]
   0x0000000000008c08 <+40>:	str	x28, [sp, #120]

648			ret = mt76_txq_schedule_pending_wcid(phy, wcid);
649			spin_lock(&phy->tx_lock);
   0x0000000000008bf0 <+16>:	add	x0, x0, #0x30
   0x0000000000008bf8 <+24>:	mov	x1, x0

650	
651			if (ret) {
652				if (list_empty(&wcid->tx_list))
653					list_add_tail(&wcid->tx_list, &phy->tx_list);
654				break;
655			}
656		}
657		spin_unlock(&phy->tx_lock);
   0x0000000000008c94 <+180>:	cmp	x0, x28
   0x0000000000008c98 <+184>:	b.eq	0x8d40 <mt76_txq_schedule_pending+352>  // b.none

one would guess that list_add_tail() (or list_empty()) somehow call list_splice_init(). However, I don't see how that would be... list_splice_init() is actually called directly in mac.c though. That's all more puzzling than helping.

The above was produced via...

./build_dir/target-aarch64_cortex-a53_musl/openwrt-sdk-24.10-SNAPSHOT-mediatek-filogic_gcc-13.3.0_musl.Linux-x86_64/staging_dir/toolchain-aarch64_cortex-a53_gcc-13.3.0_musl/bin/aarch64-openwrt-linux-gdb ./staging_dir/target-aarch64_cortex-a53_musl/root-mediatek/lib/modules/6.6.73/mt76.ko
[…]
(gdb) dir ./build_dir/target-aarch64_cortex-a53_musl/linux-mediatek_filogic/linux-6.6.73/drivers/net/wireless/mediatek/mt76
(gdb) dir ./build_dir/target-aarch64_cortex-a53_musl/openwrt-sdk-24.10-SNAPSHOT-mediatek-filogic_gcc-13.3.0_musl.Linux-x86_64/build_dir/target-aarch64_cortex-a53_musl/linux-mediatek_filogic/linux-6.6.73
(gdb) set substitute-path ../mt76-2025.02.14~e5fef138 .

on top of current openwrt-24.10 (b7b6ae7424) and a minor ccache patch of mine.

I would like to add dump_stack() and printk() but I don't know how to do that correctly. Is there a practical way to do this somewhat structured (i.e. with git support)? I don't fancy editing inside build_dir a lot because I haven't grasped the openwrt build system.

It's also simply not working AFAICT. That's what I did:

  1. edit build_dir/target-aarch64_cortex-a53_musl/linux-mediatek_filogic/linux-6.6.73/drivers/net/wireless/mediatek/mt76/tx.c
  2. edit build_dir/target-aarch64_cortex-a53_musl/linux-mediatek_filogic/linux-6.6.73/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
  3. edit build_dir/target-aarch64_cortex-a53_musl/openwrt-sdk-24.10-SNAPSHOT-mediatek-filogic_gcc-13.3.0_musl.Linux-x86_64/build_dir/target-aarch64_cortex-a53_musl/linux-mediatek_filogic/linux-6.6.73/include/linux/list.h
  4. run make target/linux/compile
  5. run make target/linux/install
  6. run make

And although I intentionally added illegal code to list.h everything built just fine - and of course showed no signs of behavior change at runtime. So obviously this is not the way... what is?

@JxnLexn
Test this PR. It will allow you to change the state of the LEDs on the 2.5G ports with LUCI. When you test it, write a comment on github.

I managed to break my Predator W6d's serial port before flashing OpenWRT on it. I checked with a scope: no output at all. Not on the holes, no signal on the pads, no signal on the small 1k resistor. Not even switching to 3v3 after turning on the power. Also I checked: there is no short to the ground (leftover solder or something). I'm guessing I must have messed up with a wrong connection to the TX pin somewhere - frying it.
Without serial port, OpenWRT is out of scope now, right? Or is there another way to flash firmware on the W6d?
It seems the RX pin still works - I can type "reboot" on my serial console and the original firmware will reboot. But trying to interrupt the boot process doesn't seem to work for some reason: when I just press 00000, the regular firmware starts. When I hold reset and WPS during a start, first two leds on the board will be blue and after about 20 seconds they turn red. I tried typing "reset" (in the hope uboot would restart), but nothing happens.
Does anyone have an idea about what to try?

Following-up with what @dywersant had mentioned: 6Ghz radio was not working by default after a fresh sysupgrade of 24.10.0.

This is because "6g" is not added to the wireless config and there is no option to do this through the LuCi UI, nor are there any error messages indicating this option is needed:

uci set wireless.radio1.band='6g'

But this is not enough to enable 6g:
hostapd will fail to load the default OpenWRT config (in my case /var/run/hostapd-phy1.conf) even after adding "6g"

This has to do with ensuring the correct 6Ghz security settings are configured as found in this hostapd test:

In that case you might see errors like this:

Pre-RSNA security methods are not allowed in 6 GHz

or

Invalid AKM suite for 6 GHz

I also explicitly set the country "US" for all radios in the UI

I used WPA3-SAE option, by itself (No mixed mode).

Also I had to set the channel and ensure that the channel was in the correct band, since in the Channel dropdown in LuCi it only shows you the 20MHz channels.

Otherwise you might see an error like this:

daemon.err hostapd: Hardware does not support configured mode
daemon.warn hostapd: phy1-ap0: IEEE 802.11 Hardware does not support configured mode (1) (hw_mode in hostapd.conf)
daemon.err hostapd: Could not select hw_mode and channel. (-2)

So for example hostapd would not load if you select the band 160MHz, but then have 45 as the channel, but it will then work if you have band 160MHz and Channel 33, at least for US.

However you can only see these errors through 'logread' in the CLI, since the LuCi UI will not show you an error if you have made an invalid channel selection or have invalid security settings for 6Ghz.

Hello, i've been reading the discussions
I just got a W6x, it looks to be cheapest of the 4 - dual band and less rom, but the rest of the specs seem to be a hybrid of the W6 and W6m. It has usb3, but only one 2.5g port (wan), the 4 lan ports are gigabit. external antennae , but only one LED in the center

Is there anything i can provide to get a test build for the W6x? only if anybody wants to, i got this off of a sale for cheap so i dont mind if it goes dead

The stock firmware lacks incredibily basic features, it doesnt event support WDS or allows me changing the LAN properly.

All, I'll be testing a W6 for a client - assuming the Wiki instructions are complete(?). They want OpenWrt (i.e., trusted over the OEM firmware). Perhaps I'll do some testing without it connected to the Internet (e.g., determine how it phones home for firmware, etc.). Anyone need to test anything on OEM firmware, etc.?

I'm OK with some ideas - except upgrading the OEM firmware.

I'm waiting on pin headers from Ama$on, so any suggestions in the meantime are appreciated. Thanks Community!

What headers did you buy?
I did mine a very janky way with probe leads. I also blew up the ground pad so just grounded to the usb cage.
Not my finest moment…

Be aware that when the flash instructions tell you to set a certain number so the menu auto boots OpenWrt this may now be different in later firmware. It will be obvious when you get to that step if needed.

As far as OEM testing, can you check if it offers split wifi (80+80) as a gui option? Thanks

I opened my W6x inside, but i could not get to the underlying chips, the RF Cage is soldered, the CPU is the same as the other models

The header seems to be different, its 4 pin (includes 3v3) and they are not dots on a straight line, but rather, little lines of solder adjacent to each other, but not aligned

The board is probably shared it has space for the extra LEDs which the w6x doesnt have (it only has a center LED, the eth ports also do not have leds)

i will get a 4 pin pogo

edit: can anyone provide a dump of the partitions? or atleast the oem kernel/rootfs ? thanks

These: https://a.co/d/810vZ5S

Will do.

Probably a stupid question: as this router runs an Asus modification of OpenWRT, wouldn't it be possible to just run sysupgrade -f straight from the Asus-OpenWRT command line? I.e. you'd still need a serial connection, but you would be saved from the extra installation step. (And as I'm sure there are reasons to not do this, I didn't dare to try, i.e. it could be impossible - I just don't know).

does it ??

does the stock cli have sysupgrade and all the other tools required available ?

I was able to start "sysupgrade" from the stock cli, so yes, it's there. What are all the other tools required? Are there any dangers trying - i.e. can I brick the system or would uboot still be available if sysupgrade sensationally breaks the Asus firmware?

it could.

depends on how badly stock sysupgrade messes things up (if we'd assume it does).

@lantis1008

So, the device appears dead-on-arrivial. The 1 Gbps switch ports seem dead (they never light up, flash, or make a link) - only the WAN (Internet) port seems powered. Lastly, one red LED is illuminated inside the case upon power on - it never goes away.

I successfully initiated a return on a "No Returns" purchase...

But in case I end up with a brick, are there any troubleshooting tips, has anyone experienced this - if so, do you think the bootloader is borked?

I think the red light was always on inside even during normal operation from memory… at least I saw a lot of it during the flashing process.

Was it new in box? Or do you suspect someone has tampered with it previously?
Opening the case is not super easy, I don’t think you would be able to do it without making it obvious you have done so which could put your return in jeopardy.

It was used, so anything was expected. The seller accepted the return on eB$a - since it wasn't functional and operational as advertised, so no cracking the case with a hammer. :hammer_and_pick:

I'll shop around more perhaps.