Gluon v2022.1.4: MediaTek MT7615E 802.11s buggy?

Moin,

ich sehe komische Effekte mit MediaTek MT7615E in Gluon v2022.1.4 …

Testsetup:

Mesh-Testsetup

»Node A« ist hier ein GL.iNet GL-MT1300 (22.03-SNAPSHOT, r20142+10-e50049) , »Node X« eine AVM FRITZ!Box 4040 (19.07-SNAPSHOT, r11430+27-ecbbb3 — Gluon v2021.1.2-ffgt). Hinter jeder Node hängt per GBit-Ethernet ein Linux-System im Freifunk-LAN. Auf „cohen“ – hängt an »Node A« – läuft „iperf3 -s“, auf „ysabell“ – hängt an »Node X« – mache ich über das 5-GHz-Mesh (2,4-GHz-Mesh ist deaktiviert) – sprich die 6m Luftlinie – iperf3 -c zur FF-Public-v6 von „cohen“:

root@ysabell:~# traceroute 2001:bf7:1322:17:a2ce:c8ff:fe5b:4714
traceroute to 2001:bf7:1322:17:a2ce:c8ff:fe5b:4714 (2001:bf7:1322:17:a2ce:c8ff:fe5b:4714), 30 hops max, 80 byte packets
 1  2001:bf7:1322:17:a2ce:c8ff:fe5b:4714 (2001:bf7:1322:17:a2ce:c8ff:fe5b:4714)  7.208 ms  10.810 ms  10.557 ms

Das Ergebnis ist … sonderbar:

root@ysabell:~# DURATION=30; echo "Sending ..."; iperf3 --format m -t $DURATION -c 2001:bf7:1322:17:a2ce:c8ff:fe5b:4714 | awk 'BEGIN{valmax=0; valmin=1000;} /Mbits\/sec/ {for(i=1; i<=NF; i++) {if($i=="Mbits/sec") {i--; break;}} val=$i; if(val>valmax) valmax=val; if(val<valmin) valmin=val;} /sender$/ {print $0;} /receiver$/ {print $0;} END{printf("Min/Max: %.1f/%.1f MBit/sec\n", valmin, valmax);}' ; echo ; sleep 5 ;  echo "Receiving ..." ; iperf3 --format m -R -t $DURATION -c 2001:bf7:1322:17:a2ce:c8ff:fe5b:4714 | awk 'BEGIN{valmax=0; valmin=1000;} /Mbits\/sec/ {for(i=1; i<=NF; i++) {if($i=="Mbits/sec") {i--; break;}} val=$i; if(val>valmax) valmax=val; if(val<valmin) valmin=val;} /sender$/ {print $0;} /receiver$/ {print $0;} END{printf("Min/Max: %.1f/%.1f MBit/sec\n", valmin, valmax);}'
Sending ...
[  5]   0.00-30.00  sec   435 KBytes  0.12 Mbits/sec  269             sender
[  5]   0.00-30.01  sec   407 KBytes  0.11 Mbits/sec                  receiver
Min/Max: 0.0/0.4 MBit/sec

Receiving ...
[  5]   0.00-30.43  sec   318 MBytes  87.7 Mbits/sec  102             sender
[  5]   0.00-30.00  sec   310 MBytes  86.7 Mbits/sec                  receiver
Min/Max: 43.3/120.0 MBit/sec
root@Node A:~# iwinfo mesh1 info
mesh1     ESSID: "17:47:de:ca:fb:ad"
          Access Point: BE:79:5B:EB:6D:4D
          Mode: Mesh Point  Channel: 44 (5.220 GHz)  HT Mode: HT20
          Center Channel 1: 44 2: unknown
          Tx-Power: 23 dBm  Link Quality: 60/70
          Signal: -50 dBm  Noise: -91 dBm
          Bit Rate: 173.3 MBit/s
          Encryption: none
          Type: nl80211  HW Mode(s): 802.11ac/n
          Hardware: 14C3:7615 7615:14C3 [MediaTek MT7615E]
          TX power offset: none
          Frequency offset: none
          Supports VAPs: yes  PHY name: phy1
