root/drivers/net/wireless/ath/ath5k/debug.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. reg_start
  2. reg_stop
  3. reg_next
  4. reg_show
  5. open_file_registers
  6. read_file_beacon
  7. write_file_beacon
  8. write_file_reset
  9. read_file_debug
  10. write_file_debug
  11. read_file_antenna
  12. write_file_antenna
  13. read_file_misc
  14. read_file_frameerrors
  15. write_file_frameerrors
  16. read_file_ani
  17. write_file_ani
  18. read_file_queue
  19. write_file_queue
  20. open_file_eeprom
  21. read_file_eeprom
  22. release_file_eeprom
  23. ath5k_debug_init_device
  24. ath5k_debug_dump_bands
  25. ath5k_debug_printrxbuf
  26. ath5k_debug_printrxbuffs
  27. ath5k_debug_printtxbuf

   1 /*
   2  * Copyright (c) 2007-2008 Bruno Randolf <bruno@thinktube.com>
   3  *
   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
   6  *  Free Software Foundation, either version 2 of the License, or (at your
   7  *  option) any later version.
   8  *
   9  *  This file is distributed in the hope that it will be useful, but
  10  *  WITHOUT ANY WARRANTY; without even the implied warranty of
  11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12  *  General Public License for more details.
  13  *
  14  *  You should have received a copy of the GNU General Public License
  15  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  16  *
  17  *
  18  * This file incorporates work covered by the following copyright and
  19  * permission notice:
  20  *
  21  * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
  22  * Copyright (c) 2004-2005 Atheros Communications, Inc.
  23  * Copyright (c) 2006 Devicescape Software, Inc.
  24  * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
  25  * Copyright (c) 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
  26  *
  27  * All rights reserved.
  28  *
  29  * Redistribution and use in source and binary forms, with or without
  30  * modification, are permitted provided that the following conditions
  31  * are met:
  32  * 1. Redistributions of source code must retain the above copyright
  33  *    notice, this list of conditions and the following disclaimer,
  34  *    without modification.
  35  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  36  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
  37  *    redistribution must be conditioned upon including a substantially
  38  *    similar Disclaimer requirement for further binary redistribution.
  39  * 3. Neither the names of the above-listed copyright holders nor the names
  40  *    of any contributors may be used to endorse or promote products derived
  41  *    from this software without specific prior written permission.
  42  *
  43  * Alternatively, this software may be distributed under the terms of the
  44  * GNU General Public License ("GPL") version 2 as published by the Free
  45  * Software Foundation.
  46  *
  47  * NO WARRANTY
  48  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  49  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  50  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
  51  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
  52  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
  53  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  54  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  55  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  56  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  57  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  58  * THE POSSIBILITY OF SUCH DAMAGES.
  59  */
  60 
  61 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  62 
  63 #include <linux/export.h>
  64 #include <linux/moduleparam.h>
  65 #include <linux/vmalloc.h>
  66 
  67 #include <linux/seq_file.h>
  68 #include <linux/list.h>
  69 #include "debug.h"
  70 #include "ath5k.h"
  71 #include "reg.h"
  72 #include "base.h"
  73 
  74 static unsigned int ath5k_debug;
  75 module_param_named(debug, ath5k_debug, uint, 0);
  76 
  77 
  78 /* debugfs: registers */
  79 
  80 struct reg {
  81         const char *name;
  82         int addr;
  83 };
  84 
  85 #define REG_STRUCT_INIT(r) { #r, r }
  86 
  87 /* just a few random registers, might want to add more */
  88 static const struct reg regs[] = {
  89         REG_STRUCT_INIT(AR5K_CR),
  90         REG_STRUCT_INIT(AR5K_RXDP),
  91         REG_STRUCT_INIT(AR5K_CFG),
  92         REG_STRUCT_INIT(AR5K_IER),
  93         REG_STRUCT_INIT(AR5K_BCR),
  94         REG_STRUCT_INIT(AR5K_RTSD0),
  95         REG_STRUCT_INIT(AR5K_RTSD1),
  96         REG_STRUCT_INIT(AR5K_TXCFG),
  97         REG_STRUCT_INIT(AR5K_RXCFG),
  98         REG_STRUCT_INIT(AR5K_RXJLA),
  99         REG_STRUCT_INIT(AR5K_MIBC),
 100         REG_STRUCT_INIT(AR5K_TOPS),
 101         REG_STRUCT_INIT(AR5K_RXNOFRM),
 102         REG_STRUCT_INIT(AR5K_TXNOFRM),
 103         REG_STRUCT_INIT(AR5K_RPGTO),
 104         REG_STRUCT_INIT(AR5K_RFCNT),
 105         REG_STRUCT_INIT(AR5K_MISC),
 106         REG_STRUCT_INIT(AR5K_QCUDCU_CLKGT),
 107         REG_STRUCT_INIT(AR5K_ISR),
 108         REG_STRUCT_INIT(AR5K_PISR),
 109         REG_STRUCT_INIT(AR5K_SISR0),
 110         REG_STRUCT_INIT(AR5K_SISR1),
 111         REG_STRUCT_INIT(AR5K_SISR2),
 112         REG_STRUCT_INIT(AR5K_SISR3),
 113         REG_STRUCT_INIT(AR5K_SISR4),
 114         REG_STRUCT_INIT(AR5K_IMR),
 115         REG_STRUCT_INIT(AR5K_PIMR),
 116         REG_STRUCT_INIT(AR5K_SIMR0),
 117         REG_STRUCT_INIT(AR5K_SIMR1),
 118         REG_STRUCT_INIT(AR5K_SIMR2),
 119         REG_STRUCT_INIT(AR5K_SIMR3),
 120         REG_STRUCT_INIT(AR5K_SIMR4),
 121         REG_STRUCT_INIT(AR5K_DCM_ADDR),
 122         REG_STRUCT_INIT(AR5K_DCCFG),
 123         REG_STRUCT_INIT(AR5K_CCFG),
 124         REG_STRUCT_INIT(AR5K_CPC0),
 125         REG_STRUCT_INIT(AR5K_CPC1),
 126         REG_STRUCT_INIT(AR5K_CPC2),
 127         REG_STRUCT_INIT(AR5K_CPC3),
 128         REG_STRUCT_INIT(AR5K_CPCOVF),
 129         REG_STRUCT_INIT(AR5K_RESET_CTL),
 130         REG_STRUCT_INIT(AR5K_SLEEP_CTL),
 131         REG_STRUCT_INIT(AR5K_INTPEND),
 132         REG_STRUCT_INIT(AR5K_SFR),
 133         REG_STRUCT_INIT(AR5K_PCICFG),
 134         REG_STRUCT_INIT(AR5K_GPIOCR),
 135         REG_STRUCT_INIT(AR5K_GPIODO),
 136         REG_STRUCT_INIT(AR5K_SREV),
 137 };
 138 
 139 static void *reg_start(struct seq_file *seq, loff_t *pos)
 140 {
 141         return *pos < ARRAY_SIZE(regs) ? (void *)&regs[*pos] : NULL;
 142 }
 143 
 144 static void reg_stop(struct seq_file *seq, void *p)
 145 {
 146         /* nothing to do */
 147 }
 148 
 149 static void *reg_next(struct seq_file *seq, void *p, loff_t *pos)
 150 {
 151         ++*pos;
 152         return *pos < ARRAY_SIZE(regs) ? (void *)&regs[*pos] : NULL;
 153 }
 154 
 155 static int reg_show(struct seq_file *seq, void *p)
 156 {
 157         struct ath5k_hw *ah = seq->private;
 158         struct reg *r = p;
 159         seq_printf(seq, "%-25s0x%08x\n", r->name,
 160                 ath5k_hw_reg_read(ah, r->addr));
 161         return 0;
 162 }
 163 
 164 static const struct seq_operations register_seq_ops = {
 165         .start = reg_start,
 166         .next  = reg_next,
 167         .stop  = reg_stop,
 168         .show  = reg_show
 169 };
 170 
 171 static int open_file_registers(struct inode *inode, struct file *file)
 172 {
 173         struct seq_file *s;
 174         int res;
 175         res = seq_open(file, &register_seq_ops);
 176         if (res == 0) {
 177                 s = file->private_data;
 178                 s->private = inode->i_private;
 179         }
 180         return res;
 181 }
 182 
 183 static const struct file_operations fops_registers = {
 184         .open = open_file_registers,
 185         .read    = seq_read,
 186         .llseek  = seq_lseek,
 187         .release = seq_release,
 188         .owner = THIS_MODULE,
 189 };
 190 
 191 
 192 /* debugfs: beacons */
 193 
 194 static ssize_t read_file_beacon(struct file *file, char __user *user_buf,
 195                                    size_t count, loff_t *ppos)
 196 {
 197         struct ath5k_hw *ah = file->private_data;
 198         char buf[500];
 199         unsigned int len = 0;
 200         unsigned int v;
 201         u64 tsf;
 202 
 203         v = ath5k_hw_reg_read(ah, AR5K_BEACON);
 204         len += snprintf(buf + len, sizeof(buf) - len,
 205                 "%-24s0x%08x\tintval: %d\tTIM: 0x%x\n",
 206                 "AR5K_BEACON", v, v & AR5K_BEACON_PERIOD,
 207                 (v & AR5K_BEACON_TIM) >> AR5K_BEACON_TIM_S);
 208 
 209         len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\n",
 210                 "AR5K_LAST_TSTP", ath5k_hw_reg_read(ah, AR5K_LAST_TSTP));
 211 
 212         len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\n\n",
 213                 "AR5K_BEACON_CNT", ath5k_hw_reg_read(ah, AR5K_BEACON_CNT));
 214 
 215         v = ath5k_hw_reg_read(ah, AR5K_TIMER0);
 216         len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\tTU: %08x\n",
 217                 "AR5K_TIMER0 (TBTT)", v, v);
 218 
 219         v = ath5k_hw_reg_read(ah, AR5K_TIMER1);
 220         len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\tTU: %08x\n",
 221                 "AR5K_TIMER1 (DMA)", v, v >> 3);
 222 
 223         v = ath5k_hw_reg_read(ah, AR5K_TIMER2);
 224         len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\tTU: %08x\n",
 225                 "AR5K_TIMER2 (SWBA)", v, v >> 3);
 226 
 227         v = ath5k_hw_reg_read(ah, AR5K_TIMER3);
 228         len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\tTU: %08x\n",
 229                 "AR5K_TIMER3 (ATIM)", v, v);
 230 
 231         tsf = ath5k_hw_get_tsf64(ah);
 232         len += snprintf(buf + len, sizeof(buf) - len,
 233                 "TSF\t\t0x%016llx\tTU: %08x\n",
 234                 (unsigned long long)tsf, TSF_TO_TU(tsf));
 235 
 236         if (len > sizeof(buf))
 237                 len = sizeof(buf);
 238 
 239         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 240 }
 241 
 242 static ssize_t write_file_beacon(struct file *file,
 243                                  const char __user *userbuf,
 244                                  size_t count, loff_t *ppos)
 245 {
 246         struct ath5k_hw *ah = file->private_data;
 247         char buf[20];
 248 
 249         count = min_t(size_t, count, sizeof(buf) - 1);
 250         if (copy_from_user(buf, userbuf, count))
 251                 return -EFAULT;
 252 
 253         buf[count] = '\0';
 254         if (strncmp(buf, "disable", 7) == 0) {
 255                 AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
 256                 pr_info("debugfs disable beacons\n");
 257         } else if (strncmp(buf, "enable", 6) == 0) {
 258                 AR5K_REG_ENABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
 259                 pr_info("debugfs enable beacons\n");
 260         }
 261         return count;
 262 }
 263 
 264 static const struct file_operations fops_beacon = {
 265         .read = read_file_beacon,
 266         .write = write_file_beacon,
 267         .open = simple_open,
 268         .owner = THIS_MODULE,
 269         .llseek = default_llseek,
 270 };
 271 
 272 
 273 /* debugfs: reset */
 274 
 275 static ssize_t write_file_reset(struct file *file,
 276                                  const char __user *userbuf,
 277                                  size_t count, loff_t *ppos)
 278 {
 279         struct ath5k_hw *ah = file->private_data;
 280         ATH5K_DBG(ah, ATH5K_DEBUG_RESET, "debug file triggered reset\n");
 281         ieee80211_queue_work(ah->hw, &ah->reset_work);
 282         return count;
 283 }
 284 
 285 static const struct file_operations fops_reset = {
 286         .write = write_file_reset,
 287         .open = simple_open,
 288         .owner = THIS_MODULE,
 289         .llseek = noop_llseek,
 290 };
 291 
 292 
 293 /* debugfs: debug level */
 294 
 295 static const struct {
 296         enum ath5k_debug_level level;
 297         const char *name;
 298         const char *desc;
 299 } dbg_info[] = {
 300         { ATH5K_DEBUG_RESET,    "reset",        "reset and initialization" },
 301         { ATH5K_DEBUG_INTR,     "intr",         "interrupt handling" },
 302         { ATH5K_DEBUG_MODE,     "mode",         "mode init/setup" },
 303         { ATH5K_DEBUG_XMIT,     "xmit",         "basic xmit operation" },
 304         { ATH5K_DEBUG_BEACON,   "beacon",       "beacon handling" },
 305         { ATH5K_DEBUG_CALIBRATE, "calib",       "periodic calibration" },
 306         { ATH5K_DEBUG_TXPOWER,  "txpower",      "transmit power setting" },
 307         { ATH5K_DEBUG_LED,      "led",          "LED management" },
 308         { ATH5K_DEBUG_DUMPBANDS, "dumpbands",   "dump bands" },
 309         { ATH5K_DEBUG_DMA,      "dma",          "dma start/stop" },
 310         { ATH5K_DEBUG_ANI,      "ani",          "adaptive noise immunity" },
 311         { ATH5K_DEBUG_DESC,     "desc",         "descriptor chains" },
 312         { ATH5K_DEBUG_ANY,      "all",          "show all debug levels" },
 313 };
 314 
 315 static ssize_t read_file_debug(struct file *file, char __user *user_buf,
 316                                    size_t count, loff_t *ppos)
 317 {
 318         struct ath5k_hw *ah = file->private_data;
 319         char buf[700];
 320         unsigned int len = 0;
 321         unsigned int i;
 322 
 323         len += snprintf(buf + len, sizeof(buf) - len,
 324                 "DEBUG LEVEL: 0x%08x\n\n", ah->debug.level);
 325 
 326         for (i = 0; i < ARRAY_SIZE(dbg_info) - 1; i++) {
 327                 len += snprintf(buf + len, sizeof(buf) - len,
 328                         "%10s %c 0x%08x - %s\n", dbg_info[i].name,
 329                         ah->debug.level & dbg_info[i].level ? '+' : ' ',
 330                         dbg_info[i].level, dbg_info[i].desc);
 331         }
 332         len += snprintf(buf + len, sizeof(buf) - len,
 333                 "%10s %c 0x%08x - %s\n", dbg_info[i].name,
 334                 ah->debug.level == dbg_info[i].level ? '+' : ' ',
 335                 dbg_info[i].level, dbg_info[i].desc);
 336 
 337         if (len > sizeof(buf))
 338                 len = sizeof(buf);
 339 
 340         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 341 }
 342 
 343 static ssize_t write_file_debug(struct file *file,
 344                                  const char __user *userbuf,
 345                                  size_t count, loff_t *ppos)
 346 {
 347         struct ath5k_hw *ah = file->private_data;
 348         unsigned int i;
 349         char buf[20];
 350 
 351         count = min_t(size_t, count, sizeof(buf) - 1);
 352         if (copy_from_user(buf, userbuf, count))
 353                 return -EFAULT;
 354 
 355         buf[count] = '\0';
 356         for (i = 0; i < ARRAY_SIZE(dbg_info); i++) {
 357                 if (strncmp(buf, dbg_info[i].name,
 358                                         strlen(dbg_info[i].name)) == 0) {
 359                         ah->debug.level ^= dbg_info[i].level; /* toggle bit */
 360                         break;
 361                 }
 362         }
 363         return count;
 364 }
 365 
 366 static const struct file_operations fops_debug = {
 367         .read = read_file_debug,
 368         .write = write_file_debug,
 369         .open = simple_open,
 370         .owner = THIS_MODULE,
 371         .llseek = default_llseek,
 372 };
 373 
 374 
 375 /* debugfs: antenna */
 376 
 377 static ssize_t read_file_antenna(struct file *file, char __user *user_buf,
 378                                    size_t count, loff_t *ppos)
 379 {
 380         struct ath5k_hw *ah = file->private_data;
 381         char buf[700];
 382         unsigned int len = 0;
 383         unsigned int i;
 384         unsigned int v;
 385 
 386         len += snprintf(buf + len, sizeof(buf) - len, "antenna mode\t%d\n",
 387                 ah->ah_ant_mode);
 388         len += snprintf(buf + len, sizeof(buf) - len, "default antenna\t%d\n",
 389                 ah->ah_def_ant);
 390         len += snprintf(buf + len, sizeof(buf) - len, "tx antenna\t%d\n",
 391                 ah->ah_tx_ant);
 392 
 393         len += snprintf(buf + len, sizeof(buf) - len, "\nANTENNA\t\tRX\tTX\n");
 394         for (i = 1; i < ARRAY_SIZE(ah->stats.antenna_rx); i++) {
 395                 len += snprintf(buf + len, sizeof(buf) - len,
 396                         "[antenna %d]\t%d\t%d\n",
 397                         i, ah->stats.antenna_rx[i], ah->stats.antenna_tx[i]);
 398         }
 399         len += snprintf(buf + len, sizeof(buf) - len, "[invalid]\t%d\t%d\n",
 400                         ah->stats.antenna_rx[0], ah->stats.antenna_tx[0]);
 401 
 402         v = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA);
 403         len += snprintf(buf + len, sizeof(buf) - len,
 404                         "\nAR5K_DEFAULT_ANTENNA\t0x%08x\n", v);
 405 
 406         v = ath5k_hw_reg_read(ah, AR5K_STA_ID1);
 407         len += snprintf(buf + len, sizeof(buf) - len,
 408                 "AR5K_STA_ID1_DEFAULT_ANTENNA\t%d\n",
 409                 (v & AR5K_STA_ID1_DEFAULT_ANTENNA) != 0);
 410         len += snprintf(buf + len, sizeof(buf) - len,
 411                 "AR5K_STA_ID1_DESC_ANTENNA\t%d\n",
 412                 (v & AR5K_STA_ID1_DESC_ANTENNA) != 0);
 413         len += snprintf(buf + len, sizeof(buf) - len,
 414                 "AR5K_STA_ID1_RTS_DEF_ANTENNA\t%d\n",
 415                 (v & AR5K_STA_ID1_RTS_DEF_ANTENNA) != 0);
 416         len += snprintf(buf + len, sizeof(buf) - len,
 417                 "AR5K_STA_ID1_SELFGEN_DEF_ANT\t%d\n",
 418                 (v & AR5K_STA_ID1_SELFGEN_DEF_ANT) != 0);
 419 
 420         v = ath5k_hw_reg_read(ah, AR5K_PHY_AGCCTL);
 421         len += snprintf(buf + len, sizeof(buf) - len,
 422                 "\nAR5K_PHY_AGCCTL_OFDM_DIV_DIS\t%d\n",
 423                 (v & AR5K_PHY_AGCCTL_OFDM_DIV_DIS) != 0);
 424 
 425         v = ath5k_hw_reg_read(ah, AR5K_PHY_RESTART);
 426         len += snprintf(buf + len, sizeof(buf) - len,
 427                 "AR5K_PHY_RESTART_DIV_GC\t\t%x\n",
 428                 (v & AR5K_PHY_RESTART_DIV_GC) >> AR5K_PHY_RESTART_DIV_GC_S);
 429 
 430         v = ath5k_hw_reg_read(ah, AR5K_PHY_FAST_ANT_DIV);
 431         len += snprintf(buf + len, sizeof(buf) - len,
 432                 "AR5K_PHY_FAST_ANT_DIV_EN\t%d\n",
 433                 (v & AR5K_PHY_FAST_ANT_DIV_EN) != 0);
 434 
 435         v = ath5k_hw_reg_read(ah, AR5K_PHY_ANT_SWITCH_TABLE_0);
 436         len += snprintf(buf + len, sizeof(buf) - len,
 437                         "\nAR5K_PHY_ANT_SWITCH_TABLE_0\t0x%08x\n", v);
 438         v = ath5k_hw_reg_read(ah, AR5K_PHY_ANT_SWITCH_TABLE_1);
 439         len += snprintf(buf + len, sizeof(buf) - len,
 440                         "AR5K_PHY_ANT_SWITCH_TABLE_1\t0x%08x\n", v);
 441 
 442         if (len > sizeof(buf))
 443                 len = sizeof(buf);
 444 
 445         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 446 }
 447 
 448 static ssize_t write_file_antenna(struct file *file,
 449                                  const char __user *userbuf,
 450                                  size_t count, loff_t *ppos)
 451 {
 452         struct ath5k_hw *ah = file->private_data;
 453         unsigned int i;
 454         char buf[20];
 455 
 456         count = min_t(size_t, count, sizeof(buf) - 1);
 457         if (copy_from_user(buf, userbuf, count))
 458                 return -EFAULT;
 459 
 460         buf[count] = '\0';
 461         if (strncmp(buf, "diversity", 9) == 0) {
 462                 ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_DEFAULT);
 463                 pr_info("debug: enable diversity\n");
 464         } else if (strncmp(buf, "fixed-a", 7) == 0) {
 465                 ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_FIXED_A);
 466                 pr_info("debug: fixed antenna A\n");
 467         } else if (strncmp(buf, "fixed-b", 7) == 0) {
 468                 ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_FIXED_B);
 469                 pr_info("debug: fixed antenna B\n");
 470         } else if (strncmp(buf, "clear", 5) == 0) {
 471                 for (i = 0; i < ARRAY_SIZE(ah->stats.antenna_rx); i++) {
 472                         ah->stats.antenna_rx[i] = 0;
 473                         ah->stats.antenna_tx[i] = 0;
 474                 }
 475                 pr_info("debug: cleared antenna stats\n");
 476         }
 477         return count;
 478 }
 479 
 480 static const struct file_operations fops_antenna = {
 481         .read = read_file_antenna,
 482         .write = write_file_antenna,
 483         .open = simple_open,
 484         .owner = THIS_MODULE,
 485         .llseek = default_llseek,
 486 };
 487 
 488 /* debugfs: misc */
 489 
 490 static ssize_t read_file_misc(struct file *file, char __user *user_buf,
 491                                    size_t count, loff_t *ppos)
 492 {
 493         struct ath5k_hw *ah = file->private_data;
 494         char buf[700];
 495         unsigned int len = 0;
 496         u32 filt = ath5k_hw_get_rx_filter(ah);
 497 
 498         len += snprintf(buf + len, sizeof(buf) - len, "bssid-mask: %pM\n",
 499                         ah->bssidmask);
 500         len += snprintf(buf + len, sizeof(buf) - len, "filter-flags: 0x%x ",
 501                         filt);
 502         if (filt & AR5K_RX_FILTER_UCAST)
 503                 len += snprintf(buf + len, sizeof(buf) - len, " UCAST");
 504         if (filt & AR5K_RX_FILTER_MCAST)
 505                 len += snprintf(buf + len, sizeof(buf) - len, " MCAST");
 506         if (filt & AR5K_RX_FILTER_BCAST)
 507                 len += snprintf(buf + len, sizeof(buf) - len, " BCAST");
 508         if (filt & AR5K_RX_FILTER_CONTROL)
 509                 len += snprintf(buf + len, sizeof(buf) - len, " CONTROL");
 510         if (filt & AR5K_RX_FILTER_BEACON)
 511                 len += snprintf(buf + len, sizeof(buf) - len, " BEACON");
 512         if (filt & AR5K_RX_FILTER_PROM)
 513                 len += snprintf(buf + len, sizeof(buf) - len, " PROM");
 514         if (filt & AR5K_RX_FILTER_XRPOLL)
 515                 len += snprintf(buf + len, sizeof(buf) - len, " XRPOLL");
 516         if (filt & AR5K_RX_FILTER_PROBEREQ)
 517                 len += snprintf(buf + len, sizeof(buf) - len, " PROBEREQ");
 518         if (filt & AR5K_RX_FILTER_PHYERR_5212)
 519                 len += snprintf(buf + len, sizeof(buf) - len, " PHYERR-5212");
 520         if (filt & AR5K_RX_FILTER_RADARERR_5212)
 521                 len += snprintf(buf + len, sizeof(buf) - len, " RADARERR-5212");
 522         if (filt & AR5K_RX_FILTER_PHYERR_5211)
 523                 snprintf(buf + len, sizeof(buf) - len, " PHYERR-5211");
 524         if (filt & AR5K_RX_FILTER_RADARERR_5211)
 525                 len += snprintf(buf + len, sizeof(buf) - len, " RADARERR-5211");
 526 
 527         len += snprintf(buf + len, sizeof(buf) - len, "\nopmode: %s (%d)\n",
 528                         ath_opmode_to_string(ah->opmode), ah->opmode);
 529 
 530         if (len > sizeof(buf))
 531                 len = sizeof(buf);
 532 
 533         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 534 }
 535 
 536 static const struct file_operations fops_misc = {
 537         .read = read_file_misc,
 538         .open = simple_open,
 539         .owner = THIS_MODULE,
 540 };
 541 
 542 
 543 /* debugfs: frameerrors */
 544 
 545 static ssize_t read_file_frameerrors(struct file *file, char __user *user_buf,
 546                                    size_t count, loff_t *ppos)
 547 {
 548         struct ath5k_hw *ah = file->private_data;
 549         struct ath5k_statistics *st = &ah->stats;
 550         char buf[700];
 551         unsigned int len = 0;
 552         int i;
 553 
 554         len += snprintf(buf + len, sizeof(buf) - len,
 555                         "RX\n---------------------\n");
 556         len += snprintf(buf + len, sizeof(buf) - len, "CRC\t%u\t(%u%%)\n",
 557                         st->rxerr_crc,
 558                         st->rx_all_count > 0 ?
 559                                 st->rxerr_crc * 100 / st->rx_all_count : 0);
 560         len += snprintf(buf + len, sizeof(buf) - len, "PHY\t%u\t(%u%%)\n",
 561                         st->rxerr_phy,
 562                         st->rx_all_count > 0 ?
 563                                 st->rxerr_phy * 100 / st->rx_all_count : 0);
 564         for (i = 0; i < 32; i++) {
 565                 if (st->rxerr_phy_code[i])
 566                         len += snprintf(buf + len, sizeof(buf) - len,
 567                                 " phy_err[%u]\t%u\n",
 568                                 i, st->rxerr_phy_code[i]);
 569         }
 570 
 571         len += snprintf(buf + len, sizeof(buf) - len, "FIFO\t%u\t(%u%%)\n",
 572                         st->rxerr_fifo,
 573                         st->rx_all_count > 0 ?
 574                                 st->rxerr_fifo * 100 / st->rx_all_count : 0);
 575         len += snprintf(buf + len, sizeof(buf) - len, "decrypt\t%u\t(%u%%)\n",
 576                         st->rxerr_decrypt,
 577                         st->rx_all_count > 0 ?
 578                                 st->rxerr_decrypt * 100 / st->rx_all_count : 0);
 579         len += snprintf(buf + len, sizeof(buf) - len, "MIC\t%u\t(%u%%)\n",
 580                         st->rxerr_mic,
 581                         st->rx_all_count > 0 ?
 582                                 st->rxerr_mic * 100 / st->rx_all_count : 0);
 583         len += snprintf(buf + len, sizeof(buf) - len, "process\t%u\t(%u%%)\n",
 584                         st->rxerr_proc,
 585                         st->rx_all_count > 0 ?
 586                                 st->rxerr_proc * 100 / st->rx_all_count : 0);
 587         len += snprintf(buf + len, sizeof(buf) - len, "jumbo\t%u\t(%u%%)\n",
 588                         st->rxerr_jumbo,
 589                         st->rx_all_count > 0 ?
 590                                 st->rxerr_jumbo * 100 / st->rx_all_count : 0);
 591         len += snprintf(buf + len, sizeof(buf) - len, "[RX all\t%u]\n",
 592                         st->rx_all_count);
 593         len += snprintf(buf + len, sizeof(buf) - len, "RX-all-bytes\t%u\n",
 594                         st->rx_bytes_count);
 595 
 596         len += snprintf(buf + len, sizeof(buf) - len,
 597                         "\nTX\n---------------------\n");
 598         len += snprintf(buf + len, sizeof(buf) - len, "retry\t%u\t(%u%%)\n",
 599                         st->txerr_retry,
 600                         st->tx_all_count > 0 ?
 601                                 st->txerr_retry * 100 / st->tx_all_count : 0);
 602         len += snprintf(buf + len, sizeof(buf) - len, "FIFO\t%u\t(%u%%)\n",
 603                         st->txerr_fifo,
 604                         st->tx_all_count > 0 ?
 605                                 st->txerr_fifo * 100 / st->tx_all_count : 0);
 606         len += snprintf(buf + len, sizeof(buf) - len, "filter\t%u\t(%u%%)\n",
 607                         st->txerr_filt,
 608                         st->tx_all_count > 0 ?
 609                                 st->txerr_filt * 100 / st->tx_all_count : 0);
 610         len += snprintf(buf + len, sizeof(buf) - len, "[TX all\t%u]\n",
 611                         st->tx_all_count);
 612         len += snprintf(buf + len, sizeof(buf) - len, "TX-all-bytes\t%u\n",
 613                         st->tx_bytes_count);
 614 
 615         if (len > sizeof(buf))
 616                 len = sizeof(buf);
 617 
 618         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 619 }
 620 
 621 static ssize_t write_file_frameerrors(struct file *file,
 622                                  const char __user *userbuf,
 623                                  size_t count, loff_t *ppos)
 624 {
 625         struct ath5k_hw *ah = file->private_data;
 626         struct ath5k_statistics *st = &ah->stats;
 627         char buf[20];
 628 
 629         count = min_t(size_t, count, sizeof(buf) - 1);
 630         if (copy_from_user(buf, userbuf, count))
 631                 return -EFAULT;
 632 
 633         buf[count] = '\0';
 634         if (strncmp(buf, "clear", 5) == 0) {
 635                 st->rxerr_crc = 0;
 636                 st->rxerr_phy = 0;
 637                 st->rxerr_fifo = 0;
 638                 st->rxerr_decrypt = 0;
 639                 st->rxerr_mic = 0;
 640                 st->rxerr_proc = 0;
 641                 st->rxerr_jumbo = 0;
 642                 st->rx_all_count = 0;
 643                 st->txerr_retry = 0;
 644                 st->txerr_fifo = 0;
 645                 st->txerr_filt = 0;
 646                 st->tx_all_count = 0;
 647                 pr_info("debug: cleared frameerrors stats\n");
 648         }
 649         return count;
 650 }
 651 
 652 static const struct file_operations fops_frameerrors = {
 653         .read = read_file_frameerrors,
 654         .write = write_file_frameerrors,
 655         .open = simple_open,
 656         .owner = THIS_MODULE,
 657         .llseek = default_llseek,
 658 };
 659 
 660 
 661 /* debugfs: ani */
 662 
 663 static ssize_t read_file_ani(struct file *file, char __user *user_buf,
 664                                    size_t count, loff_t *ppos)
 665 {
 666         struct ath5k_hw *ah = file->private_data;
 667         struct ath5k_statistics *st = &ah->stats;
 668         struct ath5k_ani_state *as = &ah->ani_state;
 669 
 670         char buf[700];
 671         unsigned int len = 0;
 672 
 673         len += snprintf(buf + len, sizeof(buf) - len,
 674                         "HW has PHY error counters:\t%s\n",
 675                         ah->ah_capabilities.cap_has_phyerr_counters ?
 676                         "yes" : "no");
 677         len += snprintf(buf + len, sizeof(buf) - len,
 678                         "HW max spur immunity level:\t%d\n",
 679                         as->max_spur_level);
 680         len += snprintf(buf + len, sizeof(buf) - len,
 681                 "\nANI state\n--------------------------------------------\n");
 682         len += snprintf(buf + len, sizeof(buf) - len, "operating mode:\t\t\t");
 683         switch (as->ani_mode) {
 684         case ATH5K_ANI_MODE_OFF:
 685                 len += snprintf(buf + len, sizeof(buf) - len, "OFF\n");
 686                 break;
 687         case ATH5K_ANI_MODE_MANUAL_LOW:
 688                 len += snprintf(buf + len, sizeof(buf) - len,
 689                         "MANUAL LOW\n");
 690                 break;
 691         case ATH5K_ANI_MODE_MANUAL_HIGH:
 692                 len += snprintf(buf + len, sizeof(buf) - len,
 693                         "MANUAL HIGH\n");
 694                 break;
 695         case ATH5K_ANI_MODE_AUTO:
 696                 len += snprintf(buf + len, sizeof(buf) - len, "AUTO\n");
 697                 break;
 698         default:
 699                 len += snprintf(buf + len, sizeof(buf) - len,
 700                         "??? (not good)\n");
 701                 break;
 702         }
 703         len += snprintf(buf + len, sizeof(buf) - len,
 704                         "noise immunity level:\t\t%d\n",
 705                         as->noise_imm_level);
 706         len += snprintf(buf + len, sizeof(buf) - len,
 707                         "spur immunity level:\t\t%d\n",
 708                         as->spur_level);
 709         len += snprintf(buf + len, sizeof(buf) - len,
 710                         "firstep level:\t\t\t%d\n",
 711                         as->firstep_level);
 712         len += snprintf(buf + len, sizeof(buf) - len,
 713                         "OFDM weak signal detection:\t%s\n",
 714                         as->ofdm_weak_sig ? "on" : "off");
 715         len += snprintf(buf + len, sizeof(buf) - len,
 716                         "CCK weak signal detection:\t%s\n",
 717                         as->cck_weak_sig ? "on" : "off");
 718 
 719         len += snprintf(buf + len, sizeof(buf) - len,
 720                         "\nMIB INTERRUPTS:\t\t%u\n",
 721                         st->mib_intr);
 722         len += snprintf(buf + len, sizeof(buf) - len,
 723                         "beacon RSSI average:\t%d\n",
 724                         (int)ewma_beacon_rssi_read(&ah->ah_beacon_rssi_avg));
 725 
 726 #define CC_PRINT(_struct, _field) \
 727         _struct._field, \
 728         _struct.cycles > 0 ? \
 729         _struct._field * 100 / _struct.cycles : 0
 730 
 731         len += snprintf(buf + len, sizeof(buf) - len,
 732                         "profcnt tx\t\t%u\t(%d%%)\n",
 733                         CC_PRINT(as->last_cc, tx_frame));
 734         len += snprintf(buf + len, sizeof(buf) - len,
 735                         "profcnt rx\t\t%u\t(%d%%)\n",
 736                         CC_PRINT(as->last_cc, rx_frame));
 737         len += snprintf(buf + len, sizeof(buf) - len,
 738                         "profcnt busy\t\t%u\t(%d%%)\n",
 739                         CC_PRINT(as->last_cc, rx_busy));
 740 #undef CC_PRINT
 741         len += snprintf(buf + len, sizeof(buf) - len, "profcnt cycles\t\t%u\n",
 742                         as->last_cc.cycles);
 743         len += snprintf(buf + len, sizeof(buf) - len,
 744                         "listen time\t\t%d\tlast: %d\n",
 745                         as->listen_time, as->last_listen);
 746         len += snprintf(buf + len, sizeof(buf) - len,
 747                         "OFDM errors\t\t%u\tlast: %u\tsum: %u\n",
 748                         as->ofdm_errors, as->last_ofdm_errors,
 749                         as->sum_ofdm_errors);
 750         len += snprintf(buf + len, sizeof(buf) - len,
 751                         "CCK errors\t\t%u\tlast: %u\tsum: %u\n",
 752                         as->cck_errors, as->last_cck_errors,
 753                         as->sum_cck_errors);
 754         len += snprintf(buf + len, sizeof(buf) - len,
 755                         "AR5K_PHYERR_CNT1\t%x\t(=%d)\n",
 756                         ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT1),
 757                         ATH5K_ANI_OFDM_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX -
 758                         ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT1)));
 759         len += snprintf(buf + len, sizeof(buf) - len,
 760                         "AR5K_PHYERR_CNT2\t%x\t(=%d)\n",
 761                         ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT2),
 762                         ATH5K_ANI_CCK_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX -
 763                         ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT2)));
 764 
 765         if (len > sizeof(buf))
 766                 len = sizeof(buf);
 767 
 768         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 769 }
 770 
 771 static ssize_t write_file_ani(struct file *file,
 772                                  const char __user *userbuf,
 773                                  size_t count, loff_t *ppos)
 774 {
 775         struct ath5k_hw *ah = file->private_data;
 776         char buf[20];
 777 
 778         count = min_t(size_t, count, sizeof(buf) - 1);
 779         if (copy_from_user(buf, userbuf, count))
 780                 return -EFAULT;
 781 
 782         buf[count] = '\0';
 783         if (strncmp(buf, "sens-low", 8) == 0) {
 784                 ath5k_ani_init(ah, ATH5K_ANI_MODE_MANUAL_HIGH);
 785         } else if (strncmp(buf, "sens-high", 9) == 0) {
 786                 ath5k_ani_init(ah, ATH5K_ANI_MODE_MANUAL_LOW);
 787         } else if (strncmp(buf, "ani-off", 7) == 0) {
 788                 ath5k_ani_init(ah, ATH5K_ANI_MODE_OFF);
 789         } else if (strncmp(buf, "ani-on", 6) == 0) {
 790                 ath5k_ani_init(ah, ATH5K_ANI_MODE_AUTO);
 791         } else if (strncmp(buf, "noise-low", 9) == 0) {
 792                 ath5k_ani_set_noise_immunity_level(ah, 0);
 793         } else if (strncmp(buf, "noise-high", 10) == 0) {
 794                 ath5k_ani_set_noise_immunity_level(ah,
 795                                                    ATH5K_ANI_MAX_NOISE_IMM_LVL);
 796         } else if (strncmp(buf, "spur-low", 8) == 0) {
 797                 ath5k_ani_set_spur_immunity_level(ah, 0);
 798         } else if (strncmp(buf, "spur-high", 9) == 0) {
 799                 ath5k_ani_set_spur_immunity_level(ah,
 800                                                   ah->ani_state.max_spur_level);
 801         } else if (strncmp(buf, "fir-low", 7) == 0) {
 802                 ath5k_ani_set_firstep_level(ah, 0);
 803         } else if (strncmp(buf, "fir-high", 8) == 0) {
 804                 ath5k_ani_set_firstep_level(ah, ATH5K_ANI_MAX_FIRSTEP_LVL);
 805         } else if (strncmp(buf, "ofdm-off", 8) == 0) {
 806                 ath5k_ani_set_ofdm_weak_signal_detection(ah, false);
 807         } else if (strncmp(buf, "ofdm-on", 7) == 0) {
 808                 ath5k_ani_set_ofdm_weak_signal_detection(ah, true);
 809         } else if (strncmp(buf, "cck-off", 7) == 0) {
 810                 ath5k_ani_set_cck_weak_signal_detection(ah, false);
 811         } else if (strncmp(buf, "cck-on", 6) == 0) {
 812                 ath5k_ani_set_cck_weak_signal_detection(ah, true);
 813         }
 814         return count;
 815 }
 816 
 817 static const struct file_operations fops_ani = {
 818         .read = read_file_ani,
 819         .write = write_file_ani,
 820         .open = simple_open,
 821         .owner = THIS_MODULE,
 822         .llseek = default_llseek,
 823 };
 824 
 825 
 826 /* debugfs: queues etc */
 827 
 828 static ssize_t read_file_queue(struct file *file, char __user *user_buf,
 829                                    size_t count, loff_t *ppos)
 830 {
 831         struct ath5k_hw *ah = file->private_data;
 832         char buf[700];
 833         unsigned int len = 0;
 834 
 835         struct ath5k_txq *txq;
 836         struct ath5k_buf *bf, *bf0;
 837         int i, n;
 838 
 839         len += snprintf(buf + len, sizeof(buf) - len,
 840                         "available txbuffers: %d\n", ah->txbuf_len);
 841 
 842         for (i = 0; i < ARRAY_SIZE(ah->txqs); i++) {
 843                 txq = &ah->txqs[i];
 844 
 845                 len += snprintf(buf + len, sizeof(buf) - len,
 846                         "%02d: %ssetup\n", i, txq->setup ? "" : "not ");
 847 
 848                 if (!txq->setup)
 849                         continue;
 850 
 851                 n = 0;
 852                 spin_lock_bh(&txq->lock);
 853                 list_for_each_entry_safe(bf, bf0, &txq->q, list)
 854                         n++;
 855                 spin_unlock_bh(&txq->lock);
 856 
 857                 len += snprintf(buf + len, sizeof(buf) - len,
 858                                 "  len: %d bufs: %d\n", txq->txq_len, n);
 859                 len += snprintf(buf + len, sizeof(buf) - len,
 860                                 "  stuck: %d\n", txq->txq_stuck);
 861         }
 862 
 863         if (len > sizeof(buf))
 864                 len = sizeof(buf);
 865 
 866         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 867 }
 868 
 869 static ssize_t write_file_queue(struct file *file,
 870                                  const char __user *userbuf,
 871                                  size_t count, loff_t *ppos)
 872 {
 873         struct ath5k_hw *ah = file->private_data;
 874         char buf[20];
 875 
 876         count = min_t(size_t, count, sizeof(buf) - 1);
 877         if (copy_from_user(buf, userbuf, count))
 878                 return -EFAULT;
 879 
 880         buf[count] = '\0';
 881         if (strncmp(buf, "start", 5) == 0)
 882                 ieee80211_wake_queues(ah->hw);
 883         else if (strncmp(buf, "stop", 4) == 0)
 884                 ieee80211_stop_queues(ah->hw);
 885 
 886         return count;
 887 }
 888 
 889 
 890 static const struct file_operations fops_queue = {
 891         .read = read_file_queue,
 892         .write = write_file_queue,
 893         .open = simple_open,
 894         .owner = THIS_MODULE,
 895         .llseek = default_llseek,
 896 };
 897 
 898 /* debugfs: eeprom */
 899 
 900 struct eeprom_private {
 901         u16 *buf;
 902         int len;
 903 };
 904 
 905 static int open_file_eeprom(struct inode *inode, struct file *file)
 906 {
 907         struct eeprom_private *ep;
 908         struct ath5k_hw *ah = inode->i_private;
 909         bool res;
 910         int i, ret;
 911         u32 eesize;     /* NB: in 16-bit words */
 912         u16 val, *buf;
 913 
 914         /* Get eeprom size */
 915 
 916         res = ath5k_hw_nvram_read(ah, AR5K_EEPROM_SIZE_UPPER, &val);
 917         if (!res)
 918                 return -EACCES;
 919 
 920         if (val == 0) {
 921                 eesize = AR5K_EEPROM_INFO_MAX + AR5K_EEPROM_INFO_BASE;
 922         } else {
 923                 eesize = (val & AR5K_EEPROM_SIZE_UPPER_MASK) <<
 924                         AR5K_EEPROM_SIZE_ENDLOC_SHIFT;
 925                 ath5k_hw_nvram_read(ah, AR5K_EEPROM_SIZE_LOWER, &val);
 926                 eesize = eesize | val;
 927         }
 928 
 929         if (eesize > 4096)
 930                 return -EINVAL;
 931 
 932         /* Create buffer and read in eeprom */
 933 
 934         buf = vmalloc(array_size(eesize, 2));
 935         if (!buf) {
 936                 ret = -ENOMEM;
 937                 goto err;
 938         }
 939 
 940         for (i = 0; i < eesize; ++i) {
 941                 if (!ath5k_hw_nvram_read(ah, i, &val)) {
 942                         ret = -EIO;
 943                         goto freebuf;
 944                 }
 945                 buf[i] = val;
 946         }
 947 
 948         /* Create private struct and assign to file */
 949 
 950         ep = kmalloc(sizeof(*ep), GFP_KERNEL);
 951         if (!ep) {
 952                 ret = -ENOMEM;
 953                 goto freebuf;
 954         }
 955 
 956         ep->buf = buf;
 957         ep->len = eesize * 2;
 958 
 959         file->private_data = (void *)ep;
 960 
 961         return 0;
 962 
 963 freebuf:
 964         vfree(buf);
 965 err:
 966         return ret;
 967 
 968 }
 969 
 970 static ssize_t read_file_eeprom(struct file *file, char __user *user_buf,
 971                                    size_t count, loff_t *ppos)
 972 {
 973         struct eeprom_private *ep = file->private_data;
 974 
 975         return simple_read_from_buffer(user_buf, count, ppos, ep->buf, ep->len);
 976 }
 977 
 978 static int release_file_eeprom(struct inode *inode, struct file *file)
 979 {
 980         struct eeprom_private *ep = file->private_data;
 981 
 982         vfree(ep->buf);
 983         kfree(ep);
 984 
 985         return 0;
 986 }
 987 
 988 static const struct file_operations fops_eeprom = {
 989         .open = open_file_eeprom,
 990         .read = read_file_eeprom,
 991         .release = release_file_eeprom,
 992         .owner = THIS_MODULE,
 993 };
 994 
 995 
 996 void
 997 ath5k_debug_init_device(struct ath5k_hw *ah)
 998 {
 999         struct dentry *phydir;
1000 
1001         ah->debug.level = ath5k_debug;
1002 
1003         phydir = debugfs_create_dir("ath5k", ah->hw->wiphy->debugfsdir);
1004         if (!phydir)
1005                 return;
1006 
1007         debugfs_create_file("debug", 0600, phydir, ah, &fops_debug);
1008         debugfs_create_file("registers", 0400, phydir, ah, &fops_registers);
1009         debugfs_create_file("beacon", 0600, phydir, ah, &fops_beacon);
1010         debugfs_create_file("reset", 0200, phydir, ah, &fops_reset);
1011         debugfs_create_file("antenna", 0600, phydir, ah, &fops_antenna);
1012         debugfs_create_file("misc", 0400, phydir, ah, &fops_misc);
1013         debugfs_create_file("eeprom", 0400, phydir, ah, &fops_eeprom);
1014         debugfs_create_file("frameerrors", 0600, phydir, ah, &fops_frameerrors);
1015         debugfs_create_file("ani", 0600, phydir, ah, &fops_ani);
1016         debugfs_create_file("queue", 0600, phydir, ah, &fops_queue);
1017         debugfs_create_bool("32khz_clock", 0600, phydir,
1018                             &ah->ah_use_32khz_clock);
1019 }
1020 
1021 /* functions used in other places */
1022 
1023 void
1024 ath5k_debug_dump_bands(struct ath5k_hw *ah)
1025 {
1026         unsigned int b, i;
1027 
1028         if (likely(!(ah->debug.level & ATH5K_DEBUG_DUMPBANDS)))
1029                 return;
1030 
1031         for (b = 0; b < NUM_NL80211_BANDS; b++) {
1032                 struct ieee80211_supported_band *band = &ah->sbands[b];
1033                 char bname[6];
1034                 switch (band->band) {
1035                 case NL80211_BAND_2GHZ:
1036                         strcpy(bname, "2 GHz");
1037                         break;
1038                 case NL80211_BAND_5GHZ:
1039                         strcpy(bname, "5 GHz");
1040                         break;
1041                 default:
1042                         printk(KERN_DEBUG "Band not supported: %d\n",
1043                                 band->band);
1044                         return;
1045                 }
1046                 printk(KERN_DEBUG "Band %s: channels %d, rates %d\n", bname,
1047                                 band->n_channels, band->n_bitrates);
1048                 printk(KERN_DEBUG " channels:\n");
1049                 for (i = 0; i < band->n_channels; i++)
1050                         printk(KERN_DEBUG "  %3d %d %.4x %.4x\n",
1051                                         ieee80211_frequency_to_channel(
1052                                                 band->channels[i].center_freq),
1053                                         band->channels[i].center_freq,
1054                                         band->channels[i].hw_value,
1055                                         band->channels[i].flags);
1056                 printk(KERN_DEBUG " rates:\n");
1057                 for (i = 0; i < band->n_bitrates; i++)
1058                         printk(KERN_DEBUG "  %4d %.4x %.4x %.4x\n",
1059                                         band->bitrates[i].bitrate,
1060                                         band->bitrates[i].hw_value,
1061                                         band->bitrates[i].flags,
1062                                         band->bitrates[i].hw_value_short);
1063         }
1064 }
1065 
1066 static inline void
1067 ath5k_debug_printrxbuf(struct ath5k_buf *bf, int done,
1068                        struct ath5k_rx_status *rs)
1069 {
1070         struct ath5k_desc *ds = bf->desc;
1071         struct ath5k_hw_all_rx_desc *rd = &ds->ud.ds_rx;
1072 
1073         printk(KERN_DEBUG "R (%p %llx) %08x %08x %08x %08x %08x %08x %c\n",
1074                 ds, (unsigned long long)bf->daddr,
1075                 ds->ds_link, ds->ds_data,
1076                 rd->rx_ctl.rx_control_0, rd->rx_ctl.rx_control_1,
1077                 rd->rx_stat.rx_status_0, rd->rx_stat.rx_status_1,
1078                 !done ? ' ' : (rs->rs_status == 0) ? '*' : '!');
1079 }
1080 
1081 void
1082 ath5k_debug_printrxbuffs(struct ath5k_hw *ah)
1083 {
1084         struct ath5k_desc *ds;
1085         struct ath5k_buf *bf;
1086         struct ath5k_rx_status rs = {};
1087         int status;
1088 
1089         if (likely(!(ah->debug.level & ATH5K_DEBUG_DESC)))
1090                 return;
1091 
1092         printk(KERN_DEBUG "rxdp %x, rxlink %p\n",
1093                 ath5k_hw_get_rxdp(ah), ah->rxlink);
1094 
1095         spin_lock_bh(&ah->rxbuflock);
1096         list_for_each_entry(bf, &ah->rxbuf, list) {
1097                 ds = bf->desc;
1098                 status = ah->ah_proc_rx_desc(ah, ds, &rs);
1099                 if (!status)
1100                         ath5k_debug_printrxbuf(bf, status == 0, &rs);
1101         }
1102         spin_unlock_bh(&ah->rxbuflock);
1103 }
1104 
1105 void
1106 ath5k_debug_printtxbuf(struct ath5k_hw *ah, struct ath5k_buf *bf)
1107 {
1108         struct ath5k_desc *ds = bf->desc;
1109         struct ath5k_hw_5212_tx_desc *td = &ds->ud.ds_tx5212;
1110         struct ath5k_tx_status ts = {};
1111         int done;
1112 
1113         if (likely(!(ah->debug.level & ATH5K_DEBUG_DESC)))
1114                 return;
1115 
1116         done = ah->ah_proc_tx_desc(ah, bf->desc, &ts);
1117 
1118         printk(KERN_DEBUG "T (%p %llx) %08x %08x %08x %08x %08x %08x %08x "
1119                 "%08x %c\n", ds, (unsigned long long)bf->daddr, ds->ds_link,
1120                 ds->ds_data, td->tx_ctl.tx_control_0, td->tx_ctl.tx_control_1,
1121                 td->tx_ctl.tx_control_2, td->tx_ctl.tx_control_3,
1122                 td->tx_stat.tx_status_0, td->tx_stat.tx_status_1,
1123                 done ? ' ' : (ts.ts_status == 0) ? '*' : '!');
1124 }

/* [<][>][^][v][top][bottom][index][help] */