aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h9
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c79
4 files changed, 68 insertions, 29 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index d4640117fa8c..dab0271f1c1a 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -184,7 +184,8 @@ enum ATH_AGGR_STATUS {
184 184
185#define ATH_TXFIFO_DEPTH 8 185#define ATH_TXFIFO_DEPTH 8
186struct ath_txq { 186struct ath_txq {
187 u32 axq_qnum; 187 int mac80211_qnum; /* mac80211 queue number, -1 means not mac80211 Q */
188 u32 axq_qnum; /* ath9k hardware queue number */
188 u32 *axq_link; 189 u32 *axq_link;
189 struct list_head axq_q; 190 struct list_head axq_q;
190 spinlock_t axq_lock; 191 spinlock_t axq_lock;
@@ -280,6 +281,11 @@ struct ath_tx_control {
280#define ATH_TX_XRETRY 0x02 281#define ATH_TX_XRETRY 0x02
281#define ATH_TX_BAR 0x04 282#define ATH_TX_BAR 0x04
282 283
284/**
285 * @txq_map: Index is mac80211 queue number. This is
286 * not necessarily the same as the hardware queue number
287 * (axq_qnum).
288 */
283struct ath_tx { 289struct ath_tx {
284 u16 seq_no; 290 u16 seq_no;
285 u32 txqsetup; 291 u32 txqsetup;
@@ -643,6 +649,7 @@ struct ath_softc {
643 struct ath9k_debug debug; 649 struct ath9k_debug debug;
644 spinlock_t nodes_lock; 650 spinlock_t nodes_lock;
645 struct list_head nodes; /* basically, stations */ 651 struct list_head nodes; /* basically, stations */
652 unsigned int tx_complete_poll_work_seen;
646#endif 653#endif
647 struct ath_beacon_config cur_beacon_conf; 654 struct ath_beacon_config cur_beacon_conf;
648 struct delayed_work tx_complete_work; 655 struct delayed_work tx_complete_work;
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 9e009ccd0069..b0cb792d38ca 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -629,9 +629,11 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
629 if (buf == NULL) 629 if (buf == NULL)
630 return -ENOMEM; 630 return -ENOMEM;
631 631
632 len += sprintf(buf, "Num-Tx-Queues: %i tx-queues-setup: 0x%x\n" 632 len += sprintf(buf, "Num-Tx-Queues: %i tx-queues-setup: 0x%x"
633 " poll-work-seen: %u\n"
633 "%30s %10s%10s%10s\n\n", 634 "%30s %10s%10s%10s\n\n",
634 ATH9K_NUM_TX_QUEUES, sc->tx.txqsetup, 635 ATH9K_NUM_TX_QUEUES, sc->tx.txqsetup,
636 sc->tx_complete_poll_work_seen,
635 "BE", "BK", "VI", "VO"); 637 "BE", "BK", "VI", "VO");
636 638
637 PR("MPDUs Queued: ", queued); 639 PR("MPDUs Queued: ", queued);
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 59c01ca4379e..5279653c90c7 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -442,9 +442,10 @@ static int ath9k_init_queues(struct ath_softc *sc)
442 sc->config.cabqReadytime = ATH_CABQ_READY_TIME; 442 sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
443 ath_cabq_update(sc); 443 ath_cabq_update(sc);
444 444
445 for (i = 0; i < WME_NUM_AC; i++) 445 for (i = 0; i < WME_NUM_AC; i++) {
446 sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i); 446 sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i);
447 447 sc->tx.txq_map[i]->mac80211_qnum = i;
448 }
448 return 0; 449 return 0;
449} 450}
450 451
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,