Which kernel are you using? Linux 6.17.0-22-generic
Which BIOS version are you using? 03.18
Which Framework Laptop 13 model are you using? AMD Ryzen™ 7040 Series
My wifi connection crashes as soon as syncthing running on my android phone connects to the network. Journalctl catches the following errors:
wpa_supplicant[78715]: TDLS: Creating peer entry for f2:6d:2d:e4:d2:31
wpa_supplicant[78715]: wlan0: CTRL-EVENT-SIGNAL-CHANGE above=1 signal=-47 noise=9999 txrate=2161300
wpa_supplicant[78715]: TDLS: Dialog Token in TPK M1 220
wpa_supplicant[78715]: nl80211: kernel reports: key addition failed
wpa_supplicant[78715]: TDLS: Failed to set TPK to the driver
I belief the kernel error is in fact an error with the mt7921e Wifi driver.
I have tried to switch to iwd as a backend (which fixed this problem by not supporting tdls) but could not connect to the eduroam network in my university, which is not an option. I also tried to disable tdls for wpa_supplicant through /etc/wpa_supplicant/wpa_supplicant.conf but it seems that it does not respect that rule, as the same error continues to occurre.
Do you have any idea how to fix the driver or at least mitigate the problem?
Okay, after another long chat with an AI chatbot I got to this “solution”:
I could not find a way to disable TDLS with wpa_supplicant and NetworkManager. So I ended up creating a file to “set tdls disabled” everytime my network turns on.
I think this is a bug in either the Ubuntu 24.04 kernel (for the MediaTek WiFi drivers) or in Ubuntu’s wpa_supplicant package, but deifinitely worth raising with SyncThing’s GitHub and PPA. But I’m glad you raised it here, I’ll watch out for SyncThing doing legitimate but weird things on WiFi when things go wrong.
Thanks, I reported it to the Ubuntu launchpad.net. Syncthing can be excluded as a source, as it happens with GSConnect (KdeConnect Clone) as well.
I got a Laptop today with the same Software config but a different wifi modul and TDLS was activated without problems.
Spent a few days digging into this. The root cause is a 2013-era mac80211 bug: when wpa_supplicant calls NL80211_CMD_NEW_KEY to install the TDLS TPK, mac80211 returns -ENOENT because the peer hasn’t reached WLAN_STA_ASSOC yet (TDLS peers defer that transition). wpa_supplicant gives up, the half-set-up peer ends up zombie, and on some drivers that cascades into the main BSS link breaking.
The check was added by Johannes Berg in 2013 as an FT roaming fix: https:[//]git[]kernel[]org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1626e0fa740dec8665a973cf2349405cdfeb46dc - the TODO comment directly above it describes the TDLS case but it never got fixed.
Sorry for that ugly link, as I new user I cannot attach more than two links in one reply.
Fix is one line in net/mac80211/cfg.c - add sta->sta.tdls to the existing exemption alongside sta->sta.epp_peer (example). To be honest, I’m not really sure if this is the right way to fix the problem, but at least it works.
Hey, I am amazed by your understanding of the matter and your capability to fix it.
Do you think your fix does have any downsides?
As mentioned above I thought it was primarly a firmeware bug, as it worked with the same kernel and a different wifi module. But if I understand you correctly it is also possible for the nl80211 kernel thing to handle the firmeware differently. Have you filled that commit somewhere it will get tested/pushed upstream?
On downsides: I can’t really test thoroughly because my only TDLS-initiating device is a Samsung Galaxy S25 Ultra, and it drops the link after a few seconds for reasons I haven’t been able to figure out (no root on the phone). What the patch does is narrow: it widens an existing -ENOENT exemption to also cover TDLS peers, so we stop rejecting key install in the specific case where a TDLS peer is still in the NONE state. The TODO comment directly above the guard from 2013 literally describes this case but it never got fixed, so in principle nothing should break.
Worth noting: the bug isn’t Syncthing/GSConnect specific, it triggers with anything that does P2P traffic over the same LAN, even plain ssh or adb over Wi-Fi.
On the firmware vs kernel question (for MT7925 specifically): the key-install rejection happens in mac80211’s ieee80211_add_key, which is generic kernel code, not driver/firmware. What differs is what happens after the rejection: wpa_supplicant gives up, the half-set-up TDLS peer sits in a zombie state, and the MT7925 firmware reacts to that zombie progressively worse over time. In my case after frequent setup-and-drop cycles the tx/rx bitrate eventually drops to 6 Mbps and the only thing that fixes it is reconnecting to the AP. There’s a recent linux-firmware update (commit) that improves the situation noticeably but doesn’t fully solve it.
On upstream: I’ve never submitted a kernel patch before, so I’d want a couple more people whose setups actually benefit from it (not just mine) to confirm before trying to send it to linux-wireless. Happy to help with testing in the meantime. Out of curiosity, which Wi-Fi card was in there when TDLS was working for you?
Im not a framework user, but I have exactly the same issue, after switching from a compiled (which did not support tdls) to the rtw88 kernel driver. I’m literally searching for weeks and the only “solution” I found was switching to iwd backend, which also doesn’t support tdls or downgrading the driver. Really nice to see someone who has the skill to pin it down. I found many postings on the web with the same problem, but most end up without or with the switch to iwd as solution.
My test setup is the base S25 as tdls client and a small home server running over wifi (realtek 8821cu). Ssh/web or nearly everything triggers tdls and i end up with a broken connection and have to restart wifi on the server.
Okay, thank you for the explanation how the kernel would act differently!
What I mean is, that the initial key rejection did not happen on the intel wifi modul with the iwlwifi driver. Or at least there is now error throwen by the mac80211. It logs just TDLS Creating peer entry … TPK set or something. Right in the first try.
EDIT: I don’t think this new firmware will find its way into my ubuntu install 24.04, or is it? I am still on Version 2505Something.
To be honest, I don’t even know what’s going on in Ubuntu, or how to properly update linux-firmware other than by rebuilding the package. For now, I’d recommend just trying the kernel patch.
After several rounds of debugging the firmware, kernel, and sniffing the surrounding network traffic, I managed to get TDLS working with the Samsung Galaxy S25 Ultra!
I’ll try to clean up the patches and publish them soon.
Here’s roughly what it looks like now:
❯ iw dev wlp4s0 station dump
Station aa:bb:cc:dd:ee:ff (on wlp4s0)
authorized: yes
authenticated: yes
associated: yes
preamble: long
WMM/WME: yes
MFP: yes
TDLS peer: no
inactive time: 2344 ms
rx bytes: 26843082
rx packets: 90255
tx bytes: 236745103
tx packets: 204918
tx retries: 7059
tx failed: 0
beacon loss: 0
rx drop misc: 714
signal: -41 [-42, -47] dBm
signal avg: -41 [-41, -49] dBm
tx bitrate: 1200.9 MBit/s 80MHz HE-MCS 11 HE-NSS 2 HE-GI 0 HE-DCM 0
tx duration: 14913024 us
rx bitrate: 1200.9 MBit/s 80MHz HE-MCS 11 HE-NSS 2 HE-GI 0 HE-DCM 0
rx duration: 19864473 us
last ack signal:-37 dBm
avg ack signal: -37 dBm
airtime weight: 256
DTIM period: 1
beacon interval:100
short slot time:yes
connected time: 9772 seconds
associated at [boottime]: 39449.609s
associated at: 1777726376627 ms
current time: 1777736148828 ms
Station ff:ee:dd:cc:bb:aa (on wlp4s0)
authorized: yes
authenticated: yes
associated: yes
preamble: long
WMM/WME: yes
MFP: no
TDLS peer: yes
inactive time: 0 ms
rx bytes: 7903555758
rx packets: 5145532
tx bytes: 188713662
tx packets: 2188161
tx retries: 38117
tx failed: 0
beacon loss: 0
rx drop misc: 3
signal: -53 [-55, -57] dBm
signal avg: -53 [-55, -57] dBm
tx bitrate: 1200.9 MBit/s 80MHz HE-MCS 11 HE-NSS 2 HE-GI 0 HE-DCM 0
tx duration: 18109325 us
rx bitrate: 864.8 MBit/s 80MHz HE-MCS 8 HE-NSS 2 HE-GI 0 HE-DCM 0
rx duration: 115579005 us
last ack signal:-47 dBm
avg ack signal: -47 dBm
airtime weight: 256
DTIM period: 1
beacon interval:100
short slot time:yes
connected time: 163 seconds
associated at [boottime]: 49058.184s
associated at: 1777735985201 ms
current time: 1777736148828 ms
In principle, you could even just recompile certain modules, but the easiest way is to take the last two commits from my repository and apply them to the entire kernel.
At this stage, my patches haven’t been accepted into the kernel yet because I disable hardware encapsulation/decapsulation acceleration, but I haven’t noticed any significant performance degradation, and it’s better than a completely broken TDLS.
so I managed to compile my Ubuntu 6.17.4+ kernel with your tdls-fix-v2 branch. I cherry picked the last 2 commits from that branch. Now my connection does not drop off anymore, but TDLS still does not work with my Pixel 6 running Android 16. The error-messages I saw in journalctl were the same as before.
Should I try running a newer (upstream) kernel? Or do you have any idea what might cause this?
Are you interested in any other logs? Or is there any debugging I could do?
Good news first: the connection no longer dropping means patch 2 (BSS guard) is doing its job.
The nl80211: kernel reports: key addition failed / TDLS: Failed to set TPK to the driver lines are the first attempt at key install, which mac80211 rejects because the TDLS peer isn’t WLAN_STA_ASSOC yet (cfg.c#n670). wpa_supplicant retries the key install after the peer is authorized (tdls.c#n2608). The comment there reads “Some drivers may not be able to config the key prior to full STA entry having been configured”, and then it sets peer->reconfig_key = 1 to retry later. So that error line alone doesn’t mean TDLS is broken.
To check whether TDLS is actually carrying data, run this while data is flowing between the laptop and the phone (in either direction):
watch -n1 iw dev wlp4s0 station dump
A TDLS peer would appear as a new entry alongside the AP, with the phone’s MAC. If the phone’s MAC never shows up, TDLS isn’t establishing at all. If it does show up, watch the rx bytes / tx bytes numbers. They should be climbing in real time on healthy TDLS.
To narrow this down further please share two snapshots of iw dev wlp4s0 station dump plus uname -r:
One at test start (just the AP entry expected)
One after 10-15 seconds of sustained data flow between the laptop and the phone (the TDLS-peer entry should appear by then if it’s establishing)
so the uname -r is 6.17.4+ (The naming here will improve once I recompile).
station dump AP only:
Station 2c:91:ab:25:d5:f1 (on wlan0)
inactive time: 171 ms
rx bytes: 412431
rx packets: 1988
tx bytes: 60973
tx packets: 374
tx retries: 405
tx failed: 4
beacon loss: 0
rx drop misc: 19
signal: -85 [-92, -85] dBm
signal avg: -84 [-91, -84] dBm
tx bitrate: 17.2 MBit/s HE-MCS 1 HE-NSS 1 HE-GI 0 HE-DCM 0
tx duration: 2118341 us
rx bitrate: 34.4 MBit/s HE-MCS 1 HE-NSS 2 HE-GI 0 HE-DCM 0
rx duration: 342403 us
last ack signal:-85 dBm
avg ack signal: -84 dBm
airtime weight: 256
authorized: yes
authenticated: yes
associated: yes
preamble: long
WMM/WME: yes
MFP: no
TDLS peer: no
DTIM period: 2
beacon interval:100
short preamble: yes
short slot time:yes
connected time: 173 seconds
associated at [boottime]: 391308.514s
associated at: 1779045455238 ms
current time: 1779045628159 ms
station dump after the error message (with both connected):
Station 2c:91:ab:25:d5:f2 (on wlan0)
inactive time: 6 ms
rx bytes: 106254621
rx packets: 71421
tx bytes: 1502369
tx packets: 18877
tx retries: 24501
tx failed: 16
beacon loss: 0
rx drop misc: 0
signal: -59 [-62, -62] dBm
signal avg: -61 [-62, -18] dBm
tx bitrate: 1080.6 MBit/s 160MHz HE-MCS 10 HE-NSS 1 HE-GI 0 HE-DCM 0
tx duration: 257699377482 us
rx bitrate: 16.2 MBit/s HE-MCS 1 HE-NSS 1 HE-GI 1 HE-DCM 0
rx duration: 257704716529 us
last ack signal:-57 dBm
avg ack signal: -56 dBm
airtime weight: 256
authorized: yes
authenticated: yes
associated: yes
preamble: long
WMM/WME: yes
MFP: no
TDLS peer: no
DTIM period: 2
beacon interval:100
short preamble: yes
short slot time:yes
connected time: 254 seconds
associated at [boottime]: 392111.805s
associated at: 1779046258529 ms
current time: 1779046512939 ms
Station f2:6d:2d:e4:d2:31 (on wlan0)
inactive time: 6503 ms
rx bytes: 524820
rx packets: 415
tx bytes: 16589
tx packets: 210
tx retries: 412
tx failed: 9
beacon loss: 0
rx drop misc: 0
signal: -45 [-49, -47] dBm
signal avg: -45 [-48, -47] dBm
tx bitrate: 6.0 MBit/s
tx duration: 2820754 us
rx bitrate: 162.5 MBit/s HE-MCS 7 HE-NSS 2 HE-GI 1 HE-DCM 0
rx duration: 71106 us
last ack signal:-45 dBm
avg ack signal: -45 dBm
airtime weight: 256
authorized: yes
authenticated: yes
associated: yes
preamble: long
WMM/WME: yes
MFP: no
TDLS peer: yes
DTIM period: 2
beacon interval:100
short preamble: yes
short slot time:yes
connected time: 144 seconds
associated at [boottime]: 392221.823s
associated at: 1779046368547 ms
current time: 1779046512939 ms
My observations have been, that on my 2,4 Ghz Wifi no attempt at TDLS was made.
After I switched to 5 Ghz it would log creating TDLS with the MAC of my phone. After a few seconds the error would show up two times but the station dump would show the entry for my phone. After a while of continuous load it would loose connection and start again logging creating tdls entry. In contrast to the other device where it would log the sucess of creating TDLS entry it still seems a little unstable, but on the other hand this seems to suggest it is working, no?
On the second test it connected after the 5th time logging the error. And remained connected for the most part of the test (looking at watch station dump) but at some point lost connection and after that failed to remain connected. There would be an entry in station dump but it would disappear as the inactive ms climbed quickly..
Sorry for a slow response, pretty busy these days.
Perhaps this depends on certain factors that aren’t known to me. It could range from router settings (some may block TDLS connections) to the behavior of the phone’s firmware. In my case, with a Keenetic Giga KN-1012 and a Samsung Galaxy S25 Ultra, it works on both 2.4 GHz and 5 GHz.
Based on the output of `iw station dump`, the TDLS connection is active and, for the most part, no longer drops due to the issues that my patches are designed to fix, but I’m not happy that so little data has been transmitted over it. According to the 802.11z standard, if devices have established a TDLS connection between themselves, the router should ignore the transmission of frames between these devices, but in your case, the majority of the traffic actually went through the AP. Could you please tell me a little more about your environment and how exactly you tested it?
I would also try running an iperf3 test between the two devices for 2 minutes to see exactly how your traffic is flowing (to check whether the transmission is interrupted for a while or not). If the iperf3 output shows that data transmission stops completely for a while, it means that something else needs to be fixed for your network card, or the radar detection is triggering, it all depends on a lot of factors, not especially TDLS-stuff. If it’s specifically an issue with the card, then unfortunately I’m pretty much helpless here, since I have a slightly different card (MT7925), and I cannot cleanly reproduce the same behavior.