ath9k: Add a debugfs file for dumping DMA status
Debugfs file location: ath9k/<wiphy>/dma Contains values in DMA debug registers. Signed-off-by: Sujith <Sujith.Manoharan@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
826d268091
commit
2a163c6de4
|
@ -1009,7 +1009,6 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints);
|
|||
|
||||
/* MAC (PCU/QCU) */
|
||||
|
||||
void ath9k_hw_dmaRegDump(struct ath_hal *ah);
|
||||
u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q);
|
||||
bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q, u32 txdp);
|
||||
bool ath9k_hw_txstart(struct ath_hal *ah, u32 q);
|
||||
|
|
|
@ -492,7 +492,6 @@ void ath9k_beacon_tasklet(unsigned long data)
|
|||
DPRINTF(sc, ATH_DBG_BEACON,
|
||||
"beacon is officially "
|
||||
"stuck\n");
|
||||
ath9k_hw_dmaRegDump(ah);
|
||||
}
|
||||
} else {
|
||||
DPRINTF(sc, ATH_DBG_BEACON,
|
||||
|
|
|
@ -92,6 +92,7 @@ struct ath9k_debug {
|
|||
int debug_mask;
|
||||
struct dentry *debugfs_root;
|
||||
struct dentry *debugfs_phy;
|
||||
struct dentry *debugfs_dma;
|
||||
};
|
||||
|
||||
void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...);
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
|
||||
#include "core.h"
|
||||
#include "reg.h"
|
||||
#include "hw.h"
|
||||
|
||||
static unsigned int ath9k_debug = DBG_DEFAULT;
|
||||
module_param_named(debug, ath9k_debug, uint, 0);
|
||||
|
@ -34,6 +36,98 @@ void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...)
|
|||
}
|
||||
}
|
||||
|
||||
static int ath9k_debugfs_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
file->private_data = inode->i_private;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t read_file_dma(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath_softc *sc = file->private_data;
|
||||
struct ath_hal *ah = sc->sc_ah;
|
||||
char buf[1024];
|
||||
unsigned int len = 0;
|
||||
u32 val[ATH9K_NUM_DMA_DEBUG_REGS];
|
||||
int i, qcuOffset = 0, dcuOffset = 0;
|
||||
u32 *qcuBase = &val[0], *dcuBase = &val[4];
|
||||
|
||||
REG_WRITE(ah, AR_MACMISC,
|
||||
((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) |
|
||||
(AR_MACMISC_MISC_OBS_BUS_1 <<
|
||||
AR_MACMISC_MISC_OBS_BUS_MSB_S)));
|
||||
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"Raw DMA Debug values:\n");
|
||||
|
||||
for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) {
|
||||
if (i % 4 == 0)
|
||||
len += snprintf(buf + len, sizeof(buf) - len, "\n");
|
||||
|
||||
val[i] = REG_READ(ah, AR_DMADBG_0 + (i * sizeof(u32)));
|
||||
len += snprintf(buf + len, sizeof(buf) - len, "%d: %08x ",
|
||||
i, val[i]);
|
||||
}
|
||||
|
||||
len += snprintf(buf + len, sizeof(buf) - len, "\n\n");
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n");
|
||||
|
||||
for (i = 0; i < ATH9K_NUM_QUEUES; i++, qcuOffset += 4, dcuOffset += 5) {
|
||||
if (i == 8) {
|
||||
qcuOffset = 0;
|
||||
qcuBase++;
|
||||
}
|
||||
|
||||
if (i == 6) {
|
||||
dcuOffset = 0;
|
||||
dcuBase++;
|
||||
}
|
||||
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%2d %2x %1x %2x %2x\n",
|
||||
i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset,
|
||||
(*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset + 3),
|
||||
val[2] & (0x7 << (i * 3)) >> (i * 3),
|
||||
(*dcuBase & (0x1f << dcuOffset)) >> dcuOffset);
|
||||
}
|
||||
|
||||
len += snprintf(buf + len, sizeof(buf) - len, "\n");
|
||||
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"qcu_stitch state: %2x qcu_fetch state: %2x\n",
|
||||
(val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"qcu_complete state: %2x dcu_complete state: %2x\n",
|
||||
(val[3] & 0x1c000000) >> 26, (val[6] & 0x3));
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"dcu_arb state: %2x dcu_fp state: %2x\n",
|
||||
(val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"chan_idle_dur: %3d chan_idle_dur_valid: %1d\n",
|
||||
(val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"txfifo_valid_0: %1d txfifo_valid_1: %1d\n",
|
||||
(val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n",
|
||||
(val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17);
|
||||
|
||||
len += snprintf(buf + len, sizeof(buf) - len, "pcu observe: 0x%x \n",
|
||||
REG_READ(ah, AR_OBS_BUS_1));
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"AR_CR: 0x%x \n", REG_READ(ah, AR_CR));
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
}
|
||||
|
||||
static const struct file_operations fops_dma = {
|
||||
.read = read_file_dma,
|
||||
.open = ath9k_debugfs_open,
|
||||
.owner = THIS_MODULE
|
||||
};
|
||||
|
||||
int ath9k_init_debug(struct ath_softc *sc)
|
||||
{
|
||||
sc->sc_debug.debug_mask = ath9k_debug;
|
||||
|
@ -47,6 +141,11 @@ int ath9k_init_debug(struct ath_softc *sc)
|
|||
if (!sc->sc_debug.debugfs_phy)
|
||||
goto err;
|
||||
|
||||
sc->sc_debug.debugfs_dma = debugfs_create_file("dma", S_IRUGO,
|
||||
sc->sc_debug.debugfs_phy, sc, &fops_dma);
|
||||
if (!sc->sc_debug.debugfs_dma)
|
||||
goto err;
|
||||
|
||||
return 0;
|
||||
err:
|
||||
ath9k_exit_debug(sc);
|
||||
|
@ -55,6 +154,7 @@ err:
|
|||
|
||||
void ath9k_exit_debug(struct ath_softc *sc)
|
||||
{
|
||||
debugfs_remove(sc->sc_debug.debugfs_dma);
|
||||
debugfs_remove(sc->sc_debug.debugfs_phy);
|
||||
debugfs_remove(sc->sc_debug.debugfs_root);
|
||||
}
|
||||
|
|
|
@ -40,78 +40,6 @@ static void ath9k_hw_set_txq_interrupts(struct ath_hal *ah,
|
|||
AR_IMR_S2_QCU_TXURN, ahp->ah_txUrnInterruptMask);
|
||||
}
|
||||
|
||||
void ath9k_hw_dmaRegDump(struct ath_hal *ah)
|
||||
{
|
||||
u32 val[ATH9K_NUM_DMA_DEBUG_REGS];
|
||||
int qcuOffset = 0, dcuOffset = 0;
|
||||
u32 *qcuBase = &val[0], *dcuBase = &val[4];
|
||||
int i;
|
||||
|
||||
REG_WRITE(ah, AR_MACMISC,
|
||||
((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) |
|
||||
(AR_MACMISC_MISC_OBS_BUS_1 <<
|
||||
AR_MACMISC_MISC_OBS_BUS_MSB_S)));
|
||||
|
||||
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "Raw DMA Debug values:\n");
|
||||
|
||||
for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) {
|
||||
if (i % 4 == 0)
|
||||
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n");
|
||||
|
||||
val[i] = REG_READ(ah, AR_DMADBG_0 + (i * sizeof(u32)));
|
||||
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "%d: %08x ", i, val[i]);
|
||||
}
|
||||
|
||||
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n\n");
|
||||
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
|
||||
"Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n");
|
||||
|
||||
for (i = 0; i < ATH9K_NUM_QUEUES;
|
||||
i++, qcuOffset += 4, dcuOffset += 5) {
|
||||
if (i == 8) {
|
||||
qcuOffset = 0;
|
||||
qcuBase++;
|
||||
}
|
||||
|
||||
if (i == 6) {
|
||||
dcuOffset = 0;
|
||||
dcuBase++;
|
||||
}
|
||||
|
||||
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
|
||||
"%2d %2x %1x %2x %2x\n",
|
||||
i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset,
|
||||
(*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset + 3),
|
||||
val[2] & (0x7 << (i * 3)) >> (i * 3),
|
||||
(*dcuBase & (0x1f << dcuOffset)) >> dcuOffset);
|
||||
}
|
||||
|
||||
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n");
|
||||
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
|
||||
"qcu_stitch state: %2x qcu_fetch state: %2x\n",
|
||||
(val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22);
|
||||
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
|
||||
"qcu_complete state: %2x dcu_complete state: %2x\n",
|
||||
(val[3] & 0x1c000000) >> 26, (val[6] & 0x3));
|
||||
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
|
||||
"dcu_arb state: %2x dcu_fp state: %2x\n",
|
||||
(val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27);
|
||||
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
|
||||
"chan_idle_dur: %3d chan_idle_dur_valid: %1d\n",
|
||||
(val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10);
|
||||
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
|
||||
"txfifo_valid_0: %1d txfifo_valid_1: %1d\n",
|
||||
(val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12);
|
||||
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
|
||||
"txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n",
|
||||
(val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17);
|
||||
|
||||
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "pcu observe 0x%x \n",
|
||||
REG_READ(ah, AR_OBS_BUS_1));
|
||||
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
|
||||
"AR_CR 0x%x \n", REG_READ(ah, AR_CR));
|
||||
}
|
||||
|
||||
u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q)
|
||||
{
|
||||
return REG_READ(ah, AR_QTXDP(q));
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <linux/nl80211.h>
|
||||
#include "core.h"
|
||||
#include "reg.h"
|
||||
#include "hw.h"
|
||||
|
||||
#define ATH_PCI_VERSION "0.1"
|
||||
|
||||
|
|
Loading…
Reference in New Issue