diff options
author | Bruno Randolf <bruno@thinktube.com> | 2008-01-22 20:27:51 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-31 22:26:35 -0500 |
commit | be9b72590c05daf34c2b55cd5b7c68375a4a795b (patch) | |
tree | b14df772e982996effc400fce57268f3547d0bc3 /drivers/net/wireless/ath5k | |
parent | 691ba2346d5b88cec62fe8db0bf336a58a07b926 (diff) |
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: Bruno Randolf <bruno@thinktube.com>
Acked-by: Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
Acked-by: Jiri Slaby <jirislaby@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/wireless/ath5k')
-rw-r--r-- | drivers/net/wireless/ath5k/base.c | 10 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/debug.c | 124 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/debug.h | 18 |
3 files changed, 115 insertions, 37 deletions
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index 72bcf321d1ce..d6599d219193 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c | |||
@@ -1980,7 +1980,7 @@ ath5k_beacon_send(struct ath5k_softc *sc) | |||
1980 | struct ath5k_buf *bf = sc->bbuf; | 1980 | struct ath5k_buf *bf = sc->bbuf; |
1981 | struct ath5k_hw *ah = sc->ah; | 1981 | struct ath5k_hw *ah = sc->ah; |
1982 | 1982 | ||
1983 | ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC, "in beacon_send\n"); | 1983 | ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n"); |
1984 | 1984 | ||
1985 | if (unlikely(bf->skb == NULL || sc->opmode == IEEE80211_IF_TYPE_STA || | 1985 | if (unlikely(bf->skb == NULL || sc->opmode == IEEE80211_IF_TYPE_STA || |
1986 | sc->opmode == IEEE80211_IF_TYPE_MNTR)) { | 1986 | sc->opmode == IEEE80211_IF_TYPE_MNTR)) { |
@@ -1996,10 +1996,10 @@ ath5k_beacon_send(struct ath5k_softc *sc) | |||
1996 | */ | 1996 | */ |
1997 | if (unlikely(ath5k_hw_num_tx_pending(ah, sc->bhalq) != 0)) { | 1997 | if (unlikely(ath5k_hw_num_tx_pending(ah, sc->bhalq) != 0)) { |
1998 | sc->bmisscount++; | 1998 | sc->bmisscount++; |
1999 | ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC, | 1999 | ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, |
2000 | "missed %u consecutive beacons\n", sc->bmisscount); | 2000 | "missed %u consecutive beacons\n", sc->bmisscount); |
2001 | if (sc->bmisscount > 3) { /* NB: 3 is a guess */ | 2001 | if (sc->bmisscount > 3) { /* NB: 3 is a guess */ |
2002 | ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC, | 2002 | ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, |
2003 | "stuck beacon time (%u missed)\n", | 2003 | "stuck beacon time (%u missed)\n", |
2004 | sc->bmisscount); | 2004 | sc->bmisscount); |
2005 | tasklet_schedule(&sc->restq); | 2005 | tasklet_schedule(&sc->restq); |
@@ -2007,7 +2007,7 @@ ath5k_beacon_send(struct ath5k_softc *sc) | |||
2007 | return; | 2007 | return; |
2008 | } | 2008 | } |
2009 | if (unlikely(sc->bmisscount != 0)) { | 2009 | if (unlikely(sc->bmisscount != 0)) { |
2010 | ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC, | 2010 | ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, |
2011 | "resume beacon xmit after %u misses\n", | 2011 | "resume beacon xmit after %u misses\n", |
2012 | sc->bmisscount); | 2012 | sc->bmisscount); |
2013 | sc->bmisscount = 0; | 2013 | sc->bmisscount = 0; |
@@ -2027,7 +2027,7 @@ ath5k_beacon_send(struct ath5k_softc *sc) | |||
2027 | 2027 | ||
2028 | ath5k_hw_put_tx_buf(ah, sc->bhalq, bf->daddr); | 2028 | ath5k_hw_put_tx_buf(ah, sc->bhalq, bf->daddr); |
2029 | ath5k_hw_tx_start(ah, sc->bhalq); | 2029 | ath5k_hw_tx_start(ah, sc->bhalq); |
2030 | ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC, "TXDP[%u] = %llx (%p)\n", | 2030 | ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n", |
2031 | sc->bhalq, (unsigned long long)bf->daddr, bf->desc); | 2031 | sc->bhalq, (unsigned long long)bf->daddr, bf->desc); |
2032 | 2032 | ||
2033 | sc->bsent++; | 2033 | sc->bsent++; |
diff --git a/drivers/net/wireless/ath5k/debug.c b/drivers/net/wireless/ath5k/debug.c index 4ba649e20269..bb581ef6d1ef 100644 --- a/drivers/net/wireless/ath5k/debug.c +++ b/drivers/net/wireless/ath5k/debug.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2007 Bruno Randolf <bruno@thinktube.com> | 2 | * Copyright (c) 2007-2008 Bruno Randolf <bruno@thinktube.com> |
3 | * | 3 | * |
4 | * This file is free software: you may copy, redistribute and/or modify it | 4 | * This file is free software: you may copy, redistribute and/or modify it |
5 | * under the terms of the GNU General Public License as published by the | 5 | * 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, | |||
200 | { | 200 | { |
201 | struct ath5k_softc *sc = file->private_data; | 201 | struct ath5k_softc *sc = file->private_data; |
202 | char buf[100]; | 202 | char buf[100]; |
203 | snprintf(buf, 100, "0x%016llx\n", ath5k_hw_get_tsf64(sc->ah)); | 203 | snprintf(buf, sizeof(buf), "0x%016llx\n", ath5k_hw_get_tsf64(sc->ah)); |
204 | return simple_read_from_buffer(user_buf, count, ppos, buf, 19); | 204 | return simple_read_from_buffer(user_buf, count, ppos, buf, 19); |
205 | } | 205 | } |
206 | 206 | ||
@@ -209,7 +209,12 @@ static ssize_t write_file_tsf(struct file *file, | |||
209 | size_t count, loff_t *ppos) | 209 | size_t count, loff_t *ppos) |
210 | { | 210 | { |
211 | struct ath5k_softc *sc = file->private_data; | 211 | struct ath5k_softc *sc = file->private_data; |
212 | if (strncmp(userbuf, "reset", 5) == 0) { | 212 | char buf[20]; |
213 | |||
214 | if (copy_from_user(buf, userbuf, min(count, sizeof(buf)))) | ||
215 | return -EFAULT; | ||
216 | |||
217 | if (strncmp(buf, "reset", 5) == 0) { | ||
213 | ath5k_hw_reset_tsf(sc->ah); | 218 | ath5k_hw_reset_tsf(sc->ah); |
214 | printk(KERN_INFO "debugfs reset TSF\n"); | 219 | printk(KERN_INFO "debugfs reset TSF\n"); |
215 | } | 220 | } |
@@ -231,8 +236,8 @@ static ssize_t read_file_beacon(struct file *file, char __user *user_buf, | |||
231 | { | 236 | { |
232 | struct ath5k_softc *sc = file->private_data; | 237 | struct ath5k_softc *sc = file->private_data; |
233 | struct ath5k_hw *ah = sc->ah; | 238 | struct ath5k_hw *ah = sc->ah; |
234 | char buf[1000]; | 239 | char buf[500]; |
235 | int len = 0; | 240 | unsigned int len = 0; |
236 | unsigned int v; | 241 | unsigned int v; |
237 | u64 tsf; | 242 | u64 tsf; |
238 | 243 | ||
@@ -277,11 +282,15 @@ static ssize_t write_file_beacon(struct file *file, | |||
277 | { | 282 | { |
278 | struct ath5k_softc *sc = file->private_data; | 283 | struct ath5k_softc *sc = file->private_data; |
279 | struct ath5k_hw *ah = sc->ah; | 284 | struct ath5k_hw *ah = sc->ah; |
285 | char buf[20]; | ||
286 | |||
287 | if (copy_from_user(buf, userbuf, min(count, sizeof(buf)))) | ||
288 | return -EFAULT; | ||
280 | 289 | ||
281 | if (strncmp(userbuf, "disable", 7) == 0) { | 290 | if (strncmp(buf, "disable", 7) == 0) { |
282 | AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE); | 291 | AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE); |
283 | printk(KERN_INFO "debugfs disable beacons\n"); | 292 | printk(KERN_INFO "debugfs disable beacons\n"); |
284 | } else if (strncmp(userbuf, "enable", 6) == 0) { | 293 | } else if (strncmp(buf, "enable", 6) == 0) { |
285 | AR5K_REG_ENABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE); | 294 | AR5K_REG_ENABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE); |
286 | printk(KERN_INFO "debugfs enable beacons\n"); | 295 | printk(KERN_INFO "debugfs enable beacons\n"); |
287 | } | 296 | } |
@@ -314,6 +323,82 @@ static const struct file_operations fops_reset = { | |||
314 | }; | 323 | }; |
315 | 324 | ||
316 | 325 | ||
326 | /* debugfs: debug level */ | ||
327 | |||
328 | static struct { | ||
329 | enum ath5k_debug_level level; | ||
330 | const char *name; | ||
331 | const char *desc; | ||
332 | } dbg_info[] = { | ||
333 | { ATH5K_DEBUG_RESET, "reset", "reset and initialization" }, | ||
334 | { ATH5K_DEBUG_INTR, "intr", "interrupt handling" }, | ||
335 | { ATH5K_DEBUG_MODE, "mode", "mode init/setup" }, | ||
336 | { ATH5K_DEBUG_XMIT, "xmit", "basic xmit operation" }, | ||
337 | { ATH5K_DEBUG_BEACON, "beacon", "beacon handling" }, | ||
338 | { ATH5K_DEBUG_CALIBRATE, "calib", "periodic calibration" }, | ||
339 | { ATH5K_DEBUG_TXPOWER, "txpower", "transmit power setting" }, | ||
340 | { ATH5K_DEBUG_LED, "led", "LED mamagement" }, | ||
341 | { ATH5K_DEBUG_DUMP_RX, "dumprx", "print received skb content" }, | ||
342 | { ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" }, | ||
343 | { ATH5K_DEBUG_DUMPMODES, "dumpmodes", "dump modes" }, | ||
344 | { ATH5K_DEBUG_TRACE, "trace", "trace function calls" }, | ||
345 | { ATH5K_DEBUG_ANY, "all", "show all debug levels" }, | ||
346 | }; | ||
347 | |||
348 | static ssize_t read_file_debug(struct file *file, char __user *user_buf, | ||
349 | size_t count, loff_t *ppos) | ||
350 | { | ||
351 | struct ath5k_softc *sc = file->private_data; | ||
352 | char buf[700]; | ||
353 | unsigned int len = 0; | ||
354 | unsigned int i; | ||
355 | |||
356 | len += snprintf(buf+len, sizeof(buf)-len, | ||
357 | "DEBUG LEVEL: 0x%08x\n\n", sc->debug.level); | ||
358 | |||
359 | for (i = 0; i < ARRAY_SIZE(dbg_info) - 1; i++) { | ||
360 | len += snprintf(buf+len, sizeof(buf)-len, | ||
361 | "%10s %c 0x%08x - %s\n", dbg_info[i].name, | ||
362 | sc->debug.level & dbg_info[i].level ? '+' : ' ', | ||
363 | dbg_info[i].level, dbg_info[i].desc); | ||
364 | } | ||
365 | len += snprintf(buf+len, sizeof(buf)-len, | ||
366 | "%10s %c 0x%08x - %s\n", dbg_info[i].name, | ||
367 | sc->debug.level == dbg_info[i].level ? '+' : ' ', | ||
368 | dbg_info[i].level, dbg_info[i].desc); | ||
369 | |||
370 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
371 | } | ||
372 | |||
373 | static ssize_t write_file_debug(struct file *file, | ||
374 | const char __user *userbuf, | ||
375 | size_t count, loff_t *ppos) | ||
376 | { | ||
377 | struct ath5k_softc *sc = file->private_data; | ||
378 | unsigned int i; | ||
379 | char buf[20]; | ||
380 | |||
381 | if (copy_from_user(buf, userbuf, min(count, sizeof(buf)))) | ||
382 | return -EFAULT; | ||
383 | |||
384 | for (i = 0; i < ARRAY_SIZE(dbg_info); i++) { | ||
385 | if (strncmp(buf, dbg_info[i].name, | ||
386 | strlen(dbg_info[i].name)) == 0) { | ||
387 | sc->debug.level ^= dbg_info[i].level; /* toggle bit */ | ||
388 | break; | ||
389 | } | ||
390 | } | ||
391 | return count; | ||
392 | } | ||
393 | |||
394 | static const struct file_operations fops_debug = { | ||
395 | .read = read_file_debug, | ||
396 | .write = write_file_debug, | ||
397 | .open = ath5k_debugfs_open, | ||
398 | .owner = THIS_MODULE, | ||
399 | }; | ||
400 | |||
401 | |||
317 | /* init */ | 402 | /* init */ |
318 | 403 | ||
319 | void | 404 | void |
@@ -326,26 +411,24 @@ void | |||
326 | ath5k_debug_init_device(struct ath5k_softc *sc) | 411 | ath5k_debug_init_device(struct ath5k_softc *sc) |
327 | { | 412 | { |
328 | sc->debug.level = ath5k_debug; | 413 | sc->debug.level = ath5k_debug; |
414 | |||
329 | sc->debug.debugfs_phydir = debugfs_create_dir(wiphy_name(sc->hw->wiphy), | 415 | sc->debug.debugfs_phydir = debugfs_create_dir(wiphy_name(sc->hw->wiphy), |
330 | ath5k_global_debugfs); | 416 | ath5k_global_debugfs); |
331 | sc->debug.debugfs_debug = debugfs_create_u32("debug", | 417 | |
332 | 0666, sc->debug.debugfs_phydir, &sc->debug.level); | 418 | sc->debug.debugfs_debug = debugfs_create_file("debug", 0666, |
419 | sc->debug.debugfs_phydir, sc, &fops_debug); | ||
333 | 420 | ||
334 | sc->debug.debugfs_registers = debugfs_create_file("registers", 0444, | 421 | sc->debug.debugfs_registers = debugfs_create_file("registers", 0444, |
335 | sc->debug.debugfs_phydir, | 422 | sc->debug.debugfs_phydir, sc, &fops_registers); |
336 | sc, &fops_registers); | ||
337 | 423 | ||
338 | sc->debug.debugfs_tsf = debugfs_create_file("tsf", 0666, | 424 | sc->debug.debugfs_tsf = debugfs_create_file("tsf", 0666, |
339 | sc->debug.debugfs_phydir, | 425 | sc->debug.debugfs_phydir, sc, &fops_tsf); |
340 | sc, &fops_tsf); | ||
341 | 426 | ||
342 | sc->debug.debugfs_beacon = debugfs_create_file("beacon", 0666, | 427 | sc->debug.debugfs_beacon = debugfs_create_file("beacon", 0666, |
343 | sc->debug.debugfs_phydir, | 428 | sc->debug.debugfs_phydir, sc, &fops_beacon); |
344 | sc, &fops_beacon); | ||
345 | 429 | ||
346 | sc->debug.debugfs_reset = debugfs_create_file("reset", 0222, | 430 | sc->debug.debugfs_reset = debugfs_create_file("reset", 0222, |
347 | sc->debug.debugfs_phydir, | 431 | sc->debug.debugfs_phydir, sc, &fops_reset); |
348 | sc, &fops_reset); | ||
349 | } | 432 | } |
350 | 433 | ||
351 | void | 434 | void |
@@ -415,8 +498,7 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) | |||
415 | struct ath5k_buf *bf; | 498 | struct ath5k_buf *bf; |
416 | int status; | 499 | int status; |
417 | 500 | ||
418 | if (likely(!(sc->debug.level & | 501 | if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET))) |
419 | (ATH5K_DEBUG_RESET | ATH5K_DEBUG_FATAL)))) | ||
420 | return; | 502 | return; |
421 | 503 | ||
422 | printk(KERN_DEBUG "rx queue %x, link %p\n", | 504 | printk(KERN_DEBUG "rx queue %x, link %p\n", |
@@ -426,7 +508,7 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) | |||
426 | list_for_each_entry(bf, &sc->rxbuf, list) { | 508 | list_for_each_entry(bf, &sc->rxbuf, list) { |
427 | ds = bf->desc; | 509 | ds = bf->desc; |
428 | status = ah->ah_proc_rx_desc(ah, ds); | 510 | status = ah->ah_proc_rx_desc(ah, ds); |
429 | if (!status || (sc->debug.level & ATH5K_DEBUG_FATAL)) | 511 | if (!status) |
430 | ath5k_debug_printrxbuf(bf, status == 0); | 512 | ath5k_debug_printrxbuf(bf, status == 0); |
431 | } | 513 | } |
432 | spin_unlock_bh(&sc->rxbuflock); | 514 | spin_unlock_bh(&sc->rxbuflock); |
diff --git a/drivers/net/wireless/ath5k/debug.h b/drivers/net/wireless/ath5k/debug.h index 2b491cbc8c80..c4fd8c43df0c 100644 --- a/drivers/net/wireless/ath5k/debug.h +++ b/drivers/net/wireless/ath5k/debug.h | |||
@@ -91,7 +91,6 @@ struct ath5k_dbg_info { | |||
91 | * @ATH5K_DEBUG_MODE: mode init/setup | 91 | * @ATH5K_DEBUG_MODE: mode init/setup |
92 | * @ATH5K_DEBUG_XMIT: basic xmit operation | 92 | * @ATH5K_DEBUG_XMIT: basic xmit operation |
93 | * @ATH5K_DEBUG_BEACON: beacon handling | 93 | * @ATH5K_DEBUG_BEACON: beacon handling |
94 | * @ATH5K_DEBUG_BEACON_PROC: beacon ISR proc | ||
95 | * @ATH5K_DEBUG_CALIBRATE: periodic calibration | 94 | * @ATH5K_DEBUG_CALIBRATE: periodic calibration |
96 | * @ATH5K_DEBUG_TXPOWER: transmit power setting | 95 | * @ATH5K_DEBUG_TXPOWER: transmit power setting |
97 | * @ATH5K_DEBUG_LED: led management | 96 | * @ATH5K_DEBUG_LED: led management |
@@ -99,7 +98,6 @@ struct ath5k_dbg_info { | |||
99 | * @ATH5K_DEBUG_DUMP_TX: print transmit skb content | 98 | * @ATH5K_DEBUG_DUMP_TX: print transmit skb content |
100 | * @ATH5K_DEBUG_DUMPMODES: dump modes | 99 | * @ATH5K_DEBUG_DUMPMODES: dump modes |
101 | * @ATH5K_DEBUG_TRACE: trace function calls | 100 | * @ATH5K_DEBUG_TRACE: trace function calls |
102 | * @ATH5K_DEBUG_FATAL: fatal errors | ||
103 | * @ATH5K_DEBUG_ANY: show at any debug level | 101 | * @ATH5K_DEBUG_ANY: show at any debug level |
104 | * | 102 | * |
105 | * The debug level is used to control the amount and type of debugging output | 103 | * The debug level is used to control the amount and type of debugging output |
@@ -115,15 +113,13 @@ enum ath5k_debug_level { | |||
115 | ATH5K_DEBUG_MODE = 0x00000004, | 113 | ATH5K_DEBUG_MODE = 0x00000004, |
116 | ATH5K_DEBUG_XMIT = 0x00000008, | 114 | ATH5K_DEBUG_XMIT = 0x00000008, |
117 | ATH5K_DEBUG_BEACON = 0x00000010, | 115 | ATH5K_DEBUG_BEACON = 0x00000010, |
118 | ATH5K_DEBUG_BEACON_PROC = 0x00000020, | 116 | ATH5K_DEBUG_CALIBRATE = 0x00000020, |
119 | ATH5K_DEBUG_CALIBRATE = 0x00000100, | 117 | ATH5K_DEBUG_TXPOWER = 0x00000040, |
120 | ATH5K_DEBUG_TXPOWER = 0x00000200, | 118 | ATH5K_DEBUG_LED = 0x00000080, |
121 | ATH5K_DEBUG_LED = 0x00000400, | 119 | ATH5K_DEBUG_DUMP_RX = 0x00000100, |
122 | ATH5K_DEBUG_DUMP_RX = 0x00001000, | 120 | ATH5K_DEBUG_DUMP_TX = 0x00000200, |
123 | ATH5K_DEBUG_DUMP_TX = 0x00002000, | 121 | ATH5K_DEBUG_DUMPMODES = 0x00000400, |
124 | ATH5K_DEBUG_DUMPMODES = 0x00004000, | 122 | ATH5K_DEBUG_TRACE = 0x00001000, |
125 | ATH5K_DEBUG_TRACE = 0x00010000, | ||
126 | ATH5K_DEBUG_FATAL = 0x80000000, | ||
127 | ATH5K_DEBUG_ANY = 0xffffffff | 123 | ATH5K_DEBUG_ANY = 0xffffffff |
128 | }; | 124 | }; |
129 | 125 | ||