Commit Graph
21 Commits
Author SHA1 Message Date
Felix Fietkau 90f731f6c9 wifi: mt76: clear offchannel state if a scan has no channel to restore
mt76_scan_complete() restores the operating channel only if the phy has one.
__mt76_set_channel() is the only function that clears phy->offchannel.
A phy can run a scan while it has no operating channel. A 6 GHz radio with
no configured interface is one example. After such a scan, the flag stays
set.

mt76_txq_schedule_list() skips each TXQ whose wcid points to a phy in this
state. All traffic for the stations on that band stops. The frames stay in
the mac80211 queues. They do not reach the hardware, and no counter shows
them. Only an unrelated channel set clears the flag.

Link: https://patch.msgid.link/[email protected]
Signed-off-by: Felix Fietkau <[email protected]>
2026-08-18 15:42:32 +02:00
Felix Fietkau 26e36bf38f wifi: mt76: check the owner of a remain-on-channel request
mvif->roc_phy points to the phy of the request that started last for the
interface. That request can end, and the phy can start a request for a
different interface. The driver does not always clear the pointer.

Two callers trust the pointer:

- mt76_vif_cleanup() aborts the request on that phy when the driver removes
  the interface.
- mt76_cancel_remain_on_channel() aborts the request on that phy for the
  interface.

If the phy holds a request for a different interface, both callers abort the
wrong request. The request of the interface stays active. Its work then runs
after the driver removes the interface. The work tears the link down through
the freed bss_conf.

Compare phy->roc_vif with the interface in both callers before the abort.

Link: https://patch.msgid.link/[email protected]
Signed-off-by: Felix Fietkau <[email protected]>
2026-08-18 15:42:32 +02:00
Shayne ChenandFelix Fietkau 43fa7d4a9e 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: 82334623af0c ("wifi: mt76: add chanctx functions for multi-channel phy support")
Co-developed-by: Rex Lu <[email protected]>
Signed-off-by: Rex Lu <[email protected]>
Signed-off-by: Shayne Chen <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Felix Fietkau <[email protected]>
2026-07-21 10:30:02 +02:00
Rajat GuptaandFelix Fietkau fe0555feb3 wifi: mt76: use kfree_rcu for offchannel link in mt76_put_vif_phy_link
mt76_put_vif_phy_link() frees the offchannel mlink with plain kfree()
after rcu_assign_pointer(NULL). However, rcu_assign_pointer only prevents
future RCU readers from obtaining the pointer -- it does not wait for
existing readers that already hold it via rcu_dereference.

The TX datapath (e.g. mt7996_mac_write_txwi) dereferences mlink->wcid
and mlink->idx under rcu_read_lock. If a TX softirq obtained the pointer
via rcu_dereference just before the NULL assignment, it will dereference
freed memory after the kfree.

struct mt76_vif_link already contains an rcu_head field that is unused at
this free site -- a developer oversight, since the adjacent
kfree_rcu_mightsleep call for rx_sc in the same function shows the
pattern was understood.

Replace kfree(mlink) with kfree_rcu(mlink, rcu_head).

Fixes: a8f424c1287c ("wifi: mt76: add multi-radio remain_on_channel functions")
Signed-off-by: Rajat Gupta <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Felix Fietkau <[email protected]>
2026-05-27 13:20:44 +02:00
Shayne ChenandFelix Fietkau ade83e44ed wifi: mt76: mt7996: Move mlink deallocation in mt7996_vif_link_remove()
Destroy mt76_vif_link struct in mt7996_vif_link_remove routine and not
in mt76_unassign_vif_chanctx(). This is necessary since, in order to
properly support MLO link reconfiguration, we will destroy mt76_vif_link
struct during AP tear-down process and not running unassign_vif_chanctx
mac80211 callback.
This patch does not introduce any regression since
mt76_assign_vif_chanctx/mt76_unassign_vif_chanctx APIs are currently
used just by MT7996 driver.

Signed-off-by: Shayne Chen <[email protected]>
Co-developed-by: Lorenzo Bianconi <[email protected]>
Signed-off-by: Lorenzo Bianconi <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Felix Fietkau <[email protected]>
2026-03-21 08:24:20 +00:00
Felix Fietkau fb6a584e71 wifi: mt76: add per-link beacon monitoring for MLO
With chanctx drivers using hardware scan or remain-on-channel,
mac80211 does not know when the radio goes off-channel, which breaks
its software beacon loss detection.

Implement per-link beacon monitoring in the driver. Track the last
beacon timestamp per link and check for beacon loss periodically from
the mac_work handler.

Beacon monitoring is initialized on association and on late link
activation, and cleared on disassociation. The beacon_mon_last
timestamp is reset when returning from offchannel and after channel
switches to prevent false beacon loss detection.

Signed-off-by: Felix Fietkau <[email protected]>
2026-03-09 04:51:09 +00:00
Felix Fietkau b451ffe2c0 wifi: mt76: send nullfunc PS frames on offchannel transitions
Since mt76 uses chanctx, mac80211 does not send nullfunc power save
notifications when the driver goes offchannel for scan or ROC.
Add mt76_offchannel_notify() to send nullfunc PM=1 before going
offchannel and PM=0 after returning, so that the AP can buffer
frames during the absence.

For MLO, iterate all vif links on the phy and set
IEEE80211_TX_CTRL_MLO_LINK so that the driver's tx_prepare_skb
resolves the correct per-link wcid.

Signed-off-by: Felix Fietkau <[email protected]>
2026-03-07 15:44:38 +00:00
Felix Fietkau 273c6f60cc wifi: mt76: optimize ROC for same-channel case
mt76_remain_on_channel() always creates an HT20 chandef and goes
offchannel, even when the ROC channel matches the operating channel.
This unnecessarily narrows bandwidth and triggers beacon stop/restart.

When the ROC channel matches the current operating channel, preserve
the full chandef and skip the offchannel transition, matching the
optimization already present in the scan code.

Extract the shared same-channel detection into mt76_offchannel_chandef()
and use it in both ROC and scan paths.

Signed-off-by: Felix Fietkau <[email protected]>
2026-03-07 13:53:44 +00:00
Felix Fietkau 42955db08a wifi: mt76: abort ROC on chanctx changes
mt76_change_chanctx() calls mt76_phy_update_channel() which switches
the hardware channel. If ROC is active on the same phy, this switches
away from the ROC channel and clears offchannel, but leaves ROC state
intact. Mac80211 still thinks the phy is on the ROC channel.

Abort any active ROC before proceeding, matching the pattern already
used in add, remove, assign, unassign, and switch chanctx functions.

Signed-off-by: Felix Fietkau <[email protected]>
2026-03-07 13:51:42 +00:00
Felix Fietkau 35e79a5bb1 wifi: mt76: check chanctx before restoring channel after ROC
mt76_remove_chanctx() sets phy->chanctx to NULL but does not clear
phy->main_chandef. If ROC is later performed on that phy, completion
tries to restore the stale main_chandef channel, programming the
hardware to sit on a channel with no active context.

Add a chanctx check to avoid restoring a channel when no context is
active.

Signed-off-by: Felix Fietkau <[email protected]>
2026-03-07 13:51:32 +00:00
Felix Fietkau b7d6e43438 wifi: mt76: add offchannel check to mt76_roc_complete
mt76_roc_complete() unconditionally calls __mt76_set_channel() to
restore the operating channel. The scan equivalent mt76_scan_complete()
checks phy->offchannel first, skipping the restore if the phy is
already back on-channel.

Without this check, ROC completion performs a redundant full hardware
channel switch when something has already moved the phy back.

Signed-off-by: Felix Fietkau <[email protected]>
2026-03-07 13:51:24 +00:00
Chad MonroeandFelix Fietkau db0460d663 wifi: mt76: fix deadlock in remain-on-channel
mt76_remain_on_channel() and mt76_roc_complete() call mt76_set_channel()
while already holding dev->mutex. Since mt76_set_channel() also acquires
dev->mutex, this results in a deadlock.

