NWA50AX Pro eth0 disconnections

Hello,
I'm experiencing a bug similar to this:

I tried with:

ethtool -s eth0 autoneg off speed 1000 duplex full

but if I disable autoneg the link becomes half duplex...

1 Like

@rainkinz can you confirm that in your case the link stays full duplex after disabling autoneg? Are you on 23.05.03 ?

Hi @Documibozu,

It actually reports half duplex after doing autoneg off:

root@Office:~# ethtool -s eth0 autoneg off speed 1000 duplex full
root@Office:~# ethtool eth0
Settings for eth0:
        Supported ports: [ ]
        Supported link modes:   10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
                                1000baseT/Full
                                2500baseT/Full
        Supported pause frame use: Symmetric Receive-only
        Supports auto-negotiation: Yes
        Supported FEC modes: Not reported
        Advertised link modes:  1000baseT/Full
        Advertised pause frame use: Symmetric Receive-only
        Advertised auto-negotiation: No
        Advertised FEC modes: Not reported
        Speed: 1000Mb/s
        Duplex: Half
        Port: Twisted Pair
        PHYAD: 5
        Transceiver: external
        Auto-negotiation: off
        MDI-X: Unknown
        Current message level: 0x000000ff (255)
                               drv probe link timer ifdown ifup rx_err tx_err
        Link detected: yes

But full duplex with autoneg on:

root@Office:~# ethtool -s eth0 autoneg on speed 1000 duplex full
root@Office:~# ethtool eth0
Settings for eth0:
        Supported ports: [ ]
        Supported link modes:   10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
                                1000baseT/Full
                                2500baseT/Full
        Supported pause frame use: Symmetric Receive-only
        Supports auto-negotiation: Yes
        Supported FEC modes: Not reported
        Advertised link modes:  1000baseT/Full
        Advertised pause frame use: Symmetric Receive-only
        Advertised auto-negotiation: Yes
        Advertised FEC modes: Not reported
        Speed: Unknown!
        Duplex: Half
        Port: Twisted Pair
        PHYAD: 5
        Transceiver: external
        Auto-negotiation: on
        MDI-X: Unknown
        Current message level: 0x000000ff (255)
                               drv probe link timer ifdown ifup rx_err tx_err
        Link detected: no

Thanks, after a reboot the AP seems to be stable with autoneg on.
Better hope it's not a cable fault 'cause it's a 15mt cable in a wall conduit :cold_sweat:

1 Like

I doubt it is. I have tried several cables and get disconnects unless I do:

ethtool -s eth0 autoneg off speed 1000 duplex full

Which sadly seems to also set it to half duplex.

Sadly I can confirm that every 4-6 hours eth0 has a glitch and the cable is not the problem (tried with a proven cable of only 1mt length).
Now i'll try to test @rainkinz solution for some days and check if it's stable.

@rainkinz sorry to bother you again.
I don't want to giveup on full duplex and I'm doing some tests.
So a little question: are you powering your AP with POE or are you using the 12volt plug?
Thanks again