root@Node X:~# iwinfo mesh1 info
mesh1     ESSID: "17:47:de:ca:fb:ad"
          Access Point: 6E:AA:42:F2:B8:65
          Mode: Mesh Point  Channel: 44 (5.220 GHz)
          Tx-Power: 23 dBm  Link Quality: 57/70
          Signal: -53 dBm  Noise: -105 dBm
          Bit Rate: 144.4 MBit/s
          Encryption: none
          Type: nl80211  HW Mode(s): 802.11nac
          Hardware: unknown [Generic MAC80211]
          TX power offset: unknown
          Frequency offset: unknown
          Supports VAPs: yes  PHY name: phy1

Irgendwas scheint mir beim MT7615E bei 802.11s buggy, denn 0,x MBit/sec sendend im Mesh ist eher Kacke.

Kann das jemand bestätigen oder widerlegen?

(Eigentlich wollte ich mit dem GL-MT1300 nur das „ich verliere den Link zur 4040“-Verhalten des Archer C6 v2 bei VHT40 gegenchecken …:innocent:)

Den würde ich mir Mal anschauen:

1 „Gefällt mir“

Danke. Aber: hmm?

Sending ...     [iperf3 --format m -t 30 -c 2001:…]
[  5]   0.00-30.00  sec   287 KBytes  0.08 Mbits/sec  203             sender
[  5]   0.00-30.00  sec   238 KBytes  0.07 Mbits/sec                  receiver
Min/Max: 0.0/0.3 MBit/sec

Receiving ...   [iperf3 --format m -R -t 30 -c 2001:…]
[  5]   0.00-30.44  sec   429 MBytes   118 Mbits/sec  301             sender
[  5]   0.00-30.00  sec   422 MBytes   118 Mbits/sec                  receiver
Min/Max: 0.6/134.0 MBit/sec
root@33332-Schalueckstr-107-cd9d:~# iw phy1 info | grep -i msdu
			Max AMSDU length: 3839 bytes
		 * maximum A-MSDU length
root@33332-Schalueckstr-107-cd9d:~# iwinfo mesh1 info | grep -i hardware
          Hardware: 14C3:7615 7615:14C3 [MediaTek MT7615E]
root@33332-Schalueckstr-107-cd9d:~# dmesg | head -2
[    0.000000] Linux version 5.10.179 (ffgt@tomjon) (mipsel-openwrt-linux-musl-gcc (OpenWrt GCC 11.2.0 r20127+10-074db57936) 11.2.0, GNU ld (GNU Binutils) 2.37) #0 SMP Tue May 16 12:11:07 2023
[    0.000000] SoC Type: MediaTek MT7621 ver:1 eco:3
root@33332-Schalueckstr-107-cd9d:~# cat /tmp/sysinfo/board_name 
glinet,gl-mt1300

Patch ist da …

ffgt@tomjon:~/build$ ls -la gluon-ffgt-v2022.1/site-ffgt/gluon-build/patches/openwrt/0013-mac80211-mask-nested-A-MSDU-support-for-mesh.patch
-rw-rw-r-- 1 ffgt ffgt 2328 May 16 14:10 gluon-ffgt-v2022.1/site-ffgt/gluon-build/patches/openwrt/0013-mac80211-mask-nested-A-MSDU-support-for-mesh.patch

… und wurde lt. build.log auch applied:

Applying ./patches/subsys/800-mac80211-mask-nested-A-MSDU-support-for-mesh.patch using plaintext:
patching file net/mac80211/agg-rx.c
make[6]: Leaving directory '/home/ffgt/build/gluon-ffgt-v2022.1/site-ffgt/gluon-build/openwrt/package/kernel/mac80211'
make[6]: Entering directory '/home/ffgt/build/gluon-ffgt-v2022.1/site-ffgt/gluon-build/openwrt/package/kernel/mac80211'

Was mache ich falsch? (FTR: Nur der MT1300 läuft unter v2022.1.4, die 4040-Gegenstelle noch mit v2021.1.2)

… und der Code entsprechend geändert:

ffgt@tomjon:~/build/gluon-ffgt-v2022.1/site-ffgt$ grep -r -A3 -B3  '!sta->mesh' $(find gluon-build -name agg-rx.c)
gluon-build/openwrt/build_dir/target-i386_pentium4_musl/linux-x86_generic/backports-5.15.92-1/net/mac80211/agg-rx.c-	mgmt->u.action.u.addba_resp.dialog_token = dialog_token;
gluon-build/openwrt/build_dir/target-i386_pentium4_musl/linux-x86_generic/backports-5.15.92-1/net/mac80211/agg-rx.c-
gluon-build/openwrt/build_dir/target-i386_pentium4_musl/linux-x86_generic/backports-5.15.92-1/net/mac80211/agg-rx.c-	capab = 0;
gluon-build/openwrt/build_dir/target-i386_pentium4_musl/linux-x86_generic/backports-5.15.92-1/net/mac80211/agg-rx.c:	if (!sta->mesh)
gluon-build/openwrt/build_dir/target-i386_pentium4_musl/linux-x86_generic/backports-5.15.92-1/net/mac80211/agg-rx.c-		capab = u16_encode_bits(amsdu, IEEE80211_ADDBA_PARAM_AMSDU_MASK);
gluon-build/openwrt/build_dir/target-i386_pentium4_musl/linux-x86_generic/backports-5.15.92-1/net/mac80211/agg-rx.c-	capab |= u16_encode_bits(policy, IEEE80211_ADDBA_PARAM_POLICY_MASK);
gluon-build/openwrt/build_dir/target-i386_pentium4_musl/linux-x86_generic/backports-5.15.92-1/net/mac80211/agg-rx.c-	capab |= u16_encode_bits(tid, IEEE80211_ADDBA_PARAM_TID_MASK);
--
gluon-build/openwrt/build_dir/target-mips_4kec_musl/linux-realtek_rtl838x/backports-5.15.92-1/net/mac80211/agg-rx.c-	mgmt->u.action.u.addba_resp.dialog_token = dialog_token;
gluon-build/openwrt/build_dir/target-mips_4kec_musl/linux-realtek_rtl838x/backports-5.15.92-1/net/mac80211/agg-rx.c-
gluon-build/openwrt/build_dir/target-mips_4kec_musl/linux-realtek_rtl838x/backports-5.15.92-1/net/mac80211/agg-rx.c-	capab = 0;
gluon-build/openwrt/build_dir/target-mips_4kec_musl/linux-realtek_rtl838x/backports-5.15.92-1/net/mac80211/agg-rx.c:	if (!sta->mesh)
gluon-build/openwrt/build_dir/target-mips_4kec_musl/linux-realtek_rtl838x/backports-5.15.92-1/net/mac80211/agg-rx.c-		capab = u16_encode_bits(amsdu, IEEE80211_ADDBA_PARAM_AMSDU_MASK);
gluon-build/openwrt/build_dir/target-mips_4kec_musl/linux-realtek_rtl838x/backports-5.15.92-1/net/mac80211/agg-rx.c-	capab |= u16_encode_bits(policy, IEEE80211_ADDBA_PARAM_POLICY_MASK);
gluon-build/openwrt/build_dir/target-mips_4kec_musl/linux-realtek_rtl838x/backports-5.15.92-1/net/mac80211/agg-rx.c-	capab |= u16_encode_bits(tid, IEEE80211_ADDBA_PARAM_TID_MASK);
--
gluon-build/openwrt/build_dir/target-x86_64_musl/linux-x86_64/backports-5.15.92-1/net/mac80211/agg-rx.c-	mgmt->u.action.u.addba_resp.dialog_token = dialog_token;
gluon-build/openwrt/build_dir/target-x86_64_musl/linux-x86_64/backports-5.15.92-1/net/mac80211/agg-rx.c-
gluon-build/openwrt/build_dir/target-x86_64_musl/linux-x86_64/backports-5.15.92-1/net/mac80211/agg-rx.c-	capab = 0;
gluon-build/openwrt/build_dir/target-x86_64_musl/linux-x86_64/backports-5.15.92-1/net/mac80211/agg-rx.c:	if (!sta->mesh)
gluon-build/openwrt/build_dir/target-x86_64_musl/linux-x86_64/backports-5.15.92-1/net/mac80211/agg-rx.c-		capab = u16_encode_bits(amsdu, IEEE80211_ADDBA_PARAM_AMSDU_MASK);
gluon-build/openwrt/build_dir/target-x86_64_musl/linux-x86_64/backports-5.15.92-1/net/mac80211/agg-rx.c-	capab |= u16_encode_bits(policy, IEEE80211_ADDBA_PARAM_POLICY_MASK);
gluon-build/openwrt/build_dir/target-x86_64_musl/linux-x86_64/backports-5.15.92-1/net/mac80211/agg-rx.c-	capab |= u16_encode_bits(tid, IEEE80211_ADDBA_PARAM_TID_MASK);
[…]
--
gluon-build/openwrt/build_dir/target-powerpc_8540_musl/linux-mpc85xx_p1010/backports-5.15.92-1/net/mac80211/agg-rx.c-	mgmt->u.action.u.addba_resp.dialog_token = dialog_token;
gluon-build/openwrt/build_dir/target-powerpc_8540_musl/linux-mpc85xx_p1010/backports-5.15.92-1/net/mac80211/agg-rx.c-
gluon-build/openwrt/build_dir/target-powerpc_8540_musl/linux-mpc85xx_p1010/backports-5.15.92-1/net/mac80211/agg-rx.c-	capab = 0;
gluon-build/openwrt/build_dir/target-powerpc_8540_musl/linux-mpc85xx_p1010/backports-5.15.92-1/net/mac80211/agg-rx.c:	if (!sta->mesh)
gluon-build/openwrt/build_dir/target-powerpc_8540_musl/linux-mpc85xx_p1010/backports-5.15.92-1/net/mac80211/agg-rx.c-		capab = u16_encode_bits(amsdu, IEEE80211_ADDBA_PARAM_AMSDU_MASK);
gluon-build/openwrt/build_dir/target-powerpc_8540_musl/linux-mpc85xx_p1010/backports-5.15.92-1/net/mac80211/agg-rx.c-	capab |= u16_encode_bits(policy, IEEE80211_ADDBA_PARAM_POLICY_MASK);
gluon-build/openwrt/build_dir/target-powerpc_8540_musl/linux-mpc85xx_p1010/backports-5.15.92-1/net/mac80211/agg-rx.c-	capab |= u16_encode_bits(tid, IEEE80211_ADDBA_PARAM_TID_MASK);
--
gluon-build/openwrt/build_dir/target-powerpc_8540_musl/linux-mpc85xx_p1020/backports-5.15.92-1/net/mac80211/agg-rx.c-	mgmt->u.action.u.addba_resp.dialog_token = dialog_token;
gluon-build/openwrt/build_dir/target-powerpc_8540_musl/linux-mpc85xx_p1020/backports-5.15.92-1/net/mac80211/agg-rx.c-
gluon-build/openwrt/build_dir/target-powerpc_8540_musl/linux-mpc85xx_p1020/backports-5.15.92-1/net/mac80211/agg-rx.c-	capab = 0;
gluon-build/openwrt/build_dir/target-powerpc_8540_musl/linux-mpc85xx_p1020/backports-5.15.92-1/net/mac80211/agg-rx.c:	if (!sta->mesh)
gluon-build/openwrt/build_dir/target-powerpc_8540_musl/linux-mpc85xx_p1020/backports-5.15.92-1/net/mac80211/agg-rx.c-		capab = u16_encode_bits(amsdu, IEEE80211_ADDBA_PARAM_AMSDU_MASK);
gluon-build/openwrt/build_dir/target-powerpc_8540_musl/linux-mpc85xx_p1020/backports-5.15.92-1/net/mac80211/agg-rx.c-	capab |= u16_encode_bits(policy, IEEE80211_ADDBA_PARAM_POLICY_MASK);
gluon-build/openwrt/build_dir/target-powerpc_8540_musl/linux-mpc85xx_p1020/backports-5.15.92-1/net/mac80211/agg-rx.c-	capab |= u16_encode_bits(tid, IEEE80211_ADDBA_PARAM_TID_MASK);