Use __mt76_set_channel() instead of mt76_set_channel().
Add cancel_delayed_work_sync() for mac_work before acquiring the mutex
in mt76_remain_on_channel() to prevent a secondary deadlock with the
mac_work workqueue.

Fixes: a8f424c1287c ("wifi: mt76: add multi-radio remain_on_channel functions")
Signed-off-by: Chad Monroe <[email protected]>
Link: https://patch.msgid.link/ace737e7b621af7c2adb33b0188011a5c1de2166.1765204256.git.chad@monroe.io
Signed-off-by: Felix Fietkau <[email protected]>
2026-01-27 12:23:26 +00:00
Felix Fietkau 33f29d2345 wifi: mt76: relicense to BSD-3-Clause-Clear
MediaTek has asked to switch from the ISC license to BSD-3-Clause-Clear,
in order to improve clarity and the legal integrity of the code.

The BSD-3-Clause license includes the "no endorsement" clause, which is
important for protecting the reputation of the original authors and
contributors by preventing unauthorized use of their names for endorsement
purposes.

This clause is absent in the BSD-2-Clause license, which is more permissive
but lacks this specific protection.

This change also cleans up the license of some Kconfig/Makefile files,
which were accidentally marked as GPL.

The GPL 2.0 remains in use on mt76x0, as well as two source files in mt7615
for which the license situation still needs to be clarified.

Signed-off-by: Felix Fietkau <[email protected]>
2025-10-13 11:11:19 +02:00
Felix Fietkau ddbe1f6eb2 wifi: mt76: abort scan/roc on hw restart
Avoid spurious channel changes and clean up allocated links

Signed-off-by: Felix Fietkau <[email protected]>
2025-09-12 13:51:36 +02:00
Felix Fietkau d70f62b8f1 wifi: mt76: fix vif link allocation
Reuse the vif deflink for link_id = 0 in order to avoid confusion with
vif->bss_conf, which also gets a link id of 0.

Link: https://patch.msgid.link/[email protected]
Signed-off-by: Felix Fietkau <[email protected]>
2025-07-07 18:03:48 +02:00
Feng JiangandFelix Fietkau b70a4a6195 wifi: mt76: scan: Fix 'mlink' dereferenced before IS_ERR_OR_NULL check
Reported-by: kernel test robot <[email protected]>
Reported-by: Dan Carpenter <[email protected]>
Closes: https://lore.kernel.org/r/[email protected]/
Fixes: 3ba20af886d1 ("wifi: mt76: scan: set vif offchannel link for scanning/roc")
Signed-off-by: Feng Jiang <[email protected]>
Link: https://patch.msgid.link/[email protected]
2025-05-21 14:30:01 +02:00
Felix Fietkau 2c068c9638 wifi: mt76: fix crash in mt76_switch_vif_chanctx
If the mode is CHANCTX_SWMODE_SWAP_CONTEXTS, the new chanctx is not
initialized yet.

Signed-off-by: Felix Fietkau <[email protected]>
2025-01-14 13:31:15 +01:00
Felix Fietkau 4d8d6e2e77 wifi: mt76: scan: set vif offchannel link for scanning/roc
The driver needs to know what vif link to use

Signed-off-by: Felix Fietkau <[email protected]>
2025-01-04 08:11:30 +01:00
Felix Fietkau f19cbcf834 wifi: mt76: add multi-radio remain_on_channel functions
This allows a driver using the generic channel context functions to
temporarily switch to another channel for off-channel rx/tx.

Signed-off-by: Felix Fietkau <[email protected]>
2024-10-27 08:52:59 +01:00
Felix Fietkau fc0ff17b53 wifi: mt76: add multi-radio support to scanning code
When scanning on a phy/vif combination that does not have an active link,
create a temporary link in order to ensure that we have a valid wcid.

Signed-off-by: Felix Fietkau <[email protected]>
2024-10-27 08:52:59 +01:00
Felix Fietkau d026be405c wifi: mt76: add chanctx functions for multi-channel phy support
This adds an implementation for the chanctx functions, which can be used
by multi-channel capable drivers. Preparation for adding MLO support.

Signed-off-by: Felix Fietkau <[email protected]>
2024-10-22 10:18:59 +02:00