diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 625a4ab37ea0..269ae8311056 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -2352,7 +2352,7 @@ static void ath10k_htt_rx_tx_fetch_ind(struct ath10k *ar, struct sk_buff *skb) num_msdus++; num_bytes += ret; } - ieee80211_return_txq(hw, txq); + ieee80211_return_txq(hw, txq, true); ieee80211_txq_schedule_end(hw, txq->ac); record->num_msdus = cpu_to_le16(num_msdus); diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index cf64d9e02a24..d39bc841ea04 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -4206,7 +4206,7 @@ static int ath10k_mac_schedule_txq(struct ieee80211_hw *hw, u32 ac) if (ret < 0) break; } - ieee80211_return_txq(hw, txq); + ieee80211_return_txq(hw, txq, true); ath10k_htt_tx_txq_update(hw, txq); if (ret == -EBUSY) break; @@ -4475,18 +4475,21 @@ static void ath10k_mac_op_wake_tx_queue(struct ieee80211_hw *hw, { u8 ac = txq->ac; int ret = 0; + bool pushed = false; + ath10k_htt_tx_txq_update(hw, txq); ieee80211_txq_schedule_start(hw, ac); txq = ieee80211_next_txq(hw, ac); if (!txq) goto out; while (ath10k_mac_tx_can_push(hw, txq)) { + pushed = true; ret = ath10k_mac_tx_push_txq(hw, txq); if (ret < 0) break; } - ieee80211_return_txq(hw, txq); + ieee80211_return_txq(hw, txq, pushed); ath10k_htt_tx_txq_update(hw, txq); out: ieee80211_txq_schedule_end(hw, ac); diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 6aab06909e76..40ff0bdbf7c9 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -117,7 +117,7 @@ void ath_tx_queue_tid(struct ath_softc *sc, struct ath_atx_tid *tid) struct ieee80211_txq *queue = container_of( (void *)tid, struct ieee80211_txq, drv_priv); - ieee80211_return_txq(sc->hw, queue); + ieee80211_return_txq(sc->hw, queue, false); } void ath9k_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *queue) @@ -1913,7 +1913,7 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq) ret = ath_tx_sched_aggr(sc, txq, tid); ath_dbg(common, QUEUE, "ath_tx_sched_aggr returned %d\n", ret); - ieee80211_return_txq(hw, queue); + ieee80211_return_txq(hw, queue, false); } out: diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 9cadfa408f50..995e19e29d9e 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -6102,7 +6102,7 @@ struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac); * Should only be called between calls to ieee80211_txq_schedule_start() * and ieee80211_txq_schedule_end(). */ -void ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq); +void ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txqi, bool to_tail); /** * ieee80211_txq_schedule_start - acquire locks for safe scheduling of an AC diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 39dc40ac5abe..530270f8cc52 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -1175,7 +1175,7 @@ static inline void schedule_and_wake_txq(struct ieee80211_local *local, struct txq_info *txqi) { spin_lock_bh(&local->active_txq_lock[txqi->txq.ac]); - ieee80211_return_txq(&local->hw, &txqi->txq); + ieee80211_return_txq(&local->hw, &txqi->txq, false); spin_unlock_bh(&local->active_txq_lock[txqi->txq.ac]); drv_wake_tx_queue(local, txqi); } diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index d8682930a469..acf0505bdd7f 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -3623,7 +3623,8 @@ struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac) EXPORT_SYMBOL(ieee80211_next_txq); void ieee80211_return_txq(struct ieee80211_hw *hw, - struct ieee80211_txq *txq) + struct ieee80211_txq *txq, + bool to_tail) { struct ieee80211_local *local = hw_to_local(hw); struct txq_info *txqi = to_txq_info(txq); @@ -3641,7 +3642,7 @@ void ieee80211_return_txq(struct ieee80211_hw *hw, */ if (wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AIRTIME_FAIRNESS) - && txqi->txq.sta) + && txqi->txq.sta && !to_tail) list_add(&txqi->schedule_order, &local->active_txqs[txq->ac]); else @@ -3652,7 +3653,6 @@ void ieee80211_return_txq(struct ieee80211_hw *hw, } EXPORT_SYMBOL(ieee80211_return_txq); -#define IEEE80211_TXQ_MAY_TX_QUANTUM 20 bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw, struct ieee80211_txq *txq) { @@ -3670,13 +3670,8 @@ bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw, if (sta->airtime[ac].deficit >= 0) goto out; - list_for_each_entry(txqi, &local->active_txqs[ac], schedule_order) { - if (!txqi->txq.sta) - continue; - sta = container_of(txqi->txq.sta, struct sta_info, sta); - sta->airtime[ac].deficit += - (IEEE80211_TXQ_MAY_TX_QUANTUM * sta->airtime_weight); - } + sta->airtime[ac].deficit += sta->airtime_weight; + list_move_tail(&txqi->schedule_order, &local->active_txqs[ac]); return false;