linux/drivers/net/wireless/ath/carl9170/debug.c
<<
>>
Prefs
   1/*
   2 * Atheros CARL9170 driver
   3 *
   4 * debug(fs) probing
   5 *
   6 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
   7 * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com>
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License as published by
  11 * the Free Software Foundation; either version 2 of the License, or
  12 * (at your option) any later version.
  13 *
  14 * This program is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17 * GNU General Public License for more details.
  18 *
  19 * You should have received a copy of the GNU General Public License
  20 * along with this program; see the file COPYING.  If not, see
  21 * http://www.gnu.org/licenses/.
  22 *
  23 * This file incorporates work covered by the following copyright and
  24 * permission notice:
  25 *    Copyright (c) 2008-2009 Atheros Communications, Inc.
  26 *
  27 *    Permission to use, copy, modify, and/or distribute this software for any
  28 *    purpose with or without fee is hereby granted, provided that the above
  29 *    copyright notice and this permission notice appear in all copies.
  30 *
  31 *    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  32 *    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  33 *    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  34 *    ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  35 *    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  36 *    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  37 *    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  38 */
  39
  40#include <linux/slab.h>
  41#include <linux/module.h>
  42#include <linux/seq_file.h>
  43#include <linux/vmalloc.h>
  44#include "carl9170.h"
  45#include "cmd.h"
  46
  47#define ADD(buf, off, max, fmt, args...)                                \
  48        off += snprintf(&buf[off], max - off, fmt, ##args);
  49
  50
  51struct carl9170_debugfs_fops {
  52        unsigned int read_bufsize;
  53        umode_t attr;
  54        char *(*read)(struct ar9170 *ar, char *buf, size_t bufsize,
  55                      ssize_t *len);
  56        ssize_t (*write)(struct ar9170 *aru, const char *buf, size_t size);
  57        const struct file_operations fops;
  58
  59        enum carl9170_device_state req_dev_state;
  60};
  61
  62static ssize_t carl9170_debugfs_read(struct file *file, char __user *userbuf,
  63                                     size_t count, loff_t *ppos)
  64{
  65        struct carl9170_debugfs_fops *dfops;
  66        struct ar9170 *ar;
  67        char *buf = NULL, *res_buf = NULL;
  68        ssize_t ret = 0;
  69        int err = 0;
  70
  71        if (!count)
  72                return 0;
  73
  74        ar = file->private_data;
  75
  76        if (!ar)
  77                return -ENODEV;
  78        dfops = container_of(file->f_op, struct carl9170_debugfs_fops, fops);
  79
  80        if (!dfops->read)
  81                return -ENOSYS;
  82
  83        if (dfops->read_bufsize) {
  84                buf = vmalloc(dfops->read_bufsize);
  85                if (!buf)
  86                        return -ENOMEM;
  87        }
  88
  89        mutex_lock(&ar->mutex);
  90        if (!CHK_DEV_STATE(ar, dfops->req_dev_state)) {
  91                err = -ENODEV;
  92                res_buf = buf;
  93                goto out_free;
  94        }
  95
  96        res_buf = dfops->read(ar, buf, dfops->read_bufsize, &ret);
  97
  98        if (ret > 0)
  99                err = simple_read_from_buffer(userbuf, count, ppos,
 100                                              res_buf, ret);
 101        else
 102                err = ret;
 103
 104        WARN_ON_ONCE(dfops->read_bufsize && (res_buf != buf));
 105
 106out_free:
 107        vfree(res_buf);
 108        mutex_unlock(&ar->mutex);
 109        return err;
 110}
 111
 112static ssize_t carl9170_debugfs_write(struct file *file,
 113        const char __user *userbuf, size_t count, loff_t *ppos)
 114{
 115        struct carl9170_debugfs_fops *dfops;
 116        struct ar9170 *ar;
 117        char *buf = NULL;
 118        int err = 0;
 119
 120        if (!count)
 121                return 0;
 122
 123        if (count > PAGE_SIZE)
 124                return -E2BIG;
 125
 126        ar = file->private_data;
 127
 128        if (!ar)
 129                return -ENODEV;
 130        dfops = container_of(file->f_op, struct carl9170_debugfs_fops, fops);
 131
 132        if (!dfops->write)
 133                return -ENOSYS;
 134
 135        buf = vmalloc(count);
 136        if (!buf)
 137                return -ENOMEM;
 138
 139        if (copy_from_user(buf, userbuf, count)) {
 140                err = -EFAULT;
 141                goto out_free;
 142        }
 143
 144        if (mutex_trylock(&ar->mutex) == 0) {
 145                err = -EAGAIN;
 146                goto out_free;
 147        }
 148
 149        if (!CHK_DEV_STATE(ar, dfops->req_dev_state)) {
 150                err = -ENODEV;
 151                goto out_unlock;
 152        }
 153
 154        err = dfops->write(ar, buf, count);
 155        if (err)
 156                goto out_unlock;
 157
 158out_unlock:
 159        mutex_unlock(&ar->mutex);
 160
 161out_free:
 162        vfree(buf);
 163        return err;
 164}
 165
 166#define __DEBUGFS_DECLARE_FILE(name, _read, _write, _read_bufsize,      \
 167                               _attr, _dstate)                          \
 168static const struct carl9170_debugfs_fops carl_debugfs_##name ##_ops = {\
 169        .read_bufsize = _read_bufsize,                                  \
 170        .read = _read,                                                  \
 171        .write = _write,                                                \
 172        .attr = _attr,                                                  \
 173        .req_dev_state = _dstate,                                       \
 174        .fops = {                                                       \
 175                .open   = simple_open,                                  \
 176                .read   = carl9170_debugfs_read,                        \
 177                .write  = carl9170_debugfs_write,                       \
 178                .owner  = THIS_MODULE                                   \
 179        },                                                              \
 180}
 181
 182#define DEBUGFS_DECLARE_FILE(name, _read, _write, _read_bufsize, _attr) \
 183        __DEBUGFS_DECLARE_FILE(name, _read, _write, _read_bufsize,      \
 184                               _attr, CARL9170_STARTED)                 \
 185
 186#define DEBUGFS_DECLARE_RO_FILE(name, _read_bufsize)                    \
 187        DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read,     \
 188                             NULL, _read_bufsize, S_IRUSR)
 189
 190#define DEBUGFS_DECLARE_WO_FILE(name)                                   \
 191        DEBUGFS_DECLARE_FILE(name, NULL, carl9170_debugfs_##name ##_write,\
 192                             0, S_IWUSR)
 193
 194#define DEBUGFS_DECLARE_RW_FILE(name, _read_bufsize)                    \
 195        DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read,     \
 196                             carl9170_debugfs_##name ##_write,          \
 197                             _read_bufsize, S_IRUSR | S_IWUSR)
 198
 199#define __DEBUGFS_DECLARE_RW_FILE(name, _read_bufsize, _dstate)         \
 200        __DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read,   \
 201                             carl9170_debugfs_##name ##_write,          \
 202                             _read_bufsize, S_IRUSR | S_IWUSR, _dstate)
 203
 204#define DEBUGFS_READONLY_FILE(name, _read_bufsize, fmt, value...)       \
 205static char *carl9170_debugfs_ ##name ## _read(struct ar9170 *ar,       \
 206                                             char *buf, size_t buf_size,\
 207                                             ssize_t *len)              \
 208{                                                                       \
 209        ADD(buf, *len, buf_size, fmt "\n", ##value);                    \
 210        return buf;                                                     \
 211}                                                                       \
 212DEBUGFS_DECLARE_RO_FILE(name, _read_bufsize)
 213
 214static char *carl9170_debugfs_mem_usage_read(struct ar9170 *ar, char *buf,
 215                                             size_t bufsize, ssize_t *len)
 216{
 217        spin_lock_bh(&ar->mem_lock);
 218
 219        ADD(buf, *len, bufsize, "jar: [%*pb]\n",
 220            ar->fw.mem_blocks, ar->mem_bitmap);
 221
 222        ADD(buf, *len, bufsize, "cookies: used:%3d / total:%3d, allocs:%d\n",
 223            bitmap_weight(ar->mem_bitmap, ar->fw.mem_blocks),
 224            ar->fw.mem_blocks, atomic_read(&ar->mem_allocs));
 225
 226        ADD(buf, *len, bufsize, "memory: free:%3d (%3d KiB) / total:%3d KiB)\n",
 227            atomic_read(&ar->mem_free_blocks),
 228            (atomic_read(&ar->mem_free_blocks) * ar->fw.mem_block_size) / 1024,
 229            (ar->fw.mem_blocks * ar->fw.mem_block_size) / 1024);
 230
 231        spin_unlock_bh(&ar->mem_lock);
 232
 233        return buf;
 234}
 235DEBUGFS_DECLARE_RO_FILE(mem_usage, 512);
 236
 237static char *carl9170_debugfs_qos_stat_read(struct ar9170 *ar, char *buf,
 238                                            size_t bufsize, ssize_t *len)
 239{
 240        ADD(buf, *len, bufsize, "%s QoS AC\n", modparam_noht ? "Hardware" :
 241            "Software");
 242
 243        ADD(buf, *len, bufsize, "[     VO            VI       "
 244                                 "     BE            BK      ]\n");
 245
 246        spin_lock_bh(&ar->tx_stats_lock);
 247        ADD(buf, *len, bufsize, "[length/limit  length/limit  "
 248                                 "length/limit  length/limit ]\n"
 249                                "[   %3d/%3d       %3d/%3d    "
 250                                 "   %3d/%3d       %3d/%3d   ]\n\n",
 251            ar->tx_stats[0].len, ar->tx_stats[0].limit,
 252            ar->tx_stats[1].len, ar->tx_stats[1].limit,
 253            ar->tx_stats[2].len, ar->tx_stats[2].limit,
 254            ar->tx_stats[3].len, ar->tx_stats[3].limit);
 255
 256        ADD(buf, *len, bufsize, "[    total         total     "
 257                                 "    total         total    ]\n"
 258                                "[%10d    %10d    %10d    %10d   ]\n\n",
 259            ar->tx_stats[0].count, ar->tx_stats[1].count,
 260            ar->tx_stats[2].count, ar->tx_stats[3].count);
 261
 262        spin_unlock_bh(&ar->tx_stats_lock);
 263
 264        ADD(buf, *len, bufsize, "[  pend/waittx   pend/waittx "
 265                                 "  pend/waittx   pend/waittx]\n"
 266                                "[   %3d/%3d       %3d/%3d    "
 267                                 "   %3d/%3d       %3d/%3d   ]\n\n",
 268            skb_queue_len(&ar->tx_pending[0]),
 269            skb_queue_len(&ar->tx_status[0]),
 270            skb_queue_len(&ar->tx_pending[1]),
 271            skb_queue_len(&ar->tx_status[1]),
 272            skb_queue_len(&ar->tx_pending[2]),
 273            skb_queue_len(&ar->tx_status[2]),
 274            skb_queue_len(&ar->tx_pending[3]),
 275            skb_queue_len(&ar->tx_status[3]));
 276
 277        return buf;
 278}
 279DEBUGFS_DECLARE_RO_FILE(qos_stat, 512);
 280
 281static void carl9170_debugfs_format_frame(struct ar9170 *ar,
 282        struct sk_buff *skb, const char *prefix, char *buf,
 283        ssize_t *off, ssize_t bufsize)
 284{
 285        struct _carl9170_tx_superframe *txc = (void *) skb->data;
 286        struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
 287        struct carl9170_tx_info *arinfo = (void *) txinfo->rate_driver_data;
 288        struct ieee80211_hdr *hdr = (void *) txc->frame_data;
 289
 290        ADD(buf, *off, bufsize, "%s %p, c:%2x, DA:%pM, sq:%4d, mc:%.4x, "
 291            "pc:%.8x, to:%d ms\n", prefix, skb, txc->s.cookie,
 292            ieee80211_get_DA(hdr), get_seq_h(hdr),
 293            le16_to_cpu(txc->f.mac_control), le32_to_cpu(txc->f.phy_control),
 294            jiffies_to_msecs(jiffies - arinfo->timeout));
 295}
 296
 297
 298static char *carl9170_debugfs_ampdu_state_read(struct ar9170 *ar, char *buf,
 299                                               size_t bufsize, ssize_t *len)
 300{
 301        struct carl9170_sta_tid *iter;
 302        struct sk_buff *skb;
 303        int cnt = 0, fc;
 304        int offset;
 305
 306        rcu_read_lock();
 307        list_for_each_entry_rcu(iter, &ar->tx_ampdu_list, list) {
 308
 309                spin_lock_bh(&iter->lock);
 310                ADD(buf, *len, bufsize, "Entry: #%2d TID:%1d, BSN:%4d, "
 311                    "SNX:%4d, HSN:%4d, BAW:%2d, state:%1d, toggles:%d\n",
 312                    cnt, iter->tid, iter->bsn, iter->snx, iter->hsn,
 313                    iter->max, iter->state, iter->counter);
 314
 315                ADD(buf, *len, bufsize, "\tWindow:  [%*pb,W]\n",
 316                    CARL9170_BAW_BITS, iter->bitmap);
 317
 318#define BM_STR_OFF(offset)                                      \
 319        ((CARL9170_BAW_BITS - (offset) - 1) / 4 +               \
 320         (CARL9170_BAW_BITS - (offset) - 1) / 32 + 1)
 321
 322                offset = BM_STR_OFF(0);
 323                ADD(buf, *len, bufsize, "\tBase Seq: %*s\n", offset, "T");
 324
 325                offset = BM_STR_OFF(SEQ_DIFF(iter->snx, iter->bsn));
 326                ADD(buf, *len, bufsize, "\tNext Seq: %*s\n", offset, "W");
 327
 328                offset = BM_STR_OFF(((int)iter->hsn - (int)iter->bsn) %
 329                                     CARL9170_BAW_BITS);
 330                ADD(buf, *len, bufsize, "\tLast Seq: %*s\n", offset, "N");
 331
 332                ADD(buf, *len, bufsize, "\tPre-Aggregation reorder buffer: "
 333                    " currently queued:%d\n", skb_queue_len(&iter->queue));
 334
 335                fc = 0;
 336                skb_queue_walk(&iter->queue, skb) {
 337                        char prefix[32];
 338
 339                        snprintf(prefix, sizeof(prefix), "\t\t%3d :", fc);
 340                        carl9170_debugfs_format_frame(ar, skb, prefix, buf,
 341                                                      len, bufsize);
 342
 343                        fc++;
 344                }
 345                spin_unlock_bh(&iter->lock);
 346                cnt++;
 347        }
 348        rcu_read_unlock();
 349
 350        return buf;
 351}
 352DEBUGFS_DECLARE_RO_FILE(ampdu_state, 8000);
 353
 354static void carl9170_debugfs_queue_dump(struct ar9170 *ar, char *buf,
 355        ssize_t *len, size_t bufsize, struct sk_buff_head *queue)
 356{
 357        struct sk_buff *skb;
 358        char prefix[16];
 359        int fc = 0;
 360
 361        spin_lock_bh(&queue->lock);
 362        skb_queue_walk(queue, skb) {
 363                snprintf(prefix, sizeof(prefix), "%3d :", fc);
 364                carl9170_debugfs_format_frame(ar, skb, prefix, buf,
 365                                              len, bufsize);
 366                fc++;
 367        }
 368        spin_unlock_bh(&queue->lock);
 369}
 370
 371#define DEBUGFS_QUEUE_DUMP(q, qi)                                       \
 372static char *carl9170_debugfs_##q ##_##qi ##_read(struct ar9170 *ar,    \
 373        char *buf, size_t bufsize, ssize_t *len)                        \
 374{                                                                       \
 375        carl9170_debugfs_queue_dump(ar, buf, len, bufsize, &ar->q[qi]); \
 376        return buf;                                                     \
 377}                                                                       \
 378DEBUGFS_DECLARE_RO_FILE(q##_##qi, 8000);
 379
 380static char *carl9170_debugfs_sta_psm_read(struct ar9170 *ar, char *buf,
 381                                           size_t bufsize, ssize_t *len)
 382{
 383        ADD(buf, *len, bufsize, "psm state: %s\n", (ar->ps.off_override ?
 384            "FORCE CAM" : (ar->ps.state ? "PSM" : "CAM")));
 385
 386        ADD(buf, *len, bufsize, "sleep duration: %d ms.\n", ar->ps.sleep_ms);
 387        ADD(buf, *len, bufsize, "last power-state transition: %d ms ago.\n",
 388            jiffies_to_msecs(jiffies - ar->ps.last_action));
 389        ADD(buf, *len, bufsize, "last CAM->PSM transition: %d ms ago.\n",
 390            jiffies_to_msecs(jiffies - ar->ps.last_slept));
 391
 392        return buf;
 393}
 394DEBUGFS_DECLARE_RO_FILE(sta_psm, 160);
 395
 396static char *carl9170_debugfs_tx_stuck_read(struct ar9170 *ar, char *buf,
 397                                            size_t bufsize, ssize_t *len)
 398{
 399        int i;
 400
 401        for (i = 0; i < ar->hw->queues; i++) {
 402                ADD(buf, *len, bufsize, "TX queue [%d]: %10d max:%10d ms.\n",
 403                    i, ieee80211_queue_stopped(ar->hw, i) ?
 404                    jiffies_to_msecs(jiffies - ar->queue_stop_timeout[i]) : 0,
 405                    jiffies_to_msecs(ar->max_queue_stop_timeout[i]));
 406
 407                ar->max_queue_stop_timeout[i] = 0;
 408        }
 409
 410        return buf;
 411}
 412DEBUGFS_DECLARE_RO_FILE(tx_stuck, 180);
 413
 414static char *carl9170_debugfs_phy_noise_read(struct ar9170 *ar, char *buf,
 415                                             size_t bufsize, ssize_t *len)
 416{
 417        int err;
 418
 419        err = carl9170_get_noisefloor(ar);
 420        if (err) {
 421                *len = err;
 422                return buf;
 423        }
 424
 425        ADD(buf, *len, bufsize, "Chain 0: %10d dBm, ext. chan.:%10d dBm\n",
 426            ar->noise[0], ar->noise[2]);
 427        ADD(buf, *len, bufsize, "Chain 2: %10d dBm, ext. chan.:%10d dBm\n",
 428            ar->noise[1], ar->noise[3]);
 429
 430        return buf;
 431}
 432DEBUGFS_DECLARE_RO_FILE(phy_noise, 180);
 433
 434static char *carl9170_debugfs_vif_dump_read(struct ar9170 *ar, char *buf,
 435                                            size_t bufsize, ssize_t *len)
 436{
 437        struct carl9170_vif_info *iter;
 438        int i = 0;
 439
 440        ADD(buf, *len, bufsize, "registered VIFs:%d \\ %d\n",
 441            ar->vifs, ar->fw.vif_num);
 442
 443        ADD(buf, *len, bufsize, "VIF bitmap: [%*pb]\n",
 444            ar->fw.vif_num, &ar->vif_bitmap);
 445
 446        rcu_read_lock();
 447        list_for_each_entry_rcu(iter, &ar->vif_list, list) {
 448                struct ieee80211_vif *vif = carl9170_get_vif(iter);
 449                ADD(buf, *len, bufsize, "\t%d = [%s VIF, id:%d, type:%x "
 450                    " mac:%pM %s]\n", i, (carl9170_get_main_vif(ar) == vif ?
 451                    "Master" : " Slave"), iter->id, vif->type, vif->addr,
 452                    iter->enable_beacon ? "beaconing " : "");
 453                i++;
 454        }
 455        rcu_read_unlock();
 456
 457        return buf;
 458}
 459DEBUGFS_DECLARE_RO_FILE(vif_dump, 8000);
 460
 461#define UPDATE_COUNTER(ar, name)        ({                              \
 462        u32 __tmp[ARRAY_SIZE(name##_regs)];                             \
 463        unsigned int __i, __err = -ENODEV;                              \
 464                                                                        \
 465        for (__i = 0; __i < ARRAY_SIZE(name##_regs); __i++) {           \
 466                __tmp[__i] = name##_regs[__i].reg;                      \
 467                ar->debug.stats.name##_counter[__i] = 0;                \
 468        }                                                               \
 469                                                                        \
 470        if (IS_STARTED(ar))                                             \
 471                __err = carl9170_read_mreg(ar, ARRAY_SIZE(name##_regs), \
 472                        __tmp, ar->debug.stats.name##_counter);         \
 473        (__err); })
 474
 475#define TALLY_SUM_UP(ar, name)  do {                                    \
 476        unsigned int __i;                                               \
 477                                                                        \
 478        for (__i = 0; __i < ARRAY_SIZE(name##_regs); __i++) {           \
 479                ar->debug.stats.name##_sum[__i] +=                      \
 480                        ar->debug.stats.name##_counter[__i];            \
 481        }                                                               \
 482} while (0)
 483
 484#define DEBUGFS_HW_TALLY_FILE(name, f)                                  \
 485static char *carl9170_debugfs_##name ## _read(struct ar9170 *ar,        \
 486         char *dum, size_t bufsize, ssize_t *ret)                       \
 487{                                                                       \
 488        char *buf;                                                      \
 489        int i, max_len, err;                                            \
 490                                                                        \
 491        max_len = ARRAY_SIZE(name##_regs) * 80;                         \
 492        buf = vmalloc(max_len);                                         \
 493        if (!buf)                                                       \
 494                return NULL;                                            \
 495                                                                        \
 496        err = UPDATE_COUNTER(ar, name);                                 \
 497        if (err) {                                                      \
 498                *ret = err;                                             \
 499                return buf;                                             \
 500        }                                                               \
 501                                                                        \
 502        TALLY_SUM_UP(ar, name);                                         \
 503                                                                        \
 504        for (i = 0; i < ARRAY_SIZE(name##_regs); i++) {                 \
 505                ADD(buf, *ret, max_len, "%22s = %" f "[+%" f "]\n",     \
 506                    name##_regs[i].nreg, ar->debug.stats.name ##_sum[i],\
 507                    ar->debug.stats.name ##_counter[i]);                \
 508        }                                                               \
 509                                                                        \
 510        return buf;                                                     \
 511}                                                                       \
 512DEBUGFS_DECLARE_RO_FILE(name, 0);
 513
 514#define DEBUGFS_HW_REG_FILE(name, f)                                    \
 515static char *carl9170_debugfs_##name ## _read(struct ar9170 *ar,        \
 516        char *dum, size_t bufsize, ssize_t *ret)                        \
 517{                                                                       \
 518        char *buf;                                                      \
 519        int i, max_len, err;                                            \
 520                                                                        \
 521        max_len = ARRAY_SIZE(name##_regs) * 80;                         \
 522        buf = vmalloc(max_len);                                         \
 523        if (!buf)                                                       \
 524                return NULL;                                            \
 525                                                                        \
 526        err = UPDATE_COUNTER(ar, name);                                 \
 527        if (err) {                                                      \
 528                *ret = err;                                             \
 529                return buf;                                             \
 530        }                                                               \
 531                                                                        \
 532        for (i = 0; i < ARRAY_SIZE(name##_regs); i++) {                 \
 533                ADD(buf, *ret, max_len, "%22s = %" f "\n",              \
 534                    name##_regs[i].nreg,                                \
 535                    ar->debug.stats.name##_counter[i]);                 \
 536        }                                                               \
 537                                                                        \
 538        return buf;                                                     \
 539}                                                                       \
 540DEBUGFS_DECLARE_RO_FILE(name, 0);
 541
 542static ssize_t carl9170_debugfs_hw_ioread32_write(struct ar9170 *ar,
 543        const char *buf, size_t count)
 544{
 545        int err = 0, i, n = 0, max_len = 32, res;
 546        unsigned int reg, tmp;
 547
 548        if (!count)
 549                return 0;
 550
 551        if (count > max_len)
 552                return -E2BIG;
 553
 554        res = sscanf(buf, "0x%X %d", &reg, &n);
 555        if (res < 1) {
 556                err = -EINVAL;
 557                goto out;
 558        }
 559
 560        if (res == 1)
 561                n = 1;
 562
 563        if (n > 15) {
 564                err = -EMSGSIZE;
 565                goto out;
 566        }
 567
 568        if ((reg >= 0x280000) || ((reg + (n << 2)) >= 0x280000)) {
 569                err = -EADDRNOTAVAIL;
 570                goto out;
 571        }
 572
 573        if (reg & 3) {
 574                err = -EINVAL;
 575                goto out;
 576        }
 577
 578        for (i = 0; i < n; i++) {
 579                err = carl9170_read_reg(ar, reg + (i << 2), &tmp);
 580                if (err)
 581                        goto out;
 582
 583                ar->debug.ring[ar->debug.ring_tail].reg = reg + (i << 2);
 584                ar->debug.ring[ar->debug.ring_tail].value = tmp;
 585                ar->debug.ring_tail++;
 586                ar->debug.ring_tail %= CARL9170_DEBUG_RING_SIZE;
 587        }
 588
 589out:
 590        return err ? err : count;
 591}
 592
 593static char *carl9170_debugfs_hw_ioread32_read(struct ar9170 *ar, char *buf,
 594                                               size_t bufsize, ssize_t *ret)
 595{
 596        int i = 0;
 597
 598        while (ar->debug.ring_head != ar->debug.ring_tail) {
 599                ADD(buf, *ret, bufsize, "%.8x = %.8x\n",
 600                    ar->debug.ring[ar->debug.ring_head].reg,
 601                    ar->debug.ring[ar->debug.ring_head].value);
 602
 603                ar->debug.ring_head++;
 604                ar->debug.ring_head %= CARL9170_DEBUG_RING_SIZE;
 605
 606                if (i++ == 64)
 607                        break;
 608        }
 609        ar->debug.ring_head = ar->debug.ring_tail;
 610        return buf;
 611}
 612DEBUGFS_DECLARE_RW_FILE(hw_ioread32, CARL9170_DEBUG_RING_SIZE * 40);
 613
 614static ssize_t carl9170_debugfs_bug_write(struct ar9170 *ar, const char *buf,
 615                                          size_t count)
 616{
 617        int err;
 618
 619        if (count < 1)
 620                return -EINVAL;
 621
 622        switch (buf[0]) {
 623        case 'F':
 624                ar->needs_full_reset = true;
 625                break;
 626
 627        case 'R':
 628                if (!IS_STARTED(ar)) {
 629                        err = -EAGAIN;
 630                        goto out;
 631                }
 632
 633                ar->needs_full_reset = false;
 634                break;
 635
 636        case 'M':
 637                err = carl9170_mac_reset(ar);
 638                if (err < 0)
 639                        count = err;
 640
 641                goto out;
 642
 643        case 'P':
 644                err = carl9170_set_channel(ar, ar->hw->conf.chandef.chan,
 645                        cfg80211_get_chandef_type(&ar->hw->conf.chandef));
 646                if (err < 0)
 647                        count = err;
 648
 649                goto out;
 650
 651        default:
 652                return -EINVAL;
 653        }
 654
 655        carl9170_restart(ar, CARL9170_RR_USER_REQUEST);
 656
 657out:
 658        return count;
 659}
 660
 661static char *carl9170_debugfs_bug_read(struct ar9170 *ar, char *buf,
 662                                       size_t bufsize, ssize_t *ret)
 663{
 664        ADD(buf, *ret, bufsize, "[P]hy reinit, [R]estart, [F]ull usb reset, "
 665            "[M]ac reset\n");
 666        ADD(buf, *ret, bufsize, "firmware restarts:%d, last reason:%d\n",
 667                ar->restart_counter, ar->last_reason);
 668        ADD(buf, *ret, bufsize, "phy reinit errors:%d (%d)\n",
 669                ar->total_chan_fail, ar->chan_fail);
 670        ADD(buf, *ret, bufsize, "reported firmware errors:%d\n",
 671                ar->fw.err_counter);
 672        ADD(buf, *ret, bufsize, "reported firmware BUGs:%d\n",
 673                ar->fw.bug_counter);
 674        ADD(buf, *ret, bufsize, "pending restart requests:%d\n",
 675                atomic_read(&ar->pending_restarts));
 676        return buf;
 677}
 678__DEBUGFS_DECLARE_RW_FILE(bug, 400, CARL9170_STOPPED);
 679
 680static const char *const erp_modes[] = {
 681        [CARL9170_ERP_INVALID] = "INVALID",
 682        [CARL9170_ERP_AUTO] = "Automatic",
 683        [CARL9170_ERP_MAC80211] = "Set by MAC80211",
 684        [CARL9170_ERP_OFF] = "Force Off",
 685        [CARL9170_ERP_RTS] = "Force RTS",
 686        [CARL9170_ERP_CTS] = "Force CTS"
 687};
 688
 689static char *carl9170_debugfs_erp_read(struct ar9170 *ar, char *buf,
 690                                       size_t bufsize, ssize_t *ret)
 691{
 692        ADD(buf, *ret, bufsize, "ERP Setting: (%d) -> %s\n", ar->erp_mode,
 693            erp_modes[ar->erp_mode]);
 694        return buf;
 695}
 696
 697static ssize_t carl9170_debugfs_erp_write(struct ar9170 *ar, const char *buf,
 698                                          size_t count)
 699{
 700        int res, val;
 701
 702        if (count < 1)
 703                return -EINVAL;
 704
 705        res = sscanf(buf, "%d", &val);
 706        if (res != 1)
 707                return -EINVAL;
 708
 709        if (!((val > CARL9170_ERP_INVALID) &&
 710              (val < __CARL9170_ERP_NUM)))
 711                return -EINVAL;
 712
 713        ar->erp_mode = val;
 714        return count;
 715}
 716
 717DEBUGFS_DECLARE_RW_FILE(erp, 80);
 718
 719static ssize_t carl9170_debugfs_hw_iowrite32_write(struct ar9170 *ar,
 720        const char *buf, size_t count)
 721{
 722        int err = 0, max_len = 22, res;
 723        u32 reg, val;
 724
 725        if (!count)
 726                return 0;
 727
 728        if (count > max_len)
 729                return -E2BIG;
 730
 731        res = sscanf(buf, "0x%X 0x%X", &reg, &val);
 732        if (res != 2) {
 733                err = -EINVAL;
 734                goto out;
 735        }
 736
 737        if (reg <= 0x100000 || reg >= 0x280000) {
 738                err = -EADDRNOTAVAIL;
 739                goto out;
 740        }
 741
 742        if (reg & 3) {
 743                err = -EINVAL;
 744                goto out;
 745        }
 746
 747        err = carl9170_write_reg(ar, reg, val);
 748        if (err)
 749                goto out;
 750
 751out:
 752        return err ? err : count;
 753}
 754DEBUGFS_DECLARE_WO_FILE(hw_iowrite32);
 755
 756DEBUGFS_HW_TALLY_FILE(hw_tx_tally, "u");
 757DEBUGFS_HW_TALLY_FILE(hw_rx_tally, "u");
 758DEBUGFS_HW_TALLY_FILE(hw_phy_errors, "u");
 759DEBUGFS_HW_REG_FILE(hw_wlan_queue, ".8x");
 760DEBUGFS_HW_REG_FILE(hw_pta_queue, ".8x");
 761DEBUGFS_HW_REG_FILE(hw_ampdu_info, ".8x");
 762DEBUGFS_QUEUE_DUMP(tx_status, 0);
 763DEBUGFS_QUEUE_DUMP(tx_status, 1);
 764DEBUGFS_QUEUE_DUMP(tx_status, 2);
 765DEBUGFS_QUEUE_DUMP(tx_status, 3);
 766DEBUGFS_QUEUE_DUMP(tx_pending, 0);
 767DEBUGFS_QUEUE_DUMP(tx_pending, 1);
 768DEBUGFS_QUEUE_DUMP(tx_pending, 2);
 769DEBUGFS_QUEUE_DUMP(tx_pending, 3);
 770DEBUGFS_READONLY_FILE(usb_tx_anch_urbs, 20, "%d",
 771                      atomic_read(&ar->tx_anch_urbs));
 772DEBUGFS_READONLY_FILE(usb_rx_anch_urbs, 20, "%d",
 773                      atomic_read(&ar->rx_anch_urbs));
 774DEBUGFS_READONLY_FILE(usb_rx_work_urbs, 20, "%d",
 775                      atomic_read(&ar->rx_work_urbs));
 776DEBUGFS_READONLY_FILE(usb_rx_pool_urbs, 20, "%d",
 777                      atomic_read(&ar->rx_pool_urbs));
 778
 779DEBUGFS_READONLY_FILE(tx_total_queued, 20, "%d",
 780                      atomic_read(&ar->tx_total_queued));
 781DEBUGFS_READONLY_FILE(tx_ampdu_scheduler, 20, "%d",
 782                      atomic_read(&ar->tx_ampdu_scheduler));
 783
 784DEBUGFS_READONLY_FILE(tx_total_pending, 20, "%d",
 785                      atomic_read(&ar->tx_total_pending));
 786
 787DEBUGFS_READONLY_FILE(tx_ampdu_list_len, 20, "%d",
 788                      ar->tx_ampdu_list_len);
 789
 790DEBUGFS_READONLY_FILE(tx_ampdu_upload, 20, "%d",
 791                      atomic_read(&ar->tx_ampdu_upload));
 792
 793DEBUGFS_READONLY_FILE(tx_janitor_last_run, 64, "last run:%d ms ago",
 794        jiffies_to_msecs(jiffies - ar->tx_janitor_last_run));
 795
 796DEBUGFS_READONLY_FILE(tx_dropped, 20, "%d", ar->tx_dropped);
 797
 798DEBUGFS_READONLY_FILE(rx_dropped, 20, "%d", ar->rx_dropped);
 799
 800DEBUGFS_READONLY_FILE(sniffer_enabled, 20, "%d", ar->sniffer_enabled);
 801DEBUGFS_READONLY_FILE(rx_software_decryption, 20, "%d",
 802                      ar->rx_software_decryption);
 803DEBUGFS_READONLY_FILE(ampdu_factor, 20, "%d",
 804                      ar->current_factor);
 805DEBUGFS_READONLY_FILE(ampdu_density, 20, "%d",
 806                      ar->current_density);
 807
 808DEBUGFS_READONLY_FILE(beacon_int, 20, "%d TU", ar->global_beacon_int);
 809DEBUGFS_READONLY_FILE(pretbtt, 20, "%d TU", ar->global_pretbtt);
 810
 811void carl9170_debugfs_register(struct ar9170 *ar)
 812{
 813        ar->debug_dir = debugfs_create_dir(KBUILD_MODNAME,
 814                ar->hw->wiphy->debugfsdir);
 815
 816#define DEBUGFS_ADD(name)                                               \
 817        debugfs_create_file(#name, carl_debugfs_##name ##_ops.attr,     \
 818                            ar->debug_dir, ar,                          \
 819                            &carl_debugfs_##name ## _ops.fops);
 820
 821        DEBUGFS_ADD(usb_tx_anch_urbs);
 822        DEBUGFS_ADD(usb_rx_pool_urbs);
 823        DEBUGFS_ADD(usb_rx_anch_urbs);
 824        DEBUGFS_ADD(usb_rx_work_urbs);
 825
 826        DEBUGFS_ADD(tx_total_queued);
 827        DEBUGFS_ADD(tx_total_pending);
 828        DEBUGFS_ADD(tx_dropped);
 829        DEBUGFS_ADD(tx_stuck);
 830        DEBUGFS_ADD(tx_ampdu_upload);
 831        DEBUGFS_ADD(tx_ampdu_scheduler);
 832        DEBUGFS_ADD(tx_ampdu_list_len);
 833
 834        DEBUGFS_ADD(rx_dropped);
 835        DEBUGFS_ADD(sniffer_enabled);
 836        DEBUGFS_ADD(rx_software_decryption);
 837
 838        DEBUGFS_ADD(mem_usage);
 839        DEBUGFS_ADD(qos_stat);
 840        DEBUGFS_ADD(sta_psm);
 841        DEBUGFS_ADD(ampdu_state);
 842
 843        DEBUGFS_ADD(hw_tx_tally);
 844        DEBUGFS_ADD(hw_rx_tally);
 845        DEBUGFS_ADD(hw_phy_errors);
 846        DEBUGFS_ADD(phy_noise);
 847
 848        DEBUGFS_ADD(hw_wlan_queue);
 849        DEBUGFS_ADD(hw_pta_queue);
 850        DEBUGFS_ADD(hw_ampdu_info);
 851
 852        DEBUGFS_ADD(ampdu_density);
 853        DEBUGFS_ADD(ampdu_factor);
 854
 855        DEBUGFS_ADD(tx_janitor_last_run);
 856
 857        DEBUGFS_ADD(tx_status_0);
 858        DEBUGFS_ADD(tx_status_1);
 859        DEBUGFS_ADD(tx_status_2);
 860        DEBUGFS_ADD(tx_status_3);
 861
 862        DEBUGFS_ADD(tx_pending_0);
 863        DEBUGFS_ADD(tx_pending_1);
 864        DEBUGFS_ADD(tx_pending_2);
 865        DEBUGFS_ADD(tx_pending_3);
 866
 867        DEBUGFS_ADD(hw_ioread32);
 868        DEBUGFS_ADD(hw_iowrite32);
 869        DEBUGFS_ADD(bug);
 870
 871        DEBUGFS_ADD(erp);
 872
 873        DEBUGFS_ADD(vif_dump);
 874
 875        DEBUGFS_ADD(beacon_int);
 876        DEBUGFS_ADD(pretbtt);
 877
 878#undef DEBUGFS_ADD
 879}
 880
 881void carl9170_debugfs_unregister(struct ar9170 *ar)
 882{
 883        debugfs_remove_recursive(ar->debug_dir);
 884}
 885