Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit be9b7259 authored by Bruno Randolf's avatar Bruno Randolf Committed by David S. Miller
Browse files

ath5k: debug level improvements



* use only one debug level for beacon debugging: unify ATH5K_DEBUG_BEACON and
ATH5K_DEBUG_BEACON_PROC.

* remove debug level ATH5K_DEBUG_FATAL. doesn't make sense as a debug level -
if it's fatal it should be logged as an error.

* fancier printing of debug levels. cat /debugfs/ath5k/phy0/debug.

* allow debug levels to be changed by echoing their name into
/debugfs/ath5k/phy0/debug. this will toggle the state, when it was off it will
be turned on and vice versa.

* use copy_from_user() when reading from the debug files. use unsigned int for
better optimization. reduce buffer sizes on stack.

drivers/net/wireless/ath5k/base.c:      Changes-licensed-under: 3-Clause-BSD
drivers/net/wireless/ath5k/debug.c:     Changes-licensed-under: GPL
drivers/net/wireless/ath5k/debug.h:     Changes-licensed-under: GPL

Signed-off-by: default avatarBruno Randolf <bruno@thinktube.com>
Acked-by: default avatarLuis R. Rodriguez <mcgrof@winlab.rutgers.edu>
Acked-by: default avatarJiri Slaby <jirislaby@gmail.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 691ba234
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -1980,7 +1980,7 @@ ath5k_beacon_send(struct ath5k_softc *sc)
	struct ath5k_buf *bf = sc->bbuf;
	struct ath5k_hw *ah = sc->ah;

	ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC, "in beacon_send\n");
	ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n");

	if (unlikely(bf->skb == NULL || sc->opmode == IEEE80211_IF_TYPE_STA ||
			sc->opmode == IEEE80211_IF_TYPE_MNTR)) {
@@ -1996,10 +1996,10 @@ ath5k_beacon_send(struct ath5k_softc *sc)
	 */
	if (unlikely(ath5k_hw_num_tx_pending(ah, sc->bhalq) != 0)) {
		sc->bmisscount++;
		ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC,
		ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
			"missed %u consecutive beacons\n", sc->bmisscount);
		if (sc->bmisscount > 3) {		/* NB: 3 is a guess */
			ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC,
			ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
				"stuck beacon time (%u missed)\n",
				sc->bmisscount);
			tasklet_schedule(&sc->restq);
@@ -2007,7 +2007,7 @@ ath5k_beacon_send(struct ath5k_softc *sc)
		return;
	}
	if (unlikely(sc->bmisscount != 0)) {
		ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC,
		ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
			"resume beacon xmit after %u misses\n",
			sc->bmisscount);
		sc->bmisscount = 0;
@@ -2027,7 +2027,7 @@ ath5k_beacon_send(struct ath5k_softc *sc)

	ath5k_hw_put_tx_buf(ah, sc->bhalq, bf->daddr);
	ath5k_hw_tx_start(ah, sc->bhalq);
	ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC, "TXDP[%u] = %llx (%p)\n",
	ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n",
		sc->bhalq, (unsigned long long)bf->daddr, bf->desc);

	sc->bsent++;
+103 −21
Original line number Diff line number Diff line
/*
 * Copyright (c) 2007 Bruno Randolf <bruno@thinktube.com>
 * Copyright (c) 2007-2008 Bruno Randolf <bruno@thinktube.com>
 *
 *  This file is free software: you may copy, redistribute and/or modify it
 *  under the terms of the GNU General Public License as published by the
@@ -200,7 +200,7 @@ static ssize_t read_file_tsf(struct file *file, char __user *user_buf,
{
	struct ath5k_softc *sc = file->private_data;
	char buf[100];
	snprintf(buf, 100, "0x%016llx\n", ath5k_hw_get_tsf64(sc->ah));
	snprintf(buf, sizeof(buf), "0x%016llx\n", ath5k_hw_get_tsf64(sc->ah));
	return simple_read_from_buffer(user_buf, count, ppos, buf, 19);
}

@@ -209,7 +209,12 @@ static ssize_t write_file_tsf(struct file *file,
				 size_t count, loff_t *ppos)
{
	struct ath5k_softc *sc = file->private_data;
	if (strncmp(userbuf, "reset", 5) == 0) {
	char buf[20];

	if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
		return -EFAULT;

	if (strncmp(buf, "reset", 5) == 0) {
		ath5k_hw_reset_tsf(sc->ah);
		printk(KERN_INFO "debugfs reset TSF\n");
	}
@@ -231,8 +236,8 @@ static ssize_t read_file_beacon(struct file *file, char __user *user_buf,
{
	struct ath5k_softc *sc = file->private_data;
	struct ath5k_hw *ah = sc->ah;
	char buf[1000];
	int len = 0;
	char buf[500];
	unsigned int len = 0;
	unsigned int v;
	u64 tsf;

@@ -277,11 +282,15 @@ static ssize_t write_file_beacon(struct file *file,
{
	struct ath5k_softc *sc = file->private_data;
	struct ath5k_hw *ah = sc->ah;
	char buf[20];

	if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
		return -EFAULT;

	if (strncmp(userbuf, "disable", 7) == 0) {
	if (strncmp(buf, "disable", 7) == 0) {
		AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
		printk(KERN_INFO "debugfs disable beacons\n");
	} else if (strncmp(userbuf, "enable", 6) == 0) {
	} else if (strncmp(buf, "enable", 6) == 0) {
		AR5K_REG_ENABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
		printk(KERN_INFO "debugfs enable beacons\n");
	}
@@ -314,6 +323,82 @@ static const struct file_operations fops_reset = {
};


/* debugfs: debug level */

