aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorBruno Randolf <bruno@thinktube.com>2008-01-22 20:27:51 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-31 22:26:35 -0500
commitbe9b72590c05daf34c2b55cd5b7c68375a4a795b (patch)
treeb14df772e982996effc400fce57268f3547d0bc3 /drivers/net/wireless
parent691ba2346d5b88cec62fe8db0bf336a58a07b926 (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')
-rw-r--r--drivers/net/wireless/ath5k/base.c10
-rw-r--r--drivers/net/wireless/ath5k/debug.c124
-rw-r--r--drivers/net/wireless/ath5k/debug.h18
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
328static 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
348static 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
373static 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
394static 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
319void 404void
@@ -326,26 +411,24 @@ void
326ath5k_debug_init_device(struct ath5k_softc *sc) 411ath5k_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
351void 434void
@@ -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