Hi,
while testing my BATMAN Mesh setup with serveral TP-Link EAP225-Outdoor v3 nodes (QCA988x 5GHz, band 36, 40MHz, ath10k driver (not ath10k_ct), OpenWRT 24.10.2), I found that the throughput went down after being out of range of a station and then getting in range again in a mobile setup.
To pinpoint the issue I set up a lab setup with 2 Vaunix attenuators (another 30 dB passive attenuator is in front of them) and TP-Link EAP225-Outdoor v3 in 2 separate Rohde & Schwarz umbrella boxes. I applied an triangle function as an attenuation course for the Vaunix attenuators. At the same time I ran an iperf3 UDP throughput test sending 50 Mbit/s from Host 1 (192.168.1.1) to Host 2 (192.168.1.1). I got the station dumps every 0.5s via ssh (connected to both via LAN). Here are the dmesg of both hosts:
dmesg of Host 1 (192.168.1.1)
dmesg of Host 2 (192.168.1.2)
[ 0.000000] Linux version 6.6.93 (builder@buildhost) (mips-openwrt-linux-musl-gcc (OpenWrt GCC 13.3.0 r28739-d9340319c6) 13.3.0, GNU ld (GNU Binutils) 2.42) #0 Mon Jun 23 20:40:36 2025
[ 0.000000] printk: bootconsole [early0] enabled
[ 0.000000] CPU0 revision is: 00019750 (MIPS 74Kc)
[ 0.000000] MIPS: machine is TP-Link EAP225-Outdoor v3
[ 0.000000] SoC: Qualcomm Atheros QCA956X ver 1 rev 0
[ 0.000000] Initrd not found or empty - disabling initrd
[ 0.000000] Primary instruction cache 64kB, VIPT, 4-way, linesize 32 bytes.
[ 0.000000] Primary data cache 32kB, 4-way, VIPT, cache aliases, linesize 32 bytes
[ 0.000000] Zone ranges:
[ 0.000000] Normal [mem 0x0000000000000000-0x0000000007ffffff]
[ 0.000000] Movable zone start for each node
[ 0.000000] Early memory node ranges
[ 0.000000] node 0: [mem 0x0000000000000000-0x0000000007ffffff]
[ 0.000000] Initmem setup node 0 [mem 0x0000000000000000-0x0000000007ffffff]
[ 0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=132768
[ 0.000000] pcpu-alloc: [0] 0
[ 0.000000] Kernel command line: console=ttyS0,115200n8 rootfstype=squashfs,jffs2
[ 0.000000] Dentry cache hash table entries: 16384 (order: 4, 65536 bytes, linear)
[ 0.000000] Inode-cache hash table entries: 8192 (order: 3, 32768 bytes, linear)
[ 0.000000] Writing ErrCtl register=00000000
[ 0.000000] Readback ErrCtl register=00000000
[ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 32480
[ 0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[ 0.000000] Memory: 119972K/131072K available (6826K kernel code, 605K rwdata, 900K rodata, 1196K init, 233K bss, 11100K reserved, 0K cma-reserved)
[ 0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[ 0.000000] NR_IRQS: 51
[ 0.000000] CPU clock: 775.000 MHz
[ 0.000000] clocksource: MIPS: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 4932285024 ns
[ 0.000002] sched_clock: 32 bits at 388MHz, resolution 2ns, wraps every 5541893118ns
[ 0.008310] Calibrating delay loop... 385.84 BogoMIPS (lpj=1929216)
[ 0.074808] pid_max: default: 32768 minimum: 301
[ 0.089083] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[ 0.096816] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[ 0.113311] RCU Tasks Trace: Setting shift to 0 and lim to 1 rcu_task_cb_adjust=1 rcu_task_cpu_ids=1.
[ 0.127653] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[ 0.138073] futex hash table entries: 256 (order: -1, 3072 bytes, linear)
[ 0.147743] pinctrl core: initialized pinctrl subsystem
[ 0.155997] NET: Registered PF_NETLINK/PF_ROUTE protocol family
[ 0.162863] thermal_sys: Registered thermal governor 'step_wise'
[ 0.164738] /ahb/apb: Fixed dependency cycle(s) with /ahb/apb/interrupt-controller@18060010
[ 0.191451] clocksource: Switched to clocksource MIPS
[ 0.207007] NET: Registered PF_INET protocol family
[ 0.212432] IP idents hash table entries: 2048 (order: 2, 16384 bytes, linear)
[ 0.221424] tcp_listen_portaddr_hash hash table entries: 1024 (order: 0, 4096 bytes, linear)
[ 0.230404] Table-perturb hash table entries: 65536 (order: 6, 262144 bytes, linear)
[ 0.238592] TCP established hash table entries: 1024 (order: 0, 4096 bytes, linear)
[ 0.246690] TCP bind hash table entries: 1024 (order: 1, 8192 bytes, linear)
[ 0.254165] TCP: Hash tables configured (established 1024 bind 1024)
[ 0.261602] MPTCP token hash table entries: 512 (order: 0, 6144 bytes, linear)
[ 0.269459] UDP hash table entries: 256 (order: 0, 4096 bytes, linear)
[ 0.276400] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes, linear)
[ 0.284665] NET: Registered PF_UNIX/PF_LOCAL protocol family
[ 0.290715] PCI: CLS 0 bytes, default 32
[ 0.299807] workingset: timestamp_bits=14 max_order=15 bucket_order=1
[ 0.308243] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[ 0.314446] jffs2: version 2.2 (NAND) (SUMMARY) (LZMA) (RTIME) (CMODE_PRIORITY) (c) 2001-2006 Red Hat, Inc.
[ 0.331956] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 251)
[ 0.343111] pinctrl-single 1804002c.pinmux: 544 pins, size 68
[ 0.350533] Serial: 8250/16550 driver, 16 ports, IRQ sharing enabled
[ 0.362568] printk: console [ttyS0] disabled
[ 0.367494] 18020000.uart: ttyS0 at MMIO 0x18020000 (irq = 11, base_baud = 1562500) is a 16550A
[ 0.376764] printk: console [ttyS0] enabled
[ 0.385835] printk: bootconsole [early0] disabled
[ 0.429693] spi-nor spi0.0: en25qh128 (16384 Kbytes)
[ 0.434998] 7 fixed-partitions partitions found on MTD device spi0.0
[ 0.441623] OF: Bad cell count for /ahb/spi@1f000000/flash@0/partitions
[ 0.448478] OF: Bad cell count for /ahb/spi@1f000000/flash@0/partitions
[ 0.455574] Creating 7 MTD partitions on "spi0.0":
[ 0.460539] 0x000000000000-0x000000020000 : "u-boot"
[ 0.468914] 0x000000020000-0x000000030000 : "partition-table"
[ 0.476886] 0x000000030000-0x000000040000 : "info"
[ 0.483959] OF: Bad cell count for /ahb/spi@1f000000/flash@0/partitions
[ 0.491158] 0x000000040000-0x000000dc0000 : "firmware"
[ 0.498874] 2 elf-loader-fw partitions found on MTD device firmware
[ 0.505417] Creating 2 MTD partitions on "firmware":
[ 0.510552] 0x000000000000-0x000000281340 : "kernel"
[ 0.515692] mtd: partition "kernel" doesn't end on an erase/write block -- force read-only
[ 0.526166] 0x000000281340-0x000000d80000 : "rootfs"
[ 0.531317] mtd: partition "rootfs" doesn't start on an erase/write block boundary -- force read-only
[ 0.542853] mtd: setting mtd5 (rootfs) as root device
[ 0.548159] 1 squashfs-split partitions found on MTD device rootfs
[ 0.554592] 0x0000009b0000-0x000000d80000 : "rootfs_data"
[ 0.562150] 0x000000dc0000-0x000000df0000 : "config"
[ 0.569386] 0x000000f30000-0x000000ff0000 : "log"
[ 0.576414] 0x000000ff0000-0x000001000000 : "art"
[ 0.583423] OF: Bad cell count for /ahb/spi@1f000000/flash@0/partitions
[ 1.621464] ag71xx-legacy 19000000.eth: connected to PHY at mdio.0:06 [uid=001cc916, driver=RTL8211F Gigabit Ethernet]
[ 1.633201] eth0: Atheros AG71xx at 0xb9000000, irq 4, mode: sgmii
[ 1.640217] i2c_dev: i2c /dev entries driver
[ 1.647604] NET: Registered PF_INET6 protocol family
[ 1.662958] Segment Routing with IPv6
[ 1.666833] In-situ OAM (IOAM) with IPv6
[ 1.671037] NET: Registered PF_PACKET protocol family
[ 1.676359] bridge: filtering via arp/ip/ip6tables is no longer available by default. Update your scripts to load br_netfilter if you need this.
[ 1.690036] 8021q: 802.1Q VLAN Support v1.8
[ 1.714836] PCI host bridge to bus 0000:00
[ 1.719087] pci_bus 0000:00: root bus resource [mem 0x12000000-0x13ffffff]
[ 1.726318] pci_bus 0000:00: root bus resource [io 0x0000]
[ 1.732107] pci_bus 0000:00: No busn resource found for root bus, will use [bus 00-ff]
[ 1.740329] pci 0000:00:00.0: [168c:0056] type 00 class 0x028000
[ 1.746584] pci 0000:00:00.0: reg 0x10: [mem 0x00000000-0x001fffff 64bit]
[ 1.753741] pci 0000:00:00.0: PME# supported from D0 D3hot
[ 1.760405] pci_bus 0000:00: busn_res: [bus 00-ff] end is updated to 00
[ 1.767307] pci 0000:00:00.0: BAR 0: assigned [mem 0x12000000-0x121fffff 64bit]
[ 1.791294] clk: Disabling unused clocks
[ 1.804778] VFS: Mounted root (squashfs filesystem) readonly on device 31:5.
[ 1.818637] Freeing unused kernel image (initmem) memory: 1196K
[ 1.824796] This architecture does not have kernel memory protection.
[ 1.831467] Run /sbin/init as init process
[ 1.835693] with arguments:
[ 1.835698] /sbin/init
[ 1.835703] with environment:
[ 1.835708] HOME=/
[ 1.835712] TERM=linux
[ 2.562960] init: Console is alive
[ 2.566870] init: - watchdog -
[ 4.215791] kmodloader: loading kernel modules from /etc/modules-boot.d/
[ 4.295425] gpio_button_hotplug: loading out-of-tree module taints kernel.
[ 4.306600] kmodloader: done loading kernel modules from /etc/modules-boot.d/*
[ 4.324664] init: - preinit -
[ 8.561479] random: crng init done
[ 14.033293] eth0: link up (1000Mbps/Full duplex)
[ 14.258968] jffs2: notice: (521) jffs2_build_xattr_subsystem: complete building xattr subsystem, 48 of xdatum (13 unchecked, 35 orphan) and 50 of xref (35 dead, 0 orphan) found.
[ 14.277117] mount_root: switching to jffs2 overlay
[ 14.284230] overlayfs: upper fs does not support tmpfile.
[ 14.298968] urandom-seed: Seeding with /etc/urandom.seed
[ 14.442831] eth0: link down
[ 14.460758] procd: - early -
[ 14.464203] procd: - watchdog -
[ 15.221679] procd: - watchdog -
[ 15.226404] procd: - ubus -
[ 15.638434] procd: - init -
[ 17.492735] kmodloader: loading kernel modules from /etc/modules.d/*
[ 18.750006] GACT probability on
[ 18.772664] Mirror/redirect action on
[ 18.812997] u32 classifier
[ 18.815819] input device check on
[ 18.819596] Actions configured
[ 18.898345] Loading modules backported from Linux version v6.12.6-0-ge9d65b48ce1a
[ 18.906135] Backport generated by backports.git v6.1.110-1-35-g410656ef04d2
[ 18.988048] urngd: v1.0.2 started.
[ 19.878746] PPP generic driver version 2.4.2
[ 19.902576] NET: Registered PF_PPPOX protocol family
[ 20.004860] ath10k 6.10 driver, optimized for CT firmware, probing pci device: 0x56.
[ 20.062381] ath10k_pci 0000:00:00.0: enabling device (0000 -> 0002)
[ 20.069172] ath10k_pci 0000:00:00.0: pci irq legacy oper_irq_mode 1 irq_mode 0 reset_mode 0
[ 23.361594] ath10k_pci 0000:00:00.0: qca9888 hw2.0 target 0x01000000 chip_id 0x00000000 sub 0000:0000
[ 23.371147] ath10k_pci 0000:00:00.0: kconfig debug 0 debugfs 1 tracing 0 dfs 1 testmode 0
[ 23.385706] ath10k_pci 0000:00:00.0: firmware ver 10.4b-ct-9888-fW-13-5ae337bb1 api 5 features mfp,peer-flow-ctrl,txstatus-noack,wmi-10.x-CT,ratemask-CT,regdump-CT,txrate-CT,flush-all-CT,pingpong-CT,ch-regs-CT,nop-CT,set-special-CT,tx-rc-CT,cust-stats-CT,txrate2-CT,beacon-cb-CT,wmi-block-ack-CT,wmi-bcn-rc-CT crc32 59e741e7
[ 23.751993] ath10k_pci 0000:00:00.0: board_file api 2 bmi_id 0:24 crc32 5968d47d
[ 25.524538] ath10k_pci 0000:00:00.0: 10.4 wmi init: vdevs: 16 peers: 48 tid: 96
[ 25.532348] ath10k_pci 0000:00:00.0: msdu-desc: 2500 skid: 32
[ 25.582321] ath10k_pci 0000:00:00.0: wmi print 'P 48/48 V 16 K 144 PH 176 T 186 msdu-desc: 2500 sw-crypt: 0 ct-sta: 0'
[ 25.593638] ath10k_pci 0000:00:00.0: wmi print 'free: 114572 iram: 12644 sram: 29508'
[ 25.829720] ath10k_pci 0000:00:00.0: htt-ver 2.2 wmi-op 6 htt-op 4 cal pre-cal-nvmem max-sta 32 raw 0 hwcrypto 1
[ 25.935062] ath: EEPROM regdomain: 0x0
[ 25.935086] ath: EEPROM indicates default country code should be used
[ 25.935092] ath: doing EEPROM country->regdmn map search
[ 25.935107] ath: country maps to regdmn code: 0x3a
[ 25.935114] ath: Country alpha2 being used: US
[ 25.935121] ath: Regpair used: 0x3a
[ 26.011657] batman_adv: B.A.T.M.A.N. advanced 2024.3-openwrt-6 (compatibility version 15) loaded
[ 26.069301] ath: EEPROM regdomain: 0x0
[ 26.069327] ath: EEPROM indicates default country code should be used
[ 26.069333] ath: doing EEPROM country->regdmn map search
[ 26.069348] ath: country maps to regdmn code: 0x3a
[ 26.069354] ath: Country alpha2 being used: US
[ 26.069362] ath: Regpair used: 0x3a
[ 26.080460] ieee80211 phy1: Selected rate control algorithm 'minstrel_ht'
[ 26.081431] ieee80211 phy1: Atheros AR9561 Rev:0 mem=0xa585bc26, irq=2
[ 26.110581] kmodloader: done loading kernel modules from /etc/modules.d/*
[ 48.693388] br-lan: port 1(eth0) entered blocking state
[ 48.698818] br-lan: port 1(eth0) entered disabled state
[ 48.704314] ag71xx-legacy 19000000.eth eth0: entered allmulticast mode
[ 48.711320] ag71xx-legacy 19000000.eth eth0: entered promiscuous mode
[ 49.996312] 8021q: adding VLAN 0 to HW filter on device bat0
[ 50.136312] br-lan: port 2(bat0) entered blocking state
[ 50.141782] br-lan: port 2(bat0) entered disabled state
[ 50.147217] bat0: entered allmulticast mode
[ 50.151843] bat0: entered promiscuous mode
[ 50.156222] br-lan: port 2(bat0) entered blocking state
[ 50.161686] br-lan: port 2(bat0) entered forwarding state
[ 50.501533] batman_adv: bat0: No IGMP Querier present - multicast optimizations disabled
[ 50.509919] batman_adv: bat0: No MLD Querier present - multicast optimizations disabled
[ 50.755330] eth0: link up (1000Mbps/Full duplex)
[ 50.760183] br-lan: port 1(eth0) entered blocking state
[ 50.765641] br-lan: port 1(eth0) entered forwarding state
[ 52.998069] ath: EEPROM regdomain: 0x8114
[ 52.998098] ath: EEPROM indicates we should expect a country code
[ 52.998106] ath: doing EEPROM country->regdmn map search
[ 52.998112] ath: country maps to regdmn code: 0x37
[ 52.998119] ath: Country alpha2 being used: DE
[ 52.998126] ath: Regpair used: 0x37
[ 52.998132] ath: regdomain 0x8114 dynamically updated by user
[ 52.998221] ath: EEPROM regdomain: 0x8114
[ 52.998228] ath: EEPROM indicates we should expect a country code
[ 52.998234] ath: doing EEPROM country->regdmn map search
[ 52.998239] ath: country maps to regdmn code: 0x37
[ 52.998245] ath: Country alpha2 being used: DE
[ 52.998251] ath: Regpair used: 0x37
[ 52.998257] ath: regdomain 0x8114 dynamically updated by user
[ 59.173732] ath10k_pci 0000:00:00.0: 10.4 wmi init: vdevs: 16 peers: 48 tid: 96
[ 59.181541] ath10k_pci 0000:00:00.0: msdu-desc: 2500 skid: 32
[ 59.231516] ath10k_pci 0000:00:00.0: wmi print 'P 48/48 V 16 K 144 PH 176 T 186 msdu-desc: 2500 sw-crypt: 0 ct-sta: 0'
[ 59.242849] ath10k_pci 0000:00:00.0: wmi print 'free: 114572 iram: 12644 sram: 29508'
[ 59.557430] ath10k_pci 0000:00:00.0: rts threshold -1
[ 59.563089] ath10k_pci 0000:00:00.0: Firmware lacks feature flag indicating a retry limit of > 2 is OK, requested limit: 4
[ 60.171824] ath10k_pci 0000:00:00.0: NOTE: Firmware DBGLOG output disabled in debug_mask: 0x10000000
[ 67.139977] batman_adv: bat0: Adding interface: phy0-mesh0
[ 67.145735] batman_adv: bat0: Interface activated: phy0-mesh0
[ 67.292421] ------------[ cut here ]------------
[ 67.297317] WARNING: CPU: 0 PID: 21 at backports-6.12.6/net/mac80211/main.c:408 0x82802a50 [mac80211@0c49faf7+0x8a000]
[ 67.308478] Modules linked in: ath9k(O) ath9k_common(O) pppoe ppp_async nft_fib_inet nf_flow_table_inet batman_adv(O) ath9k_hw(O) ath10k_pci(O) ath10k_core(O) ath(O) pppox ppp_generic nft_reject_ipv6 nft_reject_ipv4 nft_reject_inet nft_reject nft_redir nft_quota nft_numgen nft_nat nft_masq nft_log nft_limit nft_hash nft_flow_offload nft_fib_ipv6 nft_fib_ipv4 nft_fib nft_ct nft_chain_nat nf_tables nf_nat nf_flow_table nf_conntrack mac80211(O) lzo cfg80211(O) slhc nfnetlink nf_reject_ipv6 nf_reject_ipv4 nf_log_syslog nf_defrag_ipv6 nf_defrag_ipv4 lzo_rle lzo_decompress lzo_compress libcrc32c hwmon crc_ccitt compat(O) sch_tbf sch_ingress sch_htb sch_hfsc em_u32 cls_u32 cls_route cls_matchall cls_fw cls_flow cls_basic act_skbedit act_mirred act_gact sha512_generic seqiv sha3_generic jitterentropy_rng drbg md5 hmac geniv rng cmac crypto_acompress gpio_button_hotplug(O) crc16 crc32c_generic
[ 67.389975] CPU: 0 PID: 21 Comm: kworker/u2:1 Tainted: G O 6.6.93 #0
[ 67.397995] Workqueue: events_unbound 0x81f80338 [cfg80211@3b2f6897+0x46000]
[ 67.405330] Stack : 00000000 8075a464 81921d2c 829901f0 00000000 00000000 00000000 00000000
[ 67.413984] 00000000 00000000 00000000 00000000 00000000 00000001 81921ce8 2800fd0e
[ 67.422641] 81921d80 00000000 00000000 81921c10 00000038 80702fe4 00000000 ffffffea
[ 67.431295] 000000d7 81921c1c 000000d7 807fb720 8071ca34 81921cc8 00000000 82802a50
[ 67.439950] 00000009 829901f0 81916750 61c88647 00000018 803d16cc 00000000 809b0000
[ 67.448607] ...
[ 67.451133] Call Trace:
[ 67.451187] [<80702fe4>] 0x80702fe4
[ 67.457327] [<82802a50>] 0x82802a50 [mac80211@0c49faf7+0x8a000]
[ 67.463508] [<803d16cc>] 0x803d16cc
[ 67.467109] [<800661e8>] 0x800661e8
[ 67.470711] [<800661f0>] 0x800661f0
[ 67.474313] [<806d99a4>] 0x806d99a4
[ 67.477956] [<800849b0>] 0x800849b0
[ 67.481636] [<82802a50>] 0x82802a50 [mac80211@0c49faf7+0x8a000]
[ 67.487795] [<80084a40>] 0x80084a40
[ 67.491618] [<82802a50>] 0x82802a50 [mac80211@0c49faf7+0x8a000]
[ 67.497776] [<8287d2e4>] 0x8287d2e4 [mac80211@0c49faf7+0x8a000]
[ 67.504264] [<81f803ec>] 0x81f803ec [cfg80211@3b2f6897+0x46000]
[ 67.510492] [<8009ed9c>] 0x8009ed9c
[ 67.514179] [<8009f35c>] 0x8009f35c
[ 67.517778] [<8009efc4>] 0x8009efc4
[ 67.521379] [<800a6738>] 0x800a6738
[ 67.524982] [<8009efc4>] 0x8009efc4
[ 67.528584] [<800a6738>] 0x800a6738
[ 67.532185] [<800a6834>] 0x800a6834
[ 67.535788] [<800a6738>] 0x800a6738
[ 67.539390] [<800a6738>] 0x800a6738
[ 67.542991] [<800619f8>] 0x800619f8
[ 67.546604]
[ 67.548528] ---[ end trace 0000000000000000 ]---
[ 136.658292] ath10k_pci 0000:00:00.0: htt tx: fixing invalid VHT TX rate code 0xff
This is the result:
On top you can see the applied attenuation of the Vaunix attenuators, which result in the RSSI course of the 2 hosts right below in graph 2. Below that in the 3rd graph is the “tx bitrate” of Host 1 and the “rx bitrate” of Host 2. In the 4th graph is the “tx bitrate” of Host 2 and the “rx bitrate” of Host 1. On the last graph is the iperf3 throughput on receiver side.
Findings:
- Graph 2: The RSSI does not go below -78dBm, probably due to receiver sensitivity?
- Graph 3 & 4: The bitrates are only properly updated before the first disconnect
- Graph 3 & 4: The bitrates do not reach 0. Even at the first time they are stuck at 6 Mbit/s.
- Graph 3 & 4: The TX & RX bitrates do not match when going out of range.
- Graph 3 & 4: The bitrates are stuck at 45 Mbit/s after the first reconnect.
- Graph 5: The throughput only reaches ~35 Mbit/s (instead of 50 Mbit/s) after the first reconnect. This is most likely due to the MCS 2 only allowing for 45 Mbit/s PHY rate.
Is this a known issue?
Thanks ![]()
Simon
BTW: This also is really bad for the BATMAN V (and probably normal 802.11s) routing decisions, as it tries to choose a MCS 2 45Mbit/s connection even though it is dead (instead of hopping over another node), resulting in no connection…