diff --git a/main.c b/main.c index dc581567..081e3451 100644 --- a/main.c +++ b/main.c @@ -269,6 +269,18 @@ static void mt76_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum sta_notify_cmd cmd, struct ieee80211_sta *sta) { + struct mt76_sta *msta = (struct mt76_sta *) sta->drv_priv; + struct mt76_dev *dev = hw->priv; + + switch (cmd) { + case STA_NOTIFY_SLEEP: + msta->sleeping = true; + mt76_stop_tx_queues(dev, sta); + break; + case STA_NOTIFY_AWAKE: + msta->sleeping = false; + break; + } } static int diff --git a/mt76.h b/mt76.h index c7330e6f..e77f641f 100644 --- a/mt76.h +++ b/mt76.h @@ -214,6 +214,7 @@ struct mt76_sta { u32 status; int n_frames; + bool sleeping; }; struct mt76_txq { @@ -345,4 +346,6 @@ void mt76_release_buffered_frames(struct ieee80211_hw *hw, enum ieee80211_frame_release_type reason, bool more_data); +void mt76_stop_tx_queues(struct mt76_dev *dev, struct ieee80211_sta *sta); + #endif diff --git a/tx.c b/tx.c index ac398c9a..abbea6ce 100644 --- a/tx.c +++ b/tx.c @@ -399,6 +399,22 @@ void mt76_txq_init(struct mt76_dev *dev, struct ieee80211_txq *txq) mtxq->hwq = &dev->q_tx[mt76_txq_get_qid(txq)]; } +void +mt76_stop_tx_queues(struct mt76_dev *dev, struct ieee80211_sta *sta) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(sta->txq); i++) { + struct ieee80211_txq *txq = sta->txq[i]; + struct mt76_txq *mtxq = (struct mt76_txq *) txq->drv_priv; + + spin_lock_bh(&mtxq->hwq->lock); + if (!list_empty(&mtxq->list)) + list_del_init(&mtxq->list); + spin_unlock_bh(&mtxq->hwq->lock); + } +} + void mt76_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq) { struct mt76_dev *dev = hw->priv;