mirror of
https://github.com/torvalds/linux.git
synced 2026-10-12 13:27:02 +02:00
wifi: mt76: set the EOSP bit in the QoS header of the last released frame
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/20260801145334.1166751-4-nbd@nbd.name Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
parent
2d16caccd2
commit
0b8d252471
|
|
@ -412,16 +412,23 @@ 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,
|
||||
enum ieee80211_frame_release_type reason)
|
||||
{
|
||||
struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||
|
||||
info->control.flags |= IEEE80211_TX_CTRL_PS_RESPONSE;
|
||||
if (last)
|
||||
if (last) {
|
||||
info->flags |= IEEE80211_TX_STATUS_EOSP |
|
||||
IEEE80211_TX_CTL_REQ_TX_STATUS;
|
||||
|
||||
if (reason == IEEE80211_FRAME_RELEASE_UAPSD &&
|
||||
ieee80211_is_data_qos(hdr->frame_control))
|
||||
*ieee80211_get_qos_ctl(hdr) |= IEEE80211_QOS_CTL_EOSP;
|
||||
}
|
||||
|
||||
mt76_skb_set_moredata(skb, !last);
|
||||
__mt76_tx_queue_skb(phy, MT_TXQ_PSD, skb, wcid, sta, NULL);
|
||||
}
|
||||
|
|
@ -454,14 +461,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);
|
||||
mt76_queue_ps_skb(phy, sta, last_skb, false,
|
||||
reason);
|
||||
|
||||
last_skb = skb;
|
||||
} while (nframes);
|
||||
}
|
||||
|
||||
if (last_skb) {
|
||||
mt76_queue_ps_skb(phy, sta, last_skb, true);
|
||||
mt76_queue_ps_skb(phy, sta, last_skb, true, reason);
|
||||
dev->queue_ops->kick(dev, hwq);
|
||||
} else {
|
||||
ieee80211_sta_eosp(sta);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user