aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h5
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c49
3 files changed, 25 insertions, 37 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index cc6ea4272fde..82aca4b6154c 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -136,6 +136,8 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
136#define ATH_MAX_ANTENNA 3 136#define ATH_MAX_ANTENNA 3
137#define ATH_RXBUF 512 137#define ATH_RXBUF 512
138#define ATH_TXBUF 512 138#define ATH_TXBUF 512
139#define ATH_TXBUF_RESERVE 5
140#define ATH_MAX_QDEPTH (ATH_TXBUF / 4 - ATH_TXBUF_RESERVE)
139#define ATH_TXMAXTRY 13 141#define ATH_TXMAXTRY 13
140#define ATH_MGT_TXMAXTRY 4 142#define ATH_MGT_TXMAXTRY 4
141 143
@@ -204,6 +206,7 @@ struct ath_txq {
204 struct list_head txq_fifo_pending; 206 struct list_head txq_fifo_pending;
205 u8 txq_headidx; 207 u8 txq_headidx;
206 u8 txq_tailidx; 208 u8 txq_tailidx;
209 int pending_frames;
207}; 210};
208 211
209struct ath_atx_ac { 212struct ath_atx_ac {
@@ -241,6 +244,7 @@ struct ath_buf {
241 struct ath_buf_state bf_state; 244 struct ath_buf_state bf_state;
242 dma_addr_t bf_dmacontext; 245 dma_addr_t bf_dmacontext;
243 struct ath_wiphy *aphy; 246 struct ath_wiphy *aphy;
247 struct ath_txq *txq;
244}; 248};
245 249
246struct ath_atx_tid { 250struct ath_atx_tid {
@@ -330,7 +334,6 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an);
330void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq); 334void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq);
331int ath_tx_init(struct ath_softc *sc, int nbufs); 335int ath_tx_init(struct ath_softc *sc, int nbufs);
332void ath_tx_cleanup(struct ath_softc *sc); 336void ath_tx_cleanup(struct ath_softc *sc);
333struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb);
334int ath_txq_update(struct ath_softc *sc, int qnum, 337int ath_txq_update(struct ath_softc *sc, int qnum,
335 struct ath9k_tx_queue_info *q); 338 struct ath9k_tx_queue_info *q);
336int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, 339int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 120708d51d45..b8b76dd2c11e 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1025,6 +1025,7 @@ static int ath9k_tx(struct ieee80211_hw *hw,
1025 struct ath_tx_control txctl; 1025 struct ath_tx_control txctl;
1026 int padpos, padsize; 1026 int padpos, padsize;
1027 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 1027 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1028 int qnum;
1028 1029
1029 if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) { 1030 if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) {
1030 ath_print(common, ATH_DBG_XMIT, 1031 ath_print(common, ATH_DBG_XMIT,
@@ -1097,11 +1098,8 @@ static int ath9k_tx(struct ieee80211_hw *hw,
1097 memmove(skb->data, skb->data + padsize, padpos); 1098 memmove(skb->data, skb->data + padsize, padpos);
1098 } 1099 }
1099 1100
1100 /* Check if a tx queue is available */ 1101 qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc);
1101 1102 txctl.txq = &sc->tx.txq[qnum];
1102 txctl.txq = ath_test_get_txq(sc, skb);
1103 if (!txctl.txq)
1104 goto exit;
1105 1103
1106 ath_print(common, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb); 1104 ath_print(common, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb);
1107 1105
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index f63f6a944d62..7547c8f9a584 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -984,32 +984,6 @@ int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype)
984 return qnum; 984 return qnum;
985} 985}
986 986
987struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb)
988{
989 struct ath_txq *txq = NULL;
990 u16 skb_queue = skb_get_queue_mapping(skb);
991 int qnum;
992
993 qnum = ath_get_hal_qnum(skb_queue, sc);
994 txq = &sc->tx.txq[qnum];
995
996 spin_lock_bh(&txq->axq_lock);
997
998 if (txq->axq_depth >= (ATH_TXBUF - 20)) {
999 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_XMIT,
1000 "TX queue: %d is full, depth: %d\n",
1001 qnum, txq->axq_depth);
1002 ath_mac80211_stop_queue(sc, skb_queue);
1003 txq->stopped = 1;
1004 spin_unlock_bh(&txq->axq_lock);
1005 return NULL;
1006 }
1007
1008 spin_unlock_bh(&txq->axq_lock);
1009
1010 return txq;
1011}
1012
1013int ath_txq_update(struct ath_softc *sc, int qnum, 987int ath_txq_update(struct ath_softc *sc, int qnum,
1014 struct ath9k_tx_queue_info *qinfo) 988 struct ath9k_tx_queue_info *qinfo)
1015{ 989{
@@ -1809,6 +1783,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
1809 struct ath_wiphy *aphy = hw->priv; 1783 struct ath_wiphy *aphy = hw->priv;
1810 struct ath_softc *sc = aphy->sc; 1784 struct ath_softc *sc = aphy->sc;
1811 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1785 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1786 struct ath_txq *txq = txctl->txq;
1812 struct ath_buf *bf; 1787 struct ath_buf *bf;
1813 int r; 1788 int r;
1814 1789
@@ -1818,10 +1793,16 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
1818 return -1; 1793 return -1;
1819 } 1794 }
1820 1795
1796 bf->txq = txctl->txq;
1797 spin_lock_bh(&bf->txq->axq_lock);
1798 if (++bf->txq->pending_frames > ATH_MAX_QDEPTH && !txq->stopped) {
1799 ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb));
1800 txq->stopped = 1;
1801 }
1802 spin_unlock_bh(&bf->txq->axq_lock);
1803
1821 r = ath_tx_setup_buffer(hw, bf, skb, txctl); 1804 r = ath_tx_setup_buffer(hw, bf, skb, txctl);
1822 if (unlikely(r)) { 1805 if (unlikely(r)) {
1823 struct ath_txq *txq = txctl->txq;
1824
1825 ath_print(common, ATH_DBG_FATAL, "TX mem alloc failure\n"); 1806 ath_print(common, ATH_DBG_FATAL, "TX mem alloc failure\n");
1826 1807
1827 /* upon ath_tx_processq() this TX queue will be resumed, we 1808 /* upon ath_tx_processq() this TX queue will be resumed, we
@@ -1829,7 +1810,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
1829 * we will at least have to run TX completionon one buffer 1810 * we will at least have to run TX completionon one buffer
1830 * on the queue */ 1811 * on the queue */
1831 spin_lock_bh(&txq->axq_lock); 1812 spin_lock_bh(&txq->axq_lock);
1832 if (sc->tx.txq[txq->axq_qnum].axq_depth > 1) { 1813 if (!txq->stopped && txq->axq_depth > 1) {
1833 ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb)); 1814 ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb));
1834 txq->stopped = 1; 1815 txq->stopped = 1;
1835 } 1816 }
@@ -1970,6 +1951,13 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
1970 tx_flags |= ATH_TX_XRETRY; 1951 tx_flags |= ATH_TX_XRETRY;
1971 } 1952 }
1972 1953
1954 if (bf->txq) {
1955 spin_lock_bh(&bf->txq->axq_lock);
1956 bf->txq->pending_frames--;
1957 spin_unlock_bh(&bf->txq->axq_lock);
1958 bf->txq = NULL;
1959 }
1960
1973 dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); 1961 dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE);
1974 ath_tx_complete(sc, skb, bf->aphy, tx_flags); 1962 ath_tx_complete(sc, skb, bf->aphy, tx_flags);
1975 ath_debug_stat_tx(sc, txq, bf, ts); 1963 ath_debug_stat_tx(sc, txq, bf, ts);
@@ -2058,8 +2046,7 @@ static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq)
2058 int qnum; 2046 int qnum;
2059 2047
2060 spin_lock_bh(&txq->axq_lock); 2048 spin_lock_bh(&txq->axq_lock);
2061 if (txq->stopped && 2049 if (txq->stopped && txq->pending_frames < ATH_MAX_QDEPTH) {
2062 sc->tx.txq[txq->axq_qnum].axq_depth <= (ATH_TXBUF - 20)) {
2063 qnum = ath_get_mac80211_qnum(txq->axq_qnum, sc); 2050 qnum = ath_get_mac80211_qnum(txq->axq_qnum, sc);
2064 if (qnum != -1) { 2051 if (qnum != -1) {
2065 ath_mac80211_start_queue(sc, qnum); 2052 ath_mac80211_start_queue(sc, qnum);