AFAICS, ist der Patch nur nutzlos? Wobei:

Linux 33332[…]cd9d 5.10.179 #0 SMP Tue May 16 22:38:50 2023 mips GNU/Linux

Wieso wurde er nur gegen backports-5.15.92-1 applied?

Ok, das ist wohl weil:

This release is based on the newest OpenWrt 22.03 release branch. It ships with Linux kernel 5.10 as well as wireless-backports 5.15.

Und nach einem Reboot der 4040 mit v2021 – umbenannt, um klarere Beschreibungen liefern zu können – klappt’s auch mit dem Durchsatz. Nanü‽

VHT40:

Sending ...
[  5] local 2001:bf7:1322:17:3a57:6041:5b9b:5ab1 port 38298 connected to 2001:bf7:1322:17:a2ce:c8ff:fe5b:4714 port 5201
-----
[  5]   0.00-30.00  sec   505 MBytes   141 Mbits/sec  5763             sender
[  5]   0.00-30.04  sec   502 MBytes   140 Mbits/sec                  receiver
-----
Min/Max: 73.4/168.0 MBit/sec

Receiving ...
[  5] local 2001:bf7:1322:17:3a57:6041:5b9b:5ab1 port 57062 connected to 2001:bf7:1322:17:a2ce:c8ff:fe5b:4714 port 5201
-----
[  5]   0.00-30.05  sec   315 MBytes  88.0 Mbits/sec  429             sender
[  5]   0.00-30.00  sec   314 MBytes  87.7 Mbits/sec                  receiver
-----
Min/Max: 62.3/120.0 MBit/sec