static struct {
	enum ath5k_debug_level level;
	const char *name;
	const char *desc;
} dbg_info[] = {
	{ ATH5K_DEBUG_RESET,	"reset",	"reset and initialization" },
	{ ATH5K_DEBUG_INTR,	"intr",		"interrupt handling" },
	{ ATH5K_DEBUG_MODE,	"mode",		"mode init/setup" },
	{ ATH5K_DEBUG_XMIT,	"xmit",		"basic xmit operation" },
	{ ATH5K_DEBUG_BEACON,	"beacon",	"beacon handling" },
	{ ATH5K_DEBUG_CALIBRATE, "calib",	"periodic calibration" },
	{ ATH5K_DEBUG_TXPOWER,	"txpower",	"transmit power setting" },
	{ ATH5K_DEBUG_LED,	"led",		"LED mamagement" },
	{ ATH5K_DEBUG_DUMP_RX,	"dumprx",	"print received skb content" },
	{ ATH5K_DEBUG_DUMP_TX,	"dumptx",	"print transmit skb content" },
	{ ATH5K_DEBUG_DUMPMODES, "dumpmodes",	"dump modes" },
	{ ATH5K_DEBUG_TRACE,	"trace",	"trace function calls" },
	{ ATH5K_DEBUG_ANY,	"all",		"show all debug levels" },
};

static ssize_t read_file_debug(struct file *file, char __user *user_buf,
				   size_t count, loff_t *ppos)
{
	struct ath5k_softc *sc = file->private_data;
	char buf[700];
	unsigned int len = 0;
	unsigned int i;

	len += snprintf(buf+len, sizeof(buf)-len,
		"DEBUG LEVEL: 0x%08x\n\n", sc->debug.level);

	for (i = 0; i < ARRAY_SIZE(dbg_info) - 1; i++) {
		len += snprintf(buf+len, sizeof(buf)-len,
			"%10s %c 0x%08x - %s\n", dbg_info[i].name,
			sc->debug.level & dbg_info[i].level ? '+' : ' ',
			dbg_info[i].level, dbg_info[i].desc);
	}
	len += snprintf(buf+len, sizeof(buf)-len,
		"%10s %c 0x%08x - %s\n", dbg_info[i].name,
		sc->debug.level == dbg_info[i].level ? '+' : ' ',
		dbg_info[i].level, dbg_info[i].desc);

	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
}

static ssize_t write_file_debug(struct file *file,
				 const char __user *userbuf,
				 size_t count, loff_t *ppos)
{
	struct ath5k_softc *sc = file->private_data;
	unsigned int i;
	char buf[20];

	if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
		return -EFAULT;

	for (i = 0; i < ARRAY_SIZE(dbg_info); i++) {
		if (strncmp(buf, dbg_info[i].name,
					strlen(dbg_info[i].name)) == 0) {
			sc->debug.level ^= dbg_info[i].level; /* toggle bit */
			break;
		}
	}
	return count;
}

static const struct file_operations fops_debug = {
	.read = read_file_debug,
	.write = write_file_debug,
	.open = ath5k_debugfs_open,
	.owner = THIS_MODULE,
};


/* init */

void
@@ -326,26 +411,24 @@ void
ath5k_debug_init_device(struct ath5k_softc *sc)
{
	sc->debug.level = ath5k_debug;

	sc->debug.debugfs_phydir = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
				ath5k_global_debugfs);
	sc->debug.debugfs_debug = debugfs_create_u32("debug",
			0666, sc->debug.debugfs_phydir, &sc->debug.level);

	sc->debug.debugfs_debug = debugfs_create_file("debug", 0666,
				sc->debug.debugfs_phydir, sc, &fops_debug);

	sc->debug.debugfs_registers = debugfs_create_file("registers", 0444,
				sc->debug.debugfs_phydir,
				sc, &fops_registers);
				sc->debug.debugfs_phydir, sc, &fops_registers);

	sc->debug.debugfs_tsf = debugfs_create_file("tsf", 0666,
				sc->debug.debugfs_phydir,
				sc, &fops_tsf);
				sc->debug.debugfs_phydir, sc, &fops_tsf);

	sc->debug.debugfs_beacon = debugfs_create_file("beacon", 0666,
				sc->debug.debugfs_phydir,
				sc, &fops_beacon);
				sc->debug.debugfs_phydir, sc, &fops_beacon);

	sc->debug.debugfs_reset = debugfs_create_file("reset", 0222,
				sc->debug.debugfs_phydir,
				sc, &fops_reset);
				sc->debug.debugfs_phydir, sc, &fops_reset);
}

void
@@ -415,8 +498,7 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah)
	struct ath5k_buf *bf;
	int status;

	if (likely(!(sc->debug.level &
	    (ATH5K_DEBUG_RESET | ATH5K_DEBUG_FATAL))))
	if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET)))
		return;

	printk(KERN_DEBUG "rx queue %x, link %p\n",
@@ -426,7 +508,7 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah)
	list_for_each_entry(bf, &sc->rxbuf, list) {
		ds = bf->desc;
		status = ah->ah_proc_rx_desc(ah, ds);
		if (!status || (sc->debug.level & ATH5K_DEBUG_FATAL))
		if (!status)
			ath5k_debug_printrxbuf(bf, status == 0);
	}
	spin_unlock_bh(&sc->rxbuflock);
+7 −11
Original line number Diff line number Diff line
@@ -91,7 +91,6 @@ struct ath5k_dbg_info {
 * @ATH5K_DEBUG_MODE: mode init/setup
 * @ATH5K_DEBUG_XMIT: basic xmit operation
 * @ATH5K_DEBUG_BEACON: beacon handling
 * @ATH5K_DEBUG_BEACON_PROC: beacon ISR proc
 * @ATH5K_DEBUG_CALIBRATE: periodic calibration
 * @ATH5K_DEBUG_TXPOWER: transmit power setting
 * @ATH5K_DEBUG_LED: led management
@@ -99,7 +98,6 @@ struct ath5k_dbg_info {
 * @ATH5K_DEBUG_DUMP_TX: print transmit skb content
 * @ATH5K_DEBUG_DUMPMODES: dump modes
 * @ATH5K_DEBUG_TRACE: trace function calls
 * @ATH5K_DEBUG_FATAL: fatal errors
 * @ATH5K_DEBUG_ANY: show at any debug level
 *
 * The debug level is used to control the amount and type of debugging output
@@ -115,15 +113,13 @@ enum ath5k_debug_level {
	ATH5K_DEBUG_MODE	= 0x00000004,
	ATH5K_DEBUG_XMIT	= 0x00000008,
	ATH5K_DEBUG_BEACON	= 0x00000010,
	ATH5K_DEBUG_BEACON_PROC	= 0x00000020,
	ATH5K_DEBUG_CALIBRATE	= 0x00000100,
	ATH5K_DEBUG_TXPOWER	= 0x00000200,
	ATH5K_DEBUG_LED		= 0x00000400,
	ATH5K_DEBUG_DUMP_RX	= 0x00001000,
	ATH5K_DEBUG_DUMP_TX	= 0x00002000,
	ATH5K_DEBUG_DUMPMODES	= 0x00004000,
	ATH5K_DEBUG_TRACE	= 0x00010000,
	ATH5K_DEBUG_FATAL	= 0x80000000,
	ATH5K_DEBUG_CALIBRATE	= 0x00000020,
	ATH5K_DEBUG_TXPOWER	= 0x00000040,
	ATH5K_DEBUG_LED		= 0x00000080,
	ATH5K_DEBUG_DUMP_RX	= 0x00000100,
	ATH5K_DEBUG_DUMP_TX	= 0x00000200,
	ATH5K_DEBUG_DUMPMODES	= 0x00000400,
	ATH5K_DEBUG_TRACE	= 0x00001000,
	ATH5K_DEBUG_ANY		= 0xffffffff
};