* [PATCH mt76-next 1/3] wifi: mt76: honour the more-data flag when releasing buffered frames
@ 2026-10-23 11:13 Felix Fietkau
2026-10-23 11:13 ` [PATCH mt76-next 2/3] wifi: mt76: mt76x02: serialise wcid drop mask updates Felix Fietkau
2026-10-23 11:13 ` [PATCH mt76-next 3/3] wifi: mt76: mt76x02: clear the wcid drop mask for all powersave responses Felix Fietkau
0 siblings, 2 replies; 3+ messages in thread
From: Felix Fietkau @ 2026-10-23 11:13 UTC (permalink / raw)
To: linux-wireless
mt76_release_buffered_frames() always clears the more-data bit on the
last released frame, so the client stops polling while frames are still
buffered for it. The .release_buffered_frames documentation in
include/net/mac80211.h requires the bit if @more_data is set or if the
released TIDs still hold frames.
Set the bit in both cases.
Fixes: 17f1de56df05 ("mt76: add common code shared between multiple chipsets")
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
drivers/net/wireless/mediatek/mt76/tx.c | 29 +++++++++++++++++++++----
1 file changed, 25 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
index b022d3843473..ea9993e9a199 100644
--- a/drivers/net/wireless/mediatek/mt76/tx.c
+++ b/drivers/net/wireless/mediatek/mt76/tx.c
@@ -420,7 +420,7 @@ mt76_txq_dequeue(struct mt76_phy *phy, struct mt76_txq *mtxq)
static void
mt76_queue_ps_skb(struct mt76_phy *phy, struct ieee80211_sta *sta,
- struct sk_buff *skb, bool last,
+ struct sk_buff *skb, bool last, bool more_data,
enum ieee80211_frame_release_type reason)
{
struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
@@ -437,10 +437,29 @@ mt76_queue_ps_skb(struct mt76_phy *phy, struct ieee80211_sta *sta,
*ieee80211_get_qos_ctl(hdr) |= IEEE80211_QOS_CTL_EOSP;
}
- mt76_skb_set_moredata(skb, !last);
+ mt76_skb_set_moredata(skb, !last || more_data);
__mt76_tx_queue_skb(phy, MT_TXQ_PSD, skb, wcid, sta, NULL);
}
+static bool
+mt76_ps_tids_pending(struct ieee80211_sta *sta, u16 tids)
+{
+ int i;
+
+ for (i = 0; tids; i++, tids >>= 1) {
+ unsigned long frames, bytes;
+
+ if (!(tids & 1) || !sta->txq[i])
+ continue;
+
+ ieee80211_txq_get_depth(sta->txq[i], &frames, &bytes);
+ if (frames)
+ return true;
+ }
+
+ return false;
+}
+
void
mt76_release_buffered_frames(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
u16 tids, int nframes,
@@ -451,6 +470,7 @@ mt76_release_buffered_frames(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
struct mt76_dev *dev = phy->dev;
struct sk_buff *last_skb = NULL;
struct mt76_queue *hwq = phy->q_tx[MT_TXQ_PSD];
+ u16 release_tids = tids;
int i;
spin_lock_bh(&hwq->lock);
@@ -470,14 +490,15 @@ mt76_release_buffered_frames(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
nframes--;
if (last_skb)
mt76_queue_ps_skb(phy, sta, last_skb, false,
- reason);
+ false, reason);
last_skb = skb;
} while (nframes);
}
if (last_skb) {
- mt76_queue_ps_skb(phy, sta, last_skb, true, reason);
+ more_data |= mt76_ps_tids_pending(sta, release_tids);
+ mt76_queue_ps_skb(phy, sta, last_skb, true, more_data, reason);
dev->queue_ops->kick(dev, hwq);
} else {
ieee80211_sta_eosp(sta);
--
2.47.3
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH mt76-next 2/3] wifi: mt76: mt76x02: serialise wcid drop mask updates
2026-10-23 11:13 [PATCH mt76-next 1/3] wifi: mt76: honour the more-data flag when releasing buffered frames Felix Fietkau
@ 2026-10-23 11:13 ` Felix Fietkau
2026-10-23 11:13 ` [PATCH mt76-next 3/3] wifi: mt76: mt76x02: clear the wcid drop mask for all powersave responses Felix Fietkau
1 sibling, 0 replies; 3+ messages in thread
From: Felix Fietkau @ 2026-10-23 11:13 UTC (permalink / raw)
To: linux-wireless
mt76x02_mac_wcid_set_drop() changes one bit of an MT_WCID_DROP word,
which holds the drop bits of 32 stations, with an unlocked
read-modify-write. On MMIO devices it runs from the rx and tx paths,
concurrently with station add and remove in process context. One update
can thus overwrite another, and the hardware then discards all traffic
of a station until its next powersave transition.
Take mt76.lock around the update on MMIO devices. On USB devices, only
station add and remove reach it. Register access there can sleep, and
mt76.mutex already serialises both.
Fixes: 7bc04215a66b ("mt76: add driver code for MT76x2e")
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
drivers/net/wireless/mediatek/mt76/mt76x02_mac.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index 158aa356b710..457767bbd8b6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -166,7 +166,8 @@ void mt76x02_mac_wcid_setup(struct mt76x02_dev *dev, u8 idx,
}
EXPORT_SYMBOL_GPL(mt76x02_mac_wcid_setup);
-void mt76x02_mac_wcid_set_drop(struct mt76x02_dev *dev, u8 idx, bool drop)
+static void
+__mt76x02_mac_wcid_set_drop(struct mt76x02_dev *dev, u8 idx, bool drop)
{
u32 val = mt76_rr(dev, MT_WCID_DROP(idx));
u32 bit = MT_WCID_DROP_MASK(idx);
@@ -176,6 +177,19 @@ void mt76x02_mac_wcid_set_drop(struct mt76x02_dev *dev, u8 idx, bool drop)
mt76_wr(dev, MT_WCID_DROP(idx), (val & ~bit) | (bit * drop));
}
+void mt76x02_mac_wcid_set_drop(struct mt76x02_dev *dev, u8 idx, bool drop)
+{
+ /* USB register access can sleep, and mt76.mutex serialises USB callers */
+ if (!mt76_is_mmio(&dev->mt76)) {
+ __mt76x02_mac_wcid_set_drop(dev, idx, drop);
+ return;
+ }
+
+ spin_lock_bh(&dev->mt76.lock);
+ __mt76x02_mac_wcid_set_drop(dev, idx, drop);
+ spin_unlock_bh(&dev->mt76.lock);
+}
+
static u16
mt76x02_mac_tx_rate_val(struct mt76x02_dev *dev,
const struct ieee80211_tx_rate *rate, u8 *nss_val)
--
2.47.3
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH mt76-next 3/3] wifi: mt76: mt76x02: clear the wcid drop mask for all powersave responses
2026-10-23 11:13 [PATCH mt76-next 1/3] wifi: mt76: honour the more-data flag when releasing buffered frames Felix Fietkau
2026-10-23 11:13 ` [PATCH mt76-next 2/3] wifi: mt76: mt76x02: serialise wcid drop mask updates Felix Fietkau
@ 2026-10-23 11:13 ` Felix Fietkau
1 sibling, 0 replies; 3+ messages in thread
From: Felix Fietkau @ 2026-10-23 11:13 UTC (permalink / raw)
To: linux-wireless
mt76x02_tx_prepare_skb() clears the drop bit of a sleeping station only
for frames on MT_TXQ_PSD. Only frames that
mt76_release_buffered_frames() releases from the driver TXQs use that
queue. Frames that mac80211 buffered itself go through the regular tx
path on their access category queue, and the hardware discards these
PS-Poll and U-APSD responses.
Clear the drop bit for every frame that mac80211 marks as a powersave
response or as exempt from powersave buffering, like
mt7603_tx_prepare_skb() does.
Fixes: 7bc04215a66b ("mt76: add driver code for MT76x2e")
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
index 3ca530f1c171..1698eb9051c3 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
@@ -158,11 +158,15 @@ int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
{
struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx_info->skb->data;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_info->skb);
struct mt76x02_txwi *txwi = txwi_ptr;
- bool ampdu = IEEE80211_SKB_CB(tx_info->skb)->flags & IEEE80211_TX_CTL_AMPDU;
+ bool ampdu = info->flags & IEEE80211_TX_CTL_AMPDU;
int hdrlen, len, pid, qsel = MT_QSEL_EDCA;
- if (qid == MT_TXQ_PSD && wcid && wcid->idx < 128)
+ if (wcid && wcid->idx < MT76x02_N_WCIDS &&
+ ((info->flags & (IEEE80211_TX_CTL_NO_PS_BUFFER |
+ IEEE80211_TX_CTL_CLEAR_PS_FILT)) ||
+ (info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE)))
mt76x02_mac_wcid_set_drop(dev, wcid->idx, false);
hdrlen = ieee80211_hdrlen(hdr->frame_control);
--
2.47.3
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-10-23 11:13 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-23 11:13 [PATCH mt76-next 1/3] wifi: mt76: honour the more-data flag when releasing buffered frames Felix Fietkau
2026-10-23 11:13 ` [PATCH mt76-next 2/3] wifi: mt76: mt76x02: serialise wcid drop mask updates Felix Fietkau
2026-10-23 11:13 ` [PATCH mt76-next 3/3] wifi: mt76: mt76x02: clear the wcid drop mask for all powersave responses Felix Fietkau
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox