a0a65f35a87e6fd6eb32991fd5b73738fbc93f12
[openwrt/openwrt.git] /
1 From: Felix Fietkau <nbd@nbd.name>
2 Date: Sun, 17 Mar 2019 14:26:59 +0100
3 Subject: [PATCH] mac80211: make ieee80211_schedule_txq schedule empty TXQs
4
5 Currently there is no way for the driver to signal to mac80211 that it should
6 schedule a TXQ even if there are no packets on the mac80211 part of that queue.
7 This is problematic if the driver has an internal retry queue to deal with
8 software A-MPDU retry.
9
10 This patch changes the behavior of ieee80211_schedule_txq to always schedule
11 the queue, as its only user (ath9k) seems to expect such behavior already:
12 it calls this function on tx status and on powersave wakeup whenever its
13 internal retry queue is not empty.
14
15 Also add an extra argument to ieee80211_return_txq to get the same behavior.
16
17 This fixes an issue on ath9k where tx queues with packets to retry (and no
18 new packets in mac80211) would not get serviced.
19
20 Fixes: 89cea7493a346 ("ath9k: Switch to mac80211 TXQ scheduling and airtime APIs")
21 Signed-off-by: Felix Fietkau <nbd@nbd.name>
22 ---
23
24 --- a/include/net/mac80211.h
25 +++ b/include/net/mac80211.h
26 @@ -6090,26 +6090,42 @@ static inline void ieee80211_txq_schedul
27 {
28 }
29
30 +void __ieee80211_schedule_txq(struct ieee80211_hw *hw,
31 + struct ieee80211_txq *txq, bool force);
32 +
33 /**
34 * ieee80211_schedule_txq - schedule a TXQ for transmission
35 *
36 * @hw: pointer as obtained from ieee80211_alloc_hw()
37 * @txq: pointer obtained from station or virtual interface
38 *
39 - * Schedules a TXQ for transmission if it is not already scheduled.
40 + * Schedules a TXQ for transmission if it is not already scheduled,
41 + * even if mac80211 does not have any packets buffered.
42 + *
43 + * The driver may call this function if it has buffered packets for
44 + * this TXQ internally.
45 */
46 -void ieee80211_schedule_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq);
47 +static inline void
48 +ieee80211_schedule_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
49 +{
50 + __ieee80211_schedule_txq(hw, txq, true);
51 +}
52
53 /**
54 * ieee80211_return_txq - return a TXQ previously acquired by ieee80211_next_txq()
55 *
56 * @hw: pointer as obtained from ieee80211_alloc_hw()
57 * @txq: pointer obtained from station or virtual interface
58 + * @force: schedule txq even if mac80211 does not have any buffered packets.
59 + *
60 + * The driver may set force=true if it has buffered packets for this TXQ
61 + * internally.
62 */
63 static inline void
64 -ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
65 +ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq,
66 + bool force)
67 {
68 - ieee80211_schedule_txq(hw, txq);
69 + __ieee80211_schedule_txq(hw, txq, force);
70 }
71
72 /**
73 --- a/net/mac80211/tx.c
74 +++ b/net/mac80211/tx.c
75 @@ -3655,8 +3655,9 @@ out:
76 }
77 EXPORT_SYMBOL(ieee80211_next_txq);
78
79 -void ieee80211_schedule_txq(struct ieee80211_hw *hw,
80 - struct ieee80211_txq *txq)
81 +void __ieee80211_schedule_txq(struct ieee80211_hw *hw,
82 + struct ieee80211_txq *txq,
83 + bool force)
84 {
85 struct ieee80211_local *local = hw_to_local(hw);
86 struct txq_info *txqi = to_txq_info(txq);
87 @@ -3664,7 +3665,8 @@ void ieee80211_schedule_txq(struct ieee8
88 spin_lock_bh(&local->active_txq_lock[txq->ac]);
89
90 if (list_empty(&txqi->schedule_order) &&
91 - (!skb_queue_empty(&txqi->frags) || txqi->tin.backlog_packets)) {
92 + (force || !skb_queue_empty(&txqi->frags) ||
93 + txqi->tin.backlog_packets)) {
94 /* If airtime accounting is active, always enqueue STAs at the
95 * head of the list to ensure that they only get moved to the
96 * back by the airtime DRR scheduler once they have a negative
97 @@ -3684,7 +3686,7 @@ void ieee80211_schedule_txq(struct ieee8
98
99 spin_unlock_bh(&local->active_txq_lock[txq->ac]);
100 }
101 -EXPORT_SYMBOL(ieee80211_schedule_txq);
102 +EXPORT_SYMBOL(__ieee80211_schedule_txq);
103
104 bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
105 struct ieee80211_txq *txq)