VHT20:

[  5] local 2001:bf7:1322:17:3a57:6041:5b9b:5ab1 port 41000 connected to 2001:bf7:1322:17:a2ce:c8ff:fe5b:4714 port 5201
-----
[  5]   0.00-30.00  sec   141 MBytes  39.6 Mbits/sec  554             sender
[  5]   0.00-30.04  sec   141 MBytes  39.3 Mbits/sec                  receiver
-----
Min/Max: 18.4/51.7 MBit/sec

Receiving ...
[  5] local 2001:bf7:1322:17:3a57:6041:5b9b:5ab1 port 54272 connected to 2001:bf7:1322:17:a2ce:c8ff:fe5b:4714 port 5201
-----
[  5]   0.00-30.06  sec   176 MBytes  49.0 Mbits/sec  353             sender
[  5]   0.00-30.00  sec   173 MBytes  48.4 Mbits/sec                  receiver
-----
Min/Max: 27.6/66.7 MBit/sec

Das, siehe Schaubild, ist von einem Linux-PC hinter einer v2021-4040 über 6m 802.11s-Mesh zum iperf3 -s auf einem Linux-PC hinter derzeit einem GL-MT1300. »Sending« bedeutet also die 4040 sendet ins Mesh, der MT1300 empfängt.

Okay-ish. Aber wieso ist »Receiving« – der MT1300 sendet, die 4040 empfängt – so viel langsamer (iwinfo zeigte für beide mesh-Interfaces »Bit Rate: 400.0 MBit/s«)? Die 4040 läuft unter v2021, blendet IEEE80211_ADDBA_PARAM_AMSDU_MASK demnach nicht aus — und zuvor war’s ja sogar schneller?

Das ganze ist ein bisschen komplex.
Tritt auch nicht immer sofort auf, wenn z. B. nur 5GHz durch ath10k bedient wird.
Auftreten tut es bei Mischsetups mit ath10k wifi und Mediatek.

Qualcomm macht hardware offloading und erzeugt die frames bis auf einen (kleinen?) Bug richtig. Mediatek nutzt die Softwareimplementierung des Linuxkernels und die hat momentan a-msdu frames leider falsch implementiert.
Das Fixen zieht sich, weil die Funktionalität verlagert werden muss an eine andere Stelle im Code.
Felix Fietkau (nbd) arbeitet daran, den Code zu überarbeiten.

a-msdu dient eigentlich der Steigerung des Durchsatzes. Der Bug sorgt leider dafür, dass massiv Pakete verworfen werden, weil die Pakete nicht richtig interpretiert werden können.
blocktrron’s vorläufiger Fix ist es, im mesh wlan nicht mehr anzuzeigen, dass man diese frames beherrscht, dann werden diese nicht mehr in der Kommunikation verwendet.
wenn man den Patch auch unter Qualcomm verwendet, dürfte das die Datenrate in reinen Qualcomm meshen verringern. Wie sehr, das kann ich leider nicht sagen.

Alles sehr doof das ganze :confused:

Intensivere technische Details, die hier eigentlich zu weit führen:

The problem is that the bug comes from a wrong assumptions in the rx processing code. The code assumes that the mesh header comes after the 802.11 header before A-MSDU subframes, when in fact the mesh header is part of each individual subframe. Fixing this flawed assumption will require some significant rework. I will work on it, but I need more time to get it done.

The issue is in the Linux stack rx code, not mt76.
ieee80211_data_to_8023_exthdr in net/wireless/util.c assumes that in mesh mode, the mesh header immediately follows the 802.11 header and applies to all subframes.
According to the 802.11-2016 standard, chapter 9.3.2.2.2, figure 9-56, the mesh header is part of each A-MSDU subframe.
Taking this into account will need some significant rework of the rx path and cfg80211 utility functions, including the mesh forwarding code.
The A-MSDU decap code needs to be adjusted to leave the mesh header in place, and mesh forwarding needs to happen later in the rx processing chain.

1 „Gefällt mir“