ath9k: Add more information to debugfs xmit file.
authorBen Greear <greearb@candelatech.com>
Mon, 10 Jan 2011 07:11:45 +0000 (23:11 -0800)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 21 Jan 2011 20:32:22 +0000 (15:32 -0500)
Should help debug strange tx lockup type issues.

Signed-off-by: Ben Greear <greearb@candelatech.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/ath/ath9k/debug.c
drivers/net/wireless/ath/ath9k/debug.h
drivers/net/wireless/ath/ath9k/mac.c
drivers/net/wireless/ath/ath9k/xmit.c

index 5075faa618d34c17108f055160e82a0088d3695b..577bc5a9835be2d0f1164738c3fb74c044ac3818 100644 (file)
@@ -599,13 +599,25 @@ do {                                                                      \
                        (unsigned int)(sc->tx.txq[WME_AC_VO].elem));    \
 } while(0)
 
+#define PRQLE(str, elem)                                               \
+do {                                                                   \
+       len += snprintf(buf + len, size - len,                          \
+                       "%s%13i%11i%10i%10i\n", str,                    \
+                       list_empty(&sc->tx.txq[WME_AC_BE].elem),        \
+                       list_empty(&sc->tx.txq[WME_AC_BK].elem),        \
+                       list_empty(&sc->tx.txq[WME_AC_VI].elem),        \
+                       list_empty(&sc->tx.txq[WME_AC_VO].elem));       \
+} while (0)
+
 static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
                              size_t count, loff_t *ppos)
 {
        struct ath_softc *sc = file->private_data;
        char *buf;
-       unsigned int len = 0, size = 2048;
+       unsigned int len = 0, size = 4000;
+       int i;
        ssize_t retval = 0;
+       char tmp[32];
 
        buf = kzalloc(size, GFP_KERNEL);
        if (buf == NULL)
@@ -628,13 +640,26 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
        PR("DELIM Underrun:  ", delim_underrun);
        PR("TX-Pkts-All:     ", tx_pkts_all);
        PR("TX-Bytes-All:    ", tx_bytes_all);
+       PR("hw-put-tx-buf:   ", puttxbuf);
+       PR("hw-tx-start:     ", txstart);
+       PR("hw-tx-proc-desc: ", txprocdesc);
 
        PRX("axq-qnum:        ", axq_qnum);
        PRX("axq-depth:       ", axq_depth);
+       PRX("axq-ampdu_depth: ", axq_ampdu_depth);
        PRX("axq-stopped      ", stopped);
        PRX("tx-in-progress   ", axq_tx_inprogress);
        PRX("pending-frames   ", pending_frames);
-
+       PRX("txq_headidx:     ", txq_headidx);
+       PRX("txq_tailidx:     ", txq_headidx);
+
+       PRQLE("axq_q empty:       ", axq_q);
+       PRQLE("axq_acq empty:     ", axq_acq);
+       PRQLE("txq_fifo_pending:  ", txq_fifo_pending);
+       for (i = 0; i < ATH_TXFIFO_DEPTH; i++) {
+               snprintf(tmp, sizeof(tmp) - 1, "txq_fifo[%i] empty: ", i);
+               PRQLE(tmp, txq_fifo[i]);
+       }
        if (len > size)
                len = size;
 
index 1e5078bd03444481b1e64794d9d7944398b91d80..cd2db3fd7b7eea5de0a469724afac8b6041a726e 100644 (file)
@@ -102,6 +102,9 @@ struct ath_interrupt_stats {
  * @desc_cfg_err: Descriptor configuration errors
  * @data_urn: TX data underrun errors
  * @delim_urn: TX delimiter underrun errors
+ * @puttxbuf: Number of times hardware was given txbuf to write.
+ * @txstart:  Number of times hardware was told to start tx.
+ * @txprocdesc:  Number of times tx descriptor was processed
  */
 struct ath_tx_stats {
        u32 tx_pkts_all;
@@ -119,6 +122,9 @@ struct ath_tx_stats {
        u32 desc_cfg_err;
        u32 data_underrun;
        u32 delim_underrun;
+       u32 puttxbuf;
+       u32 txstart;
+       u32 txprocdesc;
 };
 
 /**
index c75d40fb86f1d16962422e54d3846d1fb23de649..5f2b93441e5c1ee4d0bda68d5051d43ab4404f07 100644 (file)
@@ -16,6 +16,8 @@
 
 #include "hw.h"
 #include "hw-ops.h"
+#include "debug.h"
+#include "ath9k.h"
 
 static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
                                        struct ath9k_tx_queue_info *qi)
@@ -50,12 +52,18 @@ EXPORT_SYMBOL(ath9k_hw_gettxbuf);
 
 void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp)
 {
+       struct ath_wiphy *aphy = ah->hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       TX_STAT_INC(q, puttxbuf);
        REG_WRITE(ah, AR_QTXDP(q), txdp);
 }
 EXPORT_SYMBOL(ath9k_hw_puttxbuf);
 
 void ath9k_hw_txstart(struct ath_hw *ah, u32 q)
 {
+       struct ath_wiphy *aphy = ah->hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       TX_STAT_INC(q, txstart);
        ath_dbg(ath9k_hw_common(ah), ATH_DBG_QUEUE,
                "Enable TXE on queue: %u\n", q);
        REG_WRITE(ah, AR_Q_TXE, 1 << q);
index ad569e152d78a074cff908cbe1cd2a5f033e2c4f..aa67d641f1402967633b0a93e6d14f0b9bd5bd0f 100644 (file)
@@ -2039,6 +2039,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
                        spin_unlock_bh(&txq->axq_lock);
                        break;
                }
+               TX_STAT_INC(txq->axq_qnum, txprocdesc);
 
                /*
                 * Remove ath_buf's of the same transmit unit from txq,