diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/xmit.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 44 |
1 files changed, 28 insertions, 16 deletions
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index c59ae43b9b35..927992732620 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -146,6 +146,28 @@ static void ath_set_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta, | |||
146 | ARRAY_SIZE(bf->rates)); | 146 | ARRAY_SIZE(bf->rates)); |
147 | } | 147 | } |
148 | 148 | ||
149 | static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq, | ||
150 | struct sk_buff *skb) | ||
151 | { | ||
152 | int q; | ||
153 | |||
154 | q = skb_get_queue_mapping(skb); | ||
155 | if (txq == sc->tx.uapsdq) | ||
156 | txq = sc->tx.txq_map[q]; | ||
157 | |||
158 | if (txq != sc->tx.txq_map[q]) | ||
159 | return; | ||
160 | |||
161 | if (WARN_ON(--txq->pending_frames < 0)) | ||
162 | txq->pending_frames = 0; | ||
163 | |||
164 | if (txq->stopped && | ||
165 | txq->pending_frames < sc->tx.txq_max_pending[q]) { | ||
166 | ieee80211_wake_queue(sc->hw, q); | ||
167 | txq->stopped = false; | ||
168 | } | ||
169 | } | ||
170 | |||
149 | static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) | 171 | static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) |
150 | { | 172 | { |
151 | struct ath_txq *txq = tid->ac->txq; | 173 | struct ath_txq *txq = tid->ac->txq; |
@@ -167,6 +189,7 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) | |||
167 | if (!bf) { | 189 | if (!bf) { |
168 | bf = ath_tx_setup_buffer(sc, txq, tid, skb); | 190 | bf = ath_tx_setup_buffer(sc, txq, tid, skb); |
169 | if (!bf) { | 191 | if (!bf) { |
192 | ath_txq_skb_done(sc, txq, skb); | ||
170 | ieee80211_free_txskb(sc->hw, skb); | 193 | ieee80211_free_txskb(sc->hw, skb); |
171 | continue; | 194 | continue; |
172 | } | 195 | } |
@@ -811,6 +834,7 @@ ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq, | |||
811 | 834 | ||
812 | if (!bf) { | 835 | if (!bf) { |
813 | __skb_unlink(skb, &tid->buf_q); | 836 | __skb_unlink(skb, &tid->buf_q); |
837 | ath_txq_skb_done(sc, txq, skb); | ||
814 | ieee80211_free_txskb(sc->hw, skb); | 838 | ieee80211_free_txskb(sc->hw, skb); |
815 | continue; | 839 | continue; |
816 | } | 840 | } |
@@ -1824,6 +1848,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_txq *txq, | |||
1824 | 1848 | ||
1825 | bf = ath_tx_setup_buffer(sc, txq, tid, skb); | 1849 | bf = ath_tx_setup_buffer(sc, txq, tid, skb); |
1826 | if (!bf) { | 1850 | if (!bf) { |
1851 | ath_txq_skb_done(sc, txq, skb); | ||
1827 | ieee80211_free_txskb(sc->hw, skb); | 1852 | ieee80211_free_txskb(sc->hw, skb); |
1828 | return; | 1853 | return; |
1829 | } | 1854 | } |
@@ -2090,6 +2115,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2090 | 2115 | ||
2091 | bf = ath_tx_setup_buffer(sc, txq, tid, skb); | 2116 | bf = ath_tx_setup_buffer(sc, txq, tid, skb); |
2092 | if (!bf) { | 2117 | if (!bf) { |
2118 | ath_txq_skb_done(sc, txq, skb); | ||
2093 | if (txctl->paprd) | 2119 | if (txctl->paprd) |
2094 | dev_kfree_skb_any(skb); | 2120 | dev_kfree_skb_any(skb); |
2095 | else | 2121 | else |
@@ -2189,7 +2215,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
2189 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 2215 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
2190 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 2216 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
2191 | struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data; | 2217 | struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data; |
2192 | int q, padpos, padsize; | 2218 | int padpos, padsize; |
2193 | unsigned long flags; | 2219 | unsigned long flags; |
2194 | 2220 | ||
2195 | ath_dbg(common, XMIT, "TX complete: skb: %p\n", skb); | 2221 | ath_dbg(common, XMIT, "TX complete: skb: %p\n", skb); |
@@ -2225,21 +2251,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
2225 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | 2251 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); |
2226 | 2252 | ||
2227 | __skb_queue_tail(&txq->complete_q, skb); | 2253 | __skb_queue_tail(&txq->complete_q, skb); |
2228 | 2254 | ath_txq_skb_done(sc, txq, skb); | |
2229 | q = skb_get_queue_mapping(skb); | ||
2230 | if (txq == sc->tx.uapsdq) | ||
2231 | txq = sc->tx.txq_map[q]; | ||
2232 | |||
2233 | if (txq == sc->tx.txq_map[q]) { | ||
2234 | if (WARN_ON(--txq->pending_frames < 0)) | ||
2235 | txq->pending_frames = 0; | ||
2236 | |||
2237 | if (txq->stopped && | ||
2238 | txq->pending_frames < sc->tx.txq_max_pending[q]) { | ||
2239 | ieee80211_wake_queue(sc->hw, q); | ||
2240 | txq->stopped = false; | ||
2241 | } | ||
2242 | } | ||
2243 | } | 2255 | } |
2244 | 2256 | ||
2245 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | 2257 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, |