aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorToke Høiland-Jørgensen <toke@toke.dk>2017-10-31 07:27:45 -0400
committerJohannes Berg <johannes.berg@intel.com>2017-12-11 06:37:51 -0500
commite937b8da5a591f141fe41aa48a2e898df9888c95 (patch)
tree7a7d3eb5261a47160fef831203a0c90fca6bee8d
parent9de18d8186cb070d22ed67a3f75a2ef5fbf3ef6f (diff)
mac80211: Add TXQ scheduling API
This adds an API to mac80211 to handle scheduling of TXQs and changes the interface between driver and mac80211 for TXQ handling as follows: - The wake_tx_queue callback interface no longer includes the TXQ. Instead, the driver is expected to retrieve that from ieee80211_next_txq() - Two new mac80211 functions are added: ieee80211_next_txq() and ieee80211_schedule_txq(). The former returns the next TXQ that should be scheduled, and is how the driver gets a queue to pull packets from. The latter is called internally by mac80211 to start scheduling a queue, and the driver is supposed to call it to re-schedule the TXQ after it is finished pulling packets from it (unless the queue emptied). The ath9k and ath10k drivers are changed to use the new API. Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--drivers/net/wireless/ath/ath10k/core.c2
-rw-r--r--drivers/net/wireless/ath/ath10k/core.h4
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c55
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h9
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c210
-rw-r--r--include/net/mac80211.h37
-rw-r--r--net/mac80211/agg-tx.c6
-rw-r--r--net/mac80211/driver-ops.h12
-rw-r--r--net/mac80211/ieee80211_i.h5
-rw-r--r--net/mac80211/main.c3
-rw-r--r--net/mac80211/sta_info.c7
-rw-r--r--net/mac80211/trace.h32
-rw-r--r--net/mac80211/tx.c49
15 files changed, 173 insertions, 262 deletions
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index b29fdbd21ead..90d16a38475f 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -2574,9 +2574,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
2574 2574
2575 mutex_init(&ar->conf_mutex); 2575 mutex_init(&ar->conf_mutex);
2576 spin_lock_init(&ar->data_lock); 2576 spin_lock_init(&ar->data_lock);
2577 spin_lock_init(&ar->txqs_lock);
2578 2577
2579 INIT_LIST_HEAD(&ar->txqs);
2580 INIT_LIST_HEAD(&ar->peers); 2578 INIT_LIST_HEAD(&ar->peers);
2581 init_waitqueue_head(&ar->peer_mapping_wq); 2579 init_waitqueue_head(&ar->peer_mapping_wq);
2582 init_waitqueue_head(&ar->htt.empty_tx_wq); 2580 init_waitqueue_head(&ar->htt.empty_tx_wq);
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 643041ef3271..4a79fdce9a08 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -347,7 +347,6 @@ struct ath10k_peer {
347}; 347};
348 348
349struct ath10k_txq { 349struct ath10k_txq {
350 struct list_head list;
351 unsigned long num_fw_queued; 350 unsigned long num_fw_queued;
352 unsigned long num_push_allowed; 351 unsigned long num_push_allowed;
353}; 352};
@@ -895,10 +894,7 @@ struct ath10k {
895 894
896 /* protects shared structure data */ 895 /* protects shared structure data */
897 spinlock_t data_lock; 896 spinlock_t data_lock;
898 /* protects: ar->txqs, artxq->list */
899 spinlock_t txqs_lock;
900 897
901 struct list_head txqs;
902 struct list_head arvifs; 898 struct list_head arvifs;
903 struct list_head peers; 899 struct list_head peers;
904 struct ath10k_peer *peer_map[ATH10K_MAX_NUM_PEER_IDS]; 900 struct ath10k_peer *peer_map[ATH10K_MAX_NUM_PEER_IDS];
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 0a947eef348d..cca4cd82853b 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3830,12 +3830,10 @@ static void ath10k_mac_txq_init(struct ieee80211_txq *txq)
3830 return; 3830 return;
3831 3831
3832 artxq = (void *)txq->drv_priv; 3832 artxq = (void *)txq->drv_priv;
3833 INIT_LIST_HEAD(&artxq->list);
3834} 3833}
3835 3834
3836static void ath10k_mac_txq_unref(struct ath10k *ar, struct ieee80211_txq *txq) 3835static void ath10k_mac_txq_unref(struct ath10k *ar, struct ieee80211_txq *txq)
3837{ 3836{
3838 struct ath10k_txq *artxq;
3839 struct ath10k_skb_cb *cb; 3837 struct ath10k_skb_cb *cb;
3840 struct sk_buff *msdu; 3838 struct sk_buff *msdu;
3841 int msdu_id; 3839 int msdu_id;
@@ -3843,12 +3841,6 @@ static void ath10k_mac_txq_unref(struct ath10k *ar, struct ieee80211_txq *txq)
3843 if (!txq) 3841 if (!txq)
3844 return; 3842 return;
3845 3843
3846 artxq = (void *)txq->drv_priv;
3847 spin_lock_bh(&ar->txqs_lock);
3848 if (!list_empty(&artxq->list))
3849 list_del_init(&artxq->list);
3850 spin_unlock_bh(&ar->txqs_lock);
3851
3852 spin_lock_bh(&ar->htt.tx_lock); 3844 spin_lock_bh(&ar->htt.tx_lock);
3853 idr_for_each_entry(&ar->htt.pending_tx, msdu, msdu_id) { 3845 idr_for_each_entry(&ar->htt.pending_tx, msdu, msdu_id) {
3854 cb = ATH10K_SKB_CB(msdu); 3846 cb = ATH10K_SKB_CB(msdu);
@@ -3978,23 +3970,17 @@ int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw,
3978void ath10k_mac_tx_push_pending(struct ath10k *ar) 3970void ath10k_mac_tx_push_pending(struct ath10k *ar)
3979{ 3971{
3980 struct ieee80211_hw *hw = ar->hw; 3972 struct ieee80211_hw *hw = ar->hw;
3981 struct ieee80211_txq *txq; 3973 struct ieee80211_txq *txq, *first = NULL;
3982 struct ath10k_txq *artxq;
3983 struct ath10k_txq *last;
3984 int ret; 3974 int ret;
3985 int max; 3975 int max;
3986 3976
3987 if (ar->htt.num_pending_tx >= (ar->htt.max_num_pending_tx / 2)) 3977 if (ar->htt.num_pending_tx >= (ar->htt.max_num_pending_tx / 2))
3988 return; 3978 return;
3989 3979
3990 spin_lock_bh(&ar->txqs_lock);
3991 rcu_read_lock(); 3980 rcu_read_lock();
3992 3981
3993 last = list_last_entry(&ar->txqs, struct ath10k_txq, list); 3982 txq = ieee80211_next_txq(hw);
3994 while (!list_empty(&ar->txqs)) { 3983 while (txq) {
3995 artxq = list_first_entry(&ar->txqs, struct ath10k_txq, list);
3996 txq = container_of((void *)artxq, struct ieee80211_txq,
3997 drv_priv);
3998 3984
3999 /* Prevent aggressive sta/tid taking over tx queue */ 3985 /* Prevent aggressive sta/tid taking over tx queue */
4000 max = 16; 3986 max = 16;
@@ -4005,18 +3991,21 @@ void ath10k_mac_tx_push_pending(struct ath10k *ar)
4005 break; 3991 break;
4006 } 3992 }
4007 3993
4008 list_del_init(&artxq->list);
4009 if (ret != -ENOENT) 3994 if (ret != -ENOENT)
4010 list_add_tail(&artxq->list, &ar->txqs); 3995 ieee80211_schedule_txq(hw, txq);
4011 3996
4012 ath10k_htt_tx_txq_update(hw, txq); 3997 ath10k_htt_tx_txq_update(hw, txq);
4013 3998
4014 if (artxq == last || (ret < 0 && ret != -ENOENT)) 3999 if (first == txq || (ret < 0 && ret != -ENOENT))
4015 break; 4000 break;
4001
4002 if (!first)
4003 first = txq;
4004
4005 txq = ieee80211_next_txq(hw);
4016 } 4006 }
4017 4007
4018 rcu_read_unlock(); 4008 rcu_read_unlock();
4019 spin_unlock_bh(&ar->txqs_lock);
4020} 4009}
4021 4010
4022/************/ 4011/************/
@@ -4250,34 +4239,22 @@ static void ath10k_mac_op_tx(struct ieee80211_hw *hw,
4250 } 4239 }
4251} 4240}
4252 4241
4253static void ath10k_mac_op_wake_tx_queue(struct ieee80211_hw *hw, 4242static void ath10k_mac_op_wake_tx_queue(struct ieee80211_hw *hw)
4254 struct ieee80211_txq *txq)
4255{ 4243{
4256 struct ath10k *ar = hw->priv; 4244 struct ieee80211_txq *txq;
4257 struct ath10k_txq *artxq = (void *)txq->drv_priv;
4258 struct ieee80211_txq *f_txq;
4259 struct ath10k_txq *f_artxq;
4260 int ret = 0; 4245 int ret = 0;
4261 int max = 16; 4246 int max = 16;
4262 4247
4263 spin_lock_bh(&ar->txqs_lock); 4248 txq = ieee80211_next_txq(hw);
4264 if (list_empty(&artxq->list))
4265 list_add_tail(&artxq->list, &ar->txqs);
4266
4267 f_artxq = list_first_entry(&ar->txqs, struct ath10k_txq, list);
4268 f_txq = container_of((void *)f_artxq, struct ieee80211_txq, drv_priv);
4269 list_del_init(&f_artxq->list);
4270 4249
4271 while (ath10k_mac_tx_can_push(hw, f_txq) && max--) { 4250 while (ath10k_mac_tx_can_push(hw, txq) && max--) {
4272 ret = ath10k_mac_tx_push_txq(hw, f_txq); 4251 ret = ath10k_mac_tx_push_txq(hw, txq);
4273 if (ret) 4252 if (ret)
4274 break; 4253 break;
4275 } 4254 }
4276 if (ret != -ENOENT) 4255 if (ret != -ENOENT)
4277 list_add_tail(&f_artxq->list, &ar->txqs); 4256 ieee80211_schedule_txq(hw, txq);
4278 spin_unlock_bh(&ar->txqs_lock);
4279 4257
4280 ath10k_htt_tx_txq_update(hw, f_txq);
4281 ath10k_htt_tx_txq_update(hw, txq); 4258 ath10k_htt_tx_txq_update(hw, txq);
4282} 4259}
4283 4260
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index ef0de4f1312c..face2bb7f357 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -246,12 +246,8 @@ struct ath_atx_tid {
246 s8 bar_index; 246 s8 bar_index;
247 bool active; 247 bool active;
248 bool clear_ps_filter; 248 bool clear_ps_filter;
249 bool has_queued;
250}; 249};
251 250
252void __ath_tx_queue_tid(struct ath_softc *sc, struct ath_atx_tid *tid);
253void ath_tx_queue_tid(struct ath_softc *sc, struct ath_atx_tid *tid);
254
255struct ath_node { 251struct ath_node {
256 struct ath_softc *sc; 252 struct ath_softc *sc;
257 struct ieee80211_sta *sta; /* station struct we're part of */ 253 struct ieee80211_sta *sta; /* station struct we're part of */
@@ -591,8 +587,7 @@ bool ath_drain_all_txq(struct ath_softc *sc);
591void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq); 587void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq);
592void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an); 588void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
593void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an); 589void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an);
594void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq); 590void ath_txq_schedule(struct ath_softc *sc);
595void ath_txq_schedule_all(struct ath_softc *sc);
596int ath_tx_init(struct ath_softc *sc, int nbufs); 591int ath_tx_init(struct ath_softc *sc, int nbufs);
597int ath_txq_update(struct ath_softc *sc, int qnum, 592int ath_txq_update(struct ath_softc *sc, int qnum,
598 struct ath9k_tx_queue_info *q); 593 struct ath9k_tx_queue_info *q);
@@ -618,7 +613,7 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
618 u16 tids, int nframes, 613 u16 tids, int nframes,
619 enum ieee80211_frame_release_type reason, 614 enum ieee80211_frame_release_type reason,
620 bool more_data); 615 bool more_data);
621void ath9k_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *queue); 616void ath9k_wake_tx_queue(struct ieee80211_hw *hw);
622 617
623/********/ 618/********/
624/* VIFs */ 619/* VIFs */
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index a3be8add56e1..f7dfcdf508ce 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -266,7 +266,7 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start)
266 } 266 }
267 work: 267 work:
268 ath_restart_work(sc); 268 ath_restart_work(sc);
269 ath_txq_schedule_all(sc); 269 ath_txq_schedule(sc);
270 } 270 }
271 271
272 sc->gtt_cnt = 0; 272 sc->gtt_cnt = 0;
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 2197aee2bb72..a768e841524d 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -1057,8 +1057,6 @@ static void ath_rx_count_airtime(struct ath_softc *sc,
1057 if (!!(sc->airtime_flags & AIRTIME_USE_RX)) { 1057 if (!!(sc->airtime_flags & AIRTIME_USE_RX)) {
1058 spin_lock_bh(&acq->lock); 1058 spin_lock_bh(&acq->lock);
1059 an->airtime_deficit[acno] -= airtime; 1059 an->airtime_deficit[acno] -= airtime;
1060 if (an->airtime_deficit[acno] <= 0)
1061 __ath_tx_queue_tid(sc, ATH_AN_2_TID(an, tidno));
1062 spin_unlock_bh(&acq->lock); 1060 spin_unlock_bh(&acq->lock);
1063 } 1061 }
1064 ath_debug_airtime(sc, an, airtime, 0); 1062 ath_debug_airtime(sc, an, airtime, 0);
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 396bf05c6bf6..bd438062a6db 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -112,62 +112,11 @@ void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq)
112 ath_tx_status(hw, skb); 112 ath_tx_status(hw, skb);
113} 113}
114 114
115void __ath_tx_queue_tid(struct ath_softc *sc, struct ath_atx_tid *tid) 115void ath9k_wake_tx_queue(struct ieee80211_hw *hw)
116{
117 struct ath_vif *avp = (struct ath_vif *) tid->an->vif->drv_priv;
118 struct ath_chanctx *ctx = avp->chanctx;
119 struct ath_acq *acq;
120 struct list_head *tid_list;
121 u8 acno = TID_TO_WME_AC(tid->tidno);
122
123 if (!ctx || !list_empty(&tid->list))
124 return;
125
126
127 acq = &ctx->acq[acno];
128 if ((sc->airtime_flags & AIRTIME_USE_NEW_QUEUES) &&
129 tid->an->airtime_deficit[acno] > 0)
130 tid_list = &acq->acq_new;
131 else
132 tid_list = &acq->acq_old;
133
134 list_add_tail(&tid->list, tid_list);
135}
136
137void ath_tx_queue_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
138{
139 struct ath_vif *avp = (struct ath_vif *) tid->an->vif->drv_priv;
140 struct ath_chanctx *ctx = avp->chanctx;
141 struct ath_acq *acq;
142
143 if (!ctx || !list_empty(&tid->list))
144 return;
145
146 acq = &ctx->acq[TID_TO_WME_AC(tid->tidno)];
147 spin_lock_bh(&acq->lock);
148 __ath_tx_queue_tid(sc, tid);
149 spin_unlock_bh(&acq->lock);
150}
151
152
153void ath9k_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *queue)
154{ 116{
155 struct ath_softc *sc = hw->priv; 117 struct ath_softc *sc = hw->priv;
156 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
157 struct ath_atx_tid *tid = (struct ath_atx_tid *) queue->drv_priv;
158 struct ath_txq *txq = tid->txq;
159
160 ath_dbg(common, QUEUE, "Waking TX queue: %pM (%d)\n",
161 queue->sta ? queue->sta->addr : queue->vif->addr,
162 tid->tidno);
163
164 ath_txq_lock(sc, txq);
165 118
166 tid->has_queued = true; 119 ath_txq_schedule(sc);
167 ath_tx_queue_tid(sc, tid);
168 ath_txq_schedule(sc, txq);
169
170 ath_txq_unlock(sc, txq);
171} 120}
172 121
173static struct ath_frame_info *get_frame_info(struct sk_buff *skb) 122static struct ath_frame_info *get_frame_info(struct sk_buff *skb)
@@ -230,14 +179,9 @@ ath_tid_pull(struct ath_atx_tid *tid)
230 struct ath_frame_info *fi; 179 struct ath_frame_info *fi;
231 int q; 180 int q;
232 181
233 if (!tid->has_queued)
234 return NULL;
235
236 skb = ieee80211_tx_dequeue(hw, txq); 182 skb = ieee80211_tx_dequeue(hw, txq);
237 if (!skb) { 183 if (!skb)
238 tid->has_queued = false;
239 return NULL; 184 return NULL;
240 }
241 185
242 if (ath_tx_prepare(hw, skb, &txctl)) { 186 if (ath_tx_prepare(hw, skb, &txctl)) {
243 ieee80211_free_txskb(hw, skb); 187 ieee80211_free_txskb(hw, skb);
@@ -254,12 +198,6 @@ ath_tid_pull(struct ath_atx_tid *tid)
254 return skb; 198 return skb;
255 } 199 }
256 200
257
258static bool ath_tid_has_buffered(struct ath_atx_tid *tid)
259{
260 return !skb_queue_empty(&tid->retry_q) || tid->has_queued;
261}
262
263static struct sk_buff *ath_tid_dequeue(struct ath_atx_tid *tid) 201static struct sk_buff *ath_tid_dequeue(struct ath_atx_tid *tid)
264{ 202{
265 struct sk_buff *skb; 203 struct sk_buff *skb;
@@ -671,7 +609,10 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
671 609
672 skb_queue_splice_tail(&bf_pending, &tid->retry_q); 610 skb_queue_splice_tail(&bf_pending, &tid->retry_q);
673 if (!an->sleeping) { 611 if (!an->sleeping) {
674 ath_tx_queue_tid(sc, tid); 612 struct ieee80211_txq *queue = container_of(
613 (void *)tid, struct ieee80211_txq, drv_priv);
614
615 ieee80211_schedule_txq(sc->hw, queue);
675 616
676 if (ts->ts_status & (ATH9K_TXERR_FILT | ATH9K_TXERR_XRETRY)) 617 if (ts->ts_status & (ATH9K_TXERR_FILT | ATH9K_TXERR_XRETRY))
677 tid->clear_ps_filter = true; 618 tid->clear_ps_filter = true;
@@ -719,8 +660,6 @@ static void ath_tx_count_airtime(struct ath_softc *sc, struct ath_node *an,
719 660
720 spin_lock_bh(&acq->lock); 661 spin_lock_bh(&acq->lock);
721 an->airtime_deficit[q] -= airtime; 662 an->airtime_deficit[q] -= airtime;
722 if (an->airtime_deficit[q] <= 0)
723 __ath_tx_queue_tid(sc, tid);
724 spin_unlock_bh(&acq->lock); 663 spin_unlock_bh(&acq->lock);
725 } 664 }
726 ath_debug_airtime(sc, an, 0, airtime); 665 ath_debug_airtime(sc, an, 0, airtime);
@@ -770,8 +709,6 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
770 } else 709 } else
771 ath_tx_complete_aggr(sc, txq, bf, bf_head, sta, tid, ts, txok); 710 ath_tx_complete_aggr(sc, txq, bf, bf_head, sta, tid, ts, txok);
772 711
773 if (!flush)
774 ath_txq_schedule(sc, txq);
775} 712}
776 713
777static bool ath_lookup_legacy(struct ath_buf *bf) 714static bool ath_lookup_legacy(struct ath_buf *bf)
@@ -1506,8 +1443,8 @@ ath_tx_form_burst(struct ath_softc *sc, struct ath_txq *txq,
1506 } while (1); 1443 } while (1);
1507} 1444}
1508 1445
1509static bool ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, 1446static int ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
1510 struct ath_atx_tid *tid) 1447 struct ath_atx_tid *tid)
1511{ 1448{
1512 struct ath_buf *bf; 1449 struct ath_buf *bf;
1513 struct ieee80211_tx_info *tx_info; 1450 struct ieee80211_tx_info *tx_info;
@@ -1515,21 +1452,18 @@ static bool ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
1515 int aggr_len = 0; 1452 int aggr_len = 0;
1516 bool aggr; 1453 bool aggr;
1517 1454
1518 if (!ath_tid_has_buffered(tid))
1519 return false;
1520
1521 INIT_LIST_HEAD(&bf_q); 1455 INIT_LIST_HEAD(&bf_q);
1522 1456
1523 bf = ath_tx_get_tid_subframe(sc, txq, tid); 1457 bf = ath_tx_get_tid_subframe(sc, txq, tid);
1524 if (!bf) 1458 if (!bf)
1525 return false; 1459 return -ENOENT;
1526 1460
1527 tx_info = IEEE80211_SKB_CB(bf->bf_mpdu); 1461 tx_info = IEEE80211_SKB_CB(bf->bf_mpdu);
1528 aggr = !!(tx_info->flags & IEEE80211_TX_CTL_AMPDU); 1462 aggr = !!(tx_info->flags & IEEE80211_TX_CTL_AMPDU);
1529 if ((aggr && txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) || 1463 if ((aggr && txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) ||
1530 (!aggr && txq->axq_depth >= ATH_NON_AGGR_MIN_QDEPTH)) { 1464 (!aggr && txq->axq_depth >= ATH_NON_AGGR_MIN_QDEPTH)) {
1531 __skb_queue_tail(&tid->retry_q, bf->bf_mpdu); 1465 __skb_queue_tail(&tid->retry_q, bf->bf_mpdu);
1532 return false; 1466 return -ENOBUFS;
1533 } 1467 }
1534 1468
1535 ath_set_rates(tid->an->vif, tid->an->sta, bf); 1469 ath_set_rates(tid->an->vif, tid->an->sta, bf);
@@ -1539,7 +1473,7 @@ static bool ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
1539 ath_tx_form_burst(sc, txq, tid, &bf_q, bf); 1473 ath_tx_form_burst(sc, txq, tid, &bf_q, bf);
1540 1474
1541 if (list_empty(&bf_q)) 1475 if (list_empty(&bf_q))
1542 return false; 1476 return -ENOENT;
1543 1477
1544 if (tid->clear_ps_filter || tid->an->no_ps_filter) { 1478 if (tid->clear_ps_filter || tid->an->no_ps_filter) {
1545 tid->clear_ps_filter = false; 1479 tid->clear_ps_filter = false;
@@ -1548,7 +1482,7 @@ static bool ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
1548 1482
1549 ath_tx_fill_desc(sc, bf, txq, aggr_len); 1483 ath_tx_fill_desc(sc, bf, txq, aggr_len);
1550 ath_tx_txqaddbuf(sc, txq, &bf_q, false); 1484 ath_tx_txqaddbuf(sc, txq, &bf_q, false);
1551 return true; 1485 return 0;
1552} 1486}
1553 1487
1554int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, 1488int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
@@ -1611,52 +1545,49 @@ void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc,
1611{ 1545{
1612 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1546 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1613 struct ath_atx_tid *tid; 1547 struct ath_atx_tid *tid;
1614 struct ath_txq *txq; 1548 struct ieee80211_txq *queue;
1615 int tidno; 1549 int tidno;
1616 1550
1617 ath_dbg(common, XMIT, "%s called\n", __func__); 1551 ath_dbg(common, XMIT, "%s called\n", __func__);
1618 1552
1619 for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) { 1553 for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) {
1620 tid = ath_node_to_tid(an, tidno); 1554 tid = ath_node_to_tid(an, tidno);
1621 txq = tid->txq; 1555 queue = container_of((void *)tid,
1622 1556 struct ieee80211_txq, drv_priv);
1623 ath_txq_lock(sc, txq);
1624
1625 if (list_empty(&tid->list)) {
1626 ath_txq_unlock(sc, txq);
1627 continue;
1628 }
1629 1557
1630 if (!skb_queue_empty(&tid->retry_q)) 1558 if (!skb_queue_empty(&tid->retry_q))
1631 ieee80211_sta_set_buffered(sta, tid->tidno, true); 1559 ieee80211_sta_set_buffered(sta, tid->tidno, true);
1632 1560
1633 list_del_init(&tid->list);
1634
1635 ath_txq_unlock(sc, txq);
1636 } 1561 }
1637} 1562}
1638 1563
1639void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an) 1564void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an)
1640{ 1565{
1641 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1566 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1567 struct ieee80211_txq *queue;
1642 struct ath_atx_tid *tid; 1568 struct ath_atx_tid *tid;
1643 struct ath_txq *txq; 1569 struct ath_txq *txq;
1644 int tidno; 1570 int tidno;
1571 bool sched, wake = false;
1645 1572
1646 ath_dbg(common, XMIT, "%s called\n", __func__); 1573 ath_dbg(common, XMIT, "%s called\n", __func__);
1647 1574
1648 for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) { 1575 for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) {
1649 tid = ath_node_to_tid(an, tidno); 1576 tid = ath_node_to_tid(an, tidno);
1650 txq = tid->txq; 1577 txq = tid->txq;
1578 queue = container_of((void *)tid,
1579 struct ieee80211_txq, drv_priv);
1651 1580
1652 ath_txq_lock(sc, txq); 1581 ath_txq_lock(sc, txq);
1653 tid->clear_ps_filter = true; 1582 tid->clear_ps_filter = true;
1654 if (ath_tid_has_buffered(tid)) { 1583 sched = !skb_queue_empty(&tid->retry_q);
1655 ath_tx_queue_tid(sc, tid); 1584 ath_txq_unlock(sc, txq);
1656 ath_txq_schedule(sc, txq); 1585
1657 } 1586 if (sched && ieee80211_schedule_txq(sc->hw, queue))
1658 ath_txq_unlock_complete(sc, txq); 1587 wake = true;
1659 } 1588 }
1589 if (wake)
1590 ath_txq_schedule(sc);
1660} 1591}
1661 1592
1662void ath9k_release_buffered_frames(struct ieee80211_hw *hw, 1593void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
@@ -1948,86 +1879,44 @@ void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
1948/* For each acq entry, for each tid, try to schedule packets 1879/* For each acq entry, for each tid, try to schedule packets
1949 * for transmit until ampdu_depth has reached min Q depth. 1880 * for transmit until ampdu_depth has reached min Q depth.
1950 */ 1881 */
1951void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq) 1882void ath_txq_schedule(struct ath_softc *sc)
1952{ 1883{
1884 struct ieee80211_hw *hw = sc->hw;
1953 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1885 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1886 struct ieee80211_txq *queue;
1954 struct ath_atx_tid *tid; 1887 struct ath_atx_tid *tid;
1955 struct list_head *tid_list; 1888 struct ath_txq *txq;
1956 struct ath_acq *acq; 1889 int ret = 0;
1957 bool active = AIRTIME_ACTIVE(sc->airtime_flags);
1958 1890
1959 if (txq->mac80211_qnum < 0) 1891 if (test_bit(ATH_OP_HW_RESET, &common->op_flags))
1960 return; 1892 return;
1961 1893
1962 if (test_bit(ATH_OP_HW_RESET, &common->op_flags)) 1894 queue = ieee80211_next_txq(hw);
1895 if (!queue)
1963 return; 1896 return;
1964 1897
1965 spin_lock_bh(&sc->chan_lock); 1898 tid = (struct ath_atx_tid *)queue->drv_priv;
1966 rcu_read_lock(); 1899 txq = tid->txq;
1967 acq = &sc->cur_chan->acq[txq->mac80211_qnum];
1968 1900
1969 if (sc->cur_chan->stopped) 1901 ath_txq_lock(sc, txq);
1902 if (txq->mac80211_qnum < 0)
1970 goto out; 1903 goto out;
1971 1904
1972begin: 1905 spin_lock_bh(&sc->chan_lock);
1973 tid_list = &acq->acq_new; 1906 rcu_read_lock();
1974 if (list_empty(tid_list)) {
1975 tid_list = &acq->acq_old;
1976 if (list_empty(tid_list))
1977 goto out;
1978 }
1979 tid = list_first_entry(tid_list, struct ath_atx_tid, list);
1980
1981 if (active && tid->an->airtime_deficit[txq->mac80211_qnum] <= 0) {
1982 spin_lock_bh(&acq->lock);
1983 tid->an->airtime_deficit[txq->mac80211_qnum] += ATH_AIRTIME_QUANTUM;
1984 list_move_tail(&tid->list, &acq->acq_old);
1985 spin_unlock_bh(&acq->lock);
1986 goto begin;
1987 }
1988
1989 if (!ath_tid_has_buffered(tid)) {
1990 spin_lock_bh(&acq->lock);
1991 if ((tid_list == &acq->acq_new) && !list_empty(&acq->acq_old))
1992 list_move_tail(&tid->list, &acq->acq_old);
1993 else {
1994 list_del_init(&tid->list);
1995 }
1996 spin_unlock_bh(&acq->lock);
1997 goto begin;
1998 }
1999
2000 1907
2001 /* 1908 if (!sc->cur_chan->stopped)
2002 * If we succeed in scheduling something, immediately restart to make 1909 ret = ath_tx_sched_aggr(sc, txq, tid);
2003 * sure we keep the HW busy.
2004 */
2005 if(ath_tx_sched_aggr(sc, txq, tid)) {
2006 if (!active) {
2007 spin_lock_bh(&acq->lock);
2008 list_move_tail(&tid->list, &acq->acq_old);
2009 spin_unlock_bh(&acq->lock);
2010 }
2011 goto begin;
2012 }
2013 1910
2014out:
2015 rcu_read_unlock(); 1911 rcu_read_unlock();
2016 spin_unlock_bh(&sc->chan_lock); 1912 spin_unlock_bh(&sc->chan_lock);
2017}
2018 1913
2019void ath_txq_schedule_all(struct ath_softc *sc) 1914out:
2020{
2021 struct ath_txq *txq;
2022 int i;
2023 1915
2024 for (i = 0; i < IEEE80211_NUM_ACS; i++) { 1916 if (ret != -ENOENT)
2025 txq = sc->tx.txq_map[i]; 1917 ieee80211_schedule_txq(hw, queue);
2026 1918
2027 spin_lock_bh(&txq->axq_lock); 1919 ath_txq_unlock(sc, txq);
2028 ath_txq_schedule(sc, txq);
2029 spin_unlock_bh(&txq->axq_lock);
2030 }
2031} 1920}
2032 1921
2033/***********/ 1922/***********/
@@ -2645,7 +2534,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
2645 2534
2646 if (list_empty(&txq->axq_q)) { 2535 if (list_empty(&txq->axq_q)) {
2647 txq->axq_link = NULL; 2536 txq->axq_link = NULL;
2648 ath_txq_schedule(sc, txq);
2649 break; 2537 break;
2650 } 2538 }
2651 bf = list_first_entry(&txq->axq_q, struct ath_buf, list); 2539 bf = list_first_entry(&txq->axq_q, struct ath_buf, list);
@@ -2697,6 +2585,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
2697 ath_tx_process_buffer(sc, txq, &ts, bf, &bf_head); 2585 ath_tx_process_buffer(sc, txq, &ts, bf, &bf_head);
2698 } 2586 }
2699 ath_txq_unlock_complete(sc, txq); 2587 ath_txq_unlock_complete(sc, txq);
2588 ath_txq_schedule(sc);
2700} 2589}
2701 2590
2702void ath_tx_tasklet(struct ath_softc *sc) 2591void ath_tx_tasklet(struct ath_softc *sc)
@@ -2711,6 +2600,7 @@ void ath_tx_tasklet(struct ath_softc *sc)
2711 ath_tx_processq(sc, &sc->tx.txq[i]); 2600 ath_tx_processq(sc, &sc->tx.txq[i]);
2712 } 2601 }
2713 rcu_read_unlock(); 2602 rcu_read_unlock();
2603 ath_txq_schedule(sc);
2714} 2604}
2715 2605
2716void ath_tx_edma_tasklet(struct ath_softc *sc) 2606void ath_tx_edma_tasklet(struct ath_softc *sc)
@@ -2796,6 +2686,7 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
2796 ath_txq_unlock_complete(sc, txq); 2686 ath_txq_unlock_complete(sc, txq);
2797 } 2687 }
2798 rcu_read_unlock(); 2688 rcu_read_unlock();
2689 ath_txq_schedule(sc);
2799} 2690}
2800 2691
2801/*****************/ 2692/*****************/
@@ -2875,7 +2766,6 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
2875 tid->baw_head = tid->baw_tail = 0; 2766 tid->baw_head = tid->baw_tail = 0;
2876 tid->active = false; 2767 tid->active = false;
2877 tid->clear_ps_filter = true; 2768 tid->clear_ps_filter = true;
2878 tid->has_queued = false;
2879 __skb_queue_head_init(&tid->retry_q); 2769 __skb_queue_head_init(&tid->retry_q);
2880 INIT_LIST_HEAD(&tid->list); 2770 INIT_LIST_HEAD(&tid->list);
2881 acno = TID_TO_WME_AC(tidno); 2771 acno = TID_TO_WME_AC(tidno);
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 906e90223066..45155803c875 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -105,9 +105,12 @@
105 * The driver is expected to initialize its private per-queue data for stations 105 * The driver is expected to initialize its private per-queue data for stations
106 * and interfaces in the .add_interface and .sta_add ops. 106 * and interfaces in the .add_interface and .sta_add ops.
107 * 107 *
108 * The driver can't access the queue directly. To dequeue a frame, it calls 108 * The driver can't access the queue directly. To obtain the next queue to pull
109 * ieee80211_tx_dequeue(). Whenever mac80211 adds a new frame to a queue, it 109 * frames from, the driver calls ieee80211_next_txq(). To dequeue a frame from a
110 * calls the .wake_tx_queue driver op. 110 * txq, it calls ieee80211_tx_dequeue(). Whenever mac80211 adds a new frame to a
111 * queue, it calls the .wake_tx_queue driver op. The driver is expected to
112 * re-schedule the txq using ieee80211_schedule_txq() if it is still active
113 * after the driver has finished pulling packets from it.
111 * 114 *
112 * For AP powersave TIM handling, the driver only needs to indicate if it has 115 * For AP powersave TIM handling, the driver only needs to indicate if it has
113 * buffered packets in the driver specific data structures by calling 116 * buffered packets in the driver specific data structures by calling
@@ -3731,8 +3734,7 @@ struct ieee80211_ops {
3731 struct ieee80211_vif *vif, 3734 struct ieee80211_vif *vif,
3732 struct ieee80211_tdls_ch_sw_params *params); 3735 struct ieee80211_tdls_ch_sw_params *params);
3733 3736
3734 void (*wake_tx_queue)(struct ieee80211_hw *hw, 3737 void (*wake_tx_queue)(struct ieee80211_hw *hw);
3735 struct ieee80211_txq *txq);
3736 void (*sync_rx_queues)(struct ieee80211_hw *hw); 3738 void (*sync_rx_queues)(struct ieee80211_hw *hw);
3737 3739
3738 int (*start_nan)(struct ieee80211_hw *hw, 3740 int (*start_nan)(struct ieee80211_hw *hw,
@@ -5883,7 +5885,7 @@ void ieee80211_unreserve_tid(struct ieee80211_sta *sta, u8 tid);
5883 * ieee80211_tx_dequeue - dequeue a packet from a software tx queue 5885 * ieee80211_tx_dequeue - dequeue a packet from a software tx queue
5884 * 5886 *
5885 * @hw: pointer as obtained from ieee80211_alloc_hw() 5887 * @hw: pointer as obtained from ieee80211_alloc_hw()
5886 * @txq: pointer obtained from station or virtual interface 5888 * @txq: pointer obtained from ieee80211_next_txq()
5887 * 5889 *
5888 * Returns the skb if successful, %NULL if no frame was available. 5890 * Returns the skb if successful, %NULL if no frame was available.
5889 */ 5891 */
@@ -5891,6 +5893,29 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
5891 struct ieee80211_txq *txq); 5893 struct ieee80211_txq *txq);
5892 5894
5893/** 5895/**
5896 * ieee80211_schedule_txq - add txq to scheduling loop
5897 *
5898 * @hw: pointer as obtained from ieee80211_alloc_hw()
5899 * @txq: pointer obtained from station or virtual interface
5900 *
5901 * Returns %true if the txq was actually added to the scheduling,
5902 * %false otherwise.
5903 */
5904bool ieee80211_schedule_txq(struct ieee80211_hw *hw,
5905 struct ieee80211_txq *txq);
5906
5907/**
5908 * ieee80211_next_txq - get next tx queue to pull packets from
5909 *
5910 * @hw: pointer as obtained from ieee80211_alloc_hw()
5911 *
5912 * Returns the next txq if successful, %NULL if no queue is eligible. If a txq
5913 * is returned, it will have been removed from the scheduler queue and needs to
5914 * be re-scheduled with ieee80211_schedule_txq() to continue to be active.
5915 */
5916struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw);
5917
5918/**
5894 * ieee80211_txq_get_depth - get pending frame/byte count of given txq 5919 * ieee80211_txq_get_depth - get pending frame/byte count of given txq
5895 * 5920 *
5896 * The values are not guaranteed to be coherent with regard to each other, i.e. 5921 * The values are not guaranteed to be coherent with regard to each other, i.e.
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 595c662a61e8..6c6cad98ce92 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -226,9 +226,13 @@ ieee80211_agg_start_txq(struct sta_info *sta, int tid, bool enable)
226 clear_bit(IEEE80211_TXQ_AMPDU, &txqi->flags); 226 clear_bit(IEEE80211_TXQ_AMPDU, &txqi->flags);
227 227
228 clear_bit(IEEE80211_TXQ_STOP, &txqi->flags); 228 clear_bit(IEEE80211_TXQ_STOP, &txqi->flags);
229
230 if (!ieee80211_schedule_txq(&sta->sdata->local->hw, txq))
231 return;
232
229 local_bh_disable(); 233 local_bh_disable();
230 rcu_read_lock(); 234 rcu_read_lock();
231 drv_wake_tx_queue(sta->sdata->local, txqi); 235 drv_wake_tx_queue(sta->sdata->local);
232 rcu_read_unlock(); 236 rcu_read_unlock();
233 local_bh_enable(); 237 local_bh_enable();
234} 238}
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index c7f93fd9ca7a..cdd76306cb8f 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -1158,16 +1158,10 @@ drv_tdls_recv_channel_switch(struct ieee80211_local *local,
1158 trace_drv_return_void(local); 1158 trace_drv_return_void(local);
1159} 1159}
1160 1160
1161static inline void drv_wake_tx_queue(struct ieee80211_local *local, 1161static inline void drv_wake_tx_queue(struct ieee80211_local *local)
1162 struct txq_info *txq)
1163{ 1162{
1164 struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->txq.vif); 1163 trace_drv_wake_tx_queue(local);
1165 1164 local->ops->wake_tx_queue(&local->hw);
1166 if (!check_sdata_in_driver(sdata))
1167 return;
1168
1169 trace_drv_wake_tx_queue(local, sdata, txq);
1170 local->ops->wake_tx_queue(&local->hw, &txq->txq);
1171} 1165}
1172 1166
1173static inline int drv_start_nan(struct ieee80211_local *local, 1167static inline int drv_start_nan(struct ieee80211_local *local,
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 26900025de2f..4155838c7bef 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -832,6 +832,7 @@ struct txq_info {
832 struct codel_vars def_cvars; 832 struct codel_vars def_cvars;
833 struct codel_stats cstats; 833 struct codel_stats cstats;
834 struct sk_buff_head frags; 834 struct sk_buff_head frags;
835 struct list_head schedule_order;
835 unsigned long flags; 836 unsigned long flags;
836 837
837 /* keep last! */ 838 /* keep last! */
@@ -1122,6 +1123,10 @@ struct ieee80211_local {
1122 struct codel_vars *cvars; 1123 struct codel_vars *cvars;
1123 struct codel_params cparams; 1124 struct codel_params cparams;
1124 1125
1126 /* protects active_txqs and txqi->schedule_order */
1127 spinlock_t active_txq_lock;
1128 struct list_head active_txqs;
1129
1125 const struct ieee80211_ops *ops; 1130 const struct ieee80211_ops *ops;
1126 1131
1127 /* 1132 /*
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 0785d04a80bc..935d6e2491b1 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -619,6 +619,9 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
619 spin_lock_init(&local->rx_path_lock); 619 spin_lock_init(&local->rx_path_lock);
620 spin_lock_init(&local->queue_stop_reason_lock); 620 spin_lock_init(&local->queue_stop_reason_lock);
621 621
622 INIT_LIST_HEAD(&local->active_txqs);
623 spin_lock_init(&local->active_txq_lock);
624
622 INIT_LIST_HEAD(&local->chanctx_list); 625 INIT_LIST_HEAD(&local->chanctx_list);
623 mutex_init(&local->chanctx_mtx); 626 mutex_init(&local->chanctx_mtx);
624 627
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 0c5627f8a104..e0bcf16df494 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -1237,12 +1237,17 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
1237 drv_sta_notify(local, sdata, STA_NOTIFY_AWAKE, &sta->sta); 1237 drv_sta_notify(local, sdata, STA_NOTIFY_AWAKE, &sta->sta);
1238 1238
1239 if (sta->sta.txq[0]) { 1239 if (sta->sta.txq[0]) {
1240 bool wake = false;
1241
1240 for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) { 1242 for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) {
1241 if (!txq_has_queue(sta->sta.txq[i])) 1243 if (!txq_has_queue(sta->sta.txq[i]))
1242 continue; 1244 continue;
1243 1245
1244 drv_wake_tx_queue(local, to_txq_info(sta->sta.txq[i])); 1246 if (ieee80211_schedule_txq(&local->hw, sta->sta.txq[i]))
1247 wake = true;
1245 } 1248 }
1249 if (wake)
1250 drv_wake_tx_queue(local);
1246 } 1251 }
1247 1252
1248 skb_queue_head_init(&pending); 1253 skb_queue_head_init(&pending);
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index 591ad02e1fa4..08eaad85942e 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -2550,35 +2550,9 @@ TRACE_EVENT(drv_tdls_recv_channel_switch,
2550 ) 2550 )
2551); 2551);
2552 2552
2553TRACE_EVENT(drv_wake_tx_queue, 2553DEFINE_EVENT(local_only_evt, drv_wake_tx_queue,
2554 TP_PROTO(struct ieee80211_local *local, 2554 TP_PROTO(struct ieee80211_local *local),
2555 struct ieee80211_sub_if_data *sdata, 2555 TP_ARGS(local)
2556 struct txq_info *txq),
2557
2558 TP_ARGS(local, sdata, txq),
2559
2560 TP_STRUCT__entry(
2561 LOCAL_ENTRY
2562 VIF_ENTRY
2563 STA_ENTRY
2564 __field(u8, ac)
2565 __field(u8, tid)
2566 ),
2567
2568 TP_fast_assign(
2569 struct ieee80211_sta *sta = txq->txq.sta;
2570
2571 LOCAL_ASSIGN;
2572 VIF_ASSIGN;
2573 STA_ASSIGN;
2574 __entry->ac = txq->txq.ac;
2575 __entry->tid = txq->txq.tid;
2576 ),
2577
2578 TP_printk(
2579 LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT " ac:%d tid:%d",
2580 LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->ac, __entry->tid
2581 )
2582); 2556);
2583 2557
2584#endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */ 2558#endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 25904af38839..842881ca8f20 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1439,6 +1439,7 @@ void ieee80211_txq_init(struct ieee80211_sub_if_data *sdata,
1439 codel_vars_init(&txqi->def_cvars); 1439 codel_vars_init(&txqi->def_cvars);
1440 codel_stats_init(&txqi->cstats); 1440 codel_stats_init(&txqi->cstats);
1441 __skb_queue_head_init(&txqi->frags); 1441 __skb_queue_head_init(&txqi->frags);
1442 INIT_LIST_HEAD(&txqi->schedule_order);
1442 1443
1443 txqi->txq.vif = &sdata->vif; 1444 txqi->txq.vif = &sdata->vif;
1444 1445
@@ -1462,6 +1463,7 @@ void ieee80211_txq_purge(struct ieee80211_local *local,
1462 1463
1463 fq_tin_reset(fq, tin, fq_skb_free_func); 1464 fq_tin_reset(fq, tin, fq_skb_free_func);
1464 ieee80211_purge_tx_queue(&local->hw, &txqi->frags); 1465 ieee80211_purge_tx_queue(&local->hw, &txqi->frags);
1466 list_del_init(&txqi->schedule_order);
1465} 1467}
1466 1468
1467int ieee80211_txq_setup_flows(struct ieee80211_local *local) 1469int ieee80211_txq_setup_flows(struct ieee80211_local *local)
@@ -1558,7 +1560,8 @@ static bool ieee80211_queue_skb(struct ieee80211_local *local,
1558 ieee80211_txq_enqueue(local, txqi, skb); 1560 ieee80211_txq_enqueue(local, txqi, skb);
1559 spin_unlock_bh(&fq->lock); 1561 spin_unlock_bh(&fq->lock);
1560 1562
1561 drv_wake_tx_queue(local, txqi); 1563 if (ieee80211_schedule_txq(&local->hw, &txqi->txq))
1564 drv_wake_tx_queue(local);
1562 1565
1563 return true; 1566 return true;
1564} 1567}
@@ -3553,6 +3556,50 @@ out:
3553} 3556}
3554EXPORT_SYMBOL(ieee80211_tx_dequeue); 3557EXPORT_SYMBOL(ieee80211_tx_dequeue);
3555 3558
3559bool ieee80211_schedule_txq(struct ieee80211_hw *hw,
3560 struct ieee80211_txq *txq)
3561{
3562 struct ieee80211_local *local = hw_to_local(hw);
3563 struct txq_info *txqi = to_txq_info(txq);
3564 bool ret = false;
3565
3566 spin_lock_bh(&local->active_txq_lock);
3567
3568 if (list_empty(&txqi->schedule_order)) {
3569 list_add_tail(&txqi->schedule_order, &local->active_txqs);
3570 ret = true;
3571 }
3572
3573 spin_unlock_bh(&local->active_txq_lock);
3574
3575 return ret;
3576}
3577EXPORT_SYMBOL(ieee80211_schedule_txq);
3578
3579struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw)
3580{
3581 struct ieee80211_local *local = hw_to_local(hw);
3582 struct txq_info *txqi = NULL;
3583
3584 spin_lock_bh(&local->active_txq_lock);
3585
3586 if (list_empty(&local->active_txqs))
3587 goto out;
3588
3589 txqi = list_first_entry(&local->active_txqs,
3590 struct txq_info, schedule_order);
3591 list_del_init(&txqi->schedule_order);
3592
3593out:
3594 spin_unlock_bh(&local->active_txq_lock);
3595
3596 if (!txqi)
3597 return NULL;
3598
3599 return &txqi->txq;
3600}
3601EXPORT_SYMBOL(ieee80211_next_txq);
3602
3556void __ieee80211_subif_start_xmit(struct sk_buff *skb, 3603void __ieee80211_subif_start_xmit(struct sk_buff *skb,
3557 struct net_device *dev, 3604 struct net_device *dev,
3558 u32 info_flags) 3605 u32 info_flags)