ath9k: Fix bug in TX DMA termination
Removing the module was slow because ath9k_hw_stopdma() was looping for a long time quantum. Use reasonable values now to fix this issue. Signed-off-by: Sujith <Sujith.Manoharan@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
f46730d13f
commit
94ff91d4af
|
@ -107,14 +107,32 @@ bool ath9k_hw_updatetxtriglevel(struct ath_hal *ah, bool bIncTrigLevel)
|
||||||
|
|
||||||
bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q)
|
bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q)
|
||||||
{
|
{
|
||||||
|
#define ATH9K_TX_STOP_DMA_TIMEOUT 4000 /* usec */
|
||||||
|
#define ATH9K_TIME_QUANTUM 100 /* usec */
|
||||||
|
|
||||||
|
struct ath_hal_5416 *ahp = AH5416(ah);
|
||||||
|
struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
|
||||||
|
struct ath9k_tx_queue_info *qi;
|
||||||
u32 tsfLow, j, wait;
|
u32 tsfLow, j, wait;
|
||||||
|
u32 wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM;
|
||||||
|
|
||||||
|
if (q >= pCap->total_queues) {
|
||||||
|
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
qi = &ahp->ah_txq[q];
|
||||||
|
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
|
||||||
|
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
REG_WRITE(ah, AR_Q_TXD, 1 << q);
|
REG_WRITE(ah, AR_Q_TXD, 1 << q);
|
||||||
|
|
||||||
for (wait = 1000; wait != 0; wait--) {
|
for (wait = wait_time; wait != 0; wait--) {
|
||||||
if (ath9k_hw_numtxpending(ah, q) == 0)
|
if (ath9k_hw_numtxpending(ah, q) == 0)
|
||||||
break;
|
break;
|
||||||
udelay(100);
|
udelay(ATH9K_TIME_QUANTUM);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ath9k_hw_numtxpending(ah, q)) {
|
if (ath9k_hw_numtxpending(ah, q)) {
|
||||||
|
@ -144,8 +162,7 @@ bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q)
|
||||||
udelay(200);
|
udelay(200);
|
||||||
REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
|
REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
|
||||||
|
|
||||||
wait = 1000;
|
wait = wait_time;
|
||||||
|
|
||||||
while (ath9k_hw_numtxpending(ah, q)) {
|
while (ath9k_hw_numtxpending(ah, q)) {
|
||||||
if ((--wait) == 0) {
|
if ((--wait) == 0) {
|
||||||
DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
|
DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
|
||||||
|
@ -153,15 +170,17 @@ bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q)
|
||||||
"msec after killing last frame\n");
|
"msec after killing last frame\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
udelay(100);
|
udelay(ATH9K_TIME_QUANTUM);
|
||||||
}
|
}
|
||||||
|
|
||||||
REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
|
REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
|
||||||
}
|
}
|
||||||
|
|
||||||
REG_WRITE(ah, AR_Q_TXD, 0);
|
REG_WRITE(ah, AR_Q_TXD, 0);
|
||||||
|
|
||||||
return wait != 0;
|
return wait != 0;
|
||||||
|
|
||||||
|
#undef ATH9K_TX_STOP_DMA_TIMEOUT
|
||||||
|
#undef ATH9K_TIME_QUANTUM
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
|
bool ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
|
||||||
|
|
Loading…
Reference in New Issue