[PATCH] wifi: mt76: mt7615: skip MT_TXD5_TX_STATUS_HOST for MT7663 group frames
Facundo Karanik
facundo.karanik at gmail.com
Sun Aug 2 16:20:55 PDT 2026
Under the right circumstances, a broadcast or multicast packet can remain
stuck in the firmware/hardware queue. Following group packets then stop
completing and accumulate. On my system, this appeared as excessive airtime
queue limit (AQL) debt, which eventually stopped batman-adv traffic on that
interface.
For a packet to potentially get stuck it must have the
`MT_TXD5_TX_STATUS_HOST` bit set and remain pending while group traffic is
held for the next DTIM because a station is in power save. The queue stalls
when such a packet is present on the queue and the final station (still
treated by the firmware as power-saving) is removed, whether explicitly or
through normal teardown after the client disappears.
In summary, the packet must:
1. Be broadcast or multicast.
2. Be pending under group power-save/DTIM handling.
3. Have the `MT_TXD5_TX_STATUS_HOST` bit set.
4. Remain pending when the final power-saving station is removed.
The fix is to leave `MT_TXD5_TX_STATUS_HOST` clear for MT7663 group
frames. These frames normally use PID 0, the no-ACK packet identifier, and
(as far as I was able to find) the driver discards TX-status reports
carrying PID 0. The report therefore has no consumer or useful
per-recipient result. If a future path assigns another PID to a group
frame, `WARN_ON_ONCE()` records a stack trace while the status-request bit
remains clear.
My broader interpretation of this failure is that the firmware/hardware
does not expect a host TX report for packets that are not aimed at a single
station. The last power-saving client leaving might have been enough of an
edge case to surface this expectation as a bug. This is speculation, of
course.
After applying this patch, every single packet matching conditions 1, 2
and 4 cleared the queue without any issues. I also did A/B testing with all
conditions present. The stall occurred in 100% of tests without the patch
and 0% with the patch (which, of course, removes condition 3).
I let it run for about a week without either the stall coming up again or
any regressions showing up. The hardware used for testing is a TP-Link
Archer C6U v1 (MT7663E PCIe), running OpenWrt 24.10.3 and Linux 6.6.104. I
do not have any reason to believe this will break on newer kernel versions
or different hardware, although I was personally not able to test either.
This patch very likely solves the issue below, but it still needs to be
tested on that setup:
https://github.com/openwrt/mt76/issues/598#issuecomment-939419710
Assisted-by: Codex:gpt-5.6-sol
Signed-off-by: Facundo Karanik <facundo.karanik at gmail.com>
---
drivers/net/wireless/mediatek/mt76/mt7615/mac.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
index aad232c5a6fa..5c846f136961 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
@@ -823,8 +823,21 @@ int mt7615_mac_write_txwi(struct mt7615_dev *dev,
__le32 *txwi,
if (!ieee80211_is_beacon(fc)) {
struct ieee80211_hw *hw = mt76_hw(dev);
+ bool mt7663_group = is_mt7663(&dev->mt76) && multicast;
- val = MT_TXD5_TX_STATUS_HOST | FIELD_PREP(MT_TXD5_PID, pid);
+ val = FIELD_PREP(MT_TXD5_PID, pid);
+ if (mt7663_group) {
+ /* Host TX status has no useful per-recipient result
+ * for group frames. On MT7663, requesting it can
+ * stall group traffic when the final power-saving
+ * station disconnects. Force the request off, and
+ * warn if the no-ACK PID invariant is violated.
+ */
+ WARN_ON_ONCE(pid != MT_PACKET_ID_NO_ACK);
+ } else {
+ val |= MT_TXD5_TX_STATUS_HOST;
+ }
+
if (!ieee80211_hw_check(hw, SUPPORTS_PS))
val |= MT_TXD5_SW_POWER_MGMT;
txwi[5] = cpu_to_le32(val);
--
2.51.0
More information about the Linux-mediatek
mailing list