aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/xmit.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/xmit.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c79
1 files changed, 54 insertions, 25 deletions
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index a83f2c54508c..2ad732d36f86 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -945,7 +945,7 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
945 [WME_AC_VI] = ATH_TXQ_AC_VI, 945 [WME_AC_VI] = ATH_TXQ_AC_VI,
946 [WME_AC_VO] = ATH_TXQ_AC_VO, 946 [WME_AC_VO] = ATH_TXQ_AC_VO,
947 }; 947 };
948 int qnum, i; 948 int axq_qnum, i;
949 949
950 memset(&qi, 0, sizeof(qi)); 950 memset(&qi, 0, sizeof(qi));
951 qi.tqi_subtype = subtype_txq_to_hwq[subtype]; 951 qi.tqi_subtype = subtype_txq_to_hwq[subtype];
@@ -979,24 +979,25 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
979 qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE | 979 qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE |
980 TXQ_FLAG_TXDESCINT_ENABLE; 980 TXQ_FLAG_TXDESCINT_ENABLE;
981 } 981 }
982 qnum = ath9k_hw_setuptxqueue(ah, qtype, &qi); 982 axq_qnum = ath9k_hw_setuptxqueue(ah, qtype, &qi);
983 if (qnum == -1) { 983 if (axq_qnum == -1) {
984 /* 984 /*
985 * NB: don't print a message, this happens 985 * NB: don't print a message, this happens
986 * normally on parts with too few tx queues 986 * normally on parts with too few tx queues
987 */ 987 */
988 return NULL; 988 return NULL;
989 } 989 }
990 if (qnum >= ARRAY_SIZE(sc->tx.txq)) { 990 if (axq_qnum >= ARRAY_SIZE(sc->tx.txq)) {
991 ath_err(common, "qnum %u out of range, max %zu!\n", 991 ath_err(common, "qnum %u out of range, max %zu!\n",
992 qnum, ARRAY_SIZE(sc->tx.txq)); 992 axq_qnum, ARRAY_SIZE(sc->tx.txq));
993 ath9k_hw_releasetxqueue(ah, qnum); 993 ath9k_hw_releasetxqueue(ah, axq_qnum);
994 return NULL; 994 return NULL;
995 } 995 }
996 if (!ATH_TXQ_SETUP(sc, qnum)) { 996 if (!ATH_TXQ_SETUP(sc, axq_qnum)) {
997 struct ath_txq *txq = &sc->tx.txq[qnum]; 997 struct ath_txq *txq = &sc->tx.txq[axq_qnum];
998 998
999 txq->axq_qnum = qnum; 999 txq->axq_qnum = axq_qnum;
1000 txq->mac80211_qnum = -1;
1000 txq->axq_link = NULL; 1001 txq->axq_link = NULL;
1001 INIT_LIST_HEAD(&txq->axq_q); 1002 INIT_LIST_HEAD(&txq->axq_q);
1002 INIT_LIST_HEAD(&txq->axq_acq); 1003 INIT_LIST_HEAD(&txq->axq_acq);
@@ -1004,14 +1005,14 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
1004 txq->axq_depth = 0; 1005 txq->axq_depth = 0;
1005 txq->axq_ampdu_depth = 0; 1006 txq->axq_ampdu_depth = 0;
1006 txq->axq_tx_inprogress = false; 1007 txq->axq_tx_inprogress = false;
1007 sc->tx.txqsetup |= 1<<qnum; 1008 sc->tx.txqsetup |= 1<<axq_qnum;
1008 1009
1009 txq->txq_headidx = txq->txq_tailidx = 0; 1010 txq->txq_headidx = txq->txq_tailidx = 0;
1010 for (i = 0; i < ATH_TXFIFO_DEPTH; i++) 1011 for (i = 0; i < ATH_TXFIFO_DEPTH; i++)
1011 INIT_LIST_HEAD(&txq->txq_fifo[i]); 1012 INIT_LIST_HEAD(&txq->txq_fifo[i]);
1012 INIT_LIST_HEAD(&txq->txq_fifo_pending); 1013 INIT_LIST_HEAD(&txq->txq_fifo_pending);
1013 } 1014 }
1014 return &sc->tx.txq[qnum]; 1015 return &sc->tx.txq[axq_qnum];
1015} 1016}
1016 1017
1017int ath_txq_update(struct ath_softc *sc, int qnum, 1018int ath_txq_update(struct ath_softc *sc, int qnum,
@@ -1973,17 +1974,16 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts,
1973 tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1; 1974 tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1;
1974} 1975}
1975 1976
1976static void ath_wake_mac80211_queue(struct ath_softc *sc, int qnum) 1977/* Has no locking. Must hold spin_lock_bh(&txq->axq_lock)
1978 * before calling this.
1979 */
1980static void __ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq)
1977{ 1981{
1978 struct ath_txq *txq; 1982 if (txq->mac80211_qnum >= 0 &&
1979 1983 txq->stopped && txq->pending_frames < ATH_MAX_QDEPTH) {
1980 txq = sc->tx.txq_map[qnum]; 1984 if (ath_mac80211_start_queue(sc, txq->mac80211_qnum))
1981 spin_lock_bh(&txq->axq_lock);
1982 if (txq->stopped && txq->pending_frames < ATH_MAX_QDEPTH) {
1983 if (ath_mac80211_start_queue(sc, qnum))
1984 txq->stopped = 0; 1985 txq->stopped = 0;
1985 } 1986 }
1986 spin_unlock_bh(&txq->axq_lock);
1987} 1987}
1988 1988
1989static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) 1989static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
@@ -2086,10 +2086,9 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
2086 else 2086 else
2087 ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, txok, 0); 2087 ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, txok, 0);
2088 2088
2089 if (txq == sc->tx.txq_map[qnum])
2090 ath_wake_mac80211_queue(sc, qnum);
2091
2092 spin_lock_bh(&txq->axq_lock); 2089 spin_lock_bh(&txq->axq_lock);
2090 __ath_wake_mac80211_queue(sc, txq);
2091
2093 if (sc->sc_flags & SC_OP_TXAGGR) 2092 if (sc->sc_flags & SC_OP_TXAGGR)
2094 ath_txq_schedule(sc, txq); 2093 ath_txq_schedule(sc, txq);
2095 spin_unlock_bh(&txq->axq_lock); 2094 spin_unlock_bh(&txq->axq_lock);
@@ -2103,6 +2102,9 @@ static void ath_tx_complete_poll_work(struct work_struct *work)
2103 struct ath_txq *txq; 2102 struct ath_txq *txq;
2104 int i; 2103 int i;
2105 bool needreset = false; 2104 bool needreset = false;
2105#ifdef CONFIG_ATH9K_DEBUGFS
2106 sc->tx_complete_poll_work_seen++;
2107#endif
2106 2108
2107 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) 2109 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
2108 if (ATH_TXQ_SETUP(sc, i)) { 2110 if (ATH_TXQ_SETUP(sc, i)) {
@@ -2116,6 +2118,34 @@ static void ath_tx_complete_poll_work(struct work_struct *work)
2116 } else { 2118 } else {
2117 txq->axq_tx_inprogress = true; 2119 txq->axq_tx_inprogress = true;
2118 } 2120 }
2121 } else {
2122 /* If the queue has pending buffers, then it
2123 * should be doing tx work (and have axq_depth).
2124 * Shouldn't get to this state I think..but
2125 * we do.
2126 */
2127 if (!(sc->sc_flags & (SC_OP_OFFCHANNEL)) &&
2128 (txq->pending_frames > 0 ||
2129 !list_empty(&txq->axq_acq) ||
2130 txq->stopped)) {
2131 ath_err(ath9k_hw_common(sc->sc_ah),
2132 "txq: %p axq_qnum: %u,"
2133 " mac80211_qnum: %i"
2134 " axq_link: %p"
2135 " pending frames: %i"
2136 " axq_acq empty: %i"
2137 " stopped: %i"
2138 " axq_depth: 0 Attempting to"
2139 " restart tx logic.\n",
2140 txq, txq->axq_qnum,
2141 txq->mac80211_qnum,
2142 txq->axq_link,
2143 txq->pending_frames,
2144 list_empty(&txq->axq_acq),
2145 txq->stopped);
2146 __ath_wake_mac80211_queue(sc, txq);
2147 ath_txq_schedule(sc, txq);
2148 }
2119 } 2149 }
2120 spin_unlock_bh(&txq->axq_lock); 2150 spin_unlock_bh(&txq->axq_lock);
2121 } 2151 }
@@ -2212,10 +2242,9 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
2212 ath_tx_complete_buf(sc, bf, txq, &bf_head, 2242 ath_tx_complete_buf(sc, bf, txq, &bf_head,
2213 &txs, txok, 0); 2243 &txs, txok, 0);
2214 2244
2215 if (txq == sc->tx.txq_map[qnum])
2216 ath_wake_mac80211_queue(sc, qnum);
2217
2218 spin_lock_bh(&txq->axq_lock); 2245 spin_lock_bh(&txq->axq_lock);
2246 __ath_wake_mac80211_queue(sc, txq);
2247
2219 if (!list_empty(&txq->txq_fifo_pending)) { 2248 if (!list_empty(&txq->txq_fifo_pending)) {
2220 INIT_LIST_HEAD(&bf_head); 2249 INIT_LIST_HEAD(&bf_head);
2221 bf = list_first_entry(&txq->txq_fifo_pending, 2250 bf = list_first_entry(&txq->txq_fifo_pending,