| Age | Commit message (Collapse) | Author |
|
Felix Fietkau says:
===================
mt76 patches for 7.4
- mt7625 NAN fixes
- mt7996 connection monitor fix
- offchannel/scan improvements
- MLO fixes
- other minor fixes
===================
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
|
Cross-merge networking fixes after downstream PR (net-7.3-rc7).
Conflicts:
include/net/strparser.h
0984ebc631792 ("strparser: make sure __strp_recv isn't running before tearing down the parser")
02fd0a2111374 ("net: strparser: removed the aborted bit and aborts counter")
https://lore.kernel.org/asYfmLsfy-SCxXjr@sirena.co.uk
Adjacent changes:
Documentation/networking/strparser.rst
5f193cdabf25 ("docs: networking: strparser: remove general mode")
0984ebc63179 ("strparser: make sure __strp_recv isn't running before tearing down the parser")
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
mt76_abort_scan() clears beacon_wait and then cancels the scan work. A
scan work that runs at that time can set beacon_wait again when it
moves to a NO_IR or radar channel. After the cancel, a beacon on that
channel makes mt76_scan_rx_beacon() queue the work again. The work then
runs without dev->mutex while mt76_scan_phy_complete() removes the scan
link, so mt76_scan_send_probe() can use the removed link. Reachable via
mac80211 cancel_hw_scan, chanctx changes, interface removal and the
mt7996 reset work.
Disable the scan works instead of cancelling them, so that no beacon
can queue them until the abort completes the scan. Enable them again
with dev->mutex held, so that a scan that mt76_hw_scan() starts after
the abort can always queue its work.
Fixes: 360552c8592d ("wifi: mt76: support upgrading passive scans to active")
Link: https://patch.msgid.link/20261007112419.1277594-9-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
mt76 runs the channels of one scan request on all radios in parallel.
Let mac80211 pass all bands in one request, so that a scan across the
2.4, 5 and 6 GHz radios takes as long as the slowest radio, not the sum
of all three.
Signed-off-by: John Crispin <john@phrozen.org>
Link: https://patch.msgid.link/20261007112419.1277594-8-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
A device with several radios on one wiphy has one scan state for the
whole device, and mt76_hw_scan() picks the radio from the band of the
first channel. A scan therefore covers one radio, and mac80211 visits
the bands one after another.
Run the scan on every radio that has a channel in the request, and let
each radio visit only its own channels. Report the scan as complete
once all radios are done, and as aborted if any of them aborted.
Build the probe request from the IEs of the band of the channel and the
common IEs, because a request can now hold the IEs of several bands.
A driver can now set SINGLE_SCAN_ON_ALL_BANDS to scan all of its radios
in parallel with one request.
Signed-off-by: John Crispin <john@phrozen.org>
Link: https://patch.msgid.link/20261007112419.1277594-7-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
mt7996_mac_write_txwi() and mt7996_tx_prepare_skb() take the own MAC,
WMM and band index of an offchannel frame from mvif->offchannel_link,
which holds one link per vif. mac80211 runs one scan or remain on
channel at a time, so a vif has at most one offchannel link today. A
scan that runs on several radios at the same time needs one offchannel
link per radio, and its frames would then be sent with the indexes of
whichever link was added last.
Each offchannel link has its own wcid, and offchannel frames are sent
on it, so take the link from the wcid of the frame. Drop
offchannel_link, which has no other user.
Link: https://patch.msgid.link/20261007112419.1277594-6-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
mt76_rx_convert() computes the signal for mac80211 from the chain
signals and overwrites the value of the signal field of struct
mt76_rx_status. Since mt792x_mac_rssi_iter() also uses the chain
signals, no code reads the field. mt7921_mac_fill_rx() is the last
driver that still sets it.
Remove the field and its computation in mt7921_mac_fill_rx().
Link: https://patch.msgid.link/20261007112419.1277594-5-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
mt792x_mac_rssi_iter() adds status->signal of auth and assoc response
frames to the BSS RSSI average, which mt7921_mcu_sta_update() and
mt7925_mcu_sta_update() send to the firmware as the station RCPI.
mt7925 never sets status->signal, since mt76_rx_convert() computes it
from the chain values later. The average is thus fed 0 dBm on mt7925.
Compute the signal from the chain values, as mt76_rx_convert() and
mt76_check_sta() do, and skip a frame without a valid chain signal. On
mt7921, the average now follows the combined value instead of the
strongest chain.
Fixes: c948b5da6bbe ("wifi: mt76: mt7925: add Mediatek Wi-Fi7 driver for mt7925 chips")
Link: https://patch.msgid.link/20261007112419.1277594-4-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
mt7921_regd_channel_update() and __mt7921_mcu_set_clc() never
release the nodes returned by mt76_find_power_limits_node(),
of_get_child_by_name() and mt76_find_channel_node(). Each regulatory
domain change and each CLC update on a device with DT power limits
leaks these references.
Release every node after use. This relies on
mt76_find_power_limits_node() also returning a reference for the
fallback node, which it does since commit 3a62c9f7ec3d ("wifi: mt76:
Fix of_node reference leak in mt76_get_rate_power_limits()").
Fixes: 09382d8f8641 ("wifi: mt76: mt7921: update the channel usage when the regd domain changed")
Link: https://patch.msgid.link/20261007112419.1277594-3-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
mt7996_mac_full_reset() and the L1 SER branch of mt7996_mac_reset_work()
abort a running scan and remain on channel. mt76_scan_complete() and
mt76_roc_complete() then skip ieee80211_scan_completed() and
ieee80211_remain_on_channel_expired() while MT76_MCU_RESET is set.
mac80211 clears a hardware scan only from the completion. After an L1
SER recovery, which does not restart the hardware, every later scan on
the wiphy is then refused, and a remain on channel stays pending until
userspace cancels it. After a full reset, ieee80211_restart_work()
warns:
WARN(test_bit(SCAN_HW_SCANNING, &local->scanning),
"%s called with hardware scan in progress\n", __func__);
Report an aborted scan to mac80211 in a reset as well, and an aborted
remain on channel unless a hardware restart follows. On a restart,
ieee80211_reconfig_roc() restarts a remain on channel that had not
begun and ends one that had. Since the scan is reported as aborted,
mac80211 does not continue it on the next band during the reset.
Fixes: b36d55610215 ("wifi: mt76: abort scan/roc on hw restart")
Link: https://patch.msgid.link/20261007112419.1277594-2-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
mt7996_mac_restart() clears MT76_MCU_RESET before it loads the firmware
again, and mac80211 adds the interfaces back only later, in
ieee80211_reconfig() after ieee80211_restart_hw(). A scan or remain on
channel that reaches mt76_hw_scan() or mt76_remain_on_channel() in
between, for example a request that waited for dev->mutex during the
reset, runs on a device that has no interfaces configured.
Mark a full reset with MT76_RESTART and refuse a scan or remain on
channel while it is set. Clear the flag in .start: ieee80211_reconfig()
adds the interfaces back before it releases the wiphy lock, so no
request runs in between. .reconfig_complete is not suitable, because
mac80211 skips it when no interface is open, and the flag would then
stay set.
Fixes: c56d6edebc1f ("wifi: mt76: mt7996: use emulated hardware scan support")
Fixes: 69d54ce7491d ("wifi: mt76: mt7996: switch to single multi-radio wiphy")
Link: https://patch.msgid.link/20261007112419.1277594-1-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
mt7996_unregister_device() leaves the RX NAPIs enabled, so
mt76_dma_cleanup() deletes enabled NAPIs and destroys page pools that
are still bound to them. On rmmod, the kernel warns in
__netif_napi_del_locked() for every RX queue and in
page_pool_disable_direct_recycling(). Until the IRQ tasklet is disabled,
an interrupt can still schedule a NAPI that was already deleted.
Disable every RX NAPI that was added before the MCU exit and the DMA
cleanup. This includes the host RRO queues: mt76_dma_init() skips them,
but mt7996_dma_rro_start() adds their NAPIs later when WED is not
active, so a check for mt76_queue_is_wed_rro() would miss them.
Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
Signed-off-by: John Crispin <john@phrozen.org>
Link: https://patch.msgid.link/20261006205936.669125-27-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
The hw-queues debugfs file builds its own queue requests, and these do
not match the register map of the MediaTek vendor driver:
- The port ID goes to bits 11:10 of the PLE queue control register, but
the field is at bits 17:16. Bits 11:10 are part of the WLAN index, so
each request reads port 0 and, for a station, the WLAN index with
bit 11 set.
- The head and tail frame IDs, the packet count and the page counters
are read as 12-bit fields, but they have 13 bits.
- The PSE queues are read from the PLE empty and queue control
registers, with bit positions that do not match the PSE queue map.
- The station queues of MT7992 and MT7990 with a WLAN index from 512 to
543 are read from register 16, but these chips keep that group in the
extension register at index 32.
- The file iterates the stations of the same ieee80211_hw once for each
band, so it shows each station queue up to three times.
- mt7996_hw_queue_read() takes the private data of the file as a
struct mt7996_phy, but it is a struct mt7996_dev. The dev member
of the phy then aliases mt76.phy.dev of the device, which points back
to the device, so the file works by chance.
A queue request also writes the queue control register 0 and then reads
the result from the queue control registers 2 and 3, without a lock.
When the global and a per-station hw-queues file are read at the same
time, one reader can get the result of the request of the other.
Describe the PLE and PSE queues in tables with the field layout of the
vendor register map, and send all queue requests through one helper,
which holds a spinlock from the write of the request to the read of its
result. A spinlock is needed because the station requests are sent from
ieee80211_iterate_stations_atomic(). Iterate the stations once.
Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
Link: https://patch.msgid.link/20261006205936.669125-26-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
The PLE register map in the MediaTek vendor driver places the free
page counter, the free page head and tail, and the HIF group page status
at 0x3a0, 0x3a4 and 0x3a8. The driver reads them at 0x380, 0x384 and
0x388, and the vendor map has the band 1 TXCMD queue empty status at
0x388. The same map has 0x100 bytes per AC for the station queue empty
bitmaps, with the MT7992 extension register at offset 0x80. The driver
uses 0x80, which cannot hold the 34 registers per AC of MT7996, so the
hw-queues file reads AC1 to AC3 of a station from the wrong register.
Use the offsets of the vendor register map.
Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
Link: https://patch.msgid.link/20261006205936.669125-25-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
When mt7996_mac_sta_change_links() removes a link from a station, it
keeps the msta_link and the firmware entry of the link. Commit
e077071e7ac4 ("wifi: mt76: mt7996: fix teardown command for an MLD
peer") removed the per-link DISCONNECT command for MLD peers, and a link
that comes back must not get a second STA_REC with EXTRA_INFO_NEW,
which commit 8e3e7567b8c1 ("mt76: mt7915: add sta_rec with
EXTRA_INFO_NEW for the first time only") says can remove the entry. A
link that comes back is therefore not connected again, and gets no rate
control, keys or authorization.
On removal, reset only the driver state of the link: its TWT flows, the
TX state and the key index. When the link comes back with its entry
still connected, send it the header translation state, rate control,
its keys and, for an authorized station, the CONN_STATE_PORT_SECURE
update without EXTRA_INFO_NEW, which also carries the header
translation state. Send the 4-address PS leave request and the block
ack sessions as for a new link, since the link can come back as a link
other than the primary link.
Fixes: e8c819df0243 ("wifi: mt76: mt7996: Destroy active sta links in mt7996_mac_sta_remove()")
Link: https://patch.msgid.link/20261006205936.669125-24-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
mt7996_ampdu_action() sends STA_REC_BA to the links that the station
has when mac80211 starts a session. A link that is brought up later
gets no STA_REC_BA, so it transmits without aggregation and, as a
recipient, is not set up for hardware reordering. mac80211 does not
start the sessions again when a link is added.
Send STA_REC_BA for each running TX and RX session on the links that
mt7996_mac_sta_change_links() brings up. For an RX session, use the
current head of the reorder window, which mt76_rx_aggr_start() keeps
on the default link, as the starting sequence number.
That head moves only when the host reorders: with hardware RRO, mt7996
marks the frames as already aggregated and mt7996_mac_fill_rx() skips
the host reorder state; with WED or the NPU active,
mt76_rx_poll_complete() does not call mt76_rx_aggr_reorder(). The
driver has no MCU query for the current window. In those modes, stop
the RX sessions with ieee80211_stop_rx_ba_session() instead, so that
the originator sets up new sessions, which then reach all links through
the regular IEEE80211_AMPDU_RX_START path.
Fixes: ef3f5941e560 ("wifi: mt76: mt7996: rework mt7996_ampdu_action to support MLO")
Link: https://patch.msgid.link/20261006205936.669125-23-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
mt7996_mac_sta_change_links() only sets up the driver state of a link
that is added to a station. The CONN_STATE_CONNECT and
CONN_STATE_PORT_SECURE STA_RECs and the rate control setup come from
mt7996_mac_sta_event(), which runs once per station state change, so a
link that becomes active after association has no firmware entry. This
is the normal case on a station interface: mac80211 activates only the
association link at first, and mt7996_sta_state() requests the other
links with ieee80211_set_active_links_async() when the station moves
to IEEE80211_STA_ASSOC. The STA_REC_MLD of the links already connected
also keeps the old set of links.
When links are added, replay the association on the links that are not
connected yet, install the keys of the station on them, and replay the
authorization if the station is authorized. mac80211 does not install
the pairwise key again, since ieee80211_key_switch_links() moves only
keys with key->link_id >= 0. Send the other links a STA_REC with only
STA_REC_MLD and STA_REC_EHT_MLD, so that their link list follows the
change. A 4-address link other than the primary link also gets the PS
leave request that mt7996_sta_set_4addr() sends on association.
If bringing up the added links fails, reset and remove them again
without flush, since the firmware can still hold an entry for their
WTBL index, and send the remaining links their STA_REC_MLD again.
While here, indent struct mt7996_key_iter_data with tabs.
Fixes: f520eceacd24 ("wifi: mt76: mt7996: Add mt7996_mac_sta_change_links callback")
Link: https://patch.msgid.link/20261006205936.669125-22-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
On association, a station link gets its BSS_INFO with the BSSID and
its broadcast STA_REC from BSS_CHANGED_BSSID before the peer STA_REC is
created, and mt7996_link_info_changed() notes that station mode maps
the peer entry through the BSSID. For a link that becomes active later,
_ieee80211_set_active_links() calls drv_change_sta_links() first and
reports BSS_CHANGED_BSSID for the link only afterwards.
Send the BSS_INFO and the broadcast STA_REC of an added station link
from mt7996_mac_sta_change_links() before its peer entry is set up when
the station is already associated, in the order of an association. The
later BSS_CHANGED_BSSID finds the BSSID recorded and does not add the
broadcast entry as new again.
This prepares for bringing up such links in the following change.
Link: https://patch.msgid.link/20261006205936.669125-21-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
mt7996_mcu_add_tx_ba() and mt7996_mcu_add_rx_ba() send STA_REC_BA to
the links that are active when mac80211 starts the session. To set up a
running session on a link that is added later, the driver needs the
parameters of that session, but it records a TX session only as a bit
in ampdu_state and keeps no RX session parameters.
Store the parameters of each running TX and RX session per TID, and
pass the set of links to update to mt7996_mcu_add_tx_ba() and
mt7996_mcu_add_rx_ba(). mt7996_ampdu_action() passes the links from
mt7996_mac_sta_links(), which are the links that have driver state.
No functional change on its own.
Link: https://patch.msgid.link/20261006205936.669125-20-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
mt7996_sta_state() turns the station state transitions into STA_REC
updates for the links of the station, but the driver keeps no record of
the state that the station reached. A link that is added after
association needs that state to be brought up to the same level as the
other links.
Record the connection state after each station event, and lower it to
CONN_STATE_CONNECT when the station leaves IEEE80211_STA_AUTHORIZED,
for example when hostapd de-authorizes it for a re-authentication.
No functional change on its own.
Link: https://patch.msgid.link/20261006205936.669125-19-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
Since the driver uses the .sta_state op, mt7996_mac_sta_init_link()
sends a STA_REC with CONN_STATE_DISCONNECT when a station link is set
up. Before that change, the first STA_REC for a station was the one
that connects it. MediaTek reports that DL OFDMA fails after a station
reconnects.
Only send a STA_REC for a station link when it connects. Until then the
firmware has no STA_REC for the link, so track whether a link is
connected, and skip rate control updates and the 4-address and decap
updates for a link that is not. wcid.sta cannot be used for this,
since it is set when the link is set up.
Fixes: 13e2e9c6b348 ("wifi: mt76: mt7996: use mac80211 .sta_state op")
Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
Link: https://patch.msgid.link/20261006205936.669125-18-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
mac80211 reports 4-address mode and decap offload once per station,
through sta_set_4addr and sta_set_decap_offload. mt7996_sta_set_4addr()
and mt7996_sta_set_decap_offload() set MT_WCID_FLAG_4ADDR and
MT_WCID_FLAG_HDR_TRANS only on the links that exist at that moment, but
the hardware keeps header translation per link. A link that is added
later starts without the flags, and a link that is removed at that time
keeps its old flags when it comes back, so the firmware gets the wrong
to_ds/from_ds pair for that link.
Keep both states in the station, and apply them to a link when the
callbacks run, when the link is set up and when it comes back.
Fixes: f520eceacd24 ("wifi: mt76: mt7996: Add mt7996_mac_sta_change_links callback")
Fixes: e8c819df0243 ("wifi: mt76: mt7996: Destroy active sta links in mt7996_mac_sta_remove()")
Link: https://patch.msgid.link/20261006205936.669125-17-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
A station link sends its broadcast STA_REC with EXTRA_INFO_NEW on every
BSS_CHANGED_BSSID. Commit 8e3e7567b8c1 ("mt76: mt7915: add sta_rec with
EXTRA_INFO_NEW for the first time only") notes that the firmware may
remove an entry that is added as new twice. Since a removed vif link
keeps its firmware entry, this happens on a link that is deactivated and
activated again: _ieee80211_set_active_links() reports
BSS_CHANGED_BSSID with the same BSSID, after ieee80211_key_switch_links()
has installed the group keys of the link, and nothing in the driver
installs them again after the entry is added as new.
Record the BSSID the entry was added with, and add it as new only for
a different BSSID. A BSSID that goes to zero on disconnection clears
the record, so that the next association adds the entry as new again.
A link that is set up clears the record as well, since the firmware has
no entry for it then.
Fixes: 08813703ac41 ("wifi: mt76: mt7996: Destroy vif active links in mt7996_remove_interface()")
Link: https://patch.msgid.link/20261006205936.669125-16-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
mt7996_mac_sta_add_links() removes all links that it was asked to add,
with flush set, when one of them fails. A link that comes back after
a removal kept its msta_link and may still have a firmware entry. The
flush frees its msta_link and returns its WTBL index to wcid_mask, so a
later station can be given an index whose entry still belongs to this
station.
Flush only the links that this call created, and remove a returning
link again without flush.
Fixes: e8c819df0243 ("wifi: mt76: mt7996: Destroy active sta links in mt7996_mac_sta_remove()")
Link: https://patch.msgid.link/20261006205936.669125-15-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
mt7996_mac_sta_init_link() puts a new link in msta->deflink whenever
the station has no primary link. A removed link keeps its msta_link
until the station is removed, and the station has no primary link
after one mt7996_mac_sta_change_links() call removes all of its links
and adds others. If the removed
primary link was in msta->deflink, the new link then overwrites it:
both link slots point to the same msta_link, and the WTBL index of the
removed link is lost, so mt7996_mac_sta_remove() never returns it to
wcid_mask.
Use msta->deflink only if no link slot of the station points to it,
and allocate the msta_link otherwise. Choose the primary link as
before.
Fixes: e8c819df0243 ("wifi: mt76: mt7996: Destroy active sta links in mt7996_mac_sta_remove()")
Link: https://patch.msgid.link/20261006205936.669125-14-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
mt7996_mac_sta_remove_link() clears deflink_id when it removes the
primary link and no secondary link is left to take its place. If the
removed link then comes back, mt7996_mac_sta_add_links() finds its
existing msta_link and only marks it valid again. deflink_id stays
IEEE80211_LINK_UNSPECIFIED, so the station has no primary link: the TXQs
keep the WLAN index that they had before, seclink_id stays unspecified,
mt7996_sta_rate_ctrl_update() finds no primary link, and
mt7996_sta_set_4addr() treats every link as a secondary link.
Make a returning link the primary link when the station has none, in
the same way as mt7996_mac_sta_init_link() does for a new link. Move the
two steps that set the primary link, and the switch to the secondary
link on removal, to helpers.
Fixes: e8c819df0243 ("wifi: mt76: mt7996: Destroy active sta links in mt7996_mac_sta_remove()")
Link: https://patch.msgid.link/20261006205936.669125-13-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
mt7996_mac_sta_init_link() takes the secondary link from
sta->valid_links. On a station interface mac80211 creates driver state
only for active links, since drv_change_sta_links() masks both link
sets with vif->active_links. With three valid links of which links 0
and 2 are active, seclink_id then points at link 1, which has no
mt7996_sta_link. mt7996_tx_prepare_skb() maps odd TIDs to seclink_id,
keeps the primary wcid for them and passes the inactive link id to
mt7996_mac_write_txwi(), which finds no vif link and falls back to OMAC
and WMM index 0.
Choose the secondary link among the links that have driver state and
are valid, and choose it again whenever such a link is added, restored
or removed. A removed secondary link now hands over to another
remaining link instead of the primary one, and a secondary link that
was promoted to primary gets a successor.
Fixes: 85cd5534a3f2 ("wifi: mt76: mt7996: use correct link_id when filling TXD and TXP")
Link: https://patch.msgid.link/20261006205936.669125-12-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
mt7996_mac_sta_init_link() takes a WTBL index from wcid_mask before it
allocates the msta_link of a link other than the first one. If that
allocation fails, the function returns -ENOMEM and the index stays set
in wcid_mask, so no later station can use it.
Return the index to wcid_mask on that error.
Fixes: dd82a9e02c05 ("wifi: mt76: mt7996: Rely on mt7996_sta_link in sta_add/sta_remove callbacks")
Link: https://patch.msgid.link/20261006205936.669125-11-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
mt76_sta_pre_rcu_remove() clears the wcid table entry of msta->deflink
only. mac80211 calls it before the synchronize_net() that ends the RCU
readers of the station, and frees the station right after
mt7996_mac_sta_remove(). For an MLD station, the wcid table entries of
the other links stay set until mt7996_mac_sta_remove(), after that
grace period. An RX or TX status reader that looks up one of these
entries in that window can follow msta_link->sta or def_wcid into the
freed station.
Clear the wcid table entries of all links of the station in
.sta_pre_rcu_remove.
Fixes: dd82a9e02c05 ("wifi: mt76: mt7996: Rely on mt7996_sta_link in sta_add/sta_remove callbacks")
Link: https://patch.msgid.link/20261006205936.669125-10-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
mt7996_sta_statistics() and mt7996_ethtool_worker() read the TX rate,
the TX counters and the ACK signal from msta->deflink. That is the
msta_link of the first link of the station, not of its primary link.
When the first link of an MLD station is removed, msta->deflink keeps
the values of the removed link, and the station reports them until it
is removed.
Read them from the link that deflink_id selects.
msta->deflink also holds the RX reorder state, the TX aggregation
state and the def_wcid target of all links. These are state of the
whole station, and wcid_to_sta() needs def_wcid at the start of
drv_priv, so they stay there.
Fixes: f520eceacd24 ("wifi: mt76: mt7996: Add mt7996_mac_sta_change_links callback")
Link: https://patch.msgid.link/20261006205936.669125-9-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
Since commit eddc7286f6bb ("wifi: mt76: mt7996: fix key add/remove
imbalance"), mt7996_vif_link_destroy() walks the vif keys with SET_KEY.
Before that commit the walk used DISABLE_KEY. The commit message says a
key for a link is added and removed only once, but a SET_KEY walk on
destroy uploads the keys again, and for a BIGTK with beaconing enabled
it also removes and adds the beacon of the link being destroyed.
Remove the walk. mac80211 removes the keys itself with set_key() calls,
which is the one removal that commit describes.
The walk currently finds no keys: mt7996_vif_link_destroy() runs for a
non-offchannel link only from mt7996_remove_interface(), and
ieee80211_do_stop() frees the keys of the interface before
drv_remove_interface(). An interface type change goes through the same
path, since mt7996 has no .change_interface. Found by inspection.
Link: https://patch.msgid.link/20261006205936.669125-8-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
mt7996_vif_link_add() and mt7996_vif_link_destroy() walk the vif keys
through mt7996_key_iter(), which passes every group key to
mt7996_set_hw_key() for the link being set up. On an MLD interface each
group key belongs to one link, as key->link_id says, so a new link gets
the GTK and BIGTK of the other links written to its group WTBL entry,
and its hw_key_idx set to their key index.
Skip keys that belong to a different link, as mt7996_set_key() already
does for keys that mac80211 installs.
Fixes: eddc7286f6bb ("wifi: mt76: mt7996: fix key add/remove imbalance")
Link: https://patch.msgid.link/20261006205936.669125-7-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
On disassociation, mt7996_mac_sta_event() sends STA_REC_MLD_OFF when
the link it handles is the last of sta->valid_links, but it handles
only active links with driver state. On a station interface with one
active link out of two valid links, no link is ever the last one, so
the firmware never gets STA_REC_MLD_OFF for the MLD.
Walk the same set of links that mt7996_mcu_sta_mld_setup_tlv()
describes, and detect the last link within that set. The per-link
event handling moves into a helper that takes the set of links, so
that a later change can bring up links that became active after
association.
Fixes: c1d6dd5d03eb ("wifi: mt76: mt7996: Add mt7996_mcu_teardown_mld_sta rouine")
Link: https://patch.msgid.link/20261006205936.669125-6-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
mt7996_mcu_sta_mld_setup_tlv() sets link_num and the TLV length from
hweight16(sta->valid_links), but fills an entry only for active links
that have driver state. On a station interface mac80211 activates only
the association link at first, and drv_change_sta_links() masks the
other links with vif->active_links, so the driver has no state for
them. A station with valid_links 0x3 and active_links 0x2 thus sends
STA_REC_MLD with link_num 2 and a second entry of zeroes, at
association and again at authorization. The zeroed entry names WTBL
index 0 and BSS index 0 as a link of the MLD.
Count the links with driver state first and describe exactly those,
with the secondary id taken from them. A link removed without flush
keeps its mt7996_sta_link but is no longer valid, so leave it out as
well.
Fixes: 00cef41d9d8f ("wifi: mt76: mt7996: Add mt7996_mcu_sta_mld_setup_tlv() and mt7996_mcu_sta_eht_mld_tlv()")
Link: https://patch.msgid.link/20261006205936.669125-5-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
mt7996_vif_link_remove() only stops an AP link and keeps its BSS, so a
link that is added again takes the early branch of mt7996_vif_link_add().
For other interface types that branch sends DEV_INFO with the new link
address. For an AP it only restarts the link, and the firmware keeps
the own MAC address the link had when it was first created.
The hardware takes A2 of an encapsulation offload frame from that
address. A reload that gives an AP MLD link a new address therefore
makes every data frame on that link carry the old address as TA. The
receiver acknowledges the frame by its RA but cannot find a key for the
TA and drops it, so the AP counts no failure. The BSS_INFO update on
BSS_CHANGED_BEACON_ENABLED restores the BSSID, but nothing sends
DEV_INFO again.
Send DEV_INFO for an AP link as well, before the link is restarted.
Fixes: 08813703ac41 ("wifi: mt76: mt7996: Destroy vif active links in mt7996_remove_interface()")
Link: https://patch.msgid.link/20261006205936.669125-4-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
mt7996_add_interface() skips a radio that has MT76_STATE_RUNNING set,
and the skip covers both the start of the radio and the call to
mt7996_set_monitor(). mt7996_init_wiphy_band() sets
MT_WF_RFCR_DROP_OTHER_UC in phy->rxfilter on every band, and
mt7996_configure_filter() does not clear it, so only
mt7996_set_monitor() does. A monitor interface that is added while an
AP runs on the same radio thus receives no unicast frame addressed to
another device.
Start only an idle radio, but put every radio of a monitor interface
into sniffer mode. mt7996_remove_interface() already clears sniffer
mode whether the radio runs or not.
Fixes: 69d54ce7491d ("wifi: mt76: mt7996: switch to single multi-radio wiphy")
Link: https://patch.msgid.link/20261006205936.669125-3-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
mt7996_mcu_set_txpower_sku() uploads the per-rate power limit table, but
the firmware applies it only after the driver enables the SKU power
limit. mt7915 does that in mt7915_mcu_set_sku_en(); mt7996 never does,
so the radio keeps the EEPROM target power and the configured tx power
has no effect.
Add the power control command and enable the table per band in
mt7996_run(), as the MediaTek vendor driver does.
The backoff table stays disabled. This driver does not build the
per-path limits; it pads that part of the message with zeros.
Fixes: f75e4779d215 ("wifi: mt76: mt7996: add txpower setting support")
Link: https://patch.msgid.link/20261006205936.669125-2-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
mt76_assign_vif_chanctx() and mt76_unassign_vif_chanctx() abort the
scan whenever the scanning vif gains or loses a link, on any radio. An
AP MLD that scans on one radio for ACS while its link on another radio
comes up therefore loses the whole scan, and hostapd gets an aborted
scan. mac80211 does not continue an aborted scan with the next band.
The scan uses the link of the vif that mt76_get_vif_phy_link() returns
for the scanning radio, so it needs to stop only for a channel context
on that radio: the new link would duplicate the offchannel link, or the
removed link is the one the scan uses. Abort only in that case, as
mt76_add_chanctx() does.
Fixes: e411b8190fe7 ("wifi: mt76: add multi-radio support to scanning code")
Link: https://patch.msgid.link/20261006205936.669125-1-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
MT7928 supports caching calibration (fact-cal) data in a
host-side DMA buffer over AXI DMA, so the firmware can reuse previously
computed calibration results across warm resets instead of recomputing
them on every bring-up.
Add a new cached_cal source file under mt7925/, built into mt7925e
since the cache is reachable only over PCIe AXI DMA, that:
- allocates a coherent DMA region laid out for the common/group/channel
fact-cal buffers plus the mapping table,
- programs the firmware with the region base/offset via the new
MCU_UNI_CMD_AXIDMA command,
- builds and streams the fact-cal mapping table to the firmware via the
new MCU_UNI_CMD_FACT_CAL command.
On MT7928 run-firmware, the cache is enabled only when the chip
advertises MT792x_CHIP_CAP_AXIDMA_EN. A carried-over buffer that still
holds FW-written cal data is reused (reused=true); a freshly allocated
zeroed buffer starts cold. The region is freed on device unregister.
The buf_info and mapping-table layouts are size-asserted to match the
MT7928 firmware ABI.
Signed-off-by: Allan Wang <allan.wang@mediatek.com>
Link: https://patch.msgid.link/20260811094538.588332-1-allan.wang@mediatek.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
Move MT76_REMOVED flag setting from mt7925_pci_remove() to after
mt76_unregister_device() completes. Setting it too early causes
mt792x_irq_handler() to drop MCU completion interrupts, timing out
teardown commands (scan abort, BSS_INFO_UPDATE, etc).
The flag must still be set before napi_disable() to prevent reset_work
from re-enabling NAPI and causing deadlock. Also guard mt792x_reset()
to skip queuing work when device is removed.
With nothing associated it still costs 9 to 10 seconds, so a bare rmmod
does reach this, just small enough there to read as normal teardown.
Fixes: eb628006a2c6 ("wifi: mt76: mt7925: Fix unregister deadlock")
Tested-by: Devin Wittmayer <lucid_duck@justthetip.ca>
Signed-off-by: Eason Lai <eason.lai@mediatek.com>
Link: https://patch.msgid.link/20260817052840.99478-1-eason.lai@mediatek.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
MT7902 does not have an MCU_WA ring and sets wm2_complete_mask to 0.
However, commit 83c65e82e5b2 ("wifi: mt76: connac2: apply new rx
all_complete_mask") populated all_complete_mask in the shared irq_map
template with MT_INT_RX_DONE_ALL, which includes MT_INT_RX_DONE_WM2.
Because MT7902 duplicates irq_map but only clears wm2_complete_mask,
its all_complete_mask still contains MT_INT_RX_DONE_WM2. This leaves
the MT7902 RX interrupt configuration inconsistent: the aggregate RX
completion mask includes WM2 even though the corresponding RX queue is
not present on MT7902.
Clear MT_INT_RX_DONE_WM2 from all_complete_mask for MT7902 as well.
Fixes: 83c65e82e5b2 ("wifi: mt76: connac2: apply new rx all_complete_mask")
Signed-off-by: Mahesh Saran <maheshsaran477@gmail.com>
Link: https://patch.msgid.link/20261006163553.11193-1-maheshsaran477@gmail.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
mt76_check_sta() adds status->signal of every received frame to the
station's RSSI average, wcid->rssi, which mt76_get_min_avg_rssi() reads
for the dynamic sensitivity of mt7603 and mt7615 and for the gain
control of mt76x0 and mt76x2.
Since commit 4550fb9e9810 ("mt76: improve signal strength reporting"),
drivers no longer set status->signal: mt76_rx_convert() computes it from
the chain values when the frame is handed to mac80211, after
mt76_check_sta() has run. Except on mt7921, which still sets it, the
average is fed zeros. mt76_get_min_avg_rssi() then returns 0, so mt7603
and mt7615 leave the sensitivity at its default, and mt76x0 and mt76x2
fall back to -75 dBm for their gain settings.
Compute the signal from the chain values in mt76_check_sta() as well,
as mt76_rx_convert() does. On mt7921, the average now follows the same
combined value that mac80211 gets instead of the strongest chain.
Tested on a TP-Link Archer XR500v with one client, switching between
the old and the new input every 30 seconds. On the MT7662E (mt76x2),
the average the AGC works with was -75 dBm, its fallback, with the old
input and -54 dBm with the new one, while iw reported -54 and -52 dBm
for the station, and the AGC mostly used its low_gain 2 setting instead
of 1. On the MT7603E, the station average was 0 with the old input and
-41 dBm with the new one, while iw reported -42 and -41 dBm. The mt7603
sensitivity still stayed at its default: a separate bug keeps it from
leaving 0.
Fixes: 4550fb9e9810 ("mt76: improve signal strength reporting")
Assisted-by: LLM
Signed-off-by: Cristian Papa <pcristian292@gmail.com>
Link: https://patch.msgid.link/20260924032639.28158-1-pcristian292@gmail.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
mt7925_irq_map sets wm2_complete_mask, but mt7925_dma_layout has no
tx done ring, so the MT_RXQ_MCU_WA queue and its NAPI are never set up.
On a chip reset, mt7925e_mac_reset() calls napi_disable() on that NAPI
and crashes:
BUG: kernel NULL pointer dereference, address: 0000000000000a40
Workqueue: mt76 mt7925_mac_reset_work [mt7925_common]
RIP: 0010:mutex_lock+0x1c/0x50
Call Trace:
napi_disable+0x1d/0x50
mt7925e_mac_reset+0x327/0x420 [mt7925e]
mt7925_mac_reset_work+0x9a/0x1a0 [mt7925_common]
Remove the WM2 mask from mt7925_irq_map and from
MT7925_INT_RX_DONE_ALL.
Fixes: c4edf9e3e0e5 ("wifi: mt76: mt7925: replace shared rx irq masks with per-chip definitions")
Signed-off-by: ck.chang <ck.chang@mediatek.com>
Link: https://patch.msgid.link/20260805092409.1489401-1-eason.lai@mediatek.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
pci_get_device() increments the reference count on the returned
struct pci_dev. In mt7996_pci_init_hif2(), three pci_get_device()
calls are made but their return values are only checked for NULL
and then discarded. pci_dev_put() is never called, causing a PCI
device reference count leak.
Fix this by storing the return value and calling pci_dev_put()
before returning, following the same pattern already used in the
sibling driver mt7915/pci.c.
Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
Cc: stable@vger.kernel.org
Signed-off-by: Linlin Yang <yanglinlin@kylinos.cn>
Link: https://patch.msgid.link/20260824092937.683240-1-yanglinlin@kylinos.cn
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
Returning a negative errno as u8 turned -ENOENT into 0xfe, wrongly
enabling CNM and NAN caps. Return int and default to no caps on error.
Fixes: e8a264ccd2de ("wifi: mt76: mt7921: move init shared code in mt792x-lib module")
Cc: stable@vger.kernel.org
Signed-off-by: Yi Cong <yicong@kylinos.cn>
Link: https://patch.msgid.link/20260824021429.43761-1-cong.yi@linux.dev
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
Pending frames can be retried after their station is no longer
available. Require a station for both MLO-specific branches and retain
the existing non-station transmission path for valid vif traffic.
Detected by static analysis and reviewed with AI-assisted source auditing.
Fixes: 7ef0c7ad735b ("wifi: mt76: mt7996: Implement MLD address translation for EAPOL")
Fixes: 85cd5534a3f2 ("wifi: mt76: mt7996: use correct link_id when filling TXD and TXP")
Assisted-by: LLM
Signed-off-by: Slavin Liu <bolin.liu@seu.edu.cn>
Link: https://patch.msgid.link/20260911060922.94383-1-bolin.liu@seu.edu.cn
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
Enable the firmware thermal protection for MT7920/MT7921/MT7922 by
sending the DowngradeTxStreamTemp chip config command each time the
firmware starts, so that the setting also applies after a chip reset.
Signed-off-by: Allen Chien <yung-lun.chien@mediatek.com>
Link: https://patch.msgid.link/20260930033630.1020235-1-jb.tsai@mediatek.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
mt76_connac_mcu_chip_config() can only send the "assert" command, so
mt76_connac_mcu_set_deep_sleep() builds the same CHIP_CONFIG request by
itself. A further command for mt7921 would add a third copy.
Make the command a parameter and send the deep sleep command through
it, like mt7925_mcu_chip_config() does for mt7925.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
mt7615_mcu_parse_response() reads the common response header before
checking its size and then consumes command-specific fields after unchecked
skb_pull() calls. A short firmware response can therefore be read beyond
its current extent.
Validate the common header and each command-specific payload before reading
it.
Fixes: 0e6a29e477f3 ("mt76: mt7615: add support to read temperature from mcu")
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Link: https://patch.msgid.link/20260830131049.2097-1-pengpeng@iscas.ac.cn
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
mt76_find_power_limits_node() and mt76_find_channel_node() return nodes
with the reference held, but mt76_get_rate_power_limits() overwrites the
"txpower-<band>" node reference and never releases the channel node
reference, leaking both.
Drop the intermediate and the channel node reference on every exit path,
and take a reference on the fallback node returned by
mt76_find_power_limits_node() so the caller's of_node_put() is balanced.
Fixes: 22b980badc0f ("mt76: add functions for parsing rate power limits from DT")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Link: https://patch.msgid.link/20260917121944.2150737-1-vulab@iscas.ac.cn
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|