提交 b3a28e68 编写于 作者: N Nick Kossifidis 提交者: John W. Linville

ath5k: Debug DMA timeouts

 * Increase timeouts on ath5k_hw_stop_tx_dma and also wait for
 tx queue to stop before checking for pending frames

 * Add a new debug level to debug dma start/stop
Signed-off-by: NNick Kossifidis <mickflemm@gmail.com>
Signed-off-by: NJohn W. Linville <linville@tuxdriver.com>
上级 80dac9ee
...@@ -312,6 +312,7 @@ static const struct { ...@@ -312,6 +312,7 @@ static const struct {
{ ATH5K_DEBUG_DUMP_RX, "dumprx", "print received skb content" }, { ATH5K_DEBUG_DUMP_RX, "dumprx", "print received skb content" },
{ ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" }, { ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" },
{ ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" }, { ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" },
{ ATH5K_DEBUG_DMA, "dma", "dma start/stop" },
{ ATH5K_DEBUG_ANI, "ani", "adaptive noise immunity" }, { ATH5K_DEBUG_ANI, "ani", "adaptive noise immunity" },
{ ATH5K_DEBUG_DESC, "desc", "descriptor chains" }, { ATH5K_DEBUG_DESC, "desc", "descriptor chains" },
{ ATH5K_DEBUG_ANY, "all", "show all debug levels" }, { ATH5K_DEBUG_ANY, "all", "show all debug levels" },
......
...@@ -95,6 +95,7 @@ struct ath5k_dbg_info { ...@@ -95,6 +95,7 @@ struct ath5k_dbg_info {
* @ATH5K_DEBUG_DUMP_RX: print received skb content * @ATH5K_DEBUG_DUMP_RX: print received skb content
* @ATH5K_DEBUG_DUMP_TX: print transmit skb content * @ATH5K_DEBUG_DUMP_TX: print transmit skb content
* @ATH5K_DEBUG_DUMPBANDS: dump bands * @ATH5K_DEBUG_DUMPBANDS: dump bands
* @ATH5K_DEBUG_DMA: debug dma start/stop
* @ATH5K_DEBUG_TRACE: trace function calls * @ATH5K_DEBUG_TRACE: trace function calls
* @ATH5K_DEBUG_DESC: descriptor setup * @ATH5K_DEBUG_DESC: descriptor setup
* @ATH5K_DEBUG_ANY: show at any debug level * @ATH5K_DEBUG_ANY: show at any debug level
...@@ -118,6 +119,7 @@ enum ath5k_debug_level { ...@@ -118,6 +119,7 @@ enum ath5k_debug_level {
ATH5K_DEBUG_DUMP_RX = 0x00000100, ATH5K_DEBUG_DUMP_RX = 0x00000100,
ATH5K_DEBUG_DUMP_TX = 0x00000200, ATH5K_DEBUG_DUMP_TX = 0x00000200,
ATH5K_DEBUG_DUMPBANDS = 0x00000400, ATH5K_DEBUG_DUMPBANDS = 0x00000400,
ATH5K_DEBUG_DMA = 0x00000800,
ATH5K_DEBUG_ANI = 0x00002000, ATH5K_DEBUG_ANI = 0x00002000,
ATH5K_DEBUG_DESC = 0x00004000, ATH5K_DEBUG_DESC = 0x00004000,
ATH5K_DEBUG_ANY = 0xffffffff ATH5K_DEBUG_ANY = 0xffffffff
......
...@@ -70,7 +70,11 @@ int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah) ...@@ -70,7 +70,11 @@ int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah)
for (i = 1000; i > 0 && for (i = 1000; i > 0 &&
(ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) != 0; (ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) != 0;
i--) i--)
udelay(10); udelay(100);
if (i)
ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
"failed to stop RX DMA !\n");
return i ? 0 : -EBUSY; return i ? 0 : -EBUSY;
} }
...@@ -217,7 +221,18 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue) ...@@ -217,7 +221,18 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
*/ */
AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXD, queue); AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXD, queue);
/*Check for pending frames*/ /* Wait for queue to stop */
for (i = 1000; i > 0 &&
(AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue) != 0);
i--)
udelay(100);
if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
"queue %i didn't stop !\n", queue);
/* Check for pending frames */
i = 1000;
do { do {
pending = ath5k_hw_reg_read(ah, pending = ath5k_hw_reg_read(ah,
AR5K_QUEUE_STATUS(queue)) & AR5K_QUEUE_STATUS(queue)) &
...@@ -248,12 +263,12 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue) ...@@ -248,12 +263,12 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
AR5K_DIAG_SW_CHANNEL_IDLE_HIGH); AR5K_DIAG_SW_CHANNEL_IDLE_HIGH);
/* Wait a while and disable mechanism */ /* Wait a while and disable mechanism */
udelay(200); udelay(400);
AR5K_REG_DISABLE_BITS(ah, AR5K_QUIET_CTL1, AR5K_REG_DISABLE_BITS(ah, AR5K_QUIET_CTL1,
AR5K_QUIET_CTL1_QT_EN); AR5K_QUIET_CTL1_QT_EN);
/* Re-check for pending frames */ /* Re-check for pending frames */
i = 40; i = 100;
do { do {
pending = ath5k_hw_reg_read(ah, pending = ath5k_hw_reg_read(ah,
AR5K_QUEUE_STATUS(queue)) & AR5K_QUEUE_STATUS(queue)) &
...@@ -263,12 +278,21 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue) ...@@ -263,12 +278,21 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5211, AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5211,
AR5K_DIAG_SW_CHANNEL_IDLE_HIGH); AR5K_DIAG_SW_CHANNEL_IDLE_HIGH);
if (pending)
ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
"quiet mechanism didn't work q:%i !\n",
queue);
} }
/* Clear register */ /* Clear register */
ath5k_hw_reg_write(ah, 0, AR5K_QCU_TXD); ath5k_hw_reg_write(ah, 0, AR5K_QCU_TXD);
if (pending) if (pending) {
ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
"tx dma didn't stop (q:%i, frm:%i) !\n",
queue, pending);
return -EBUSY; return -EBUSY;
}
} }
/* TODO: Check for success on 5210 else return error */ /* TODO: Check for success on 5210 else return error */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册