Commit Graph

46390 Commits

Author SHA1 Message Date
Arend van Spriel
5c4b13cb50 wifi: ath6kl: use pre-assigned cookie for remain_on_channel and mgmt_tx
Stop generating cookies in ath6kl_remain_on_channel() and
ath6kl_mgmt_tx(). cfg80211 now pre-assigns the cookie before calling
into the driver.

For remain_on_channel, store the pre-assigned cookie in
vif->last_roc_id. Widen last_roc_id and last_cancel_roc_id from u32
to u64 to hold the full 64-bit cookie value.

For mgmt_tx, store the pre-assigned cookie in wmi->last_mgmt_tx_cookie
so the firmware TX status event handler can pass the correct cookie to
cfg80211_mgmt_tx_status(). Thread the cookie through the powersave
queue (ath6kl_mgmt_buff) so it is available when the frame is
eventually dequeued and sent.

Assisted-by: Claude:claude-sonnet-4-6
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Link: https://patch.msgid.link/20260731123509.1975281-4-arend.vanspriel@broadcom.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
2026-08-02 17:40:06 +02:00
Ping-Ke Shih
86c3125c75 wifi: rtw89: 8922d: enable Makefile and Kconfig for RTL8922DE
RTL8922DE is a WiFi 7 chipset, supporting 2x2 2GHz/5GHz/6GHz 4096/1024-QAM
160MHz channels. As STA, AP and P2P modes work well, enable this chipset.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260730060220.55844-8-pkshih@realtek.com
2026-08-02 09:55:20 +08:00
Ching-Te Ku
97b81c10fe wifi: rtw89: coex: Update Wi-Fi/Bluetooth coexistence version to 9.24.1
The 9.24.1 coexistence version included firmware 0.35.111.X support for
RTL8922A/D, 0.24.97.X support for RTL8852C, 0.29.133.X support for
RTL8852B chip family.

Signed-off-by: Ching-Te Ku <ku920601@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260730060220.55844-7-pkshih@realtek.com
2026-08-02 09:55:04 +08:00
Ching-Te Ku
dd7e70e76b wifi: rtw89: coex: Port _update_bt_ctrl_lps() for BT profile-based LPS control
The old lps_ctrl_scbd logic in _update_bt_scbd() blocked WiFi LPS only
when mode == BTC_WLINK_V0_2G_STA, which created a dead-lock while
WiFi already in LPS suppressed TDD binding so mode was never set to
BTC_WLINK_V0_2G_STA, lps_ctrl_scbd stayed 0, and WiFi remained stuck
in LPS. Port _update_bt_ctrl_lps() from the reference implementation to
check BT profile existence (A2DP, HFP, PAN) for both radios directly,
with out_of_band and freerun guards so LPS is only blocked when WiFi and
Bluetooth actually share a band. Call it from both _update_bt_scbd() and
_update_bt_info() so profile changes reported via either SCBD or BT info
C2H correctly update lps_ctrl_scbd. Also remove the dead
lps_ctrl_scbd_last field.

Signed-off-by: Ching-Te Ku <ku920601@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260730060220.55844-6-pkshih@realtek.com
2026-08-02 09:53:22 +08:00
Ching-Te Ku
4d9f081150 wifi: rtw89: coex: Change Wi-Fi link_mode_v0 translating timing
Logic should only get explicit link_mode only, to cover the old branch
link_mode_v0 using (old branch firmware needed) should do translating
after link_mode is settled. And the coexistence logic has already updated
to new branch style, so the logic should use new link_mode, don't need
to consider link_mode_v0. To prevent unexpected logic bug, refine the
related logic.

Signed-off-by: Ching-Te Ku <ku920601@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260730060220.55844-5-pkshih@realtek.com
2026-08-02 09:53:06 +08:00
Ching-Te Ku
8847c1b12b wifi: rtw89: coex: Clear BT link weight when BT is disabled
When a BT device is disabled, _update_bt_link_cnt() is no longer called
for that device, so its link_weight[] retains stale values from the last
active period. _set_bind_info() then computes a non-zero band score for
the disabled device, which can lead to an incorrect tdd_bind.rf_band
selection and ultimately wrong coexistence policy.

Clear link_weight[] for any disabled BT device at the start of the
_set_bind_info() loop so that stale scores are not carried forward.

Signed-off-by: Ching-Te Ku <ku920601@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260730060220.55844-4-pkshih@realtek.com
2026-08-02 09:52:50 +08:00
Ching-Te Ku
cf7f33eb04 wifi: rtw89: coex: Fix BT-info parsing for 5/6 GHz band & dual Bluetooth
The _update_bt_info() function always parsed BT-info for bt0 and used a
single raw_info buffer regardless of which BT device sent the packet or
which RF band it belongs to. This caused two bugs:

1. BT-info packets from bt1 were incorrectly parsed into bt0's state.

2. BT-info packets from 5/6 GHz BT (L1 bit7=1) overwrote the 2.4 GHz
   link_info and raw_info, breaking duplicate detection across bands.

Fix by adding the bid parameter to select bt0/bt1, detecting the 5/6 GHz
band flag (L1 bit7) to route packets into link_info_56g with a dedicated
raw_info_56g buffer, and updating the early-return mask to ignore bit7
when checking the length field.

Signed-off-by: Ching-Te Ku <ku920601@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260730060220.55844-3-pkshih@realtek.com
2026-08-02 09:51:10 +08:00
Ching-Te Ku
e62f0baca0 wifi: rtw89: coex: Fix Bluetooth link weight not updated on profile change
_update_bt_link_cnt() was missing the bt->link_weight[].
Without it, link_weight stays at the initial value of 5
(set on BT re-enable) regardless of the active BT profile.

_set_bind_info() uses link_weight to compute b2g_score/b5g_score, which
determines tdd_bind.rf_band. With a stale weight of 5 (below the active
profile threshold), tdd_bind.rf_band may not reflect the actual RF band,
causing mode_v0 in _run_coex() to remain 0 (BTC_WLINK_NOLINK), which
incorrectly triggers _action_wl_nc() instead of the BT-profile action.

Add the link_weight calculation to _update_bt_link_cnt() using the same
weighting table as Formal (BIS/A2DP-sink: 70, A2DP: 40-60, PAN/active: 30,
no-profile: 5, else: 9) and call _update_bt_link_cnt() from
_update_bt_info() after parsing the profile exist flags, replacing the
open-coded link_cnt increment that omitted le-audio profiles.

Signed-off-by: Ching-Te Ku <ku920601@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260730060220.55844-2-pkshih@realtek.com
2026-08-02 09:50:54 +08:00
Po-Hao Huang
d946a4e031 wifi: rtw89: change scan offload format to V3 for WiFi 7 IC
Adapt H2C format to fit firmware version after 0.35.113.2, which
only supports active scanning with a provided SSID list.
The wildcard_6ghz field is no longer required for WiFi 7 chips' new
format, but not removed since WiFi 6 still requires it.
Keep original H2C style also to support older firmwares.

Signed-off-by: Po-Hao Huang <phhuang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260729124354.3231368-4-pkshih@realtek.com
2026-08-02 09:31:24 +08:00
Po-Hao Huang
58c0d447c5 wifi: rtw89: fix scan offload version check logic
The version check with less than should check for smallest upper-bound
first, or some branch will be unreachable.

Signed-off-by: Po-Hao Huang <phhuang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260729124354.3231368-3-pkshih@realtek.com
2026-08-02 09:31:07 +08:00
Dian-Syuan Yang
304720870f wifi: rtw89: refine RX filter configuration for WiFi 7 generation
When an AP interface is registered and starts AP, mac80211 calls the
configure_filter() to clear B_AX_A_UC_CAM_MATCH and B_AX_A_BC_CAM_MATCH
so that frames from un-associated stations can be received. However, for
a dedicated AP interface created via iw command, configure_filter() is
only triggered on the initial AP startup. Since the interface remains up
even after hostapd stops, and it isn't triggered again on later restarts.
Additionally, each AP start causes IPS leave, reverting the RX filter to
its default value.

For WiFi 7 chips, the default value is hardcoded in rx_fltr_init_be(),
so the reverted value does not match hal.rx_fltr. Therefore, refine
the behavior of WiFi 7 chips to align with the WiFi 6 implementation.

Signed-off-by: Dian-Syuan Yang <dian_syuan0116@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260729124354.3231368-2-pkshih@realtek.com
2026-08-02 09:29:26 +08:00
Yuhang.chen
667c12782a wifi: rtw89: pci: add .shutdown callback to stop rfkill polling on reboot
Since the hardware rfkill polling was introduced, arm64 platforms can
panic with an asynchronous SError during warm reboot:

  SError Interrupt on CPU8, code 0x00000000be000011 -- SError
  Workqueue: events_power_efficient rfkill_poll [rfkill]
    rtw89_pci_ops_read8+0x94/0x160 [rtw89_pci]
    rtw89_core_rfkill_poll+0x50/0x1e0 [rtw89_core]
    rtw89_ops_rfkill_poll+0x40/0x68 [rtw89_core]
    ieee80211_rfkill_poll+0x3c/0x70 [mac80211]
    cfg80211_rfkill_poll+0x40/0x2a0 [cfg80211]
    rfkill_poll+0x30/0x88 [rfkill]
  Kernel panic - not syncing: Asynchronous SError Interrupt

On the reboot path the kernel only runs device_shutdown(), which calls
each driver's .shutdown callback; .remove is not invoked.  The rtw89 PCI
driver had no .shutdown callback, so nothing stopped the rfkill polling
work while the platform was tearing the PCIe link down.  Once the link
is gone, the next MMIO read from the poll handler targets a
non-responding device and is reported as a fatal asynchronous SError on
arm64.

Add rtw89_pci_shutdown(), wired to all rtw89 PCI device drivers, which
sets a new RTW89_FLAG_SHUTDOWN flag (mirroring the USB
RTW89_FLAG_UNPLUGGED pattern).  When the flag is set,
rtw89_ops_rfkill_poll() returns early, so no MMIO read is issued to the
chip after shutdown begins and the SError no longer occurs.

This does not call the full .remove path from .shutdown, to keep the
shutdown handler minimal and avoid running the non-idempotent teardown
twice.

Fixes: 0b38e6277a ("wifi: rtw89: add support for hardware rfkill")
Cc: stable@vger.kernel.org
Suggested-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Yuhang.chen <yhchen312@gmail.com>
Acked-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260729014142.2746777-1-yhchen312@gmail.com
2026-08-02 09:14:34 +08:00
Jose Ignacio Tornos Martinez
4df22710a7 wifi: mt76: mt7996: remove beacon_int_min_gcd from ADHOC interface combinations
The driver fails to register with error -22 (EINVAL) due to a cfg80211
validation failure in wiphy_verify_iface_combinations().

