Factory data and device trees can point several bands at a single MAC
address. Publishing it once per band hands the same address to userspace
repeatedly, which then assigns it to more than one BSS.
Signed-off-by: Felix Fietkau <[email protected]>
mt76 already runs its own beacon monitor. mt76_beacon_mon_check() walks
the affiliated links of an MLD, counts a miss per link, and holds off
while the phy is off channel. mt7996 feeds it via mt76_rx_beacon() but
never claims CONNECTION_MONITOR, so mac80211 arms its legacy monitor on
top.
That one knows a single interface rather than a set of links, and it
keeps counting while the radio is away serving another link, so it
reaches its seven beacon intervals and tears down an association that is
still carrying traffic on the other links.
Signed-off-by: Felix Fietkau <[email protected]>
roc_phy on the shared per-interface data names the phy of the one started last,
which may have ended or moved on to another interface since. Both users take it
at face value: an interface going away aborts whatever it names, and cancelling
one for an interface acts on it without asking whose it is.
Aborting a stranger's leaves the interface's own outstanding one behind, and its
work then runs once the interface is gone, tearing the link down through the
freed bss_conf:
Unable to handle kernel paging request at virtual address 000043c218ce0afd
Workqueue: phy0 mt76_roc_complete_work [mt76]
pc : mt76_connac_mcu_sta_basic_tlv+0xdc/0x260 [mt76_connac_lib]
Call trace:
mt76_connac_mcu_sta_basic_tlv
mt7996_mcu_add_sta
mt7996_vif_link_destroy
mt7996_vif_link_remove
mt76_put_vif_phy_link
mt76_roc_complete
mt76_roc_complete_work
Check the interface before acting on it in both places.
Signed-off-by: Felix Fietkau <[email protected]>
The firmware wants active links removed from the BSSINFO table as the interface
is destroyed, so a link stays registered from its first chanctx assignment until
the interface goes away, and adding one the driver already holds does nothing.
mac80211 hands a non-AP MLD a fresh address whenever it sets a link up, though,
so a link coming back after a failed attempt carries an address the hardware was
never told about, on a BSS that was never revisited: it authenticates from an
address nothing answers, every time, until the interface is torn down for good.
Program the address and the BSS again, the pair the initial add sets up, which
is for a station what mt7996_mcu_mld_link_oper() does for an AP.
Signed-off-by: Felix Fietkau <[email protected]>
Currently, the FILS discovery template is always fetched from the default
link of a virtual interface in both Multi-Link Operation (MLO) and
non-MLO cases. However, in the MLO case there is a need to fetch the FILS
discovery template from a specific link instead of the default link.
Hence, add support for fetching the FILS discovery template based on the
link ID from the corresponding link data.
Signed-off-by: Sriram R <[email protected]>
Co-developed-by: Raj Kumar Bhagat <[email protected]>
Signed-off-by: Raj Kumar Bhagat <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Johannes Berg <[email protected]>
In the final version of 802.11be-2024, Transition Delay and Padding
Delay subfield are for both EMLSR and EMLMR. Depending if the mode is
EMLSR or EMLMR, the interpretation of the encoded value might change.
Define all the constants and helpers to interpret delay subfields both
in EMLSR and EMLMR mode.
Signed-off-by: Pablo Martin-Gomez <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Johannes Berg <[email protected]>
Currently, the unsolicited probe response template is always fetched from
the default link of a virtual interface in both Multi-Link Operation (MLO)
and non-MLO cases. However, in the MLO case there is a need to fetch the
unsolicited probe response template from a specific link instead of the
default link.
Hence, add support for fetching the unsolicited probe response template
based on the link ID from the corresponding link data.
Signed-off-by: Sriram R <[email protected]>
Co-developed-by: Raj Kumar Bhagat <[email protected]>
Signed-off-by: Raj Kumar Bhagat <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Johannes Berg <[email protected]>
The action code actually serves to identify the type of action
frame, so it really isn't part of the per-type structure. Pull
it out and have it in the general action frame format.
In theory, whether or not the action code is present in this
way is up to each category, but all categories that are defined
right now all have that value.
While at it, and since this change requires changing all users,
remove the 'u' and make it an anonymous union in this case, so
that all code using this changes.
Change IEEE80211_MIN_ACTION_SIZE to take an argument which says
how much of the frame is needed, e.g. category, action_code or
the specific frame type that's defined in the union. Again this
also ensures that all code is updated.
In some cases, fix bugs where the SKB length was checked after
having accessed beyond the checked length, in particular in FTM
code, e.g. ieee80211_is_ftm().
Link: https://patch.msgid.link/20260226183607.67e71846b59e.I9a24328e3ffcaae179466a935f1c3345029f9961@changeid
Signed-off-by: Johannes Berg <[email protected]>
The last frame of a service period was always sent with MORE_DATA clear,
regardless of what mac80211 asked for and regardless of what is left in
the released TIDs. mac80211 sets @more_data when other TIDs still hold
buffered frames, and it expects the driver to set the bit itself when the
released TIDs hold more than the requested number of frames. Neither was
done, so a client that trusts MORE_DATA stops polling and its remaining
traffic sits in the queues until the next TIM or until the client leaves
powersave.
Pass the flag down to the last frame and add what is still queued for the
released TIDs.
Signed-off-by: Felix Fietkau <[email protected]>
One MT_WCID_DROP register word holds the drop bits of 32 stations, and the
read-modify-write that flips a single bit is not serialised against
anything. On MMIO devices mt76x02_sta_ps() runs it from the rx path while
mt76x02_tx_prepare_skb() runs it from the tx path, so an update for one
station can be lost, or an old value can be written back over it. A
station whose drop bit is restored that way has all of its traffic
discarded by the hardware until its next powersave transition.
Take mt76.lock around the update. USB devices can only reach this from
station setup, where register access may sleep and mt76.mutex already
serialises the only two callers.
Signed-off-by: Felix Fietkau <[email protected]>
Only frames that the driver has buffered in an ieee80211_txq are released
through mt76_release_buffered_frames() and end up on the PSD queue. Frames
that mac80211 buffered itself are handed back through the regular tx path
and go out on the access category queue of the frame. Clearing the drop
mask for MT_TXQ_PSD alone therefore misses them, and the hardware keeps
discarding PS-Poll and U-APSD responses for a station that is still marked
as sleeping. The client polls again on the next TIM and never receives
anything, so its traffic stalls until it leaves powersave.
Key off the tx info flags instead, the same way mt7603_tx_prepare_skb()
does. This covers both release paths and any other frame that mac80211
marks as exempt from powersave buffering.
Signed-off-by: Felix Fietkau <[email protected]>
The driver fails to register with error -22 (EINVAL) due to a cfg80211
validation failure in wiphy_verify_iface_combinations().
Commit 5ef0e8e2653b ("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 56271da29c52
("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: 5ef0e8e2653b ("wifi: mt76: mt7996: fix iface combination for different chipsets")
Signed-off-by: Jose Ignacio Tornos Martinez <[email protected]>
Tested-by: Alex Gavin <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Felix Fietkau <[email protected]>
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 <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Felix Fietkau <[email protected]>
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.
Signed-off-by: Felix Fietkau <[email protected]>
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: 377aa17d2aed ("wifi: mt76: mt7996: Add NPU offload support to MT7996 driver")
Signed-off-by: Felix Fietkau <[email protected]>
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 <[email protected]>
Signed-off-by: Felix Fietkau <[email protected]>
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: dedf2ec30fe4 ("wifi: mt76: fix queue assignment for deauth packets")
Signed-off-by: Peter Chiu <[email protected]>
Signed-off-by: Felix Fietkau <[email protected]>
Single-adie mt7986 binds its only phy to band 1. The eeprom parse
stores that phy's chainmask unshifted (chainshift is still 0 at that
point) but then sets chainshift to the mask width, so every consumer
that shifts by band_idx * chainshift disagrees with the storage:
mt7915_mcu_set_chan_info() sends rx_path 0 to the firmware with the
default mask, and mt7915_set_antenna() stores a band-shifted mask
inconsistent with the parse-time default.
Derive chainshift only from a band-0 main phy. In the single-phy
band-1 configuration the chains are numbered from 0 like a band-0 phy,
so with chainshift kept at 0 the stored mask, the set_antenna path, the
channel switch command and the RX chain report all agree on unshifted
masks. Drop the now-redundant empty-mask fallback in the RX path.
Dual-phy DBDC configurations parse the band-0 phy first and are
unaffected.
Fixes: 006b9d4ad5bf ("mt76: mt7915: introduce band_idx in mt7915_phy")
Signed-off-by: Felix Fietkau <[email protected]>
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 <[email protected]>
Signed-off-by: Felix Fietkau <[email protected]>
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 <[email protected]>
Signed-off-by: Felix Fietkau <[email protected]>
The per-station DRR config value packs the BSS group into bits 0-3;
the bit 4-5 AC priority and bit 6-7 WMM ID fields follow. The group
mask covered bits 0-5, overlapping the AC priority field, and the BWC
group value was written as a bare constant that ignored the station's
group. Narrow the group mask and derive the BWC group from it.
Signed-off-by: Felix Fietkau <[email protected]>
The EFUSE_ACCESS response carries a valid flag that was ignored, so
reading an unwritten efuse block copied garbage into the eeprom data.
Return -ENODATA for invalid blocks and leave the corresponding eeprom
range untouched (zero-initialised) when loading the full eeprom from
efuse.
Fixes: e57b7901469f ("mt76: add mac80211 driver for MT7915 PCIe-based chipsets")
Signed-off-by: Felix Fietkau <[email protected]>
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.
Signed-off-by: Felix Fietkau <[email protected]>
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.
Derive the chain mask from the RX path chainmask instead, shifted by
the band index of the phy owning the frame. On single-adie mt7986 the
main phy is bound to band 1 but its default chainmask is stored
without the band shift, unlike the mask set by mt7915_set_antenna();
fall back to the raw mask when the band group is empty to cover both
stored forms.
Fixes: e57b7901469f ("mt76: add mac80211 driver for MT7915 PCIe-based chipsets")
Signed-off-by: Felix Fietkau <[email protected]>
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: 83eafc9251d6 ("wifi: mt76: mt7996: add wed tx support")
Signed-off-by: Felix Fietkau <[email protected]>
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: f6c87411d15f ("wifi: mt76: mt7996: rework register mapping for mt7990")
Signed-off-by: Felix Fietkau <[email protected]>
STA_REC_UPDATE and BSS_INFO_UPDATE carry variable-size payloads,
including beacon templates that grow considerably with 11v MBSS and
MLD configurations, and firmware can legitimately take longer than 2
seconds to process them. Since a message timeout now triggers a full
device reset, a false timeout on these commands is punished harshly.
Keep the shorter timeout for the small fixed-size commands and move
STA_REC_UPDATE/BSS_INFO_UPDATE back to the 5 second default.
Fixes: beb01caa570c ("wifi: mt76: mt7996: decrease timeout for commonly issued MCU commands")
Signed-off-by: Felix Fietkau <[email protected]>
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: 3687854d3e7e ("wifi: mt76: mt7996: add locking for accessing mapped registers")
Signed-off-by: StanleyYP Wang <[email protected]>
Signed-off-by: Felix Fietkau <[email protected]>
seq_id from the WED RRO indication is a 12-bit field (0-4095), but only
values up to MT7996_RRO_MAX_SESSION map into wed_rro.addr_elem[], which
has MT7996_RRO_ADDR_ELEM_LEN (128) entries. A larger session id computes
an out-of-bounds element index that is then read and, on a signature
mismatch, written. Reject an out-of-range session id.
Fixes: a09d2f9d69af ("wifi: mt76: Convert mt76_wed_rro_ind to LE")
Signed-off-by: Felix Fietkau <[email protected]>
mt7915_coredump_build()/mt7996_coredump_build() wrote dump_mem->len
unconditionally, but the allocation only reserves room for the memory
dump header when coredump_memdump is enabled and memdump_buf_len is
non-zero. In the default configuration the allocation ends right after
the fixed header, so the write landed one struct past the buffer. Only
populate the memory-dump section when it was actually allocated.
Fixes: 4dbcb9125cc3 ("wifi: mt76: mt7915: enable coredump support")
Fixes: 878161d5d4a4 ("wifi: mt76: mt7996: enable coredump support")
Signed-off-by: Felix Fietkau <[email protected]>
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: f68d67623dec ("mt76: mt7915: add Wireless Ethernet Dispatch support")
Signed-off-by: Felix Fietkau <[email protected]>
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: 7b8e1ae886e4 ("mt76: mt7915: rework hardware/phy initialization")
Signed-off-by: Felix Fietkau <[email protected]>
mt7915_thermal_init() registered the thermal cooling device and its sysfs
link, then returned the hwmon registration error without undoing them.
The cooling device (not devm-managed) and the link then leaked, and its
callbacks referenced the freed phy. Unregister the cooling device before
returning the error.
Fixes: 0ae3ff568451 ("mt76: mt7915: fix hwmon temp sensor mem use-after-free")
Signed-off-by: Felix Fietkau <[email protected]>
Two unsolicited event handlers trusted firmware-provided lengths:
mt7996_mcu_rx_all_sta_info_event() looped over res->sta_num without
checking it against skb->len, reading the flex array out of bounds; and
mt7996_mcu_rx_log_message() could compute a negative or oversized length
from tlv->len and feed it to %.*s and the debugfs log path. Bound both
against the actual skb length.
Fixes: adde3eed4a75 ("wifi: mt76: mt7996: Add mcu commands for getting sta tx statistic")
Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
Signed-off-by: Felix Fietkau <[email protected]>
mt7915_eeprom_load_default() copied mt7915_eeprom_size() bytes from the
firmware blob after only checking that it was non-NULL. A truncated
default bin caused an out-of-bounds read past the firmware buffer into
the EEPROM image. Reject a blob smaller than the EEPROM size.
Fixes: beed8bea8d74 ("mt76: mt7915: add mt7916 calibrated data support")
Signed-off-by: Felix Fietkau <[email protected]>
mt7915_mcu_get_eeprom() copied a 16-byte block out of the firmware
response skb without checking that the response was long enough to hold
it. A short or malformed response could read past the end of the skb.
Reject a response shorter than the response header.
Fixes: 888208d1ccc4 ("wifi: mt76: mt7915: set correct background radar capability")
Signed-off-by: Felix Fietkau <[email protected]>
mt7996_mcu_get_eeprom() copied the event->eeprom payload out of the
firmware response skb without checking that the response actually held
the bytes being read. A short or malformed response could read past the
end of the skb. Reject a response shorter than the event header and bound
each copy to the payload present in the skb.
Fixes: 0da2e410705e ("wifi: mt76: mt7996: extend flexibility of mt7996_mcu_get_eeprom()")
Signed-off-by: Felix Fietkau <[email protected]>
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: cacdd67812c6 ("mt76: mt7915: add mt7915_mmio_probe() as a common probing function")
Signed-off-by: Felix Fietkau <[email protected]>
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: 1609b014aa29 ("wifi: mt76: mt7996: Overwrite unspecified link_id in mt7996_tx()")
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Felix Fietkau <[email protected]>
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: a9384b36a42a ("wifi: mt76: mt7996: rework set/get_tsf callabcks to support MLO")
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Felix Fietkau <[email protected]>
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/[email protected]
Signed-off-by: Felix Fietkau <[email protected]>
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/[email protected]
Signed-off-by: Felix Fietkau <[email protected]>
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/[email protected]
Signed-off-by: Felix Fietkau <[email protected]>
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/[email protected]
Signed-off-by: Felix Fietkau <[email protected]>
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/[email protected]
Signed-off-by: Felix Fietkau <[email protected]>
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: c948b5da6bbe ("wifi: mt76: mt7925: add Mediatek Wi-Fi7 driver for mt7925 chips")
Signed-off-by: shengwei.lu <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Felix Fietkau <[email protected]>
__mt7915_mcu_add_sta() issued the SET_DRR_CTRL command that assigns the
VoW BSS group before sending the STA_REC that instantiates the station
in the firmware, and dropped the STA_REC skb unsent if that command was
rejected. On mt7996 the same ordering made client mode association fail
once the command occupying that slot started to depend on the station
record already existing.
Signed-off-by: Felix Fietkau <[email protected]>