(Original post below)
The Problem
The MediaTek MT7925 (WiFi 7) and MT7921 (WiFi 6E) drivers in Linux kernels 6.8–6.19 have several bugs that cause:
-
Kernel panics (NULL pointer dereferences)
-
System hangs (mutex deadlocks)
-
WiFi drops requiring reboot
These issues are particularly bad on Framework Laptop 16 and Framework Desktop systems, often crashing every few minutes in certain WiFi environments—especially with:
-
Multi-AP setups with roaming
-
WiFi 6E/7 with 6 GHz band
-
WiFi 7 Multi-Link Operation (MLO)
The Root Cause
The crashes occur in the mt7925_mac_reset_work → ieee80211_iterate_interfaces path when the driver tries to recover from firmware hiccups but encounters NULL pointers and mutex deadlocks due to missing safety checks in the upstream driver.
BUG: kernel NULL pointer dereference, address: 0000000000000000
Workqueue: mt76 mt7925_mac_reset_work [mt7925_common]
RIP: mt76_connac_mcu_uni_add_dev+0xf1/0x210 [mt76_connac_lib]
The Solution: Patched Driver Packages
I’ve created a 12-patch series that fixes these kernel-side bugs. The patches are now available as easy-to-install packages for all major distros.
New Documentation Site
Overview - Linux MT7921/MT7925 WiFi Driver Fixes
Complete documentation including installation guides, known issues, crash analysis, and architecture deep-dives.
Quick Install
Arch Linux (AUR)
yay -S mt76-mt7925-dkms
Debian / Ubuntu
curl -1sLf 'https://dl.cloudsmith.io/public/mt76/packages/setup.deb.sh' | sudo -E bash
sudo apt update && sudo apt install mt76-mt7925-dkms
Fedora / RHEL
curl -1sLf 'https://dl.cloudsmith.io/public/mt76/packages/setup.rpm.sh' | sudo -E bash
sudo dnf install mt76-mt7925-dkms
Manual (any distro)
git clone https://github.com/zbowling/mt7925.git
cd mt7925/dkms && sudo ./install.sh
Requirements: Kernel 6.17+ (for older kernels, see the patch method)
What Gets Fixed
| Issue | Status |
|-------|--------|
| NULL pointer crashes in VIF iteration |
Fixed |
| Mutex deadlocks in suspend/resume |
Fixed |
| List corruption in wcid cleanup |
Fixed |
| MCU timeout → kernel panic |
Now recovers gracefully |
| ROC (remain-on-channel) deadlocks |
Fixed |
| MLO link pointer crashes |
Fixed |
What’s NOT Fixed (Firmware Issues)
| Issue | Status |
|-------|--------|
| MCU timeouts during MLO roaming |
Driver recovers, but FW still times out |
| Lower throughput vs Intel cards |
Firmware/hardware limitation |
| Frequent deauth cycles |
Partially mitigated |
The firmware is encrypted and can’t be patched. My goal is to make the kernel driver handle firmware misbehavior gracefully instead of crashing.
Patch Summary (v1.4.1)
12 patches addressing:
-
Deadlock in ROC abort (Sean Wang, upstream)
-
List corruption in wcid cleanup
-
NULL pointer in rate control work
-
Mutex deadlock in suspend path
-
NULL checks for MLO operations
-
Mutex protection in critical paths
-
MCU command error handling
-
Lockdep assertions for debugging
-
MLO roaming and ROC setup fixes
-
BA session teardown during beacon loss
-
ROC deadlocks and race conditions
-
Double wcid initialization race
Upstream Status
I’m actively working with MediaTek to get these patches merged upstream. Some patches (like #1) are already in the upstream queue. The full series is under review.
Until upstream merges these, this DKMS package provides immediate relief.
Resources
-
Documentation: Overview - Linux MT7921/MT7925 WiFi Driver Fixes -
:octocat: GitHub: GitHub - zbowling/mt7925: Fixes for crashes in MediaTek mt7925
-
Packages: Cloudsmith Repository -
Report Issues: GitHub · Where software is built -
Crash Logs: mt7925/crashes at main · zbowling/mt7925 · GitHub
Verify Installation
After installing, verify with:
dkms status | grep mt76-mt7925
# Should show: mt76-mt7925/1.4.1, <kernel>, x86_64: installed
modinfo mt7925e | grep filename
# Should show: /lib/modules/.../updates/dkms/mt7925e.ko
If this helps you, please share your experience! Knowing which systems and environments benefit helps prioritize fixes and provides data for upstream submissions.
Original post
Hitting a kernel panic freeze that I thought was related to Thunderbolt 5, but it turns out it’s wifi related. Switched to Ethernet for now.
Which Linux distro are you using?
Ubuntu
Which release version?
Ubuntu 25.10
(If rolling release, last date updated?)
N/A (not a rolling release)
Which kernel are you using?
6.17.0-8-generic
Which BIOS version are you using?
03.04 (released 11/19/2025)
Which Framework Desktop model are you using?
AMD Ryzen™ AI Max 395 Series
System freezes/lockups caused by kernel panic in the MediaTek MT7925e WiFi driver
The root cause seems to be a NULL pointer dereference in mt76_connac_mcu_uni_add_dev() function (offset 0xba) during WiFi reset workflow. This occurs when the driver attempts to reconnect after WiFi association failures or timeouts.
quasi-stack trace: mt7925_mac_reset_work → ieee80211_iterate_interfaces → mt7925_vif_connect_iter → mt76_connac_mcu_uni_add_dev [NULL pointer dereference]
Dump
[ 654.968920] [ T12] mt7925e 0000:c0:00.0: WM Firmware Version: ____000000, Build Time: 20250721232943
[ 655.737302] [ T12] BUG: kernel NULL pointer dereference, address: 0000000000000000
[ 655.737320] [ T12] #PF: supervisor read access in kernel mode
[ 655.737324] [ T12] #PF: error_code(0x0000) - not-present page
[ 655.737328] [ T12] PGD 0 P4D 0
[ 655.737334] [ T12] Oops: Oops: 0000 [#1] SMP NOPTI
[ 655.737342] [ T12] CPU: 20 UID: 0 PID: 12 Comm: kworker/u128:0 Kdump: loaded Tainted: G OE 6.17.0-8-generic #8-Ubuntu PREEMPT(voluntary)
[ 655.737350] [ T12] Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
[ 655.737351] [ T12] Hardware name: Framework Desktop (AMD Ryzen AI Max 300 Series)/FRANMFCP06, BIOS 03.04 11/19/2025
[ 655.737354] [ T12] Workqueue: mt76 mt7925_mac_reset_work [mt7925_common]
[ 655.737370] [ T12] RIP: 0010:mt76_connac_mcu_uni_add_dev+0xba/0x1f0 [mt76_connac_lib]
[ 655.737385] [ T12] Code: cc 66 44 89 5d d2 44 88 45 d4 44 88 4d d5 88 65 d7 c6 45 dc 01 88 55 dd 0f b7 97 b8 00 00 00 88 4d ef 66 89 55 e4 66 89 55 ea <48> 8b 16 8b 12 83 fa 03 0f 84 0c 01 00 00 77 1b 83 fa 01 0f 84 f5
[ 655.737388] [ T12] RSP: 0018:ffffd07fc018fcb0 EFLAGS: 00010282
[ 655.737392] [ T12] RAX: 000000000000ff00 RBX: ffff8a4449442040 RCX: 0000000000000000
[ 655.737394] [ T12] RDX: 0000000000000013 RSI: 0000000000000000 RDI: ffff8a44c7d7a4b0
[ 655.737396] [ T12] RBP: ffffd07fc018fcf8 R08: 0000000000000001 R09: 0000000000000000
[ 655.737397] [ T12] R10: 0000000000000000 R11: 0000000000000020 R12: ffff8a4449442040
[ 655.737399] [ T12] R13: ffff8a44c7d79f08 R14: 0000000000000000 R15: ffff8a44c7d78a80
[ 655.737401] [ T12] FS: 0000000000000000(0000) GS:ffff8a53ca47f000(0000) knlGS:0000000000000000
[ 655.737403] [ T12] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 655.737404] [ T12] CR2: 0000000000000000 CR3: 00000009e2a40000 CR4: 0000000000f50ef0
[ 655.737406] [ T12] PKRU: 55555554
[ 655.737408] [ T12] Call Trace:
[ 655.737411] [ T12]
[ 655.737416] [ T12] mt7925_vif_connect_iter+0xcb/0x240 [mt7925_common]
[ 655.737423] [ T12] __iterate_interfaces+0x92/0x130 [mac80211]
[ 655.737500] [ T12] ? __pfx_mt7925_vif_connect_iter+0x10/0x10 [mt7925_common]
[ 655.737506] [ T12] ieee80211_iterate_interfaces+0x3d/0x60 [mac80211]
[ 655.737549] [ T12] ? __pfx_mt7925_vif_connect_iter+0x10/0x10 [mt7925_common]
[ 655.737553] [ T12] mt7925_mac_reset_work+0x105/0x190 [mt7925_common]
[ 655.737559] [ T12] process_one_work+0x18b/0x370
[ 655.737567] [ T12] worker_thread+0x317/0x450
[ 655.737570] [ T12] ? __pfx_worker_thread+0x10/0x10
[ 655.737573] [ T12] kthread+0x108/0x220
[ 655.737577] [ T12] ? __pfx_kthread+0x10/0x10
[ 655.737579] [ T12] ret_from_fork+0x131/0x150
[ 655.737585] [ T12] ? __pfx_kthread+0x10/0x10
[ 655.737587] [ T12] ret_from_fork_asm+0x1a/0x30
[ 655.737592] [ T12]
[ 655.737594] [ T12] Modules linked in: tls snd_seq_dummy snd_hrtimer xt_mark veth nf_conntrack_netlink xt_nat xt_tcpudp xt_conntrack xt_MASQUERADE bridge stp llc xfrm_user xfrm_algo xt_set ip_set nft_chain_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 xt_addrtype nft_compat ccm nf_tables rfcomm cmac algif_hash algif_skcipher af_alg overlay qrtr bnep binfmt_misc nls_iso8859_1 intel_rapl_msr amd_atl intel_rapl_common snd_hda_codec_alc269 edac_mce_amd snd_hda_scodec_component snd_hda_codec_realtek_lib snd_hda_codec_atihdmi snd_hda_codec_generic mt7925e snd_hda_codec_hdmi btusb mt7925_common btrtl kvm_amd btintel mt792x_lib snd_hda_intel btbcm snd_hda_codec mt76_connac_lib btmtk leds_cros_ec kvm gpio_cros_ec irqbypass cros_ec_sysfs led_class_multicolor cros_ec_hwmon cros_ec_debugfs snd_hda_core cros_ec_chardev mt76 polyval_clmulni ghash_clmulni_intel bluetooth snd_seq_midi spd5118 cros_ec_dev aesni_intel snd_intel_dspcfg rapl mac80211 snd_seq_midi_event snd_intel_sdw_acpi snd_rawmidi snd_hwdep wmi_bmof cfg80211 snd_seq
[ 655.737656] [ T12] snd_pcm amd_pmf amdxdna snd_seq_device amdtee gpu_sched snd_timer input_leds i2c_piix4 snd i2c_smbus libarc4 amd_sfh ccp soundcore joydev tee cros_ec_lpcs platform_profile cros_ec amd_pmc cros_ec_proto mac_hid sch_fq_codel msr parport_pc ppdev lp parport efi_pstore nfnetlink dmi_sysfs ip_tables x_tables autofs4 typec_displayport typec_thunderbolt hid_generic ucsi_acpi typec_ucsi usbhid typec hid amdgpu(OE) amddrm_ttm_helper(OE) amdttm(OE) amddrm_buddy(OE) amdxcp(OE) amddrm_exec(OE) drm_suballoc_helper amd_sched(OE) amdkcl(OE) drm_panel_backlight_quirks i2c_algo_bit drm_ttm_helper ttm drm_display_helper nvme cec nvme_core gpio_keys rc_core r8169 nvme_keyring thunderbolt realtek nvme_auth video wmi soc_button_array 8250_dw
[ 655.737713] [ T12] CR2: 0000000000000000
[ 325.069133] [ T1940] wlp192s0: Limiting TX power to 30 (30 - 0) dBm as advertised by d8:b3:70:f8:9e:7d
[ 329.056447] [ T1948] wlp192s0: Limiting TX power to 30 (30 - 0) dBm as advertised by d8:b3:70:f8:9e:7c
[ 493.378637] [ T215] audit: type=1400 audit(1767142510.031:274): apparmor=“AUDIT” operation=“userns_create” class=“namespace” info=“Userns create - transitioning profile” profile=“unconfined” pid=35160 comm=“(insights)” requested=“userns_create” target=“unprivileged_userns” execpath=“/usr/lib/systemd/systemd-executor”
[ 493.378689] [ T215] audit: type=1400 audit(1767142510.032:275): apparmor=“AUDIT” operation=“userns_create” class=“namespace” info=“Userns create - transitioning profile” profile=“unconfined” pid=35161 comm=“(insights)” requested=“userns_create” target=“unprivileged_userns” execpath=“/usr/lib/systemd/systemd-executor”
[ 493.379084] [ T215] audit: type=1400 audit(1767142510.032:276): apparmor=“DENIED” operation=“capable” class=“cap” profile=“unprivileged_userns” pid=35160 comm=“(insights)” capability=21 capname=“sys_admin”
[ 493.379172] [ T215] audit: type=1400 audit(1767142510.032:277): apparmor=“DENIED” operation=“capable” class=“cap” profile=“unprivileged_userns” pid=35161 comm=“(insights)” capability=21 capname=“sys_admin”
[ 633.912593] [ T2428] wlp192s0: disconnect from AP d8:b3:70:f8:9e:7b for new auth to d8:b3:70:f8:9e:7b
[ 634.298743] [ T2428] wlp192s0: [link 2] regulatory prevented using AP config, downgraded
[ 634.458674] [ T2428] wlp192s0: authenticate with d8:b3:70:f8:9e:7b (local address=fe:6c:b0:38:0d:3e)
[ 634.597675] [ T2428] wlp192s0: send auth to d8:b3:70:f8:9e:7b (try 1/3)
[ 634.604083] [ T209] wlp192s0: authenticated
[ 634.607417] [ T2428] wlp192s0: aborting authentication with d8:b3:70:f8:9e:7b by local choice (Reason: 3=DEAUTH_LEAVING)
[ 635.031798] [ T2428] wlp192s0: authenticate with d8:b3:70:f8:9e:7b (local address=92:fb:4b:57:88:de)
[ 635.171103] [ T2428] wlp192s0: send auth to d8:b3:70:f8:9e:7b (try 1/3)
[ 635.178869] [ T209] wlp192s0: authenticated
[ 635.183695] [ T209] wlp192s0: associate with d8:b3:70:f8:9e:7b (try 1/3)
[ 635.301217] [ T209] wlp192s0: associate with d8:b3:70:f8:9e:7b (try 2/3)
[ 635.405206] [ T257] wlp192s0: associate with d8:b3:70:f8:9e:7b (try 3/3)
[ 635.434065] [ T209] wlp192s0: RX AssocResp from d8:b3:70:f8:9e:7b (capab=0x1111 status=30 aid=0)
[ 635.434122] [ T209] wlp192s0: d8:b3:70:f8:9e:7b rejected association temporarily; comeback duration 1000 TU (1024 ms)
[ 635.437631] [ T209] wlp192s0: RX AssocResp from d8:b3:70:f8:9e:7b (capab=0x1111 status=30 aid=1902)
[ 635.437731] [ T209] wlp192s0: d8:b3:70:f8:9e:7b rejected association temporarily; comeback duration 896 TU (917 ms)
[ 635.443989] [ T209] wlp192s0: RX AssocResp from d8:b3:70:f8:9e:7b (capab=0x1111 status=30 aid=1070)
[ 635.444021] [ T209] wlp192s0: d8:b3:70:f8:9e:7b rejected association temporarily; comeback duration 795 TU (814 ms)
[ 636.292753] [ T257] wlp192s0: association with d8:b3:70:f8:9e:7b timed out
[ 639.364878] [ T257] mt7925e 0000:c0:00.0: Message 00020002 (seq 6) timeout
[ 645.381238] [ T257] mt7925e 0000:c0:00.0: Message 00020003 (seq 7) timeout
[ 648.516818] [ T257] mt7925e 0000:c0:00.0: Message 00020002 (seq 8) timeout
[ 651.524770] [ T257] mt7925e 0000:c0:00.0: Message 00020002 (seq 9) timeout
[ 654.532940] [ T257] mt7925e 0000:c0:00.0: Message 00020001 (seq 10) timeout
[ 654.626615] [ T12] mt7925e 0000:c0:00.0: HW/SW Version: 0x8a108a10, Build Time: 20250721232852a
[ 654.968920] [ T12] mt7925e 0000:c0:00.0: WM Firmware Version: ____000000, Build Time: 20250721232943
[ 655.737302] [ T12] BUG: kernel NULL pointer dereference, address: 0000000000000000
[ 655.737320] [ T12] #PF: supervisor read access in kernel mode
[ 655.737324] [ T12] #PF: error_code(0x0000) - not-present page
[ 655.737328] [ T12] PGD 0 P4D 0
[ 655.737334] [ T12] Oops: Oops: 0000 [#1] SMP NOPTI
[ 655.737342] [ T12] CPU: 20 UID: 0 PID: 12 Comm: kworker/u128:0 Kdump: loaded Tainted: G OE 6.17.0-8-generic #8-Ubuntu PREEMPT(voluntary)
[ 655.737350] [ T12] Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
[ 655.737351] [ T12] Hardware name: Framework Desktop (AMD Ryzen AI Max 300 Series)/FRANMFCP06, BIOS 03.04 11/19/2025
[ 655.737354] [ T12] Workqueue: mt76 mt7925_mac_reset_work [mt7925_common]
[ 655.737370] [ T12] RIP: 0010:mt76_connac_mcu_uni_add_dev+0xba/0x1f0 [mt76_connac_lib]
[ 655.737385] [ T12] Code: cc 66 44 89 5d d2 44 88 45 d4 44 88 4d d5 88 65 d7 c6 45 dc 01 88 55 dd 0f b7 97 b8 00 00 00 88 4d ef 66 89 55 e4 66 89 55 ea <48> 8b 16 8b 12 83 fa 03 0f 84 0c 01 00 00 77 1b 83 fa 01 0f 84 f5
[ 655.737388] [ T12] RSP: 0018:ffffd07fc018fcb0 EFLAGS: 00010282
[ 655.737392] [ T12] RAX: 000000000000ff00 RBX: ffff8a4449442040 RCX: 0000000000000000
[ 655.737394] [ T12] RDX: 0000000000000013 RSI: 0000000000000000 RDI: ffff8a44c7d7a4b0
[ 655.737396] [ T12] RBP: ffffd07fc018fcf8 R08: 0000000000000001 R09: 0000000000000000
[ 655.737397] [ T12] R10: 0000000000000000 R11: 0000000000000020 R12: ffff8a4449442040
[ 655.737399] [ T12] R13: ffff8a44c7d79f08 R14: 0000000000000000 R15: ffff8a44c7d78a80
[ 655.737401] [ T12] FS: 0000000000000000(0000) GS:ffff8a53ca47f000(0000) knlGS:0000000000000000
[ 655.737403] [ T12] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 655.737404] [ T12] CR2: 0000000000000000 CR3: 00000009e2a40000 CR4: 0000000000f50ef0
[ 655.737406] [ T12] PKRU: 55555554
[ 655.737408] [ T12] Call Trace:
[ 655.737411] [ T12]
[ 655.737416] [ T12] mt7925_vif_connect_iter+0xcb/0x240 [mt7925_common]
[ 655.737423] [ T12] __iterate_interfaces+0x92/0x130 [mac80211]
[ 655.737500] [ T12] ? __pfx_mt7925_vif_connect_iter+0x10/0x10 [mt7925_common]
[ 655.737506] [ T12] ieee80211_iterate_interfaces+0x3d/0x60 [mac80211]
[ 655.737549] [ T12] ? __pfx_mt7925_vif_connect_iter+0x10/0x10 [mt7925_common]
[ 655.737553] [ T12] mt7925_mac_reset_work+0x105/0x190 [mt7925_common]
[ 655.737559] [ T12] process_one_work+0x18b/0x370
[ 655.737567] [ T12] worker_thread+0x317/0x450
[ 655.737570] [ T12] ? __pfx_worker_thread+0x10/0x10
[ 655.737573] [ T12] kthread+0x108/0x220
[ 655.737577] [ T12] ? __pfx_kthread+0x10/0x10
[ 655.737579] [ T12] ret_from_fork+0x131/0x150
[ 655.737585] [ T12] ? __pfx_kthread+0x10/0x10
[ 655.737587] [ T12] ret_from_fork_asm+0x1a/0x30
[ 655.737592] [ T12]
[ 655.737594] [ T12] Modules linked in: tls snd_seq_dummy snd_hrtimer xt_mark veth nf_conntrack_netlink xt_nat xt_tcpudp xt_conntrack xt_MASQUERADE bridge stp llc xfrm_user xfrm_algo xt_set ip_set nft_chain_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 xt_addrtype nft_compat ccm nf_tables rfcomm cmac algif_hash algif_skcipher af_alg overlay qrtr bnep binfmt_misc nls_iso8859_1 intel_rapl_msr amd_atl intel_rapl_common snd_hda_codec_alc269 edac_mce_amd snd_hda_scodec_component snd_hda_codec_realtek_lib snd_hda_codec_atihdmi snd_hda_codec_generic mt7925e snd_hda_codec_hdmi btusb mt7925_common btrtl kvm_amd btintel mt792x_lib snd_hda_intel btbcm snd_hda_codec mt76_connac_lib btmtk leds_cros_ec kvm gpio_cros_ec irqbypass cros_ec_sysfs led_class_multicolor cros_ec_hwmon cros_ec_debugfs snd_hda_core cros_ec_chardev mt76 polyval_clmulni ghash_clmulni_intel bluetooth snd_seq_midi spd5118 cros_ec_dev aesni_intel snd_intel_dspcfg rapl mac80211 snd_seq_midi_event snd_intel_sdw_acpi snd_rawmidi snd_hwdep wmi_bmof cfg80211 snd_seq
[ 655.737656] [ T12] snd_pcm amd_pmf amdxdna snd_seq_device amdtee gpu_sched snd_timer input_leds i2c_piix4 snd i2c_smbus libarc4 amd_sfh ccp soundcore joydev tee cros_ec_lpcs platform_profile cros_ec amd_pmc cros_ec_proto mac_hid sch_fq_codel msr parport_pc ppdev lp parport efi_pstore nfnetlink dmi_sysfs ip_tables x_tables autofs4 typec_displayport typec_thunderbolt hid_generic ucsi_acpi typec_ucsi usbhid typec hid amdgpu(OE) amddrm_ttm_helper(OE) amdttm(OE) amddrm_buddy(OE) amdxcp(OE) amddrm_exec(OE) drm_suballoc_helper amd_sched(OE) amdkcl(OE) drm_panel_backlight_quirks i2c_algo_bit drm_ttm_helper ttm drm_display_helper nvme cec nvme_core gpio_keys rc_core r8169 nvme_keyring thunderbolt realtek nvme_auth video wmi soc_button_array 8250_dw
[ 655.737713] [ T12] CR2: 0000000000000000