diff options
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ath9k.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 49 |
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 | ||
209 | struct ath_atx_ac { | 212 | struct 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 | ||
246 | struct ath_atx_tid { | 250 | struct ath_atx_tid { |
@@ -330,7 +334,6 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an); | |||
330 | void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq); | 334 | void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq); |
331 | int ath_tx_init(struct ath_softc *sc, int nbufs); | 335 | int ath_tx_init(struct ath_softc *sc, int nbufs); |
332 | void ath_tx_cleanup(struct ath_softc *sc); | 336 | void ath_tx_cleanup(struct ath_softc *sc); |
333 | struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb); | ||
334 | int ath_txq_update(struct ath_softc *sc, int qnum, | 337 | int ath_txq_update(struct ath_softc *sc, int qnum, |
335 | struct ath9k_tx_queue_info *q); | 338 | struct ath9k_tx_queue_info *q); |
336 | int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | 339 | int 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 | ||
987 | struct 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 | |||
1013 | int ath_txq_update(struct ath_softc *sc, int qnum, | 987 | int 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); |