I'm having the same issue, NWA50AX-Pro eth0 goes down particularly when under load.
I can reliably reproduce this with iperf3 from a WiFi client to my firewall (that's directly connected to eth0).

This only occurs with traffic from a WiFi client through the AP to a device behind eth0.

Running iperf -R (reversing traffic flow, from firewall to client), there are no issues.
Running iperf (-R) from WiFi client to the AP itself (and vice versa) has no issues.
Running iperf (-R) from AP to firewall (and vice versa) has no issues either!

Only when traffic gets bridged AND flows out of eth0, the link on eth0 goes down.

Autonegotiation and Flow Control do not matter, what's actually fixing the issue is setting eth0 to Half Duplex. The NWA50AX-Pro does not support ethtool -A to disable flow control, but my firewall (intel NIC) does. Log on the Zyxel (note: Full Duplex but flow control off):

Mon May 27 19:18:47 2024 kern.info kernel: [345135.165146] mtk_soc_eth 15100000.ethernet eth0: Link is Down
Mon May 27 19:18:47 2024 kern.info kernel: [345135.171772] br-lan: port 1(eth0) entered disabled state
Mon May 27 19:18:47 2024 daemon.notice netifd: Network device 'eth0' link is down
Mon May 27 19:18:51 2024 kern.info kernel: [345139.324308] mtk_soc_eth 15100000.ethernet eth0: Link is Up - 1Gbps/Full - flow control off
Mon May 27 19:18:51 2024 kern.info kernel: [345139.332694] br-lan: port 1(eth0) entered blocking state
Mon May 27 19:18:51 2024 kern.info kernel: [345139.338014] br-lan: port 1(eth0) entered forwarding state
Mon May 27 19:18:51 2024 daemon.notice netifd: Network device 'eth0' link is up
Mon May 27 19:19:03 2024 kern.info kernel: [345150.761284] mtk_soc_eth 15100000.ethernet eth0: Link is Down
Mon May 27 19:19:03 2024 kern.info kernel: [345150.768055] br-lan: port 1(eth0) entered disabled state
Mon May 27 19:19:03 2024 daemon.notice netifd: Network device 'eth0' link is down
Mon May 27 19:19:07 2024 kern.info kernel: [345154.920383] mtk_soc_eth 15100000.ethernet eth0: Link is Up - 1Gbps/Full - flow control off

System load seems fine, 18% CPU usage by sys during iperf. Powered through 12VDC. I've set the TX queue length to 9999 on eth0 + br-lan (default: 1000) but that made no difference either.

What the?

1 Like

How is this device powered?

Through the wall wart that came with the device (12V DC I assume)

Double check that it is the right one. It must be 12V supplying at least 2A.

Yes the supply says 12V 2A

Ok... good. Do you happen to have another adapter with the same specs? If so, try swapping to see if that improves the situation. A failing power adapter could result in what you are seeing.

In the meantime, let's take a look at the configuration:

Please connect to your OpenWrt device using ssh and copy the output of the following commands and post it here using the "Preformatted text </> " button:
grafik
Remember to redact passwords, MAC addresses and any public IP addresses you may have:

ubus call system board
cat /etc/config/network
cat /etc/config/wireless
cat /etc/config/dhcp
cat /etc/config/firewall
1 Like

Current config:

root@ddap1:~# ubus call system board
{
	"kernel": "5.15.150",
	"hostname": "ddap1",
	"system": "ARMv8 Processor rev 4",
	"model": "ZyXEL NWA50AX Pro",
	"board_name": "zyxel,nwa50ax-pro",
	"rootfs_type": "squashfs",
	"release": {
		"distribution": "OpenWrt",
		"version": "23.05.3",
		"revision": "r23809-234f1a2efa",
		"target": "mediatek/filogic",
		"description": "OpenWrt 23.05.3 r23809-234f1a2efa"
	}
}
root@ddap1:~# cat /etc/config/network

config interface 'loopback'
	option device 'lo'
	option proto 'static'
	option ipaddr '127.0.0.1'
	option netmask '255.0.0.0'

config globals 'globals'
	option ula_prefix 'fd82:eaa9:9db5::/48'

config device
	option name 'br-lan'
	option type 'bridge'
	list ports 'eth0'
	option ipv6 '0'
	option txqueuelen '9999'

config interface 'lan'
	option device 'br-lan'
	option proto 'static'
	option ipaddr '192.168.1.2'
	option netmask '255.255.255.0'
	option delegate '0'
	list dns '192.168.1.1'
	option gateway '192.168.1.1'

config device
	option name 'eth0'
	option txqueuelen '9999'

root@ddap1:~# cat /etc/config/wireless

config wifi-device 'radio0'
	option type 'mac80211'
	option path 'platform/18000000.wifi'
	option channel '1'
	option band '2g'
	option htmode 'HE20'
	option disabled '1'

config wifi-iface 'default_radio0'
	option device 'radio0'
	option network 'lan'
	option mode 'ap'
	option ssid 'OpenWrt'
	option encryption 'none'

config wifi-device 'radio1'
	option type 'mac80211'
	option path 'platform/18000000.wifi+1'
	option channel '36'
	option band '5g'
	option htmode 'HE80'
	option cell_density '0'

config wifi-iface 'default_radio1'
	option device 'radio1'
	option network 'lan'
	option mode 'ap'
	option ssid 'redacted'
	option encryption 'psk2+ccmp'
	option key 'redacted'

root@ddap1:~# cat /etc/config/dhcp

config dhcp 'lan'
	option interface 'lan'
	option start '100'
	option limit '150'
	option leasetime '12h'
	option dhcpv4 'server'
	option ignore '1'

config dhcp 'wan'
	option interface 'wan'
	option ignore '1'

config odhcpd 'odhcpd'
	option maindhcp '0'
	option leasefile '/tmp/hosts/odhcpd'
	option leasetrigger '/usr/sbin/odhcpd-update'
	option loglevel '4'

root@ddap1:~# cat /etc/config/firewall
config defaults
	option syn_flood	1
	option input		REJECT
	option output		ACCEPT
	option forward		REJECT
# Uncomment this line to disable ipv6 rules
#	option disable_ipv6	1

config zone
	option name		lan
	list   network		'lan'
	option input		ACCEPT
	option output		ACCEPT
	option forward		ACCEPT

config zone
	option name		wan
	list   network		'wan'
	list   network		'wan6'
	option input		REJECT
	option output		ACCEPT
	option forward		REJECT
	option masq		1
	option mtu_fix		1

config forwarding
	option src		lan
	option dest		wan

# We need to accept udp packets on port 68,
# see https://dev.openwrt.org/ticket/4108
config rule
	option name		Allow-DHCP-Renew
	option src		wan
	option proto		udp
	option dest_port	68
	option target		ACCEPT
	option family		ipv4

# Allow IPv4 ping
config rule
	option name		Allow-Ping
	option src		wan
	option proto		icmp
	option icmp_type	echo-request
	option family		ipv4
	option target		ACCEPT

config rule
	option name		Allow-IGMP
	option src		wan
	option proto		igmp
	option family		ipv4
	option target		ACCEPT

# Allow DHCPv6 replies
# see https://github.com/openwrt/openwrt/issues/5066
config rule
	option name		Allow-DHCPv6
	option src		wan
	option proto		udp
	option dest_port	546
	option family		ipv6
	option target		ACCEPT

config rule
	option name		Allow-MLD
	option src		wan
	option proto		icmp
	option src_ip		fe80::/10
	list icmp_type		'130/0'
	list icmp_type		'131/0'
	list icmp_type		'132/0'
	list icmp_type		'143/0'
	option family		ipv6
	option target		ACCEPT

# Allow essential incoming IPv6 ICMP traffic
config rule
	option name		Allow-ICMPv6-Input
	option src		wan
	option proto	icmp
	list icmp_type		echo-request
	list icmp_type		echo-reply
	list icmp_type		destination-unreachable
	list icmp_type		packet-too-big
	list icmp_type		time-exceeded
	list icmp_type		bad-header
	list icmp_type		unknown-header-type
	list icmp_type		router-solicitation
	list icmp_type		neighbour-solicitation
	list icmp_type		router-advertisement
	list icmp_type		neighbour-advertisement
	option limit		1000/sec
	option family		ipv6
	option target		ACCEPT

# Allow essential forwarded IPv6 ICMP traffic
config rule
	option name		Allow-ICMPv6-Forward
	option src		wan
	option dest		*
	option proto		icmp
	list icmp_type		echo-request
	list icmp_type		echo-reply
	list icmp_type		destination-unreachable
	list icmp_type		packet-too-big
	list icmp_type		time-exceeded
	list icmp_type		bad-header
	list icmp_type		unknown-header-type
	option limit		1000/sec
	option family		ipv6
	option target		ACCEPT

config rule
	option name		Allow-IPSec-ESP
	option src		wan
	option dest		lan
	option proto		esp
	option target		ACCEPT

config rule
	option name		Allow-ISAKMP
	option src		wan
	option dest		lan
	option dest_port	500
	option proto		udp
	option target		ACCEPT


### EXAMPLE CONFIG SECTIONS
-- snip only comments here --

I'll have to look for another power supply, but I doubt it's that since running concurrent iperfs client -> AP and AP -> firewall has no link drops.

Remove the last two lines here:

and delete this:

Reboot and try again.

The link still drops under load, config and full dmesg:


  _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M
 -----------------------------------------------------
 OpenWrt 23.05.3, r23809-234f1a2efa
 -----------------------------------------------------
root@ddap1:~# cat /etc/config/network 

config interface 'loopback'
	option device 'lo'
	option proto 'static'
	option ipaddr '127.0.0.1'
	option netmask '255.0.0.0'

config globals 'globals'
	option ula_prefix 'fd82:eaa9:9db5::/48'

config device
	option name 'br-lan'
	option type 'bridge'
	list ports 'eth0'

config interface 'lan'
	option device 'br-lan'
	option proto 'static'
	option ipaddr '192.168.1.2'
	option netmask '255.255.255.0'
	option delegate '0'
	list dns '192.168.1.1'
	option gateway '192.168.1.1'

root@ddap1:~# dmesg
[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
[    0.000000] Linux version 5.15.150 (builder@buildhost) (aarch64-openwrt-linux-musl-gcc (OpenWrt GCC 12.3.0 r23809-234f1a2efa) 12.3.0, GNU ld (GNU Binutils) 2.40.0) #0 SMP Fri Mar 22 22:09:42 2024
[    0.000000] Machine model: ZyXEL NWA50AX Pro
[    0.000000] earlycon: uart8250 at MMIO32 0x0000000011002000 (options '')
[    0.000000] printk: bootconsole [uart8250] enabled
[    0.000000] Zone ranges:
[    0.000000]   DMA      [mem 0x0000000040000000-0x000000005fffffff]
[    0.000000]   DMA32    empty
[    0.000000]   Normal   empty
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000040000000-0x0000000042ffffff]
[    0.000000]   node   0: [mem 0x0000000043000000-0x000000004302ffff]
[    0.000000]   node   0: [mem 0x0000000043030000-0x0000000047c7ffff]
[    0.000000]   node   0: [mem 0x0000000047c80000-0x0000000047ffffff]
[    0.000000]   node   0: [mem 0x0000000048000000-0x000000005fffffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000040000000-0x000000005fffffff]
[    0.000000] psci: probing for conduit method from DT.
[    0.000000] psci: PSCIv1.1 detected in firmware.
[    0.000000] psci: Using standard PSCI v0.2 function IDs
[    0.000000] psci: MIGRATE_INFO_TYPE not supported.
[    0.000000] psci: SMC Calling Convention v1.2
[    0.000000] percpu: Embedded 18 pages/cpu s33112 r8192 d32424 u73728
[    0.000000] pcpu-alloc: s33112 r8192 d32424 u73728 alloc=18*4096
[    0.000000] pcpu-alloc: [0] 0 [0] 1 
[    0.000000] Detected VIPT I-cache on CPU0
[    0.000000] CPU features: detected: GIC system register CPU interface
[    0.000000] CPU features: kernel page table isolation disabled by kernel configuration
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 129024
[    0.000000] Kernel command line: console=ttyS0,115200n1 earlycon=uart8250,mmio32,0x11002000 loglevel=1 bootVer=V1.08 bootImage=0
[    0.000000] Unknown kernel command line parameters "bootVer=V1.08 bootImage=0", will be passed to user space.
[    0.000000] Dentry cache hash table entries: 65536 (order: 7, 524288 bytes, linear)
[    0.000000] Inode-cache hash table entries: 32768 (order: 6, 262144 bytes, linear)
[    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] Memory: 498532K/524288K available (8384K kernel code, 906K rwdata, 1472K rodata, 448K init, 300K bss, 25756K reserved, 0K cma-reserved)
[    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=2, Nodes=1
[    0.000000] rcu: Hierarchical RCU implementation.
[    0.000000] rcu: 	RCU restricting CPUs from NR_CPUS=4 to nr_cpu_ids=2.
[    0.000000] 	Tracing variant of Tasks RCU enabled.
[    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies.
[    0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=2
[    0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
[    0.000000] GICv3: GIC: Using split EOI/Deactivate mode
[    0.000000] GICv3: 640 SPIs implemented
[    0.000000] GICv3: 0 Extended SPIs implemented
[    0.000000] GICv3: Distributor has no Range Selector support
[    0.000000] Root IRQ handler: 0xffffffc008010090
[    0.000000] GICv3: 16 PPIs implemented
[    0.000000] GICv3: CPU0: found redistributor 0 region 0:0x000000000c080000
[    0.000000] arch_timer: cp15 timer(s) running at 13.00MHz (phys).
[    0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x2ff89eacb, max_idle_ns: 440795202429 ns
[    0.000000] sched_clock: 56 bits at 13MHz, resolution 76ns, wraps every 4398046511101ns
[    0.000140] Calibrating delay loop (skipped), value calculated using timer frequency.. 26.00 BogoMIPS (lpj=130000)
[    0.000150] pid_max: default: 32768 minimum: 301
[    0.000439] Mount-cache hash table entries: 1024 (order: 1, 8192 bytes, linear)
[    0.000448] Mountpoint-cache hash table entries: 1024 (order: 1, 8192 bytes, linear)
[    0.001790] rcu: Hierarchical SRCU implementation.
[    0.002165] smp: Bringing up secondary CPUs ...
[    0.002508] Detected VIPT I-cache on CPU1
[    0.002536] GICv3: CPU1: found redistributor 1 region 0:0x000000000c0a0000
[    0.002566] CPU1: Booted secondary processor 0x0000000001 [0x410fd034]
[    0.002637] smp: Brought up 1 node, 2 CPUs
[    0.002645] SMP: Total of 2 processors activated.
[    0.002649] CPU features: detected: 32-bit EL0 Support
[    0.002652] CPU features: detected: CRC32 instructions
[    0.002679] CPU features: emulated: Privileged Access Never (PAN) using TTBR0_EL1 switching
[    0.002742] CPU: All CPU(s) started at EL2
[    0.002752] alternatives: patching kernel code
[    0.006295] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[    0.006316] futex hash table entries: 512 (order: 3, 32768 bytes, linear)
[    0.006461] pinctrl core: initialized pinctrl subsystem
[    0.007335] NET: Registered PF_NETLINK/PF_ROUTE protocol family
[    0.007686] DMA: preallocated 128 KiB GFP_KERNEL pool for atomic allocations
[    0.007715] DMA: preallocated 128 KiB GFP_KERNEL|GFP_DMA pool for atomic allocations
[    0.007752] DMA: preallocated 128 KiB GFP_KERNEL|GFP_DMA32 pool for atomic allocations
[    0.008091] thermal_sys: Registered thermal governor 'fair_share'
[    0.008096] thermal_sys: Registered thermal governor 'bang_bang'
[    0.008099] thermal_sys: Registered thermal governor 'step_wise'
[    0.008102] thermal_sys: Registered thermal governor 'user_space'
[    0.008315] ASID allocator initialised with 65536 entries
[    0.008784] pstore: Registered ramoops as persistent store backend
[    0.008789] ramoops: using 0x10000@0x42ff0000, ecc: 0
[    0.019159] cryptd: max_cpu_qlen set to 1000
[    0.021532] SCSI subsystem initialized
[    0.021701] libata version 3.00 loaded.
[    0.022963] clocksource: Switched to clocksource arch_sys_counter
[    0.023596] NET: Registered PF_INET protocol family
[    0.023699] IP idents hash table entries: 8192 (order: 4, 65536 bytes, linear)
[    0.024210] tcp_listen_portaddr_hash hash table entries: 256 (order: 0, 4096 bytes, linear)
[    0.024230] Table-perturb hash table entries: 65536 (order: 6, 262144 bytes, linear)
[    0.024238] TCP established hash table entries: 4096 (order: 3, 32768 bytes, linear)
[    0.024268] TCP bind hash table entries: 4096 (order: 4, 65536 bytes, linear)
[    0.024321] TCP: Hash tables configured (established 4096 bind 4096)
[    0.024398] UDP hash table entries: 256 (order: 1, 8192 bytes, linear)
[    0.024415] UDP-Lite hash table entries: 256 (order: 1, 8192 bytes, linear)
[    0.024540] NET: Registered PF_UNIX/PF_LOCAL protocol family
[    0.024570] PCI: CLS 0 bytes, default 64
[    0.026763] workingset: timestamp_bits=46 max_order=17 bucket_order=0
[    0.030458] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[    0.030472] jffs2: version 2.2 (NAND) (SUMMARY) (LZMA) (RTIME) (CMODE_PRIORITY) (c) 2001-2006 Red Hat, Inc.
[    0.064495] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 251)
[    0.065287] pwm-mediatek 10048000.pwm: clock: top fail: -517
[    0.074080] Serial: 8250/16550 driver, 16 ports, IRQ sharing enabled
[    0.076519] printk: console [ttyS0] disabled
[    0.096692] 11002000.serial: ttyS0 at MMIO 0x11002000 (irq = 18, base_baud = 2500000) is a ST16650V2
[    0.096748] printk: console [ttyS0] enabled
[    0.096754] printk: bootconsole [uart8250] disabled
[    0.097581] cacheinfo: Unable to detect cache hierarchy for CPU 0
[    0.101157] loop: module loaded
[    0.101173] Loading iSCSI transport class v2.0-870.
[    0.103677] spi spi0.0: setup: ignoring unsupported mode bits a00
[    0.104876] spi-nand spi0.0: calibration result: 0x3
[    0.104976] spi-nand spi0.0: Winbond SPI NAND was found.
[    0.104982] spi-nand spi0.0: 256 MiB, block size: 128 KiB, page size: 2048, OOB size: 128
[    0.105585] Signature found at block 2047 [0x0ffe0000]
[    0.105591] NMBM management region starts at block 1920 [0x0f000000]
[    0.108067] First info table with writecount 0 found in block 1920
[    0.115520] Second info table with writecount 0 found in block 1923
[    0.115533] NMBM has been successfully attached
[    0.115866] 11 fixed-partitions partitions found on MTD device spi0.0
[    0.116417] Creating 11 MTD partitions on "spi0.0":
[    0.116435] 0x000000000000-0x000000100000 : "BL2"
[    0.117696] 0x000000100000-0x000000180000 : "u-boot-env"
[    0.118604] 0x000000180000-0x000000380000 : "Factory"
[    0.120641] 0x000000380000-0x000000580000 : "FIP"
[    0.122655] 0x000000580000-0x000003780000 : "ubi"
[    0.161194] 0x000003780000-0x000006980000 : "ubi_1"
[    0.190323] 0x000006980000-0x00000a580000 : "rootfs-data"
[    0.224465] 0x00000a580000-0x00000e000000 : "logs"
[    0.258768] 0x00000e000000-0x00000ef00000 : "myzyxel"
[    0.267875] 0x00000ef00000-0x00000ef80000 : "bootconfig"
[    0.268689] 0x00000ef80000-0x00000f000000 : "mrd"
[    2.975825] Maxlinear Ethernet GPY211C mdio-bus:05: Firmware Version: 0x8899 (release)
[    2.977992] mtk_soc_eth 15100000.ethernet eth0: mediatek frame engine at 0xffffffc009500000, irq 82
[    2.979226] i2c_dev: i2c /dev entries driver
[    2.980312] mtk-wdt 1001c000.watchdog: Watchdog enabled (timeout=31 sec, nowayout=0)
[    2.981116] NET: Registered PF_INET6 protocol family
[    2.983136] Segment Routing with IPv6
[    2.983172] In-situ OAM (IOAM) with IPv6
[    2.983230] NET: Registered PF_PACKET protocol family
[    2.983280] bridge: filtering via arp/ip/ip6tables is no longer available by default. Update your scripts to load br_netfilter if you need this.
[    2.983480] 8021q: 802.1Q VLAN Support v1.8
[    2.984583] pstore: Using crash dump compression: deflate
[    2.994627] UBI: auto-attach mtd4
[    2.994649] ubi0: default fastmap pool size: 20
[    2.994656] ubi0: default fastmap WL pool size: 10
[    2.994660] ubi0: attaching mtd4
[    3.319790] ubi0: scanning is finished
[    3.329622] ubi0: attached mtd4 (name "ubi", size 50 MiB)
[    3.329641] ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes
[    3.329648] ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 2048
[    3.329653] ubi0: VID header offset: 2048 (aligned 2048), data offset: 4096
[    3.329657] ubi0: good PEBs: 400, bad PEBs: 0, corrupted PEBs: 0
[    3.329662] ubi0: user volume: 3, internal volumes: 1, max. volumes count: 128
[    3.329669] ubi0: max/mean erase counter: 2/1, WL threshold: 4096, image sequence number: 2089050211
[    3.329676] ubi0: available PEBs: 0, total reserved PEBs: 400, PEBs reserved for bad PEB handling: 38
[    3.329739] ubi0: background thread "ubi_bgt0d" started, PID 435
[    3.331698] block ubiblock0_1: created from ubi0:1(rootfs)
[    3.331720] ubiblock: device ubiblock0_1 (rootfs) set to be root filesystem
[    3.339432] VFS: Mounted root (squashfs filesystem) readonly on device 254:0.
[    3.339635] Freeing unused kernel memory: 448K
[    3.383019] Run /sbin/init as init process
[    3.383027]   with arguments:
[    3.383029]     /sbin/init
[    3.383032]   with environment:
[    3.383033]     HOME=/
[    3.383036]     TERM=linux
[    3.383038]     bootVer=V1.08
[    3.383040]     bootImage=0
[    3.598022] init: Console is alive
[    3.598162] init: - watchdog -
[    4.010244] kmodloader: loading kernel modules from /etc/modules-boot.d/*
[    4.036112] kmodloader: done loading kernel modules from /etc/modules-boot.d/*
[    4.041969] init: - preinit -
[    4.416818] mtk_soc_eth 15100000.ethernet eth0: PHY [mdio-bus:05] driver [Maxlinear Ethernet GPY211C] (irq=POLL)
[    4.419816] mtk_soc_eth 15100000.ethernet eth0: configuring for phy/2500base-x link mode
[    4.440407] random: procd: uninitialized urandom read (4 bytes read)
[    6.506439] UBIFS (ubi0:2): Mounting in unauthenticated mode
[    6.506551] UBIFS (ubi0:2): background thread "ubifs_bgt0_2" started, PID 540
[    6.556714] UBIFS (ubi0:2): recovery needed
[    6.652726] UBIFS (ubi0:2): recovery completed
[    6.652797] UBIFS (ubi0:2): UBIFS: mounted UBI device 0, volume 2, name "rootfs_data"
[    6.652805] UBIFS (ubi0:2): LEB size: 126976 bytes (124 KiB), min./max. I/O unit sizes: 2048 bytes/2048 bytes
[    6.652813] UBIFS (ubi0:2): FS size: 35680256 bytes (34 MiB, 281 LEBs), max 291 LEBs, journal size 1777664 bytes (1 MiB, 14 LEBs)
[    6.652822] UBIFS (ubi0:2): reserved for root: 1685265 bytes (1645 KiB)
[    6.652827] UBIFS (ubi0:2): media format: w5/r0 (latest is w5/r0), UUID CB5543E9-C141-4434-8333-8DDA8094897B, small LPT model
[    6.664007] mount_root: switching to ubifs overlay
[    6.672466] overlayfs: null uuid detected in lower fs '/', falling back to xino=off,index=off,nfs_export=off.
[    6.680839] urandom-seed: Seeding with /etc/urandom.seed
[    6.852981] random: crng init done
[    6.873891] procd: - early -
[    6.873984] procd: - watchdog -
[    7.419886] procd: - watchdog -
[    7.422326] procd: - ubus -
[    7.477466] procd: - init -
[    7.770784] kmodloader: loading kernel modules from /etc/modules.d/*
[    7.779802] crypto-safexcel 10320000.crypto: EIP97:230(0,1,4,4)-HIA:270(0,5,5),PE:150/433(alg:7fcdfc00)/0/0/0
[    7.786365] Loading modules backported from Linux version v6.1.24-0-g0102425ac76b
[    7.786377] Backport generated by backports.git v5.15.92-1-44-gd6ea70fafd36
[    7.985384] urngd: v1.0.2 started.
[    8.163228] mt798x-wmac 18000000.wifi: HW/SW Version: 0x8a108a10, Build Time: 20221208201745a
[    8.163228] 
[    8.373835] mt798x-wmac 18000000.wifi: WM Firmware Version: ____000000, Build Time: 20221208201806
[    8.476905] mt798x-wmac 18000000.wifi: WA Firmware Version: DEV_000000, Build Time: 20221208202048
[    8.590620] PPP generic driver version 2.4.2
[    8.591617] NET: Registered PF_PPPOX protocol family
[    8.596795] kmodloader: done loading kernel modules from /etc/modules.d/*
[    8.984358] mtdblock: MTD device 'mrd' is NAND, please consider using UBI block devices instead.
[    9.352268] mtdblock: MTD device 'mrd' is NAND, please consider using UBI block devices instead.
[   11.468612] mtk_soc_eth 15100000.ethernet eth0: PHY [mdio-bus:05] driver [Maxlinear Ethernet GPY211C] (irq=POLL)
[   11.482058] mtk_soc_eth 15100000.ethernet eth0: configuring for phy/2500base-x link mode
[   11.492341] br-lan: port 1(eth0) entered blocking state
[   11.497644] br-lan: port 1(eth0) entered disabled state
[   11.503122] device eth0 entered promiscuous mode
[   12.527743] br-lan: port 2(phy1-ap0) entered blocking state
[   12.533355] br-lan: port 2(phy1-ap0) entered disabled state
[   12.539151] device phy1-ap0 entered promiscuous mode
[   12.544287] br-lan: port 2(phy1-ap0) entered blocking state
[   12.549869] br-lan: port 2(phy1-ap0) entered forwarding state
[   12.556011] br-lan: port 2(phy1-ap0) entered disabled state
[   12.984677] IPv6: ADDRCONF(NETDEV_CHANGE): phy1-ap0: link becomes ready
[   12.991402] br-lan: port 2(phy1-ap0) entered blocking state
[   12.996996] br-lan: port 2(phy1-ap0) entered forwarding state
[   13.003012] IPv6: ADDRCONF(NETDEV_CHANGE): br-lan: link becomes ready
[   15.683408] mtk_soc_eth 15100000.ethernet eth0: Link is Up - 1Gbps/Full - flow control off
[   15.691707] br-lan: port 1(eth0) entered blocking state
[   15.696943] br-lan: port 1(eth0) entered forwarding state
[   66.643005] mtk_soc_eth 15100000.ethernet eth0: Link is Down
[   66.649555] br-lan: port 1(eth0) entered disabled state
[   70.802703] mtk_soc_eth 15100000.ethernet eth0: Link is Up - 1Gbps/Full - flow control off
[   70.811002] br-lan: port 1(eth0) entered blocking state
[   70.816239] br-lan: port 1(eth0) entered forwarding state

I ran some more tests.

Different power supply: same issue
Different ports on firewall: same issue
Switch between AP and firewall: rock solid, zero retries reported by iperf in a 10-minute run from wifi client to firewall
Laptop wired to AP's eth0: solid, but instead of link down the bandwidth drops from ~500Mbit/s to 100-200Mbit/s with 1000's of retries

With only these findings in mind I'd suspect the firewall to be the culprit, BUT iperf directly from AP to firewall as well as wired laptop to firewall run just fine at full gigabit speed, and then there are those retries when the 2nd laptop is connected to AP's LAN port.

Both the wired laptop and the switch auto-negotiate "1Gbps/Full - flow control rx/tx" with AP's eth0.

How can I troubleshoot this further?
I've never tried the stock firmware on the AP, maybe that's worth a shot?

Yes, it is. If the problem still manifests, it means it is either an issue with the AP hardware (such as power/thermal issues), or it is something upstream of the AP. If it doesn't show up, then it is something with OpenWrt (config or other issues).

Only to add my 2 cents.
It seems that this kind of problem are recurring with filogic soho poe AP with 2.5gb ports.

It's been documented also for netgear wax220

See here:

Netgear wax220 drops lots of packets on 1000baseT/Full Link · Issue #13407 · openwrt/openwrt · GitHub

I suggest to add something in the wiki until the bug is investigated and mitigated.

Personally I can add that I had to return the zyxel for this problem.
I buyed a WAX220 but it was also affected under openwrt.
So I switched to the official firmware and it has been flawless!

Before wiki additions are made or bugs filed, it would be a good idea to know if the problem is OpenWrt specific or a function of the AP or the upstream network.