Also avoid the extra udelay(100) in the case that we'd exit the loop. This will be used later in ath5k_reset() to check for pending frames before enabling fast switching.
Signed-off-by: Bob Copeland <m...@bobcopeland.com> --- drivers/net/wireless/ath/ath5k/ath5k.h | 1 + drivers/net/wireless/ath/ath5k/dma.c | 45 ++++++++++++++++++++++++++----- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index fecbcd9..3ed6908 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1297,6 +1297,7 @@ void ath5k_hw_start_rx_dma(struct ath5k_hw *ah); u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah); int ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr); int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue); +int ath5k_hw_tx_pending(struct ath5k_hw *ah); int ath5k_hw_stop_beacon_queue(struct ath5k_hw *ah, unsigned int queue); u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue); int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c index 2481f9c..83c1a94 100644 --- a/drivers/net/wireless/ath/ath5k/dma.c +++ b/drivers/net/wireless/ath/ath5k/dma.c @@ -177,6 +177,37 @@ int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue) } /** + * ath5k_hw_tx_pending_queue - Return number of frames QCU has pending in DCU + * + * @ah: The &struct ath5k_hw + * @queue: The hw queue number + */ +static int ath5k_hw_tx_pending_queue(struct ath5k_hw *ah, unsigned int queue) +{ + return ath5k_hw_reg_read(ah, AR5K_QUEUE_STATUS(queue)) & + AR5K_QCU_STS_FRMPENDCNT; +} + +/** + * ath5k_hw_tx_pending - Return number of frames pending in DCU (all queues) + * + * @ah: The &struct ath5k_hw + */ +int ath5k_hw_tx_pending(struct ath5k_hw *ah) +{ + int i, count = 0; + + if (ah->ah_version == AR5K_AR5210) + return count; + + for (i = 0; i < AR5K_NUM_TX_QUEUES; i++) + count += ath5k_hw_tx_pending_queue(ah, i); + + return count; +} + + +/** * ath5k_hw_stop_tx_dma - Stop DMA transmit on a specific queue * * @ah: The &struct ath5k_hw @@ -248,10 +279,9 @@ static int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue) /* Check for pending frames */ i = 1000; do { - pending = ath5k_hw_reg_read(ah, - AR5K_QUEUE_STATUS(queue)) & - AR5K_QCU_STS_FRMPENDCNT; - udelay(100); + pending = ath5k_hw_tx_pending_queue(ah, queue); + if (pending) + udelay(100); } while (--i && pending); /* For 2413+ order PCU to drop packets using @@ -284,10 +314,9 @@ static int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue) /* Re-check for pending frames */ i = 100; do { - pending = ath5k_hw_reg_read(ah, - AR5K_QUEUE_STATUS(queue)) & - AR5K_QCU_STS_FRMPENDCNT; - udelay(100); + pending = ath5k_hw_tx_pending_queue(ah, queue); + if (pending) + udelay(100); } while (--i && pending); AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5211, -- 1.7.6 _______________________________________________ ath5k-devel mailing list ath5k-devel@lists.ath5k.org https://lists.ath5k.org/mailman/listinfo/ath5k-devel