diff --git a/tx.c b/tx.c index dc60a966..4507fd15 100644 --- a/tx.c +++ b/tx.c @@ -591,10 +591,22 @@ mt76_txq_schedule_list(struct mt76_phy *phy, enum mt76_txq_id qid) if (!mt76_txq_stopped(q)) n_frames = mt76_txq_send_burst(phy, q, mtxq, wcid); - ieee80211_return_txq(phy->hw, txq, false); - if (unlikely(n_frames < 0)) return n_frames; + + /* + * Keep the station in the airtime scheduler only while it + * makes progress or the shared queue is stopped. A PS + * station that cannot be drained consumes no airtime, so + * its DRR deficit never goes negative and returning it here + * would pin it at the head of the device-wide active_txqs + * list, starving all other stations on every band. Leave it + * unscheduled instead and let mt76_tx_complete_skb() re-arm + * it once a buffered frame completes. + */ + if (n_frames > 0 || mt76_txq_stopped(q)) + ieee80211_return_txq(phy->hw, txq, false); + ret += n_frames; continue; }