[PATCH] wifi: mt76: mt7615: skip MT_TXD5_TX_STATUS_HOST for MT7663 group frames
Facundo Karanik <[email protected]> Sun, 2 Aug 2026 16:20:55 -0700
| Newsgroups | org.infradead.lists.linux-mediatek,org.kernel.vger.linux-wireless |
|---|---|
| Message-ID | <CAHNRTq83iAAFyYNB5D0eg3HJggJNq3xjO8Z1zi9=+yGe4uy_Lw@mail.gmail.com> |
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 <[email protected]> --- 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