Commit 5ef0e8e265 ("wifi: mt76: mt7996: fix iface combination for
different chipsets") added beacon_int_min_gcd to if_comb_global and
if_comb_global_7992, but these combinations include ADHOC (IBSS)
interface type. This violates a cfg80211 rule from commit 56271da29c
("cfg80211: disallow beacon_int_min_gcd with IBSS") that explicitly
forbids combining ADHOC with beacon_int_min_gcd.

The restriction exists because beacon_int_min_gcd requires static,
predictable beacon intervals to coordinate multiple beaconing interfaces,
but ADHOC interfaces have dynamic beacon intervals that change when
joining different networks, making the GCD constraint unenforceable.

Remove beacon_int_min_gcd from the interface combinations that include
ADHOC because they are not necessary for ADHOC operation. The if_comb
combination (AP/MESH/STA only, without ADHOC) correctly retains
beacon_int_min_gcd for multi-AP coordination.

Fixes: 5ef0e8e265 ("wifi: mt76: mt7996: fix iface combination for different chipsets")
Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
Tested-by: Alex Gavin <alex.gavin@candelatech.com>
Link: https://patch.msgid.link/20260702104337.679536-1-jtornosm@redhat.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 17:55:26 +00:00
Devin Wittmayer
6f6c9800e5 wifi: mt76: mt792x: do not advertise active monitor
mt76_phy_init() sets NL80211_FEATURE_ACTIVE_MONITOR for every mt76 device,
but mt792x firmware does not honor it: entering active monitor mode stops
RX. Gate the feature behind a new per-phy no_active_monitor flag and set it
for mt792x.

Signed-off-by: Devin Wittmayer <lucid_duck@justthetip.ca>
Link: https://patch.msgid.link/20260722011302.113060-1-lucid_duck@justthetip.ca
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 17:55:25 +00:00
Linghui Wu
4f25071afe wifi: ath10k: snoc: use memcpy_fromio() for MSA ramdump
On WCN3990/SNOC the MSA region is mapped with devm_memremap(MEMREMAP_WT).
On arm64 such a mapping is not Normal-cacheable, so unaligned accesses to
it are not permitted. ath10k_msa_dump_memory() copies the region with a
plain memcpy(), whose optimized __pi_memcpy_generic implementation issues
wide/unaligned loads. This triggers an alignment fault (FSC=0x21) Oops in
ath10k_snoc_fw_crashed_dump() while collecting the devcoredump:

  Unable to handle kernel paging request ... FSC=0x21: alignment fault
  pc : __pi_memcpy_generic
  lr : ath10k_snoc_fw_crashed_dump [ath10k_snoc]

The Oops both leaves the firmware RAM dump buffer zeroed (no dump is
captured) and crashes the kernel, which in turn breaks modem SSR
recovery.

Use memcpy_fromio(), which only performs accesses that are valid for such
a device-memory mapping. The generic memcpy_fromio() implementation aligns
the source before issuing word-sized reads and stores the destination with
put_unaligned(), so it is also safe for the coherent DMA allocation used on
the non-reserved-memory path. ath11k and ath12k use the same pattern
when copying target memory into crash dumps, so call it unconditionally
here too.
The MEMREMAP_WT pointer is a plain void *, so an explicit __iomem cast is
needed; use __force to keep sparse happy.

Tested-on: WCN3990 hw1.0 SNOC WLAN.HL.3.3.7.c5-00107-QCAHLSWMTPL-1

Fixes: 3f14b73c38 ("ath10k: Enable MSA region dump support for WCN3990")
Signed-off-by: Linghui Wu <linghui.wu@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Link: https://patch.msgid.link/20260727072629.2297208-1-linghui.wu@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
2026-08-01 08:50:27 -07:00
Linghui Wu
35a3da9fe1 wifi: ath10k: filter non-UTF testmode events
When UTF monitor is enabled, ath10k forwards WMI events to nl80211
testmode. Non-UTF events can therefore be delivered to userspace and
confuse FTM tools which expect only UTF responses.

Only forward known UTF event IDs from WMI event namespaces that route
events through ath10k_tm_event_wmi(), and drop other WMI events while UTF
monitor is active. READY events are still handled by the normal WMI
receive path.

Tested-on: WCN3990 hw1.0 SNOC WLAN.HL.3.3.7.c5-00093.2-QCAHLSWMTPL-1

Signed-off-by: Linghui Wu <linghui.wu@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Link: https://patch.msgid.link/20260730023226.707008-1-linghui.wu@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
2026-08-01 08:50:27 -07:00
Reshma Immaculate Rajkumar
1e33f8acd8 wifi: ath12k: fix encrypted EAPOL TX in encap offload mode
When a vif operates with IEEE80211_OFFLOAD_ENCAP_ENABLED,
mac80211 delivers EAPOL frames to ath12k in native-WiFi format.

Unencrypted EAPOL frames used during the initial 4-way
handshake are already handled through the existing
is_diff_encap path. However, EAPOL frames transmitted during
GTK rekeying carry ATH12K_SKB_CIPHER_SET and continue through
the normal native-WiFi transmit path.

Firmware encryption requires RAW frames with cipher-specific IV and ICV
fields correctly provisioned in the skb. Passing encrypted EAPOL frames
in native-WiFi format results in incorrect IV provisioning, leading to
an invalid ICV and frame drop.

Fix this by detecting the EAPOL frames that need HW encryption and
converting them to firmware-encrypted RAW frames before transmission.
Reserve IV space after the MAC header, append ICV space at the tail,
select the appropriate firmware encryption type and request
firmware-side encryption.

Introduce ath12k_dp_tx_crypto_iv_len() and ath12k_dp_tx_crypto_icv_len()
helpers in the TX path to obtain cipher-specific IV and ICV lengths.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01270-QCAHKSWPL_SILICONZ-1

Fixes: d29591d5b5 ("wifi: ath12k: Advertise encapsulation/decapsulation offload support to mac80211")
Signed-off-by: Reshma Immaculate Rajkumar <reshma.rajkumar@oss.qualcomm.com>
Reviewed-by: Aishwarya R <aishwarya.r@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Link: https://patch.msgid.link/20260729171732.668367-1-reshma.rajkumar@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
2026-08-01 08:50:27 -07:00
Felix Fietkau
4330a0ef9f wifi: mt76: mt7996: fix out-of-bounds link array access in mt7996_tx()
When mac80211 leaves the link unspecified, mt7996_tx() substitutes the
primary link id of the station or vif. That value is
IEEE80211_LINK_UNSPECIFIED (0xf) until the first link has been added,
and it is then used unchecked to index vif->link_conf[],
mvif->mt76.link[] and sta->link[], all of which hold
IEEE80211_MLD_MAX_NUM_LINKS (15) entries.

Clamp the primary link id to the default link before using it, and use
the clamped value for the link_sta fallback as well.

Fixes: 1609b014aa ("wifi: mt76: mt7996: Overwrite unspecified link_id in mt7996_tx()")
Link: https://patch.msgid.link/20260801145334.1166751-10-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 15:22:41 +00:00
Felix Fietkau
9ba744a28c wifi: mt76: reject out-of-range link ids in mt76_vif_link()
mt76_vif_link() indexes mvif->link[] without validating link_id, but
callers pass mvif->deflink_id / msta->deflink_id, which hold
IEEE80211_LINK_UNSPECIFIED (0xf) until the first link has been added.
Since IEEE80211_MLD_MAX_NUM_LINKS is 15, that reads one element past the
end of the array, aliasing mt76_vif_data.offchannel_link.

Reachable via mt7996_set_tsf()/mt7996_offset_tsf() and
mt7996_net_fill_forward_path(). Bounds check link_id and return NULL,
matching mt7996_sta_link() and mt7996_sta_link_protected().

Fixes: a9384b36a4 ("wifi: mt76: mt7996: rework set/get_tsf callabcks to support MLO")
Link: https://patch.msgid.link/20260801145334.1166751-9-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 15:22:41 +00:00
Felix Fietkau
0bbd6c52df wifi: mt76: mt7603: file buffered frames under the TID reported to mac80211
The PS queue filed redirected frames under the TID taken from the TXD,
while mac80211 was told about the TID taken from the QoS header, or TID 0
for anything that is not a QoS data frame. When the two disagree,
mt7603_release_buffered_frames() skips the frame because it does not
match the requested TIDs, so it stays in the PS queue until the station
wakes up. Buffered MMPDUs hit this whenever they were sent on a
non-zero TID.

Use one TID for both.

Link: https://patch.msgid.link/20260801145334.1166751-8-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 15:22:41 +00:00
Felix Fietkau
636a883e2f wifi: mt76: mt7603: restore hardware PS buffering after a service period
Releasing buffered frames has to turn off the PSE redirect for the
station, otherwise the released frames are looped straight back into the
driver PS queue. Nothing ever turns it back on: mt7603_sta_ps() only runs
on an observed PM bit transition, and MT_WCID_FLAG_PS keeps mt76 from
reporting the same state twice. After the first service period the
hardware therefore treats a dozing station as awake and transmits at it
directly, which is where the retry storms and the packet loss reported
against U-APSD clients come from.

Re-arm hardware buffering from mt7603_mac_work() for every station that
is still known to be asleep, once the PSD queue has drained and the
released frames have passed the redirect stage. Frames that are still
queued belong to the service period that was just served, so unlike on a
sleep transition they must not be pulled back with mt7603_filter_tx().

Track the sleep state separately from the WTBL state, so a station that
wakes up while the re-arm is pending is not put back to sleep.

Link: https://patch.msgid.link/20260801145334.1166751-7-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 15:22:41 +00:00
Felix Fietkau
d5001f493f wifi: mt76: mt7603: tell mac80211 when the PS queue has run empty
mt7603_rx_loopback_skb() marks a TID as buffered when the hardware
redirects a frame into the driver PS queue, but nothing ever clears that
state again. mac80211 therefore keeps the TIM bit set for the station and
keeps routing every service period to the driver, which also prevents it
from releasing frames it has buffered itself.

Clear the buffered state for every requested TID that has no frames left
in the PS queue.

Link: https://patch.msgid.link/20260801145334.1166751-6-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 15:22:41 +00:00
Felix Fietkau
697badc27a wifi: mt76: mt7603: fix U-APSD service period termination
Frames released from the driver PS queue were all tagged with MORE_DATA
and none of them ever carried the EOSP bit, so from the client's point of
view a U-APSD service period was started but never finished. Clients that
keep their receiver on until EOSP arrives stop sending trigger frames,
and all downlink traffic for that station stalls until they give up.
ieee80211_sta_eosp() only cleared the service period state inside
mac80211, which is why the mismatch went unnoticed.

Assign MORE_DATA per frame and set the wire EOSP bit on the last one. If
the last released frame is a bufferable MMPDU it has no QoS control field
to carry EOSP, so let mac80211 append a QoS-Null frame instead.

Also stop handing the remaining frame budget to
mt76_release_buffered_frames() once frames have been released from the PS
queue: both would signal the end of the same service period. Releasing
fewer frames than requested is allowed, and MORE_DATA tells the client to
trigger again.

Link: https://patch.msgid.link/20260801145334.1166751-5-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 15:22:41 +00:00
Felix Fietkau
0b8d252471 wifi: mt76: set the EOSP bit in the QoS header of the last released frame
When the driver implements .release_buffered_frames, mac80211 leaves the
U-APSD signalling entirely to the driver: "In this case it is also
responsible for setting the EOSP flag in the QoS header of the frames"
(include/net/mac80211.h). Only IEEE80211_TX_STATUS_EOSP was being set,
which merely ends the service period inside mac80211, so on air the
service period was never terminated. Clients that wait for EOSP before
going back to doze keep the SP open and stop triggering, which stalls all
downlink traffic for that station.

Set the wire EOSP bit on the last frame of a U-APSD service period.
EOSP has no meaning for a PS-Poll response, so pass the release reason
down and leave those frames alone.

Link: https://patch.msgid.link/20260801145334.1166751-4-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 15:22:41 +00:00
Felix Fietkau
2d16caccd2 wifi: mt76: mt7996: handle UNI PS sync events
Enable MT_DRV_HW_PS_BUFFERING and handle MCU_UNI_EVENT_PS_SYNC with
all three TLV formats (single client, multi-client packed entries,
and bitmap).

Link: https://patch.msgid.link/20260801145334.1166751-3-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 15:22:41 +00:00
Felix Fietkau
dc930cf883 wifi: mt76: mt7915: handle MCU PS sync events
Enable MT_DRV_HW_PS_BUFFERING and handle MCU_EXT_EVENT_PS_SYNC to
track station power-save state via firmware notifications.

Link: https://patch.msgid.link/20260801145334.1166751-2-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 15:22:41 +00:00
Felix Fietkau
a547b414bf wifi: mt76: add PS buffering support for HW-managed TIM drivers
Add MT_DRV_HW_PS_BUFFERING flag for drivers where firmware controls
the TIM bit based on buffered frames. Instead of blocking all TX to
PS stations (which starves firmware and prevents TIM from being set),
allow limited frame delivery using AQL pending airtime as the
throttle. Replenish the firmware buffer on TX completion.

Add mt76_sta_ps_transition() helper for drivers to call from MCU
PS sync events.

Link: https://patch.msgid.link/20260801145334.1166751-1-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 15:22:41 +00:00
shengwei.lu
404c4e564f wifi: mt76: mt7925: Fix EHT Beamformee SS subfields to meet 802.11be minimum
Per IEEE 802.11be, the Beamformee SS <= 80/160/320 MHz 3-bit subfields
in the EHT PHY Capabilities are encoded as (Nss - 1) and are required
to be >= 3 (i.e. at least 4 SS receive capability) whenever SU
Beamformee is advertised.

MT7925 is a 2x2 STA (sts = 2), so directly filling (sts - 1) = 1
violates the spec minimum. Clamp the encoded value to 3 when sts <= 3,
otherwise use (sts - 1). This is applied consistently to the
BEAMFORMEE_SS <= 80 MHz (split across phy_cap_info[0]/[1]), <= 160 MHz
and <= 320 MHz (6 GHz only) subfields.

Fixes: c948b5da6b ("wifi: mt76: mt7925: add Mediatek Wi-Fi7 driver for mt7925 chips")
Signed-off-by: shengwei.lu <shengwei.lu@mediatek.com>
Link: https://patch.msgid.link/20260723031108.2017653-1-jb.tsai@mediatek.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 14:49:43 +00:00
Dmitry Antipov
f0be077b7b wifi: mt76: mt7915: simplify mt7915_sys_recovery_set()
Use convenient ' kstrtou16_from_user()'
to simplify 'mt7915_sys_recovery_set()'.

Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
Link: https://patch.msgid.link/20260723180430.747789-1-dmantipov@yandex.ru
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 14:49:43 +00:00
Jeff Hsu
5f23b939a3 wifi: mt76: mt7925: skip DMA re-init selectively
Add a flag to skip it on chips that don't need it.

Signed-off-by: Jeff Hsu <Jeff.Hsu@mediatek.com>
Link: https://patch.msgid.link/20260706024306.47806-1-jb.tsai@mediatek.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 14:49:43 +00:00
Felix Fietkau
fc7801b7f1 wifi: mt76: mt7925: fix infinite loop in UNI event TLV parsing
The event TLV loops accept a zero-length TLV, which advances neither the
cursor nor the remaining length, so a malformed event hangs the caller.
mt7925_mcu_uni_roc_event() additionally walked past the end of the skb,
since it never checked the declared length against the remainder.

Replace the five open-coded loops with a shared iterator that rejects
lengths below the TLV header and beyond the remaining buffer, and check
the per-tag payload sizes before dereferencing them.

While here, make the RSSI monitor event read from the current TLV rather
than from the start of the list.

Link: https://patch.msgid.link/20260727150434.1778520-15-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 14:49:43 +00:00
StanleyYP Wang
d8eb7952fa wifi: mt76: mt7996: add scan dwell time hw cap
Add NL80211_EXT_FEATURE_SET_SCAN_DWELL support in driver.
This allows user to specify channel dwell time during scanning.

Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
Link: https://patch.msgid.link/20260727150434.1778520-14-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 14:49:43 +00:00
Felix Fietkau
6613d2104f wifi: mt76: mt7915: update SKU power limits after changing antennas
Changing the antenna configuration updates the stream capabilities but
left the per-path SKU power limits and path delta compensation stale
until the next channel switch. Reapply the SKU table like mt7996
already does.

Link: https://patch.msgid.link/20260727150434.1778520-13-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 14:49:43 +00:00
Howard Hsu
de3afeafbc wifi: mt76: mt7996: reject iTWT setup requests from MLD stations
The firmware does not support individual TWT agreements with non-AP MLDs,
and the driver only tracks TWT flow state on the default link, which may
not be the link the agreement was negotiated on. Reject TWT setup
requests from MLD stations instead of programming an unsupported
configuration.

Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
Link: https://patch.msgid.link/20260727150434.1778520-12-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 14:49:43 +00:00
Peter Chiu
3999d15cfc wifi: mt76: fix queue assignment for disassoc packets
Like deauth, a disassoc frame sent to a client in powersave mode can get
stuck in a tx queue along with other buffered frames, filling up hardware
queues with frames that are only released after the WTBL slot is reused
for another client.

Move disassoc packets to the ALTX queue, matching the existing deauth
handling.

Fixes: dedf2ec30f ("wifi: mt76: fix queue assignment for deauth packets")
Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
Link: https://patch.msgid.link/20260727150434.1778520-11-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 14:49:43 +00:00
StanleyYP Wang
d22f7f29c6 wifi: mt76: mt7996: remove repeater muar config
Repeater mode is not supported currently, so remove it.
get_omac_idx() only hands out HW_BSSID/EXT_BSSID indices, so the
omac_idx >= REPEATER_BSSID_START call sites are unreachable.

Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
Link: https://patch.msgid.link/20260727150434.1778520-10-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 14:49:43 +00:00
Felix Fietkau
b53c44fe65 wifi: mt76: mt7915: report RX chain signal for all RX paths
status->chains was set from the antenna mask, which is derived from the
number of spatial streams, while the chain_signal array is filled from
all RCPI fields. On boards where the number of RX paths exceeds the
stream count, e.g. the 3T3R mt7916/mt7981 variant with 2 streams on the
5 GHz band, the RSSI of the extra chains was never reported.

Use the band local RX path chainmask instead.

Fixes: e57b790146 ("mt76: add mac80211 driver for MT7915 PCIe-based chipsets")
Link: https://patch.msgid.link/20260727150434.1778520-9-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 14:49:43 +00:00
Felix Fietkau
ea891799ec wifi: mt76: mt7915: fix chainmask handling for non-dbdc phys on band 1
On single-adie mt7986 the only phy is bound to band 1, but its chainmask
is stored unshifted, because dev->chainshift is still zero while the
eeprom is parsed for the main phy. mt7915_set_antenna() on the other
hand shifts by chainshift * band_idx, so the representation of the
chainmask changed as soon as the antenna configuration was touched.
Until then, mt7915_mcu_set_chan_info() passed rx_path = 0 to the
firmware, since shifting the unshifted mask down clears all bits.

Keep the unshifted form for that case and add helpers for the band local
chainmask, so that only the band 1 phy of a dbdc device uses the shifted
form.

Fixes: 3eb50cc905 ("wifi: mt76: mt7915: rely on band_idx of mt76_phy")
Link: https://patch.msgid.link/20260727150434.1778520-8-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 14:49:43 +00:00
Felix Fietkau
6a4cabff12 wifi: mt76: mt7996: do not leave state behind after a failed WED attach
mt7996_mmio_wed_init() set dev->mt76.hwrro_mode and rx_token_size while
building the WED configuration, before knowing whether the WED attach
can succeed. A failed attach left the enlarged rx_token_size behind and
reset hwrro_mode to MT76_HWRRO_OFF, clobbering the values that another
RX datapath owner may have configured earlier in probe: on Airoha
platforms with the wed_enable module parameter set, this broke the NPU
offload configuration set up by mt76_npu_init() (NPU offload requires
HW-RRO and a larger rx token space, and the attach always fails there
since no SoC has both an Airoha NPU and MTK WED).

Move both assignments after a successful attach, next to the existing
success-only dma_dev/irq assignments. This is safe for the regular WED
attach case: the first consumer of either field runs after probe
continues (mtk_wed_device_attach() only invokes the init_buf callback;
rx buffers are allocated via init_rx_buf from mtk_wed_start(), long
after mt7996_mmio_wed_init() has returned).

Within the WED configuration the HW-RRO checks were constant: the mode
was assigned unconditionally right before them, and the hif2 path is
only reachable after a successful main attach has set it. Resolve them
to their constant values and drop the dead branches.

Fixes: 377aa17d2a ("wifi: mt76: mt7996: Add NPU offload support to MT7996 driver")
Link: https://patch.msgid.link/20260727150434.1778520-7-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 14:49:43 +00:00
Felix Fietkau
7c1924332e wifi: mt76: mt7996: do not attach hif2 WED when the main WED attach failed
If the WED attach for the primary PCIe function fails, the probe path
still attached wed_hif2 for the secondary function, leaving the device
in an inconsistent half-WED configuration that crashes later. The hif2
call also re-enabled hwrro_mode, which the failed primary attach had
just turned off.

Skip the hif2 WED setup when the primary WED device is not active.

Fixes: 83eafc9251 ("wifi: mt76: mt7996: add wed tx support")
Link: https://patch.msgid.link/20260727150434.1778520-6-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 14:49:43 +00:00
StanleyYP Wang
eb906eeff2 wifi: mt76: mt7996: fix reg addr remap when addr is 0
When addr is less than the hardcoded threshold in __mt7996_reg_addr,
it indicates that remapping is unnecessary.
Currently, the flow remaps address 0x0 to MT_HIF_REMAP_BASE_L2,
which is incorrect.
To address this, modify __mt7996_reg_addr to return INVALID_REG_ADDR
if the address is not below the hardcoded value or is not present in
the mt7996_reg_map array.
Additionally, update the remap condition to check if addr is equal to
INVALID_REG_ADDR.

Fixes: 3687854d3e ("wifi: mt76: mt7996: add locking for accessing mapped registers")
Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
Link: https://patch.msgid.link/20260727150434.1778520-5-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 14:49:43 +00:00
Felix Fietkau
8370aebd26 wifi: mt76: mt7915: release hif2 reference on probe IRQ failure
The hif2 reference obtained by mt7915_pci_init_hif2() is only released on
error paths that key off dev->hif2, which is not assigned until after the
IRQ setup. If pci_alloc_irq_vectors() or the primary devm_request_irq()
fails, the reference leaks. Drop it explicitly on those paths via
mt7915_put_hif2().

Fixes: f68d67623d ("mt76: mt7915: add Wireless Ethernet Dispatch support")
Link: https://patch.msgid.link/20260727150434.1778520-4-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 14:49:43 +00:00
Felix Fietkau
15b960014f wifi: mt76: mt7915: fix ext PHY use-after-free on register error path
After mt7915_register_ext_phy() succeeded, a failure of the main PHY
mt7915_init_debugfs() or mt7915_coredump_register() unwound through
free_phy2, which called ieee80211_free_hw() on the ext PHY hw while it
was still registered with mac80211, since mt76_unregister_device() only
unregisters the main hw. Unregister the ext PHY (thermal + phy + hw)
first and skip the redundant free.

Fixes: 7b8e1ae886 ("mt76: mt7915: rework hardware/phy initialization")
Link: https://patch.msgid.link/20260727150434.1778520-3-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 14:49:43 +00:00
Felix Fietkau
3ae8ad277e wifi: mt76: mt7915: fix double hif2 init on the non-WED path
mt7915_pci_init_hif2() was called unconditionally and again inside the
WED-inactive branch. The helper increments the global hif_idx, writes the
PCIe RECOG_ID register and takes a get_device() reference via
mt7915_pci_get_hif2(), while removal only drops one reference. On non-WED
dual-hif hardware this double-incremented hif_idx, wrote RECOG_ID twice and
leaked a device reference. Only the call inside the WED-inactive branch is
correct; drop the unconditional one. hif2 is already initialised to NULL.

Fixes: cacdd67812 ("mt76: mt7915: add mt7915_mmio_probe() as a common probing function")
Link: https://patch.msgid.link/20260727150434.1778520-2-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 14:49:43 +00:00
Felix Fietkau
d0b750072a wifi: mt76: mt7996: fix MIB TX aggregation counter registers for mt7990
The MIB_TSCR0-7 counters read by mt7996_mac_update_stats() are
hardcoded at the mt7996/mt7992 offsets 0x6b0-0x6d0, but mt7990 moved
them to 0x750-0x770, so TX AMPDU statistics were read from unrelated
registers on that chip. Move the offsets into the per-chip register
tables.

Fixes: f6c87411d1 ("wifi: mt76: mt7996: rework register mapping for mt7990")
Link: https://patch.msgid.link/20260727150434.1778520-1-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 14:49:42 +00:00
Chad Monroe
a3da1f2a3e wifi: mt76: mt7996: hold dev->mutex in remove_interface teardown
mt7996_remove_interface() destroys the remaining vif links, clearing
omac_mask, vif_mask and mld_idx_mask, with only the wiphy mutex held.
Those masks are modified under dev->mutex everywhere else, so the
unlocked clears can race the scan-link teardown and the reset work
and lose updates.

Take dev->mutex around the link destroy loop, matching
mt7996_add_interface() and mt7915_remove_interface(). The mutex is
released before mt76_vif_cleanup(), which aborts a pending scan and
takes the mutex itself.

Signed-off-by: Chad Monroe <chad@monroe.io>
Link: https://patch.msgid.link/20260724124813.3961474-29-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 14:49:42 +00:00
Chad Monroe
4c3cf4a8b1 wifi: mt76: serialize scan-link teardown with dev->mutex
The offchannel scan link is allocated in mt76_hw_scan() under
dev->mutex, but torn down without it: mt76_scan_complete() runs from
mt76_scan_work() on the mac80211 workqueue, or from mt76_abort_scan(),
and calls mt76_put_vif_phy_link(), whose vif_link_remove clears the
per-phy omac_mask and the device-wide vif_mask/mld_idx_mask with plain
read-modify-write. A vif link add or remove for another interface,
running concurrently under dev->mutex, can interleave with these
unlocked writes and lose an update: a cleared bit belonging to a live
link gets handed out again (two links sharing an omac/bss/wcid index,
breaking own-MAC unicast RX for the first one), or a freed bit stays
set until reboot and eventually exhausts the index space.

Take dev->mutex around the scan completion, mirroring the ROC teardown
in mt76_roc_complete_work()/mt76_abort_roc(), and switch the channel
restore to __mt76_set_channel() since the caller now holds the lock.
mt76_abort_scan() keeps cancelling the scan work before taking the
mutex, so the work-vs-abort ordering is unchanged.

Signed-off-by: Chad Monroe <chad@monroe.io>
Link: https://patch.msgid.link/20260724124813.3961474-28-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 14:49:42 +00:00
Felix Fietkau
6ff1c217a0 wifi: mt76: set MT76_SCANNING when starting a hw scan
The scan state bit is cleared by mt76_scan_complete(), but nothing ever
sets it: mt76_sw_scan() is only called for drivers without hw scan
support. As a result, all MT76_SCANNING checks are inert for drivers
using mt76_hw_scan(), including the DFS state handling in
mt76_phy_dfs_state() and the guard against manually triggered radar
detection while scanning.

Set the bit when the scan request is accepted. Since every channel
programmed while scanning now evaluates the DFS state as disabled and
stops the radar detector, re-program the operating channel at scan
completion regardless of the off-channel state, after the scanning bit
has been cleared. Otherwise a scan whose last visited channel was the
operating channel, or one that returned to it early because of
associated stations, would leave radar detection stopped until the
next channel switch.

Fixes: 31083e3854 ("wifi: mt76: add code for emulating hardware scanning")
Link: https://patch.msgid.link/20260724124813.3961474-27-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 14:49:42 +00:00
Felix Fietkau
75d2a4e212 wifi: mt76: mt7996: clear stale link state on full reset
After a full chip reset, mac80211 reconfig replays interface, link and
channel context setup. mt7996_vif_link_add() short-circuits when the
link_id is still marked in mvif->valid_links, a state introduced for
postponing link teardown to interface removal. The reset path frees the
link structures without clearing those bits, so the replayed setup never
re-creates dev_info/bss_info/STA records in the restarted firmware and
never re-registers the link wcid, leaving the device inoperative.

The reset path also leaks every allocated MLD index: per-link indices
and the per-vif group/remap indices are re-allocated from scratch during
reconfig, but the old bits stay set in the masks, so repeated full
resets exhaust the index space.

Clear valid_links in the reset vif iterator and reset the MLD index
masks alongside the existing omac_mask clearing.

Fixes: ace5d3b6b4 ("wifi: mt76: mt7996: improve hardware restart reliability")
Fixes: 08813703ac ("wifi: mt76: mt7996: Destroy vif active links in mt7996_remove_interface()")
Link: https://patch.msgid.link/20260724124813.3961474-26-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 14:49:42 +00:00
Felix Fietkau
7e4208e9f6 wifi: mt76: mt7996: free vif links after clearing wcid entries on full reset
mt7996_mac_reset_vif_iter() queues non-default vif links for kfree_rcu
while dev->wcid[] still holds pointers to the wcid embedded in each
freed link; mt76_reset_device() then dereferences those entries and
runs mt76_wcid_cleanup() on them. If a grace period elapses in between,
the cleanup operates on freed memory.

Run mt76_reset_device() first, so the wcid entries are cleaned up and
cleared while the links are still valid.

Fixes: ace5d3b6b4 ("wifi: mt76: mt7996: improve hardware restart reliability")
Link: https://patch.msgid.link/20260724124813.3961474-25-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 14:49:42 +00:00
Chad Monroe
496ea8ceb2 wifi: mt76: mt7915: trigger L1 SER on PLE MDP RIOC hang
WM firmware can enter a partial failure state where RX is hung.

Detect this condition by monitoring SER_PLE_ERR_1 for MDP_RIOC_HANG_ERR
and trigger L1 SER to restore operation. Use transition detection on the
error bit to fire only once per new occurrence, preventing an infinite
SER loop when the bit remains set across checks.

Signed-off-by: Chad Monroe <chad@monroe.io>
Suggested-by: Ryder Lee <ryder.lee@mediatek.com>
Link: https://patch.msgid.link/20260724124813.3961474-24-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 14:49:42 +00:00
Felix Fietkau
98aff74779 wifi: mt76: mt7615: fix NULL deref in mt7615_mac_set_rates
mt7615_tx() falls back to the vif BSS wcid when mac80211 hands a frame
over without a station, e.g. while a station is being torn down, and to
the global wcid when there is no vif either. Both tx_prepare_skb
implementations derive a mt7615_sta from that wcid unconditionally and,
if the rate control probe flag is set, pass it to mt7615_mac_set_rates(),
which dereferences the NULL vif backpointer of the per-vif embedded sta:

  Unable to handle kernel read from unreadable memory at virtual
  address 0000000000000002
  ...
  pc : mt7615_mac_set_rates
  lr : mt7615_tx_prepare_skb

Neither entry is rate controlled by mac80211: the embedded sta has an
empty rate set, and for the global wcid the container_of does not yield a
valid mt7615_sta at all. Only resolve the sta for wcids that belong to a
station.

Reported-by: Chad Monroe <chad@monroe.io>
Link: https://patch.msgid.link/20260724124813.3961474-23-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 14:49:42 +00:00
Chad Monroe
e11fddd347 wifi: mt76: fix stuck TX queues after SER with no active interfaces
When a firmware watchdog triggers full SER recovery before any VAPs
are up, mac80211 skips drv_reconfig_complete() because open_count is
zero. This leaves the DRIVER queue stop reason set permanently,
blocking all TX when interfaces eventually start.

Signed-off-by: Chad Monroe <chad@monroe.io>
Link: https://patch.msgid.link/20260724124813.3961474-22-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 14:49:42 +00:00
Chad Monroe
54caf306b2 wifi: mt76: mt7996: select net_setup_tc handler at runtime
The net_setup_tc callback is chosen at compile time and the WED
handler shadows the NPU one when CONFIG_NET_MEDIATEK_SOC_WED is
enabled. mt76_wed_net_setup_tc() returns -EOPNOTSUPP without an
active WED device, so on boards using the Airoha NPU with a WED
enabled kernel the tc offload block is never bound and PPE flow
offload for wireless traffic is silently disabled.

Dispatch on the active offload backend instead: use the WED handler
when a WED device is attached and fall back to the NPU handler
otherwise. Builds without MT76_NPU keep the old behavior through the
mt76_npu_net_setup_tc() stub.

Signed-off-by: Chad Monroe <chad@monroe.io>
Link: https://patch.msgid.link/20260724124813.3961474-21-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 14:49:42 +00:00
Felix Fietkau
1fdf2b5958 wifi: mt76: fix queue reg access when building WED and NPU together
Move the offload specific parts of Q_READ/Q_WRITE into
mt76_dma_handle_read/write, which return false to fall back to
readl/writel. The WED and NPU #ifdefs now live inside those helpers
instead of selecting between mutually exclusive macro definitions, so a
kernel with both enabled supports both at runtime.

Also fixes the NPU path dereferencing a hardcoded q instead of the macro
argument.

Link: https://patch.msgid.link/20260724124813.3961474-20-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 14:49:42 +00:00
Felix Fietkau
6f8d8c4580 wifi: mt76: mt7996: wake MCU waiters before aborting scan in L1 SER
The L1 reset path calls mt76_abort_scan() between setting MT76_MCU_RESET
and waking mcu.wait. A scan work blocked on an in-flight MCU command
does not re-evaluate its wait condition until woken, so the
cancel_delayed_work_sync() inside the abort sleeps out the full MCU
timeout before recovery can proceed, adding several seconds of SER
latency. mt7996_mac_full_reset() and the mt7915 counterpart already
order the wake-up first.

Wake mcu.wait immediately after setting MT76_MCU_RESET so in-flight
commands bail out before the abort synchronises against them.

Fixes: b36d556102 ("wifi: mt76: abort scan/roc on hw restart")
Link: https://patch.msgid.link/20260724124813.3961474-19-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 14:49:42 +00:00
Felix Fietkau
ccb4bda277 wifi: mt76: mt7996: skip key upload when adding an offchannel link
No hw keys are ever uploaded for scanning/roc links and the link remove
path already skips the key iteration for them. The add path still runs
it, and since mt7996_set_hw_key() resolves the target through
mvif->link[link_id] rather than the offchannel link, starting a scan on
another band re-uploads the group keys of the link sharing the same
link_id, re-sending its BSS cipher info and, for BIGTK with beacon
protection on an AP link, toggling its beacons off and on.

Skip the key iteration for offchannel links, mirroring the remove path.

Fixes: 69d54ce749 ("wifi: mt76: mt7996: switch to single multi-radio wiphy")
Link: https://patch.msgid.link/20260724124813.3961474-18-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 14:49:42 +00:00
Felix Fietkau
16a04441ea wifi: mt76: mt7915: unlink TWT flow if the MCU rejects the agreement
The flow is added to dev->twt_list before sending the agreement to the
firmware, but the error path leaves it linked while flowid_mask is
never set. The flow slot can then be reused and memset while still on
the list, corrupting twt_list, and station removal leaves a dangling
entry behind that mt7915_mac_twt_sched_list_add() later walks.

Fixes: 3782b69d03 ("mt76: mt7915: introduce mt7915_mac_add_twt_setup routine")
Link: https://patch.msgid.link/20260724124813.3961474-17-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 14:49:42 +00:00
Peter Chiu
490d81fd0c wifi: mt76: mt7996: leave PS when a 4-address connection is established
Because 4 address non-AMSDU packets do not have a bssid field, the
hardware cannot get the bssid. Without the bssid, stations are not
able to leave PS mode due to HW design. Wake up non-setup links when
4-address mode is established to prevent this issue.

mt7992 and mt7990 handle this via the BSSID mapping band config
instead, so restrict the command to mt7996.

Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
Link: https://patch.msgid.link/20260724124813.3961474-16-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-08-01 14:49:36 +00:00
Doruk Tan Ozturk
3bbd05723d wifi: ath6kl: clamp assoc request/response lengths before subtracting IE offsets
ath6kl_cfg80211_connect_event() subtracts fixed IE offsets from
assoc_req_len (-= 4) and assoc_resp_len (-= 6), both u8, with no lower
bound. The aggregate check recently added to ath6kl_wmi_connect_event_rx()
bounds the declared lengths from above (their sum must fit the received
event), but an assoc request/response shorter than its fixed offset still
underflows here: the u8 wraps to ~250, and cfg80211_connect_result() /
cfg80211_roamed() then treat that wrapped value as the IE length and copy
that many bytes out of the small assoc_info buffer to user space via
nl80211, disclosing adjacent slab memory.

Clamp both lengths to their offsets before subtracting.

Found by 0sec (https://0sec.ai) using automated source analysis; the
missing lower bound is evident from source. Compile-tested.

Fixes: bdcd817079 ("Add ath6kl cleaned up driver")
Cc: stable@vger.kernel.org
Assisted-by: 0sec:claude-opus-4-8
Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
Link: https://patch.msgid.link/20260713213251.21161-1-doruk@0sec.ai
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
2026-07-31 07:40:11 -07:00
Jeff Johnson
0293be2212 wifi: ath11k: fix leak in ath11k_service_ready_ext_event()
Currently, during ath11k_service_ready_ext_event() processing,
svc_rdy_ext.mac_phy_caps can be allocated during TLV parsing. This is a
temporary allocation that is freed on the success path, but not on the
error path. If parsing succeeds far enough to allocate mac_phy_caps and
then fails on a later TLV, the allocation leaks. So free the allocation
on the error path.

Compile tested only.

Fixes: 5b90fc760d ("ath11k: fix wmi service ready ext tlv parsing")
Assisted-by: Claude:claude-sonnet-4-6
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Link: https://patch.msgid.link/20260727-ath11k_service_ready_ext_event-memleak-v1-1-e8373d27bdd1@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
2026-07-31 07:40:11 -07:00
ZhaoJinming
8ab38bbac0 wifi: ath11k: fix resource leak on error in ext IRQ setup
In ath11k_ahb_config_irq(), when a CE request_irq() fails, the function
returns the error immediately without freeing the CE IRQs that were
successfully registered in previous loop iterations. The probe error
path does not call ath11k_ahb_free_irq() either, so the previously
registered CE IRQ handlers remain attached to the interrupt lines and
are never released.

In ath11k_ahb_config_ext_irq(), when an external request_irq() fails,
the error is only logged and the loop continues. The function then
returns 0 indicating success, leaving the device in a partially
configured state where some external IRQs are not registered. This
causes enable_irq()/disable_irq()/free_irq() to be called on
unregistered IRQs during runtime and remove/shutdown, triggering
WARN_ON(!desc->action), and missing interrupt handlers lead to data
loss.

Additionally, if alloc_netdev_dummy() fails for a later IRQ group, the
function returns -ENOMEM without freeing the ext IRQs and napi_ndev
that were successfully set up for earlier groups.

Fix all three issues: propagate the error up to the caller and unwind
all successfully registered IRQs and allocated resources on failure.
Also move ab->irq_num[irq_idx] assignment after request_irq() succeeds
in the ext IRQ path to match the CE IRQ path and avoid storing a stale
IRQ number on failure.

Signed-off-by: ZhaoJinming <zhaojinming@uniontech.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Link: https://patch.msgid.link/20260729020005.219253-1-zhaojinming@uniontech.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
2026-07-31 07:40:10 -07:00
Peter Chiu
043e042666 wifi: mt76: mt7996: add mcu command to set bssid mapping address
When receiving a 4 address non-AMSDU packet, there is no bssid in the
address fields, which breaks powersave handling for 4-address peers.
Set the mcu command to use A1 as bssid when receiving 4 address
non-AMSDU packets on mt7992 and mt7990.

Also skip mt7996_mac_init_band() for invalid bands, so the command is
only sent for bands that actually exist on the device.

Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
Link: https://patch.msgid.link/20260724124813.3961474-15-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:41 +00:00
Felix Fietkau
1df5433559 wifi: mt76: only consume the WO drop bit on WED v2 devices
The RX path is handled by the WO MCU only on WED v2 hardware. On WED
v3 the same buf1 bit does not carry drop information, so evaluating it
there causes spurious RX drops.

Fixes: e4d2b8bcac ("wifi: mt76: drop the incorrect scatter and gather frame")
Link: https://patch.msgid.link/20260724124813.3961474-14-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:41 +00:00
StanleyYP Wang
dbca5c4d29 wifi: mt76: mt7996: add missing rdd_idx check when enabling background radar
Add the missing rdd idx check (< 0) in
mt7996_mcu_rdd_background_enable(). mt7996_get_rdd_idx() returns -1
for phys without 5 GHz support, and the negative index was passed to
the RDD MCU command unchecked.

Fixes: 1529e335f9 ("wifi: mt76: mt7996: rework radar HWRDD idx")
Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
Link: https://patch.msgid.link/20260724124813.3961474-13-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:41 +00:00
Felix Fietkau
04280d0a56 wifi: mt76: mt7915: use little-endian for bss_info_ra wire fields
train_up_high_thres, train_up_rule_rssi and low_traffic_thres were
declared as host-native short in a firmware-facing TLV and assigned
host-order constants, so on a big-endian host the firmware received
byte-swapped rate-adaptation thresholds. Declare them __le16 and convert
with cpu_to_le16().

Fixes: e57b790146 ("mt76: add mac80211 driver for MT7915 PCIe-based chipsets")
Link: https://patch.msgid.link/20260724124813.3961474-12-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:41 +00:00
Felix Fietkau
4238535e85 wifi: mt76: report data NSS for STBC frames in RX rate decode
The RX rate decoder set status->nss straight from the PRXV NSTS field,
which for STBC frames is twice the data spatial-stream count. cfg80211
then reported a doubled RX bitrate in station dumps and radiotap. Halve
nss for STBC, matching the TX status path.

Fixes: 98686cd216 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
Fixes: d832f5e738 ("mt76: connac: move mt76_connac2_mac_fill_rx_rate in connac module")
Link: https://patch.msgid.link/20260724124813.3961474-11-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:41 +00:00
Felix Fietkau
e995d3dccc wifi: mt76: cancel reset and rc work on device unregister
Both drivers cancelled dump_work on unregister but left reset_work and
rc_work to be flushed only by destroy_workqueue() in mt76_free_device(),
which runs after the hw is unregistered and the hardware stopped. A
reset_work that fires in that window calls ieee80211_restart_hw() and
re-arms mac_work on an unregistered hw, and rc_work touches station state
being torn down. Cancel both up front, alongside dump_work.

Fixes: e57b790146 ("mt76: add mac80211 driver for MT7915 PCIe-based chipsets")
Fixes: 98686cd216 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
Link: https://patch.msgid.link/20260724124813.3961474-10-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:41 +00:00
Felix Fietkau
151a6cf0d1 wifi: mt76: mt7996: don't leak MLD group index on remap alloc failure
mt7996_change_vif_links() sets the mld_idx_mask group bit before
allocating the remap index. If the remap allocation fails it jumped to
the exit without clearing that bit, permanently consuming one of the 16
MLD group slots. Release the group bit on the error path.

Fixes: 4fb3b4e7d1 ("wifi: mt76: mt7996: fix MLD group index assignment")
Link: https://patch.msgid.link/20260724124813.3961474-9-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:40 +00:00
Felix Fietkau
50c66bab32 wifi: mt76: mt7996: reserve space for the CSA-abort countdown TLV
When a CSA countdown is active, mt7996_mcu_beacon_cntdwn() emits two
bss_bcn_cntdwn_tlv entries (the CSA countdown and the CCA-abort BCC), but
MT7996_BEACON_UPDATE_SIZE only reserved one. With MBSSID enabled and a
near-maximum beacon template the extra 8 bytes could push the offload
command past MT7996_MAX_BSS_OFFLOAD_SIZE and trigger skb_over_panic().
Reserve room for both countdown TLVs.

Fixes: 98686cd216 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
Link: https://patch.msgid.link/20260724124813.3961474-8-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:40 +00:00
Felix Fietkau
29fe963d86 wifi: mt76: fix ER-SU 106-tone RU check in RX rate decode
MT_PHY_TYPE_HE_EXT_SU is an enum value (9), not a bit flag, so the
bitwise test "*mode & MT_PHY_TYPE_HE_EXT_SU" also matches OFDM, HT-GF and
several HE/EHT modes. Only genuine ER-SU should be classified as a
106-tone RU at 40 MHz; use an equality comparison.

Fixes: 98686cd216 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
Fixes: d832f5e738 ("mt76: connac: move mt76_connac2_mac_fill_rx_rate in connac module")
Link: https://patch.msgid.link/20260724124813.3961474-7-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:40 +00:00
Felix Fietkau
e8b76a6e0d wifi: mt76: decode the full VHT Rx STBC capability field
The Rx STBC subfield of the VHT capabilities is a 3-bit cumulative value,
but the driver only tested the RXSTBC_1 bit when advertising the peer's
Rx STBC support to firmware. A peer reporting Rx STBC of 2, 3 or 4 has
that bit clear, so STBC was never used towards it. Test the full
IEEE80211_VHT_CAP_RXSTBC_MASK, matching the HT path.

Fixes: 046d2e7c50 ("mac80211: prepare sta handling for MLO support")
Fixes: 2660fde82f ("wifi: mt76: mt7996: Update mt7996_mcu_add_rate_ctrl to MLO")
Link: https://patch.msgid.link/20260724124813.3961474-6-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:40 +00:00
Felix Fietkau
6190db312b wifi: mt76: mt7996: hold dev->mt76.mutex while disabling tx worker in SER
mt7996_mac_reset_work() parked the tx worker and disabled the RX/TX NAPIs
before taking dev->mt76.mutex. mt76_worker_disable()/_enable() are plain
kthread park/unpark, not refcounted, and __mt76_set_channel() toggles the
same worker and the MT76_RESET bit under the mutex. An L1 SER racing a
channel switch could therefore have the worker unparked and MT76_RESET
cleared while the reset path resets the DMA rings, corrupting descriptors
or tokens. Take the mutex before disabling the worker, as mt7915 does.

Fixes: 27015b6fbc ("wifi: mt76: mt7996: enable full system reset support")
Link: https://patch.msgid.link/20260724124813.3961474-5-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:40 +00:00
Felix Fietkau
2fb6480c52 wifi: mt76: mt7915: unwind state on add_interface failure
When mt76_wcid_alloc() fails, mt7915_add_interface() returned without
clearing the vif_mask/omac_mask bits it had already set, without removing
the firmware dev info added earlier, and without clearing a monitor_vif
pointer to the vif mac80211 is about to free. mac80211 does not call
remove_interface() for a failed add, so the indices and firmware dev
entry leaked permanently and testmode could dereference the stale
monitor_vif. Add a proper error unwind.

Fixes: b619e01380 ("mt76: fix MBSS index condition in DBDC mode")
Link: https://patch.msgid.link/20260724124813.3961474-4-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:40 +00:00
Felix Fietkau
6689b4a65e wifi: mt76: fix out-of-bounds access in mmio copy helpers
mt76_mmio_write_copy() and mt76_mmio_read_copy() iterate up to
ALIGN(len, 4), so a length that is not a multiple of four reads past the
source buffer (write_copy) or writes past the destination (read_copy).
Copy the aligned body in the loop and handle the remaining tail through a
4-byte bounce buffer, keeping the register access width unchanged.

Fixes: 2df00805f7 ("wifi: mt76: mmio_*_copy fix byte order and alignment")
Link: https://patch.msgid.link/20260724124813.3961474-3-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:40 +00:00
Felix Fietkau
44af52467e wifi: mt76: mt7996: bound TLV walk in mt7996_mcu_get_chip_config
The response TLV loop advanced by tlv->len without a minimum, so a
theoretical firmware response containing a zero-length TLV could spin
forever, hanging the CPU during device probe.
The u32 payload was also read without bounds checking.
Reject a short fixed field, stop on a TLV whose length underruns the
header or overruns the skb.

Fixes: 5d33053be6 ("wifi: mt76: mt7996: add variants support")
Link: https://patch.msgid.link/20260724124813.3961474-2-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:40 +00:00
Felix Fietkau
cbeed70967 wifi: mt76: fix HE DCM max-RU capability encoding
sta_rec_he.dcm_rx_max_nss was assigned twice: the second assignment,
sourced from HE PHY capability byte 8 (DCM max RU), overwrote the RX-NSS
value and left dcm_max_ru at zero. Every associated HE station advertising
DCM support was configured in firmware with a wrong dcm_rx_max_nss and a
zero dcm_max_ru. Store the DCM max-RU value in dcm_max_ru as intended.

The same copy-paste error existed in both the shared connac2 path and the
mt7915 path.

Fixes: c336318f57 ("mt76: mt7915: add HE capabilities support for peers")
Fixes: 67aa27431c ("mt76: mt7921: rely on mt76_connac_mcu common library")
Link: https://patch.msgid.link/20260724124813.3961474-1-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:40 +00:00
Rex Lu
3310e71a74 wifi: mt76: check txfree done event on the WED hw path
Check the txfree done event DW1 bit 15 when WED is enabled, to avoid
the driver reading a txfree done event before WED has finished reading
it. No need to check this flag on WED v2, otherwise SER will occur.

The bit position was previously defined as MT_DMA_CTL_BURST, which is
unused; rename it to match its function on the txfree ring.

Fixes: 83eafc9251 ("wifi: mt76: mt7996: add wed tx support")
Signed-off-by: Rex Lu <rex.lu@mediatek.com>
Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
Link: https://patch.msgid.link/20260722082610.2699628-2-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:40 +00:00
Felix Fietkau
dd59a6126a wifi: mt76: mt7915: poll the correct SLP CTRL register for the second adie
The clock enable path for the second adie sets MT_ADIE_SLP_CTRL_CK0(1)
but polled the busy bit of MT_ADIE_SLP_CTRL_CK0(0), so dual-adie
bring-up could proceed before the adie1 clock was stable.

Fixes: 99ad32a4ca ("mt76: mt7915: add support for MT7986")
Link: https://patch.msgid.link/20260722082610.2699628-18-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:40 +00:00
Felix Fietkau
e1f97c10a4 wifi: mt76: fix RXDMAD_C buffer recycling race
The RXDMAD_C buffers come from the RRO data queues' page pools, which are
bound to a different NAPI, so the direct page-pool recycle used here could
race the owning NAPI; take the non-direct path as is already done for WED
RX queues.

Fixes: e50d4d710e ("wifi: mt76: Add mt76_dma_get_rxdmad_c_buf utility routione")
Link: https://patch.msgid.link/20260722082610.2699628-17-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:40 +00:00
Felix Fietkau
d3ecac68f7 wifi: mt76: fix uninitialised RXDMAD_C descriptor info
Unlike other WED-RRO queues, RXDMAD_C frames continue into the skb build
path, but mt76_dma_get_buf() skips the desc->info read for RRO queues, so
the uninitialised on-stack info was stored into skb->cb and passed to
rx_skb(); initialise it to zero.

Fixes: e50d4d710e ("wifi: mt76: Add mt76_dma_get_rxdmad_c_buf utility routione")
Link: https://patch.msgid.link/20260722082610.2699628-16-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:40 +00:00
Felix Fietkau
6650c85321 wifi: mt76: allow TX aggregation on the VO queue
The TX aggregation check skipped TIDs 6 and 7, so all voice-priority
traffic was sent without a BA session and therefore unaggregated,
limiting throughput for stations that map bulk traffic to VO. The
hardware handles aggregation on the VO queue fine, and a peer that
prefers unaggregated voice frames can still decline the ADDBA request.

Remove the skip from both the connac2 and the mt7996 aggregation setup
paths.

Link: https://patch.msgid.link/20260722082610.2699628-15-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:40 +00:00
Felix Fietkau
422dd2db28 wifi: mt76: fix stranded frames in mt76_txq_schedule_pending
A wcid is added to phy->tx_list whenever either tx_pending or
tx_offchannel becomes non-empty, but the requeue check after a partial
schedule required BOTH queues to be non-empty. When
mt76_txq_schedule_pending_wcid() returns -1 (queue stopped or
MT76_RESET) it leaves frames in tx_pending while tx_offchannel is empty,
so the wcid is dropped from every scheduling list and its frames stall
until the next mt76_tx() for that wcid or wcid cleanup. This strands
EAPOL/mgmt/nullfunc frames under momentary queue-full or across
scan/channel-switch, causing association and 4-way-handshake timeouts.

Requeue when either queue still holds frames, matching the enqueue
condition.

Fixes: 0b3be9d1d3 ("wifi: mt76: add separate tx scheduling queue for off-channel tx")
Link: https://patch.msgid.link/20260722082610.2699628-14-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:40 +00:00
Felix Fietkau
deaa2e3656 wifi: mt76: mt7996: fix TX DMA mapping leak for AddBA req frames
mt7996/mt7992 hand the firmware a HW MAC-TXP for AddBA req action frames
(MT_TXD7_MAC_TXD, set in mt7996_mac_write_txwi_80211()), but are otherwise
FW-TXP devices. On tx free mt76_connac_txp_skb_unmap() therefore decodes
the per-frame txp as a struct mt76_connac_fw_txp. For a MAC-TXP the
fw_txp.nbuf byte aliases the AddBA TID word (MT_TXP1_TID_ADDBA), which is
always zero, so the unmap loop runs zero times and the skb DMA mapping in
buf[1] is never unmapped. buf[1].skip_unmap is set unconditionally, so the
generic DMA-ring cleanup skips it as well.

Each AddBA req therefore leaks one TX DMA mapping, roughly one per
(re)association. With WED enabled these mappings are bounced through the
WED swiotlb pool, so under continuous client reconnect churn the pool is
exhausted after ~1-2 days, after which DMA mapping fails for WED, the WiFi
MCU and other on-SoC consumers.

Keep the deferred (token release) unmap that the design relies on, and add
an mt7996-specific txp unmap that inspects MT_TXD7_MAC_TXD and unmaps
buf[1] from the MAC-TXP layout for those frames, delegating to
mt76_connac_txp_skb_unmap() otherwise.

Cc: stable@vger.kernel.org
Fixes: cb6ebbdffe ("wifi: mt76: mt7996: support writing MAC TXD for AddBA Request")
Link: https://patch.msgid.link/20260722082610.2699628-13-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:40 +00:00
Felix Fietkau
5caa622956 wifi: mt76: fix 4th chain ACK RSSI bitmask in sta_poll
The per-chain response-frame RSSI values are packed one per byte, but the
4th chain was extracted with GENMASK(31, 14) instead of GENMASK(31, 24).
The wrong mask overlaps chains 1-3 and shifts by 14, producing a garbage
chain-3 value that corrupts ack_signal/avg_ack_signal on 4x4 radios.
Extract the correct byte.

Fixes: a71b648e35 ("wifi: mt76: mt7915: add ack signal support")
Fixes: ea5d99d07f ("wifi: mt76: mt7996: enable ack signal support")
Fixes: 67fc7a304b ("wifi: mt76: mt7921: add ack signal support")
Fixes: c948b5da6b ("wifi: mt76: mt7925: add Mediatek Wi-Fi7 driver for mt7925 chips")
Link: https://patch.msgid.link/20260722082610.2699628-12-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:40 +00:00
Felix Fietkau
2361457374 wifi: mt76: mt7915: write RX header translation bit to the correct register
MT_MDP_DCR0_RX_HDR_TRANS_EN is a field of MT_MDP_DCR0, but monitor-mode
handling applied it to the per-band MT_DMA_DCR0 register instead. As a
result RX header translation was never disabled in the MDP when entering
monitor mode, and an undocumented bit of MT_DMA_DCR0 was toggled. Target
MT_MDP_DCR0, matching the mt7996 driver.

Fixes: b249101858 ("wifi: mt76: mt7915: fix monitor mode issues")
Link: https://patch.msgid.link/20260722082610.2699628-11-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:40 +00:00
Felix Fietkau
d4d92ccded wifi: mt76: mt7996: don't report a zero TX bitrate
mt7996_sta_statistics() set NL80211_STA_INFO_TX_BITRATE unconditionally
after the block that already sets it, so a station with no rate info yet
was reported to userspace with a valid-but-zero TX rate. Drop the
redundant unconditional assignments; the in-block ones are sufficient.

Fixes: b34f346b91 ("wifi: mt76: mt7996: drop return in mt7996_sta_statistics")
Link: https://patch.msgid.link/20260722082610.2699628-10-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:40 +00:00
Felix Fietkau
4a2f4be532 wifi: mt76: mt7915: avoid nss underflow in mt7915_mcu_get_sta_nss
If a peer's VHT/HE MCS map has no supported spatial stream (all fields
0x3), the loop exits with nss == 0 and the function returned (u8)-1 (255),
which was then written into the firmware sta_rec_bf beamforming fields.
Clamp the result to 0.

Fixes: 89029a8548 ("mt76: mt7915: add Tx beamformer support")
Link: https://patch.msgid.link/20260722082610.2699628-9-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:40 +00:00
Felix Fietkau
6486e11a6e wifi: mt76: mt7915: clear wcid mask under mutex after RCU pointer clear
mt7915_remove_interface() cleared the wcid mask bit with no lock held and
before clearing the RCU wcid pointer. The mask is a non-atomic RMW shared
with the allocators, which all run under dev->mt76.mutex; on DBDC the two
wiphys share one mt76_dev, so this raced add_interface/sta_add on the
other band and could leak or double-hand-out a wcid. Clearing the bit
before the RCU pointer also let a concurrent allocation reuse the index
and publish its wcid, which the subsequent NULL assignment then wiped.
Move the clear into the existing mutex section, after the RCU pointer is
cleared.

Fixes: f3049b88b2 ("wifi: mt76: mt7915: allocate vif wcid in the same range as stations")
Link: https://patch.msgid.link/20260722082610.2699628-8-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:39 +00:00
Felix Fietkau
6469ae71e7 wifi: mt76: mt7996: set MT76_MCU_RESET before waking MCU waiters on full reset
mt7996_mac_full_reset() called wake_up(&dev->mt76.mcu.wait) without first
setting MT76_MCU_RESET. The MCU response wait condition only checks the
response queue and that bit, so the wake-up released nobody: a thread
blocked in an MCU command against the dead firmware (typically holding
dev->mt76.mutex) stayed asleep until its multi-second timeout, stalling
recovery. Set the bit before the wake-up, as mt7915 does.

Fixes: 27015b6fbc ("wifi: mt76: mt7996: enable full system reset support")
Link: https://patch.msgid.link/20260722082610.2699628-7-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:39 +00:00
Felix Fietkau
2243778a5f wifi: mt76: mt7996: validate RX band_idx before dereferencing phys[]
band_idx comes from a 2-bit descriptor field (0-3) and was used directly
to index dev->mt76.phys[] (size __MT_MAX_BAND == 3) and dereference the
result. A corrupt or reserved descriptor value could index out of bounds
or hit a NULL phy on parts with fewer bands. Reject invalid band indices,
mirroring mt7996_rx_get_wcid().

Fixes: 98686cd216 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
Link: https://patch.msgid.link/20260722082610.2699628-6-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:39 +00:00
Michael-CY Lee
f137fabc13 wifi: mt76: assign link_id when sending probe request during scan
The link_id in info->control.flags is required by mt7996 to select the
correct mt76_wcid for transmission.

Not assigning the link_id in info->control.flags is equivalent to
assigning the link_id to 0, causing mt7996 to select link_id 0 for
transmission, so probe requests sent on behalf of an MLD vif scanning
via a different link were transmitted with the wrong per-link wcid.

Fixes: 31083e3854 ("wifi: mt76: add code for emulating hardware scanning")
Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
Link: https://patch.msgid.link/20260722082610.2699628-5-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:39 +00:00
Michael-CY Lee
8ae659743b wifi: mt76: fix non-AQL packet accounting for MLO stations
__mt76_tx_queue_skb() overrides the wcid passed by the driver with
sta->drv_priv, so the wcid might incorrectly be changed after TX,
causing wcid->non_aql_packets to be counted on the wrong wcid. For
example, on the AP side, if a station's setup link is the 5G link and
the station uses 2G to transmit a frame, the value of non_aql_packets
is increased on the 5G wcid but decreased on the 2G wcid. Once the
inflated counter exceeds MT_MAX_NON_AQL_PKT, the TX scheduler
permanently refuses to service the station.

Drop the reassignment and account on the wcid used for transmission.
This also records the actual wcid in the queue entry.

Fixes: e1378e5228 ("mt76: rely on AQL for burst size limits on tx queueing")
Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
Link: https://patch.msgid.link/20260722082610.2699628-4-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:39 +00:00
Peter Chiu
ce35ecffc9 wifi: mt76: mt7996: fix MLD ID in MAC TXD and HIF TXP
Problem:
MCU command timeout while the firmware state is normal, and the
firmware keeps showing the error log "ERROR!! NO PAUSE...".

Root cause:
If the MLD_ID field in the TXD is neither the primary link id nor the
secondary link id, it may lead to a firmware busy loop when the third
link is in power saving mode.

Remap frames directed to a third link to the primary link wcid. Since
TX status events and txfree completions carry the wcid the firmware
saw, use the remapped wcid for packet id tracking and non-AQL packet
accounting as well, while the frame keeps its original link context
for addressing, band and OMAC selection.

Fixes: 85cd5534a3 ("wifi: mt76: mt7996: use correct link_id when filling TXD and TXP")
Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
Link: https://patch.msgid.link/20260722082610.2699628-3-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:39 +00:00
Rex Lu
86897f1066 wifi: mt76: fix RX data queuing of RRO 3.0
For RRO 3.0, RX data released from a RRO data queue should be put to
the indicator queue. The frames are processed and completed in the
context of the indicator queue NAPI, which only polls skbs queued on
the MT_RXQ_RRO_IND list; frames queued under the data queue id are
left sitting on that list until the data queue NAPI happens to run,
stalling and reordering RX data.

Fixes: b1e58e137b ("wifi: mt76: mt7996: Introduce RRO MSDU callbacks")
Signed-off-by: Rex Lu <rex.lu@mediatek.com>
Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
Link: https://patch.msgid.link/20260722082610.2699628-1-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:39 +00:00
Shayne Chen
29e889c4ad wifi: mt76: mt7996: fix capability of EHT-MCS 15 in MRU
According to the definition in IEEE Std 802.11be-2024, Table 9-417r:
- If 80 MHz is not supported, bit 1-3 are set to 0.
- If 160 MHz is not supported, bit 2-3 are set to 0.
- If 320 MHz is not supported, bit 3 is set to 0.

Fixes: 348533eb96 ("wifi: mt76: mt7996: add EHT capability init")
Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
Link: https://patch.msgid.link/20260313062150.3165433-2-shayne.chen@mediatek.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:39 +00:00
Chad Monroe
2087f02992 wifi: mt76: mt7996: fix non-MLD station num_sta leak
The MLO link-reconfiguration rework moved the per-phy num_sta
decrement inside a link_valid guard. link_valid is only set for
MLO links, but num_sta is incremented for every station link,
including the non-MLO deflink. Non-MLO stations bump num_sta
on association and never drop it on removal.

A non-zero num_sta forces connected-mode off-channel scanning which
prevents the directed probe exchange needed to find hidden APs.

Decrement phy->num_sta on the actual link teardown, pairing it with
the unconditional increment on link creation.

Fixes: e8c819df02 ("wifi: mt76: mt7996: Destroy active sta links in mt7996_mac_sta_remove()")
Signed-off-by: Chad Monroe <chad@monroe.io>
Link: https://patch.msgid.link/20260721185333.2419297-2-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:39 +00:00
Chad Monroe
6bb5066cfc wifi: mt76: mt7996: fix EAPOL source BSS for non-MLD stations
A non-MLD station's EAPOL and data frames are tagged with link_id ==
IEEE80211_LINK_UNSPECIFIED, which now skips the per-link lookup in
mt7996_mac_write_txwi() and leaves omac_idx/band_idx/wmm_idx at slot
0. When the radio also runs AP VAPs the station's omac is non-zero
(get_omac_idx() prefers HW BSSID slots 1-3), so its EAPOL frames
egress from the wrong BSS and the 4-way handshake times out even
though association succeeds.

In mt7996_tx_prepare_skb(), resolve the link from the peer wcid when
link_id is UNSPECIFIED and the wcid is not the global entry, restoring
the pre-MLO behaviour for station traffic.

Fixes: 729c83a333 ("wifi: mt76: mt7996: fix reading zeroed info->control.flags after mt76_tx_status_skb_add()")
Signed-off-by: Chad Monroe <chad@monroe.io>
Link: https://patch.msgid.link/20260721185333.2419297-1-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:39 +00:00
Charlie-cy Wu
9b80bd9cab wifi: mt76: mt7921: add regulatory wiphy self manager support
Introduce regulatory wiphy self-managed mode support for MT7921,
allowing the driver to manage its own regulatory domain independently
from the kernel's regulatory framework.

Signed-off-by: Charlie-cy Wu <Charlie-cy.Wu@mediatek.com>
Link: https://patch.msgid.link/20260609065036.577329-1-jb.tsai@mediatek.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:39 +00:00
Charlie-cy Wu
e9f3f1cc13 wifi: mt76: mt7925: add regulatory wiphy self manager support
Introduce regulatory wiphy self-managed mode support for MT7925,
allowing the driver to manage its own regulatory domain independently
from the kernel's regulatory framework.

Signed-off-by: Charlie-cy Wu <Charlie-cy.Wu@mediatek.com>
Link: https://patch.msgid.link/20260609065024.577079-1-jb.tsai@mediatek.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:39 +00:00
Charlie-cy Wu
1f83a8378e wifi: mt76: mt7921: refactor regd update to fix recursive mutex deadlock
Split mt7921_mcu_regd_update() into two functions to prevent recursive
mutex acquisition. Introduce __mt7921_mcu_regd_update() as the internal
implementation that assumes the mutex is already held by the caller,
while mt7921_mcu_regd_update() remains as the external interface that
handles mutex acquisition and release.

This fixes a deadlock issue when mt7921_regd_set_6ghz_power_type() is
called with the device mutex already held. Without this change, calling
mt7921_mcu_regd_update() would attempt to acquire the same mutex again,
causing a recursive lock deadlock.

The __mt7921_mcu_regd_update() function can be safely called when the
caller has already acquired the device mutex, avoiding the deadlock
while maintaining proper synchronization for regulatory domain updates.

Fixes: e88098133e ("wifi: mt76: mt7921: refactor regulatory notifier flow")
Signed-off-by: Charlie-cy Wu <Charlie-cy.Wu@mediatek.com>
Link: https://patch.msgid.link/20260629083543.153564-1-jb.tsai@mediatek.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:39 +00:00
Eason Lai
808f2767d4 wifi: mt76: mt792x: Fix memory leak in SDIO TX path
When tx_prepare_skb() returns an error in the SDIO TX path, the
skb is not freed, leading to a memory leak. This can occur when
zero-length frames (such as WNM NULL frames) are dropped to prevent
potential hardware TX hangs.

Fix this by properly releasing the skb with ieee80211_tx_status_ext()
when tx_prepare_skb() fails.

Fixes: b747fa3438 ("mt76: mt7915: drop zero-length packet to avoid Tx hang")
Signed-off-by: Eason Lai <Eason.Lai@mediatek.com>
Link: https://patch.msgid.link/20260703005945.2244533-1-eason.lai@mediatek.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:39 +00:00
Jared.Huang
9ddb7487aa wifi: mt76: mt7925: fix msg len mismatch between driver and firmware
The mt7925_tx_power_limit_tlv struct begins with a 4-byte rsv[] field
that acts as a UNI command header prefix. The firmware dispatcher did
not use the 4-byte rsv[] and will only check the payloads after the
4-byte rsv[] As a result, the total message length minus the 4-byte
prefix. Fix this by setting len to msg_len - 4.

Fixes: ccb186326b ("wifi: mt76: mt7925: fix incorrect length field in txpower command")
Signed-off-by: Jared.Huang <jared.huang@mediatek.com>
Link: https://patch.msgid.link/20260617071320.1808499-1-jb.tsai@mediatek.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:39 +00:00
Jared.Huang
8a27c5c764 wifi: mt76: mt7925: update clc before setting sar power table
Fix the power table update sequence to ensure CLC is loaded before
setting SAR power table.

The firmware requires CLC baseline to be established first
to properly calculate the final power limit as min(clc_limit, rate_limit,sar_limit).

Fixes: 9557b6fe0c ("wifi: mt76: mt7925: refine the txpower initialization flow")
Signed-off-by: Jared.Huang <jared.huang@mediatek.com>
Link: https://patch.msgid.link/20260617071305.1808394-1-jb.tsai@mediatek.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:39 +00:00
Sean Wang
525c3eb235 wifi: mt76: mt7925: support new WoW pattern TLV
Newer mt7925 firmware uses a shorter WoW pattern TLV with rsv[3]. Select
the v2 layout based on the firmware build date, while keeping the old
layout for older firmware.

This also makes the WoW pattern handling compatible with newer devices
such as MT7928.

Tested-by: Stella Liu <yu-ching.liu@mediatek.com>
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Link: https://patch.msgid.link/20260615212137.477893-1-sean.wang@kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:39 +00:00
Sean Wang
7673a2a159 wifi: mt76: mt7927: use real monitor vifs for dual-band monitors
MT7927 needs monitor interfaces to be passed to the driver as real vifs
so each monitor interface can be configured with its own band context.

This is required to support concurrent 2 GHz and 5 GHz monitor operation
on the same hw.

Keep the existing virtual monitor behavior for older chips.

Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Link: https://patch.msgid.link/20260613225144.2414283-2-sean.wang@kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:39 +00:00
Sean Wang
c410102bbf wifi: mt76: mt7927: set band index for sniffer mode
Use the active channel context to select the SNIFFER command band index on
MT7927, and fall back to the PHY chandef when no channel context is
available.

Also pass the same band index to the sniffer channel configuration. This
keeps monitor setup on the correct band, especially when multiple PHY band
contexts are present.

Fixes: 35a5dcc717 ("wifi: mt76: mt7925: add MT7927 PCIe support")
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Tested-by: Devin Wittmayer <lucid_duck@justthetip.ca>
Link: https://patch.msgid.link/20260613225144.2414283-1-sean.wang@kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:39 +00:00
Eason Lai
915672c5ae wifi: mt76: mt7921: Add PCIe AER handler support to prevent system crash
When an AER error occurs and the bus is hung, the register reads return
0xFFFFFFFF, causing the DMA queue state to be corrupted and resulting in
an invalid memory access when accessing q->desc[] or q->entry[].

Unable to handle kernel paging request at virtual address
ffffffc01099eac0
pc : mt76_dma_add_buf+0x124/0x188 [mt76]
lr : mt76_dma_rx_fill+0x11c/0x1d8 [mt76]
sp : ffffffc016d9bbf0
x29: ffffffc016d9bc10 x28: 0000000000000000
x27: 0000000000000000 x26: ffffffb7855e50b8
x25: ffffffb80d04f000 x24: 0000000000000000
x23: 0000000000000ec0 x22: ffffffb796803648
x21: ffffffb796801f80 x20: ffffffb7968035f8
x19: 0000000000000ec0 x18: 0000000000000000
x17: 000000004ec00000 x16: 000000000ec00000
x15: ffffffc01099eac0 x14: 000000004ec00000
x13: 00000000ffc5a000 x12: ffffffc016d9bc32
x11: 00000000ffffffff x10: 0000000000000002
x9 : 0000000000000000 x8 : 000000000000b4ac
x7 : 0000000000000a20 x6 : ffffffb6c1806400
x5 : 0000000000000000 x4 : ffffffb80d04f000
x3 : 0000000000000000 x2 : 0000000000000001
x1 : 000000000ec04000 x0 : ffffffb7968035f8
Call trace:
 mt76_dma_add_buf+0x124/0x188 [mt76 (HASH:1029 4)]
 mt76_dma_rx_reset+0xe8/0xfc [mt76 (HASH:1029 4)]
 mt7921_wpdma_reset+0x188/0x1b0 [mt7921e (HASH:ee48 5)]
 mt7921e_mac_reset+0x128/0x418 [mt7921e (HASH:ee48 5)]
 mt7921_mac_reset_work+0xac/0x1a8 [mt7921_common (HASH:f721 6)]
 process_one_work+0x188/0x514
 worker_thread+0x12c/0x300
 kthread+0x140/0x1fc
 ret_from_fork+0x10/0x30

Fix the invalid memory access by validating the DMA index read from the
hardware before it is used as a queue index. An out-of-range value, such
as the 0xFFFFFFFF returned while the bus is hung, is now clamped so it can
no longer corrupt q->head or q->tail. In addition, check the bus_hung flag
in mt7921_mac_reset_work() before attempting the reset sequence, reject MCU
messages while the bus is hung, and install no-op bus operations when an
unrecoverable AER error is detected, preventing further invalid hardware
accesses.

Due to hardware limitations - such as the lack of a connected hardware
reset pin or the absence of host re-probe functionality - affected Wi-Fi
devices may not fully recover to a normal operational state after
certain errors, even with AER enabled.

Fixes: 17f1de56df ("mt76: add common code shared between multiple chipsets")
Co-developed-by: Sean Wang <sean.wang@mediatek.com>
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Co-developed-by: Jeff Hsu <jeff.hsu@mediatek.com>
Signed-off-by: Jeff Hsu <jeff.hsu@mediatek.com>
Signed-off-by: Eason Lai <Eason.Lai@mediatek.com>
Co-developed-by: Michael Lo <michael.lo@mediatek.com>
Link: https://patch.msgid.link/20260506070458.3096180-1-jb.tsai@mediatek.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:39 +00:00
Devin Wittmayer
81faf57832 wifi: mt76: mt7925: cancel mlo_pm_work on stop
mt7925 queues mlo_pm_work with a 5 second delay during multi-link
power-save setup and never cancels it on the stop path. If the device is
torn down inside that window, the work outlives the teardown and its timer
fires afterwards, trying to queue onto the workqueue that is already gone:

  workqueue: cannot queue mt7925_mlo_pm_work [mt7925_common] on wq phy0
  WARNING: kernel/workqueue.c:2283 at __queue_work+0x59/0xa0, CPU#1: swapper/1/0
   call_timer_fn+0x2a/0x140
   __run_timers+0x203/0x330
   run_timer_softirq+0x86/0xf0

mt7921 already has its own stop callback, so add one for mt7925 that
cancels the work before calling mt792x_stop(). mt7925_ops backs both the
PCIe and USB drivers, so this covers both.

Fixes: 276a568832 ("wifi: mt76: mt7925: update the power-saving flow")
Cc: stable@vger.kernel.org
Tested-by: Traockl <281473483+Traockl@users.noreply.github.com>
Signed-off-by: Devin Wittmayer <lucid_duck@justthetip.ca>
Link: https://patch.msgid.link/20260627202946.25598-1-lucid_duck@justthetip.ca
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:38 +00:00
Wentao Guan
2889e84282 wifi: mt76: mt7925: cancel pending mlo_pm_work
If the device is reset, suspended or unregistered within that window,
the pending work can still run and access vif/bss data that may already
be freed, or send MCU commands while the firmware is not available.

Add cancel_delayed_work_sync(&dev->mlo_pm_work) in all relevant teardown
and suspend paths:

 - mt7925_mac_reset_work()        (chip reset recovery)
 - mt7925e_unregister_device()    (PCIe unbind)
 - mt7925_pci_suspend()           (PCIe bus suspend)
 - mt7925_suspend()               (mac80211 suspend)
 - mt7925u_suspend()              (USB bus / runtime suspend)

This ensures the work is stopped before the device state becomes
invalid.

Assisted-by: kimi-cli:kimi-k2.7 code
Assisted-by: atomcode:glm-5.2 #Reported-by

Fixes: 276a568832 ("wifi: mt76: mt7925: update the power-saving flow")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
Link: https://patch.msgid.link/20260630090218.3202029-1-guanwentao@uniontech.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:38 +00:00
JB Tsai
eb628006a2 wifi: mt76: mt7925: Fix unregister deadlock
During device shutdown or removal, a deadlock can occur between the
PCIe remove path and the driver's asynchronous reset work.

The unregistration path calls napi_disable() before cancelling the
reset work. If the reset work runs concurrently, it may re-enable NAPI
and schedule it. Because the device is being unregistered, this can
lead to NAPI state corruption where NAPI is marked as scheduled but
never polled, causing subsequent napi_disable() calls to hang forever.

Fix this by:
1. Moving cancel_work_sync(&dev->reset_work) to the very start of
   mt7925e_unregister_device(), ensuring it is stopped before NAPI
   is disabled.
2. Setting the MT76_REMOVED flag early in the PCI remove path to
   prevent new reset work from being queued.
3. Checking MT76_REMOVED in mt7925_mac_reset_work() and aborting the
   reset early if the device is being removed.

Co-developed-by: Fei Shao <fshao@google.com>
Signed-off-by: JB Tsai <jb.tsai@mediatek.com>
Tested-by: Rafael Passos <rafael@rcpassos.me>
Link: https://patch.msgid.link/20260630090610.586954-1-jb.tsai@mediatek.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:38 +00:00
Devin Wittmayer
ef3e34874d wifi: mt76: mt7925: ensure tx headroom in usb_sdio_tx_prepare_skb
mt7925_usb_sdio_tx_prepare_skb() pushes a TX descriptor and a USB
header onto every skb and assumes the headroom for them is already
there. That holds for locally generated traffic, where mac80211
reserves hw->extra_tx_headroom, but forwarded frames are sent through
ieee80211_8023_xmit(), which does not reserve it. Bridge a wired
interface to an mt7925u AP and the first forwarded frame that arrives
short panics the kernel:

 skbuff: skb_under_panic: len:415 put:4 tail:0x19b end:0x640 dev:wlan1
 kernel BUG at net/core/skbuff.c:212!
 Call trace:
  skb_panic+0x58/0x60 (P)
  skb_push+0x58/0x60
  mt7925_usb_sdio_tx_prepare_skb+0xf8/0x1b8 [mt7925_common]
  mt76u_tx_queue_skb+0xa0/0x1f8 [mt76_usb]
  __mt76_tx_queue_skb+0x54/0xe8 [mt76]
  mt76_txq_schedule.part.0+0x204/0x478 [mt76]
  mt76_txq_schedule_all+0x50/0x80 [mt76]
  mt792x_tx_worker+0x68/0x100 [mt792x_lib]
  __mt76_worker_fn+0x84/0x150 [mt76]

Whether a given setup hits it depends on how much headroom the ingress
netdev leaves in its rx skbs. Reproduced on a Raspberry Pi 5 bridging
onboard ethernet to a Netgear A9000; originally reported on an MT7986
router running OpenWrt. Nick Morrow's testing on a Pi 4 (bcmgenet),
which leaves more headroom, helped narrow the trigger to the ingress
path.

The same bug was fixed on mt7921 by commit 98c4d0abf5 ("mt76:
mt7921: don't assume adequate headroom for SDIO headers"), but mt7925
was copied from mt7921 without the fix. Add the same guard here.

Fixes: c948b5da6b ("wifi: mt76: mt7925: add Mediatek Wi-Fi7 driver for mt7925 chips")
Cc: stable@vger.kernel.org
Link: https://github.com/morrownr/mt76/issues/52
Signed-off-by: Devin Wittmayer <lucid_duck@justthetip.ca>
Link: https://patch.msgid.link/20260715023348.59506-1-lucid_duck@justthetip.ca
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:38 +00:00
Ahmed Naseef
d16447d747 wifi: mt76: mt7603: add 0x7592 EEPROM chip ID
Some EcoNet based routers ship an on-flash EEPROM whose chip-id is
0x7592 instead of the expected 0x7603. The device probes as PCI
14c3:7603 and the hardware MT_HW_CHIPID register reports 0x7603,
independent of the EEPROM value.

This is seen across multiple EcoNet EN751221 and EN7528 based devices
(for example the Genexis Platinum 4410).

Signed-off-by: Ahmed Naseef <naseefkm@gmail.com>
Link: https://patch.msgid.link/20260719082530.3879831-1-naseefkm@gmail.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:38 +00:00
Ryan Leung
313f1a27eb wifi: mt76: mt7915: add thermal zone device registration
Register the mt7915 phy as a thermal zone sensor using
devm_thermal_of_zone_register() so that device tree thermal-zones
nodes can reference the Wi-Fi chip as a temperature source. This
allows the kernel thermal governor to control external cooling
devices such as PWM fans based on Wi-Fi chip temperature.

Registration is non-fatal: -ENODEV is returned when no
thermal-sensors DT property references this device, which is the
expected case on platforms without a thermal zone configured.

Signed-off-by: Ryan Leung <untilscour@protonmail.com>
Link: https://patch.msgid.link/20260719-mt7915-thermal-zone-device-registration-v2-1-0eac68c2741e@protonmail.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:38 +00:00
Eason Lai
217f9e7bb0 wifi: mt76: mt792x: fix use-after-free in mt76_rx_poll_complete
A use-after-free issue occurs in mt76_rx_poll_complete due to a race
condition. The STA has already been removed, but the rx_status still
had a pointer to the wcid in the STA.

Set the links' wcid pointers to be NULL for a MLD in
mt7925_sta_pre_rcu_remove()

BUG: KASAN: invalid-access in mt76_rx_poll_complete+0x280/0x470
Call trace:
dump_backtrace+0xec/0x128
show_stack+0x18/0x28
dump_stack_lvl+0x40/0xc8
print_report+0x1b8/0x710
kasan_report+0xe0/0x144
do_bad_area+0x120/0x260
do_tag_check_fault+0x20/0x34
do_mem_abort+0x54/0xa8
el1_abort+0x3c/0x5c
el1h_64_sync_handler+0x40/0xcc
el1h_64_sync+0x7c/0x80
mt76_rx_poll_complete+0x280/0x470
mt76_dma_rx_poll+0x114/0x51c
mt792x_poll_rx+0x60/0xf8
napi_threaded_poll_loop+0xe0/0x450
napi_threaded_poll+0x80/0x9c
kthread+0x11c/0x158
ret_from_fork+0x10/0x20

Fixes: c948b5da6b ("wifi: mt76: mt7925: add Mediatek Wi-Fi7 driver for mt7925 chips")
Signed-off-by: Eason Lai <Eason.Lai@mediatek.com>
Link: https://patch.msgid.link/20260701010654.956863-1-eason.lai@mediatek.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:38 +00:00
Kenneth Kasilag
3c004f73d6 wifi: mt76: mt7996: expose per-band MAC addresses to cfg80211
mt7996/mt7992 are single-wiphy, multi-band devices. The driver assigns
each band its own MAC address from a per-band EEPROM entry, or derives
it from the primary band's address when that entry is empty, however
only the primary band's is published as perm_addr. The per-band
addresses are not exposed to cfg80211, so consumers usually fall back
to deriving one from perm_addr.

Store each band's address in wiphy->addresses[], indexed by radio, so
cfg80211 exposes the address the hardware actually uses for that radio.
addresses[0] is the primary band and matches perm_addr, as cfg80211
requires.

Link: https://github.com/openwrt/openwrt/issues/23578
Tested-on: Gemtek W1700K (MT7996)
Signed-off-by: Kenneth Kasilag <kenneth@kasilag.me>
Link: https://patch.msgid.link/20260620013850.3949359-1-kenneth@kasilag.me
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:38 +00:00
Bryam Vargas
13b3c29a78 wifi: mt76: mt7996: bound the device EEPROM address before the EFUSE copy
mt7996_mcu_get_eeprom() derives the destination of the EFUSE/EXT block
copy from the address reported by the MCU response (event->addr, a
device-controlled __le32) and clamps only the copy length, never the
destination offset into dev->mt76.eeprom.data. A malicious or
malfunctioning device can report an arbitrary address and drive an
out-of-bounds write of up to MT7996_EXT_EEPROM_BLOCK_SIZE bytes past
eeprom.data.

Reject a response whose address would place the copy outside eeprom.data
before deriving the destination pointer. Devices that echo the requested
in-bounds offset are unaffected.

Fixes: 98686cd216 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Link: https://patch.msgid.link/20260625-b4-disp-16f99062-v1-2-aee52ecf61b9@proton.me
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:38 +00:00
Bryam Vargas
44b5adfe49 wifi: mt76: mt7915: bound the device EEPROM address before the EFUSE copy
mt7915_mcu_get_eeprom() copies a fixed EFUSE block into the driver's
dev->mt76.eeprom.data buffer at the offset reported by the MCU response
(res->addr, a device-controlled __le32) without checking it against the
buffer size. A malicious or malfunctioning device can report an arbitrary
address and drive a 16-byte out-of-bounds write past eeprom.data.

Reject a response whose address would place the copy outside eeprom.data
before deriving the destination pointer. Devices that echo the requested
in-bounds offset are unaffected.

Fixes: e57b790146 ("mt76: add mac80211 driver for MT7915 PCIe-based chipsets")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Link: https://patch.msgid.link/20260625-b4-disp-16f99062-v1-1-aee52ecf61b9@proton.me
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:38 +00:00
Prashant Rahul
4361f16601 wifi: mt76: mt7921: fix memory leak when skb_linearize fails in mcu rx event
The ownership of sk_buff skb is passed to mt7921_queue_rx_skb, each
path inside it under the switch case handles cleaning of skb and it
is true for mt7921_mcu_rx_event as well.

mt7921_mcu_rx_event, on a success path, either queues skb via
mt76_mcu_rx_event or cleans it immediately inside
mt7921_mcu_uni_rx_unsolicited_event.

However inside mt7921_mcu_rx_event, if skb_linearize fails, the function
returns immediately and never bothers cleaning skb which leaks skb.

Since skb is fully owned at this point, it is safe to call
dev_kfree_skb which fixes the leak.

Granted, the skb_linearize failure is rare as it can only fail under
heavy memory usage, but at the same time, leaking memory under heavy
memory usage can worsen the OOM condition.

Signed-off-by: Prashant Rahul <prashantrahul23@gmail.com>
Link: https://patch.msgid.link/20260716-mt7921-mem-leak-v1-1-6e9c0ea19f63@gmail.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:38 +00:00
Zhi-Jun You
bade0d238b wifi: mt76: mt7915: fix net_fill_forward_path for non-DBDC mt7986
Current implementation assumes that the hardware supports DBDC or single
band and binds to band0.

This causes net_fill_forward_path to select the wrong queue for non-DBDC
mt7986 because it binds to band1 and getting the following in dmesg:

ieee80211 phy2: WA: --> drop by reaseon:1, msdu id = 0xc002 but failed!
mtk_wed1: error status=00000002
ieee80211 phy2: WA: txblk
10324e00
len = 128
DW0 : 10 00 00 00
DW1 : 00 00 00 00
DW2 : 00 00 00 00
DW3 : 72 0f 94 68
DW4 : 00 00 00 00
DW5 : ff 03 00 00
DW6 : 00 00 3c 40
DW7 : 00 17 dd 14
DW8 : 79 6f 00 00
DW9 : 02 c0 00 00
DW10 : 58 c5 34 10
DW11 : 00 00 00 00
DW12 : 00 06 3e 00
DW13 : 00 00 00 80
DW14 : 10 8c 00 00
DW15 : 00 00 00 00
DW16 : 00 00 00 00
DW17 : 00 00 00 00
DW18 : 00 00 00 00
DW19 : 00 00 00 00
DW20 : 00 00 00 00
DW21 : 00 00 00 00
DW22 : 00 00 00 00
DW23 : 00 00 00 00
DW24 : 00 00 00 00
DW25 : 00 00 00 00
DW26 : 00 00 00 00
DW27 : 00 00 00 00
DW28 : 00 00 00 00
DW29 : 00 00 00 00
DW30 : 00 00 00 00
DW31 : 00 00 00 00

Fix it by using phy->mt76->band_idx for queue which works for both
non-DBDC and DBDC devices.

Fixes: f68d67623d ("mt76: mt7915: add Wireless Ethernet Dispatch support")
Suggested-by: Benjamin Larsson <benjamin.larsson@genexis.eu>
Signed-off-by: Zhi-Jun You <hujy652@gmail.com>
Link: https://patch.msgid.link/20260715152113.553-2-hujy652@gmail.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:38 +00:00
Zhi-Jun You
8a177dabee wifi: mt76: wed: fix kernel panic on non-DBDC MT7986
In mt76_wed_init_rx_buf, it's hardcoded to use MT_RXQ_MAIN.
But for non-DBDC MT7986 MT_RXQ_BAND1 is used for RX data queue which
leads to kernel panic when attaching WED.

Use the correct RX queue by checking WED version and band_idx.

v2 and band 1 -> MT_RXQ_BAND1
Others -> MT_RXQ_MAIN

Kernel panic:

Unable to handle kernel access to user memory outside uaccess routines at virtual address 0000000000000000
Mem abort info:
  ESR = 0x0000000096000005
  EC = 0x25: DABT (current EL), IL = 32 bits
  SET = 0, FnV = 0
  EA = 0, S1PTW = 0
  FSC = 0x05: level 1 translation fault
Data abort info:
  ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000
  CM = 0, WnR = 0, TnD = 0, TagAccess = 0
  GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
Internal error: Oops: 0000000096000005 [#1]  SMP
CPU: 1 UID: 0 PID: 925 Comm: kmodloader Tainted: G           O        6.18.26 #0 NONE
Tainted: [O]=OOT_MODULE
Hardware name: Acer Connect Vero W6m (DT)
pstate: 40400005 (nZcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : page_pool_alloc_frag_netmem+0x1c/0x1bc
lr : page_pool_alloc_frag+0xc/0x34
sp : ffffffc081dab660
x29: ffffffc081dab660 x28: ffffffc081dabc60 x27: ffffff80091af040
x26: 0000008000000000 x25: ffffff80091a8898 x24: ffffff80091a5440
x23: 0000000000001000 x22: 0000000140000000 x21: ffffff80091a2040
x20: ffffff8003f1d780 x19: 0000000000000000 x18: 0000000000000020
x17: ffffffbfbf0ac000 x16: ffffffc080ee0000 x15: ffffff80049d47ca
x14: 000000000000037b x13: 000000000000037b x12: 0000000000000001
x11: 0000000000000000 x10: 0000000000000000 x9 : 0000000000000000
x8 : ffffff8003f1d7c0 x7 : 0000000000000000 x6 : ffffff8003f1d780
x5 : 0000000000000680 x4 : 0000000000000000 x3 : 0000000000002824
x2 : 0000000000000000 x1 : ffffffc081dab71c x0 : 0000000000000000
Call trace:
 page_pool_alloc_frag_netmem+0x1c/0x1bc (P)
 page_pool_alloc_frag+0xc/0x34
 mt76_wed_init_rx_buf+0xf8/0x2ac [mt76]
 mtk_wed_start+0x79c/0x12ac
 mt7915_dma_start+0x274/0x63c [mt7915e]
 mt7915_dma_start+0x5b4/0x63c [mt7915e]
 mt7915_dma_init+0x49c/0x81c [mt7915e]
 mt7915_register_device+0x24c/0x530 [mt7915e]
 mt7915_mmio_probe+0x91c/0x1980 [mt7915e]
 platform_probe+0x58/0xa0
 really_probe+0xb8/0x2a8
 __driver_probe_device+0x74/0x118
 driver_probe_device+0x3c/0xe0
 __driver_attach+0x88/0x154
 bus_for_each_dev+0x60/0xb0
 driver_attach+0x20/0x28
 bus_add_driver+0xdc/0x200
 driver_register+0x64/0x118
 __platform_driver_register+0x20/0x30
 init_module+0x74/0x1000 [mt7915e]
 do_one_initcall+0x4c/0x1f8
 do_init_module+0x50/0x210
 load_module+0x15f8/0x1b10
 __do_sys_init_module+0x1a8/0x260
 __arm64_sys_init_module+0x18/0x20
 invoke_syscall.constprop.0+0x4c/0xd0
 do_el0_svc+0x3c/0xd0
 el0_svc+0x18/0x60
 el0t_64_sync_handler+0x98/0xdc
 el0t_64_sync+0x158/0x15c
Code: aa0003f3 a9025bf5 a90363f7 d2820017 (b9400000)

Signed-off-by: Zhi-Jun You <hujy652@gmail.com>
Link: https://patch.msgid.link/20260715152113.553-1-hujy652@gmail.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:38 +00:00
Laxman Acharya Padhya
653c6e289b wifi: mt76: mt7996: validate default EEPROM firmware size
The default EEPROM firmware is parsed and copied as a full EEPROM
without checking its length. A truncated file can make the driver
read beyond the firmware buffer during variant validation or the
fallback copy.

Reject files shorter than MT7996_EEPROM_SIZE before parsing or
copying the firmware.

Fixes: 98686cd216 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
Cc: stable@vger.kernel.org
Signed-off-by: Laxman Acharya Padhya <acharyalaxman8848@gmail.com>
Link: https://patch.msgid.link/20260713115412.67095-1-acharyalaxman8848@gmail.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:38 +00:00
Laxman Acharya Padhya
9417c5818a wifi: mt76: mt7921: validate CLC firmware records
The CLC region is supplied by firmware, but the loader trusts the
region count and each record length. A malformed image can make the
region table pointer precede the firmware buffer, make the record loop
fail to advance, or index phy->clc past its end. Validate the table and
record bounds before dereferencing or copying.

Fixes: 23bdc5d8ca ("wifi: mt76: mt7921: introduce Country Location Control support")
Signed-off-by: Laxman Acharya Padhya <acharyalaxman8848@gmail.com>
Link: https://patch.msgid.link/CAMyXUJmh=WfwC4_KHupNxYR5e2Gy5QhBDL5TSG6XEW-XLa+X4Q@mail.gmail.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:38 +00:00
Sean Wang
7910bd565d wifi: mt76: mt792x: quiesce USB paths on disconnect
USB disconnect can leave reset/init work, TX worker, and MCU waiters active
while the device is being removed. Stop those paths before unregistering
the device to avoid teardown waiting on firmware or queue activity after
disconnect.

Run WFSYS reset after USB queue deinit so removal does not issue the reset
while USB traffic may still be queued.

Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Link: https://patch.msgid.link/20260613224131.2396026-7-sean.wang@kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:38 +00:00
Sean Wang
b994cb409f wifi: mt76: mt792x: enable USB UDMA TX timeout
Configure the USB UDMA TX timeout limit and enable timeout detection
during DMA initialization, matching the vendor driver setup. Use a
longer timeout to avoid false alarms.

Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Link: https://patch.msgid.link/20260613224131.2396026-6-sean.wang@kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:38 +00:00
Sean Wang
a4803d1801 wifi: mt76: mt792x: drain USB UDMA before WFSYS reset
Stop USB UDMA RX/TX and wait for idle before WFSYS reset.
Warn if the engine remains busy.

Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Link: https://patch.msgid.link/20260613224131.2396026-5-sean.wang@kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:38 +00:00
Sean Wang
e137e5fd24 wifi: mt76: mt792x: stop USB register access after bus hang
Mark the mt792x USB bus hung on the first control timeout and switch
register access to no-op bus ops. Each failed vendor request may spend
up to MT_VEND_REQ_MAX_RETRY * MT_VEND_REQ_TOUT_MS, about 3 seconds, and
teardown/reset paths can keep issuing such requests after the device has
stopped responding.

Also skip the USB WFSYS reset path after bus_hung is set, since it uses
UHW vendor requests as well.

mt7925u 1-2:1.3: vendor request req:63 off:0018 failed:-110
mt7925u 1-2:1.3: vendor request req:63 off:0018 failed:-110
mt7925u 1-2:1.3: vendor request req:63 off:0018 failed:-110
mt7925u 1-2:1.3: vendor request req:63 off:0018 failed:-110
mt7925u 1-2:1.3: vendor request req:63 off:0018 failed:-110

Avoid repeating those register reads after the bus is known to be hung by
switching register access to no-op handlers.

Fixes: 0d2afe09fa ("mt76: mt7921: add mt7921u driver")
Fixes: c948b5da6b ("wifi: mt76: mt7925: add Mediatek Wi-Fi7 driver for mt7925 chips")
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Link: https://patch.msgid.link/20260613224131.2396026-4-sean.wang@kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:38 +00:00
Sean Wang
c781b74c3f wifi: mt76: mt7925: skip reset work on hung bus
Skip mt7925 reset handling once the bus is marked hung.

A hung bus cannot be recovered by issuing another device reset. Continuing
the reset path may only send more failing MCU or register accesses and
delay teardown. Return early from reset work and the USB reset path so the
failed device can be torn down quickly.

Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Link: https://patch.msgid.link/20260613224131.2396026-3-sean.wang@kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:38 +00:00
Sean Wang
7e87dc3b21 wifi: mt76: mt7925: stop init retries on hung bus
Stop retrying hardware init once the bus is marked hung.

The control path is no longer usable at that point, so more retries only
issue failing device accesses, including MCU commands or register
operations, and delay teardown. Exit early and let the failed device be
torn down quickly.

Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Link: https://patch.msgid.link/20260613224131.2396026-2-sean.wang@kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:37 +00:00
Shayne Chen
70869cc429 wifi: mt76: fix handling channel context with different bands in mt76_switch_vif_chanctx()
When performing channel switches on different radios within a short
timeframe, channel contexts with different bands can be carried for
each struct ieee80211_vif_chanctx_switch.

Rework mt76_switch_vif_chanctx() to properly handle this scenario.

Fixes: 82334623af ("wifi: mt76: add chanctx functions for multi-channel phy support")
Co-developed-by: Rex Lu <rex.lu@mediatek.com>
Signed-off-by: Rex Lu <rex.lu@mediatek.com>
Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
Link: https://patch.msgid.link/20260720090102.190729-1-shayne.chen@mediatek.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:37 +00:00
David Bauer
965cbdbdfb wifi: mt76: mt7603: free beacon SKB on error
The SKB containing the generated beacon is not freed when the beacon
queue is deected stuck and scheduled for recovery.

Fixes potential memory leaks in case the beacon queue is detected stuck.

Signed-off-by: David Bauer <mail@david-bauer.net>
Link: https://patch.msgid.link/20260611215658.259324-1-mail@david-bauer.net
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:37 +00:00
Ethan Nelson-Moore
429e516d4f wifi: mt76: mt7996: remove code guarded by nonexistent config option
A small piece of code in mt7996.h depends on CONFIG_MTK_DEBUG, which
has never been defined in the kernel. Remove this dead code.

Discovered while searching for CONFIG_* symbols referenced in code but
not defined in any Kconfig file.

Signed-off-by: Ethan Nelson-Moore <enelsonmoore@gmail.com>
Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
Link: https://patch.msgid.link/20260610041050.206950-1-enelsonmoore@gmail.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:37 +00:00
Ethan Nelson-Moore
31beda21fb wifi: mt76: mt7925: remove code guarded by nonexistent config option
A small piece of code in mt7925/regs.h depends on CONFIG_MT76_DEV, which
has never been defined in the kernel. Remove this dead code.

Discovered while searching for CONFIG_* symbols referenced in code but
not defined in any Kconfig file.

Signed-off-by: Ethan Nelson-Moore <enelsonmoore@gmail.com>
Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
Link: https://patch.msgid.link/20260610042429.222717-1-enelsonmoore@gmail.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:37 +00:00
Devin Wittmayer
ddae0bcb01 wifi: mt76: mt76x02: report rx FCS errors to mac80211
When the fcsfail filter is enabled the hardware passes frames with a bad
FCS up to the driver, but mt76x02_mac_process_rx() never checks
MT_RXINFO_CRCERR and hands them to mac80211 without
RX_FLAG_FAILED_FCS_CRC. In monitor mode the radiotap flags byte then
never gets IEEE80211_RADIOTAP_F_BADFCS set and corrupted frames cannot be
told apart from clean ones.

Set RX_FLAG_FAILED_FCS_CRC from the descriptor CRC error bit, matching
mt7603, mt7615, mt7915, mt7921, mt7925 and mt7996.

Reported-by: 0072a70 <90307219+0072a70@users.noreply.github.com>
Closes: https://github.com/morrownr/mt76/issues/38
Tested-by: 0072a70 <90307219+0072a70@users.noreply.github.com>
Signed-off-by: Devin Wittmayer <lucid_duck@justthetip.ca>
Link: https://patch.msgid.link/20260613002544.27750-3-lucid_duck@justthetip.ca
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:37 +00:00
Devin Wittmayer
81497634d9 wifi: mt76: mt76x02: do not WARN on invalid rx descriptor length
The MPDU length in the rx descriptor comes from the hardware. In
monitor mode with the fcsfail filter enabled, the hardware passes up
corrupted frames, and a corrupted frame can report a length larger
than the received buffer. The bounds check correctly discards such
frames, but its WARN_ON_ONCE wrapper means any over-the-air garbage
frame taints the kernel, and panics it on the first such frame when
panic_on_warn is set.

Drop the WARN and discard the frame silently, matching what
commit c2d4c8723d ("mt76x2: remove some harmless WARN_ONs in tx
status and rx path") did for the neighboring rx and tx status paths.

Observed immediately on rx with an MT7612U in fcsfail monitor mode
on a busy channel.

Fixes: 7bc04215a6 ("mt76: add driver code for MT76x2e")
Signed-off-by: Devin Wittmayer <lucid_duck@justthetip.ca>
Link: https://patch.msgid.link/20260613002544.27750-2-lucid_duck@justthetip.ca
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:37 +00:00
Sean Wang
420e0bbd52 wifi: mt76: mt792x: advertise NAN data support
Advertise NAN and NAN data support when firmware exposes NAN
capability.

Add NAN interface combinations on top of the dynamic combination
framework, advertise 2.4 GHz and 5 GHz NAN bands, and enable secure
NAN.

Keep the base interface combinations unchanged when NAN is unavailable
so existing STA/AP/P2P modes keep the same limits.

Co-developed-by: Stella Liu <yu-ching.liu@mediatek.com>
Signed-off-by: Stella Liu <yu-ching.liu@mediatek.com>
Co-developed-by: Jeremy Yu <chengwei.yu@mediatek.com>
Signed-off-by: Jeremy Yu <chengwei.yu@mediatek.com>
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Link: https://patch.msgid.link/20260625001834.475094-10-sean.wang@kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:37 +00:00
Sean Wang
9bb39d09ab wifi: mt76: mt792x: build iface combinations dynamically
Move mt792x interface combination selection into a helper and store the
selected table in mt792x device state.

This keeps the existing non-CNM and CNM combinations unchanged while
making later firmware-gated extensions add combinations without touching
the common wiphy setup path.

Co-developed-by: Stella Liu <yu-ching.liu@mediatek.com>
Signed-off-by: Stella Liu <yu-ching.liu@mediatek.com>
Co-developed-by: Jeremy Yu <chengwei.yu@mediatek.com>
Signed-off-by: Jeremy Yu <chengwei.yu@mediatek.com>
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Link: https://patch.msgid.link/20260625001834.475094-9-sean.wang@kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:37 +00:00
Sean Wang
0f3605e4f8 wifi: mt76: mt7925: wire up NAN operations
Wire mac80211 NAN start, stop and change_conf callbacks to the mt7925 NAN
MCU helpers. Track the active NAN vif and notify mac80211 on cluster join
events.

Initialize NAN PHY capabilities after the supported bands are ready.

Co-developed-by: Stella Liu <yu-ching.liu@mediatek.com>
Signed-off-by: Stella Liu <yu-ching.liu@mediatek.com>
Co-developed-by: Jeremy Yu <chengwei.yu@mediatek.com>
Signed-off-by: Jeremy Yu <chengwei.yu@mediatek.com>
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Link: https://patch.msgid.link/20260625001834.475094-8-sean.wang@kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:37 +00:00
Sean Wang
4ee3d2a5f2 wifi: mt76: add init_wiphy callback
Add an optional callback for drivers to finalize wiphy state after mt76
has initialized the supported bands and before registration.

Co-developed-by: Stella Liu <yu-ching.liu@mediatek.com>
Signed-off-by: Stella Liu <yu-ching.liu@mediatek.com>
Co-developed-by: Jeremy Yu <chengwei.yu@mediatek.com>
Signed-off-by: Jeremy Yu <chengwei.yu@mediatek.com>
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Link: https://patch.msgid.link/20260625001834.475094-7-sean.wang@kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:37 +00:00
Sean Wang
9824fb4edb wifi: mt76: mt7925: add NAN MCU handling
Route NAN MCU responses and unsolicited events through the mt7925 MCU
path, and handle NAN-specific BSS and station TLVs.

Co-developed-by: Stella Liu <yu-ching.liu@mediatek.com>
Signed-off-by: Stella Liu <yu-ching.liu@mediatek.com>
Co-developed-by: Jeremy Yu <chengwei.yu@mediatek.com>
Signed-off-by: Jeremy Yu <chengwei.yu@mediatek.com>
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Link: https://patch.msgid.link/20260625001834.475094-6-sean.wang@kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:37 +00:00
Sean Wang
a5487a6824 wifi: mt76: mt7925: add NAN MCU helpers
Add the mt7925 NAN MCU ABI and helpers for enable, disable, configuration
updates, availability updates and peer schedule commands.

Upper-layer integration is added by later patches.

Co-developed-by: Stella Liu <yu-ching.liu@mediatek.com>
Signed-off-by: Stella Liu <yu-ching.liu@mediatek.com>
Co-developed-by: Jeremy Yu <chengwei.yu@mediatek.com>
Signed-off-by: Jeremy Yu <chengwei.yu@mediatek.com>
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Link: https://patch.msgid.link/20260625001834.475094-5-sean.wang@kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:37 +00:00
Sean Wang
b7ab9f780d wifi: mt76: connac: add NAN connection type
Introduce a dedicated NAN connection type for connac firmware and use it
for NAN interface device, BSS and station records.

Add the common NAN MCU command and event IDs used by mt7925.

Co-developed-by: Stella Liu <yu-ching.liu@mediatek.com>
Signed-off-by: Stella Liu <yu-ching.liu@mediatek.com>
Co-developed-by: Jeremy Yu <chengwei.yu@mediatek.com>
Signed-off-by: Jeremy Yu <chengwei.yu@mediatek.com>
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Link: https://patch.msgid.link/20260625001834.475094-4-sean.wang@kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:37 +00:00
Sean Wang
9080164f3b wifi: mt76: mt7925: guard BSS capability lookups
mt7925 BSS setup may dereference missing channel data or query HE 6 GHz
capabilities for an iftype without HE support.

Guard both lookups before adding NAN paths that can use partially
configured BSS state.

Co-developed-by: Stella Liu <yu-ching.liu@mediatek.com>
Signed-off-by: Stella Liu <yu-ching.liu@mediatek.com>
Co-developed-by: Jeremy Yu <chengwei.yu@mediatek.com>
Signed-off-by: Jeremy Yu <chengwei.yu@mediatek.com>
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Link: https://patch.msgid.link/20260625001834.475094-3-sean.wang@kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:37 +00:00
Sean Wang
a7c71a3465 wifi: mt76: mt792x: advertise mgmt frame registration
Advertise multicast management frame registration support so userspace
can subscribe to multicast management and action frames.

This capability is required for NAN discovery and related operations.

Co-developed-by: Stella Liu <yu-ching.liu@mediatek.com>
Signed-off-by: Stella Liu <yu-ching.liu@mediatek.com>
Co-developed-by: Jeremy Yu <chengwei.yu@mediatek.com>
Signed-off-by: Jeremy Yu <chengwei.yu@mediatek.com>
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Link: https://patch.msgid.link/20260625001834.475094-2-sean.wang@kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:37 +00:00
Filip Bakreski
5323d3e50c wifi: mt76: mt76u: use a threaded NAPI for the RX path
The USB RX path delivers frames to the stack via mt76_rx_complete() with
a NULL napi pointer, taking the netif_receive_skb_list() path, so it never
benefits from GRO -- unlike the DMA-based mt76 drivers, which pass a real
napi and use napi_gro_receive(). For bulk TCP traffic this is costly, as
every segment traverses the stack individually.

Service the MT_RXQ_MAIN queue from a threaded NAPI, reusing mt76_dev's
existing napi_dev and napi[] rather than adding new fields. The URB
completion handler schedules the napi; its poll drains the URBs, builds
the skbs, resubmits and delivers them through napi_gro_receive(). The MCU
queue stays on the existing RX worker. This enables GRO and moves RX
processing into its own kernel thread, parallelising the datapath.

On mt7921u at HE-MCS 11 (2x2, 80 MHz; fast.com, multiple streams) this
averages ~588 Mbit/s, versus ~424 Mbit/s when the same napi is instead
driven manually from the RX worker, and ~380 Mbit/s for the unmodified
driver.

Suggested-by: Lorenzo Bianconi <lorenzo@kernel.org>
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Filip Bakreski <phial@phiality.com>
Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20260609105301.196302-1-phial@phiality.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:37 +00:00
David Bauer
a92cd5dd79 wifi: mt76: mt7915: configure noise floor reporting on reset
When performing a full system recovery of the MCU on a dual-phy
platform, band 0 (usually 2.4GHz) stops reading correct noise floor
data.

This is due to noise floor reporting only being configured correctly
for the second device PHY.

Configure the respective registers correctly after restarting the MCU
firmware to fix reported noise-floor values.

Signed-off-by: David Bauer <mail@david-bauer.net>
Link: https://patch.msgid.link/20260516144944.2574053-1-mail@david-bauer.net
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:37 +00:00
Emery Hsin
e65b4ca339 wifi: mt76: mt7925: add MT7928 PCIe support
Register MT7928 (0x7928, 0x7935) in the PCI device table and
declare MODULE_FIRMWARE for all four MT7928 firmware blobs.

Signed-off-by: Emery Hsin <emery.hsin@mediatek.com>
Link: https://patch.msgid.link/20260612075339.2578327-5-jb.tsai@mediatek.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:37 +00:00
Emery Hsin
8905038d58 wifi: mt76: mt7925: add MT7928 per-chip PCIe register definitions
MT7928 maps PCIe MAC registers through base 0x74040000. Add
MT7928_PCIE_MAC_{INT_ENABLE,PM} macros and override dev->pcie_reg
at probe time for MT7928 hardware.

Signed-off-by: Xiong <xiong.huang@mediatek.com>
Signed-off-by: Emery Hsin <emery.hsin@mediatek.com>
Link: https://patch.msgid.link/20260612075339.2578327-4-jb.tsai@mediatek.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:37 +00:00
Emery Hsin
f26fda0c6a wifi: mt76: mt7925: align scan IE and EFUSE TLV lengths to 4 bytes for MT7928
MT7928 firmware requires 4-byte aligned TLV payloads. Round up
UNI_SCAN_IE allocation with ALIGN(..., 4) and track padded length.

Signed-off-by: Xiong <xiong.huang@mediatek.com>
Signed-off-by: Emery Hsin <emery.hsin@mediatek.com>
Link: https://patch.msgid.link/20260612075339.2578327-3-jb.tsai@mediatek.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:37 +00:00
Emery Hsin
d93e31ba9f wifi: mt76: mt7925: add MMIO register remapping table for MT7928
MT7928 has a different physical address layout. Add a dedicated
mt7928_fixed_map[] remapping table and select it at runtime. Set
mdev->rev early in probe for correct chip revision detection.

Signed-off-by: Leon Yen <leon.yen@mediatek.com>
Signed-off-by: Emery Hsin <emery.hsin@mediatek.com>
Link: https://patch.msgid.link/20260612075339.2578327-2-jb.tsai@mediatek.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-31 12:25:36 +00:00