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        ADD(buf, *len, bufsize, "jar: [");
 218
 219        spin_lock_bh(&ar->mem_lock);
 220
 221        *len += bitmap_scnprintf(&buf[*len], bufsize - *len,
 222                                  ar->mem_bitmap, ar->fw.mem_blocks);
 223
 224        ADD(buf, *len, bufsize, "]\n");
 225
 226        ADD(buf, *len, bufsize, "cookies: used:%3d / total:%3d, allocs:%d\n",
 227            bitmap_weight(ar->mem_bitmap, ar->fw.mem_blocks),
 228            ar->fw.mem_blocks, atomic_read(&ar->mem_allocs));
 229
 230        ADD(buf, *len, bufsize, "memory: free:%3d (%3d KiB) / total:%3d KiB)\n",
 231            atomic_read(&ar->mem_free_blocks),
 232            (atomic_read(&ar->mem_free_blocks) * ar->fw.mem_block_size) / 1024,
 233            (ar->fw.mem_blocks * ar->fw.mem_block_size) / 1024);
 234
 235        spin_unlock_bh(&ar->mem_lock);
 236
 237        return buf;
 238}
 239DEBUGFS_DECLARE_RO_FILE(mem_usage, 512);
 240
 241static char *carl9170_debugfs_qos_stat_read(struct ar9170 *ar, char *buf,
 242                                            size_t bufsize, ssize_t *len)
 243{
 244        ADD(buf, *len, bufsize, "%s QoS AC\n", modparam_noht ? "Hardware" :
 245            "Software");
 246
 247        ADD(buf, *len, bufsize, "[     VO            VI       "
 248                                 "     BE            BK      ]\n");
 249
 250        spin_lock_bh(&ar->tx_stats_lock);
 251        ADD(buf, *len, bufsize, "[length/limit  length/limit  "
 252                                 "length/limit  length/limit ]\n"
 253                                "[   %3d/%3d       %3d/%3d    "
 254                                 "   %3d/%3d       %3d/%3d   ]\n\n",
 255            ar->tx_stats[0].len, ar->tx_stats[0].limit,
 256            ar->tx_stats[1].len, ar->tx_stats[1].limit,
 257            ar->tx_stats[2].len, ar->tx_stats[2].limit,
 258            ar->tx_stats[3].len, ar->tx_stats[3].limit);
 259
 260        ADD(buf, *len, bufsize, "[    total         total     "
 261                                 "    total         total    ]\n"
 262                                "[%10d    %10d    %10d    %10d   ]\n\n",
 263            ar->tx_stats[0].count, ar->tx_stats[1].count,
 264            ar->tx_stats[2].count, ar->tx_stats[3].count);
 265
 266        spin_unlock_bh(&ar->tx_stats_lock);
 267
 268        ADD(buf, *len, bufsize, "[  pend/waittx   pend/waittx "
 269                                 "  pend/waittx   pend/waittx]\n"
 270                                "[   %3d/%3d       %3d/%3d    "
 271                                 "   %3d/%3d       %3d/%3d   ]\n\n",
 272            skb_queue_len(&ar->tx_pending[0]),
 273            skb_queue_len(&ar->tx_status[0]),
 274            skb_queue_len(&ar->tx_pending[1]),
 275            skb_queue_len(&ar->tx_status[1]),
 276            skb_queue_len(&ar->tx_pending[2]),
 277            skb_queue_len(&ar->tx_status[2]),
 278            skb_queue_len(&ar->tx_pending[3]),
 279            skb_queue_len(&ar->tx_status[3]));
 280
 281        return buf;
 282}
 283DEBUGFS_DECLARE_RO_FILE(qos_stat, 512);
 284
 285static void carl9170_debugfs_format_frame(struct ar9170 *ar,
 286        struct sk_buff *skb, const char *prefix, char *buf,
 287        ssize_t *off, ssize_t bufsize)
 288{
 289        struct _carl9170_tx_superframe *txc = (void *) skb->data;
 290        struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
 291        struct carl9170_tx_info *arinfo = (void *) txinfo->rate_driver_data;
 292        struct ieee80211_hdr *hdr = (void *) txc->frame_data;
 293
 294        ADD(buf, *off, bufsize, "%s %p, c:%2x, DA:%pM, sq:%4d, mc:%.4x, "
 295            "pc:%.8x, to:%d ms\n", prefix, skb, txc->s.cookie,
 296            ieee80211_get_DA(hdr), get_seq_h(hdr),
 297            le16_to_cpu(txc->f.mac_control), le32_to_cpu(txc->f.phy_control),
 298            jiffies_to_msecs(jiffies - arinfo->timeout));
 299}
 300
 301
 302static char *carl9170_debugfs_ampdu_state_read(struct ar9170 *ar, char *buf,
 303                                               size_t bufsize, ssize_t *len)
 304{
 305        struct carl9170_sta_tid *iter;
 306        struct sk_buff *skb;
 307        int cnt = 0, fc;
 308        int offset;
 309
 310        rcu_read_lock();
 311        list_for_each_entry_rcu(iter, &ar->tx_ampdu_list, list) {
 312
 313                spin_lock_bh(&iter->lock);
 314                ADD(buf, *len, bufsize, "Entry: #%2d TID:%1d, BSN:%4d, "
 315                    "SNX:%4d, HSN:%4d, BAW:%2d, state:%1d, toggles:%d\n",
 316                    cnt, iter->tid, iter->bsn, iter->snx, iter->hsn,
 317                    iter->max, iter->state, iter->counter);
 318
 319                ADD(buf, *len, bufsize, "\tWindow:  [");
 320
 321                *len += bitmap_scnprintf(&buf[*len], bufsize - *len,
 322                        iter->bitmap, CARL9170_BAW_BITS);
 323
 324#define BM_STR_OFF(offset)                                      \
 325        ((CARL9170_BAW_BITS - (offset) - 1) / 4 +               \
 326         (CARL9170_BAW_BITS - (offset) - 1) / 32 + 1)
 327
 328                ADD(buf, *len, bufsize, ",W]\n");
 329
 330                offset = BM_STR_OFF(0);
 331                ADD(buf, *len, bufsize, "\tBase Seq: %*s\n", offset, "T");
 332
 333                offset = BM_STR_OFF(SEQ_DIFF(iter->snx, iter->bsn));
 334                ADD(buf, *len, bufsize, "\tNext Seq: %*s\n", offset, "W");
 335
 336                offset = BM_STR_OFF(((int)iter->hsn - (int)iter->bsn) %
 337                                     CARL9170_BAW_BITS);
 338                ADD(buf, *len, bufsize, "\tLast Seq: %*s\n", offset, "N");
 339
 340                ADD(buf, *len, bufsize, "\tPre-Aggregation reorder buffer: "
 341                    " currently queued:%d\n", skb_queue_len(&iter->queue));
 342
 343                fc = 0;
 344                skb_queue_walk(&iter->queue, skb) {
 345                        char prefix[32];
 346
 347                        snprintf(prefix, sizeof(prefix), "\t\t%3d :", fc);
 348                        carl9170_debugfs_format_frame(ar, skb, prefix, buf,
 349                                                      len, bufsize);
 350
 351                        fc++;
 352                }
 353                spin_unlock_bh(&iter->lock);
 354                cnt++;
 355        }
 356        rcu_read_unlock();
 357
 358        return buf;
 359}
 360DEBUGFS_DECLARE_RO_FILE(ampdu_state, 8000);
 361
 362static void carl9170_debugfs_queue_dump(struct ar9170 *ar, char *buf,
 363        ssize_t *len, size_t bufsize, struct sk_buff_head *queue)
 364{
 365        struct sk_buff *skb;
 366        char prefix[16];
 367        int fc = 0;
 368
 369        spin_lock_bh(&queue->lock);
 370        skb_queue_walk(queue, skb) {
 371                snprintf(prefix, sizeof(prefix), "%3d :", fc);
 372                carl9170_debugfs_format_frame(ar, skb, prefix, buf,
 373                                              len, bufsize);
 374                fc++;
 375        }
 376        spin_unlock_bh(&queue->lock);
 377}
 378
 379#define DEBUGFS_QUEUE_DUMP(q, qi)                                       \
 380static char *carl9170_debugfs_##q ##_##qi ##_read(struct ar9170 *ar,    \
 381        char *buf, size_t bufsize, ssize_t *len)                        \
 382{                                                                       \
 383        carl9170_debugfs_queue_dump(ar, buf, len, bufsize, &ar->q[qi]); \
 384        return buf;                                                     \
 385}                                                                       \
 386DEBUGFS_DECLARE_RO_FILE(q##_##qi, 8000);
 387
 388static char *carl9170_debugfs_sta_psm_read(struct ar9170 *ar, char *buf,
 389                                           size_t bufsize, ssize_t *len)
 390{
 391        ADD(buf, *len, bufsize, "psm state: %s\n", (ar->ps.off_override ?
 392            "FORCE CAM" : (ar->ps.state ? "PSM" : "CAM")));
 393
 394        ADD(buf, *len, bufsize, "sleep duration: %d ms.\n", ar->ps.sleep_ms);
 395        ADD(buf, *len, bufsize, "last power-state transition: %d ms ago.\n",
 396            jiffies_to_msecs(jiffies - ar->ps.last_action));
 397        ADD(buf, *len, bufsize, "last CAM->PSM transition: %d ms ago.\n",
 398            jiffies_to_msecs(jiffies - ar->ps.last_slept));
 399
 400        return buf;
 401}
 402DEBUGFS_DECLARE_RO_FILE(sta_psm, 160);
 403
 404static char *carl9170_debugfs_tx_stuck_read(struct ar9170 *ar, char *buf,
 405                                            size_t bufsize, ssize_t *len)
 406{
 407        int i;
 408
 409        for (i = 0; i < ar->hw->queues; i++) {
 410                ADD(buf, *len, bufsize, "TX queue [%d]: %10d max:%10d ms.\n",
 411                    i, ieee80211_queue_stopped(ar->hw, i) ?
 412                    jiffies_to_msecs(jiffies - ar->queue_stop_timeout[i]) : 0,
 413                    jiffies_to_msecs(ar->max_queue_stop_timeout[i]));
 414
 415                ar->max_queue_stop_timeout[i] = 0;
 416        }
 417
 418        return buf;
 419}
 420DEBUGFS_DECLARE_RO_FILE(tx_stuck, 180);
 421
 422static char *carl9170_debugfs_phy_noise_read(struct ar9170 *ar, char *buf,
 423                                             size_t bufsize, ssize_t *len)
 424{
 425        int err;
 426
 427        err = carl9170_get_noisefloor(ar);
 428        if (err) {
 429                *len = err;
 430                return buf;
 431        }
 432
 433        ADD(buf, *len, bufsize, "Chain 0: %10d dBm, ext. chan.:%10d dBm\n",
 434            ar->noise[0], ar->noise[2]);
 435        ADD(buf, *len, bufsize, "Chain 2: %10d dBm, ext. chan.:%10d dBm\n",
 436            ar->noise[1], ar->noise[3]);
 437
 438        return buf;
 439}
 440DEBUGFS_DECLARE_RO_FILE(phy_noise, 180);
 441
 442static char *carl9170_debugfs_vif_dump_read(struct ar9170 *ar, char *buf,
 443                                            size_t bufsize, ssize_t *len)
 444{
 445        struct carl9170_vif_info *iter;
 446        int i = 0;
 447
 448        ADD(buf, *len, bufsize, "registered VIFs:%d \\ %d\n",
 449            ar->vifs, ar->fw.vif_num);
 450
 451        ADD(buf, *len, bufsize, "VIF bitmap: [");
 452
 453        *len += bitmap_scnprintf(&buf[*len], bufsize - *len,
 454                                 &ar->vif_bitmap, ar->fw.vif_num);
 455
 456        ADD(buf, *len, bufsize, "]\n");
 457
 458        rcu_read_lock();
 459        list_for_each_entry_rcu(iter, &ar->vif_list, list) {
 460                struct ieee80211_vif *vif = carl9170_get_vif(iter);
 461                ADD(buf, *len, bufsize, "\t%d = [%s VIF, id:%d, type:%x "
 462                    " mac:%pM %s]\n", i, (carl9170_get_main_vif(ar) == vif ?
 463                    "Master" : " Slave"), iter->id, vif->type, vif->addr,
 464                    iter->enable_beacon ? "beaconing " : "");
 465                i++;
 466        }
 467        rcu_read_unlock();
 468
 469        return buf;
 470}
 471DEBUGFS_DECLARE_RO_FILE(vif_dump, 8000);
 472
 473#define UPDATE_COUNTER(ar, name)        ({                              \
 474        u32 __tmp[ARRAY_SIZE(name##_regs)];                             \
 475        unsigned int __i, __err = -ENODEV;                              \
 476                                                                        \
 477        for (__i = 0; __i < ARRAY_SIZE(name##_regs); __i++) {           \
 478                __tmp[__i] = name##_regs[__i].reg;                      \
 479                ar->debug.stats.name##_counter[__i] = 0;                \
 480        }                                                               \
 481                                                                        \
 482        if (IS_STARTED(ar))                                             \
 483                __err = carl9170_read_mreg(ar, ARRAY_SIZE(name##_regs), \
 484                        __tmp, ar->debug.stats.name##_counter);         \
 485        (__err); })
 486
 487#define TALLY_SUM_UP(ar, name)  do {                                    \
 488        unsigned int __i;                                               \
 489                                                                        \
 490        for (__i = 0; __i < ARRAY_SIZE(name##_regs); __i++) {           \
 491                ar->debug.stats.name##_sum[__i] +=                      \
 492                        ar->debug.stats.name##_counter[__i];            \
 493        }                                                               \
 494} while (0)
 495
 496#define DEBUGFS_HW_TALLY_FILE(name, f)                                  \
 497static char *carl9170_debugfs_##name ## _read(struct ar9170 *ar,        \
 498         char *dum, size_t bufsize, ssize_t *ret)                       \
 499{                                                                       \
 500        char *buf;                                                      \
 501        int i, max_len, err;                                            \
 502                                                                        \
 503        max_len = ARRAY_SIZE(name##_regs) * 80;                         \
 504        buf = vmalloc(max_len);                                         \
 505        if (!buf)                                                       \
 506                return NULL;                                            \
 507                                                                        \
 508        err = UPDATE_COUNTER(ar, name);                                 \
 509        if (err) {                                                      \
 510                *ret = err;                                             \
 511                return buf;                                             \
 512        }                                                               \
 513                                                                        \
 514        TALLY_SUM_UP(ar, name);                                         \
 515                                                                        \
 516        for (i = 0; i < ARRAY_SIZE(name##_regs); i++) {                 \
 517                ADD(buf, *ret, max_len, "%22s = %" f "[+%" f "]\n",     \
 518                    name##_regs[i].nreg, ar->debug.stats.name ##_sum[i],\
 519                    ar->debug.stats.name ##_counter[i]);                \
 520        }                                                               \
 521                                                                        \
 522        return buf;                                                     \
 523}                                                                       \
 524DEBUGFS_DECLARE_RO_FILE(name, 0);
 525
 526#define DEBUGFS_HW_REG_FILE(name, f)                                    \
 527static char *carl9170_debugfs_##name ## _read(struct ar9170 *ar,        \
 528        char *dum, size_t bufsize, ssize_t *ret)                        \
 529{                                                                       \
 530        char *buf;                                                      \
 531        int i, max_len, err;                                            \
 532                                                                        \
 533        max_len = ARRAY_SIZE(name##_regs) * 80;                         \
 534        buf = vmalloc(max_len);                                         \
 535        if (!buf)                                                       \
 536                return NULL;                                            \
 537                                                                        \
 538        err = UPDATE_COUNTER(ar, name);                                 \
 539        if (err) {                                                      \
 540                *ret = err;                                             \
 541                return buf;                                             \
 542        }                                                               \
 543                                                                        \
 544        for (i = 0; i < ARRAY_SIZE(name##_regs); i++) {                 \
 545                ADD(buf, *ret, max_len, "%22s = %" f "\n",              \
 546                    name##_regs[i].nreg,                                \
 547                    ar->debug.stats.name##_counter[i]);                 \
 548        }                                                               \
 549                                                                        \
 550        return buf;                                                     \
 551}                                                                       \
 552DEBUGFS_DECLARE_RO_FILE(name, 0);
 553
 554static ssize_t carl9170_debugfs_hw_ioread32_write(struct ar9170 *ar,
 555        const char *buf, size_t count)
 556{
 557        int err = 0, i, n = 0, max_len = 32, res;
 558        unsigned int reg, tmp;
 559
 560        if (!count)
 561                return 0;
 562
 563        if (count > max_len)
 564                return -E2BIG;
 565
 566        res = sscanf(buf, "0x%X %d", &reg, &n);
 567        if (res < 1) {
 568                err = -EINVAL;
 569                goto out;
 570        }
 571
 572        if (res == 1)
 573                n = 1;
 574
 575        if (n > 15) {
 576                err = -EMSGSIZE;
 577                goto out;
 578        }
 579
 580        if ((reg >= 0x280000) || ((reg + (n << 2)) >= 0x280000)) {
 581                err = -EADDRNOTAVAIL;
 582                goto out;
 583        }
 584
 585        if (reg & 3) {
 586                err = -EINVAL;
 587                goto out;
 588        }
 589
 590        for (i = 0; i < n; i++) {
 591                err = carl9170_read_reg(ar, reg + (i << 2), &tmp);
 592                if (err)
 593                        goto out;
 594
 595                ar->debug.ring[ar->debug.ring_tail].reg = reg + (i << 2);
 596                ar->debug.ring[ar->debug.ring_tail].value = tmp;
 597                ar->debug.ring_tail++;
 598                ar->debug.ring_tail %= CARL9170_DEBUG_RING_SIZE;
 599        }
 600
 601out:
 602        return err ? err : count;
 603}
 604
 605static char *carl9170_debugfs_hw_ioread32_read(struct ar9170 *ar, char *buf,
 606                                               size_t bufsize, ssize_t *ret)
 607{
 608        int i = 0;
 609
 610        while (ar->debug.ring_head != ar->debug.ring_tail) {
 611                ADD(buf, *ret, bufsize, "%.8x = %.8x\n",
 612                    ar->debug.ring[ar->debug.ring_head].reg,
 613                    ar->debug.ring[ar->debug.ring_head].value);
 614
 615                ar->debug.ring_head++;
 616                ar->debug.ring_head %= CARL9170_DEBUG_RING_SIZE;
 617
 618                if (i++ == 64)
 619                        break;
 620        }
 621        ar->debug.ring_head = ar->debug.ring_tail;
 622        return buf;
 623}
 624DEBUGFS_DECLARE_RW_FILE(hw_ioread32, CARL9170_DEBUG_RING_SIZE * 40);
 625
 626static ssize_t carl9170_debugfs_bug_write(struct ar9170 *ar, const char *buf,
 627                                          size_t count)
 628{
 629        int err;
 630
 631        if (count < 1)
 632                return -EINVAL;
 633
 634        switch (buf[0]) {
 635        case 'F':
 636                ar->needs_full_reset = true;
 637                break;
 638
 639        case 'R':
 640                if (!IS_STARTED(ar)) {
 641                        err = -EAGAIN;
 642                        goto out;
 643                }
 644
 645                ar->needs_full_reset = false;
 646                break;
 647
 648        case 'M':
 649                err = carl9170_mac_reset(ar);
 650                if (err < 0)
 651                        count = err;
 652
 653                goto out;
 654
 655        case 'P':
 656                err = carl9170_set_channel(ar, ar->hw->conf.chandef.chan,
 657                        cfg80211_get_chandef_type(&ar->hw->conf.chandef));
 658                if (err < 0)
 659                        count = err;
 660
 661                goto out;
 662
 663        default:
 664                return -EINVAL;
 665        }
 666
 667        carl9170_restart(ar, CARL9170_RR_USER_REQUEST);
 668
 669out:
 670        return count;
 671}
 672
 673static char *carl9170_debugfs_bug_read(struct ar9170 *ar, char *buf,
 674                                       size_t bufsize, ssize_t *ret)
 675{
 676        ADD(buf, *ret, bufsize, "[P]hy reinit, [R]estart, [F]ull usb reset, "
 677            "[M]ac reset\n");
 678        ADD(buf, *ret, bufsize, "firmware restarts:%d, last reason:%d\n",
 679                ar->restart_counter, ar->last_reason);
 680        ADD(buf, *ret, bufsize, "phy reinit errors:%d (%d)\n",
 681                ar->total_chan_fail, ar->chan_fail);
 682        ADD(buf, *ret, bufsize, "reported firmware errors:%d\n",
 683                ar->fw.err_counter);
 684        ADD(buf, *ret, bufsize, "reported firmware BUGs:%d\n",
 685                ar->fw.bug_counter);
 686        ADD(buf, *ret, bufsize, "pending restart requests:%d\n",
 687                atomic_read(&ar->pending_restarts));
 688        return buf;
 689}
 690__DEBUGFS_DECLARE_RW_FILE(bug, 400, CARL9170_STOPPED);
 691
 692static const char *const erp_modes[] = {
 693        [CARL9170_ERP_INVALID] = "INVALID",
 694        [CARL9170_ERP_AUTO] = "Automatic",
 695        [CARL9170_ERP_MAC80211] = "Set by MAC80211",
 696        [CARL9170_ERP_OFF] = "Force Off",
 697        [CARL9170_ERP_RTS] = "Force RTS",
 698        [CARL9170_ERP_CTS] = "Force CTS"
 699};
 700
 701static char *carl9170_debugfs_erp_read(struct ar9170 *ar, char *buf,
 702                                       size_t bufsize, ssize_t *ret)
 703{
 704        ADD(buf, *ret, bufsize, "ERP Setting: (%d) -> %s\n", ar->erp_mode,
 705            erp_modes[ar->erp_mode]);
 706        return buf;
 707}
 708
 709static ssize_t carl9170_debugfs_erp_write(struct ar9170 *ar, const char *buf,
 710                                          size_t count)
 711{
 712        int res, val;
 713
 714        if (count < 1)
 715                return -EINVAL;
 716
 717        res = sscanf(buf, "%d", &val);
 718        if (res != 1)
 719                return -EINVAL;
 720
 721        if (!((val > CARL9170_ERP_INVALID) &&
 722              (val < __CARL9170_ERP_NUM)))
 723                return -EINVAL;
 724
 725        ar->erp_mode = val;
 726        return count;
 727}
 728
 729DEBUGFS_DECLARE_RW_FILE(erp, 80);
 730
 731static ssize_t carl9170_debugfs_hw_iowrite32_write(struct ar9170 *ar,
 732        const char *buf, size_t count)
 733{
 734        int err = 0, max_len = 22, res;
 735        u32 reg, val;
 736
 737        if (!count)
 738                return 0;
 739
 740        if (count > max_len)
 741                return -E2BIG;
 742
 743        res = sscanf(buf, "0x%X 0x%X", &reg, &val);
 744        if (res != 2) {
 745                err = -EINVAL;
 746                goto out;
 747        }
 748
 749        if (reg <= 0x100000 || reg >= 0x280000) {
 750                err = -EADDRNOTAVAIL;
 751                goto out;
 752        }
 753
 754        if (reg & 3) {
 755                err = -EINVAL;
 756                goto out;
 757        }
 758
 759        err = carl9170_write_reg(ar, reg, val);
 760        if (err)
 761                goto out;
 762
 763out:
 764        return err ? err : count;
 765}
 766DEBUGFS_DECLARE_WO_FILE(hw_iowrite32);
 767
 768DEBUGFS_HW_TALLY_FILE(hw_tx_tally, "u");
 769DEBUGFS_HW_TALLY_FILE(hw_rx_tally, "u");
 770DEBUGFS_HW_TALLY_FILE(hw_phy_errors, "u");
 771DEBUGFS_HW_REG_FILE(hw_wlan_queue, ".8x");
 772DEBUGFS_HW_REG_FILE(hw_pta_queue, ".8x");
 773DEBUGFS_HW_REG_FILE(hw_ampdu_info, ".8x");
 774DEBUGFS_QUEUE_DUMP(tx_status, 0);
 775DEBUGFS_QUEUE_DUMP(tx_status, 1);
 776DEBUGFS_QUEUE_DUMP(tx_status, 2);
 777DEBUGFS_QUEUE_DUMP(tx_status, 3);
 778DEBUGFS_QUEUE_DUMP(tx_pending, 0);
 779DEBUGFS_QUEUE_DUMP(tx_pending, 1);
 780DEBUGFS_QUEUE_DUMP(tx_pending, 2);
 781DEBUGFS_QUEUE_DUMP(tx_pending, 3);
 782DEBUGFS_READONLY_FILE(usb_tx_anch_urbs, 20, "%d",
 783                      atomic_read(&ar->tx_anch_urbs));
 784DEBUGFS_READONLY_FILE(usb_rx_anch_urbs, 20, "%d",
 785                      atomic_read(&ar->rx_anch_urbs));
 786DEBUGFS_READONLY_FILE(usb_rx_work_urbs, 20, "%d",
 787                      atomic_read(&ar->rx_work_urbs));
 788DEBUGFS_READONLY_FILE(usb_rx_pool_urbs, 20, "%d",
 789                      atomic_read(&ar->rx_pool_urbs));
 790
 791DEBUGFS_READONLY_FILE(tx_total_queued, 20, "%d",
 792                      atomic_read(&ar->tx_total_queued));
 793DEBUGFS_READONLY_FILE(tx_ampdu_scheduler, 20, "%d",
 794                      atomic_read(&ar->tx_ampdu_scheduler));
 795
 796DEBUGFS_READONLY_FILE(tx_total_pending, 20, "%d",
 797                      atomic_read(&ar->tx_total_pending));
 798
 799DEBUGFS_READONLY_FILE(tx_ampdu_list_len, 20, "%d",
 800                      ar->tx_ampdu_list_len);
 801
 802DEBUGFS_READONLY_FILE(tx_ampdu_upload, 20, "%d",
 803                      atomic_read(&ar->tx_ampdu_upload));
 804
 805DEBUGFS_READONLY_FILE(tx_janitor_last_run, 64, "last run:%d ms ago",
 806        jiffies_to_msecs(jiffies - ar->tx_janitor_last_run));
 807
 808DEBUGFS_READONLY_FILE(tx_dropped, 20, "%d", ar->tx_dropped);
 809
 810DEBUGFS_READONLY_FILE(rx_dropped, 20, "%d", ar->rx_dropped);
 811
 812DEBUGFS_READONLY_FILE(sniffer_enabled, 20, "%d", ar->sniffer_enabled);
 813DEBUGFS_READONLY_FILE(rx_software_decryption, 20, "%d",
 814                      ar->rx_software_decryption);
 815DEBUGFS_READONLY_FILE(ampdu_factor, 20, "%d",
 816                      ar->current_factor);
 817DEBUGFS_READONLY_FILE(ampdu_density, 20, "%d",
 818                      ar->current_density);
 819
 820DEBUGFS_READONLY_FILE(beacon_int, 20, "%d TU", ar->global_beacon_int);
 821DEBUGFS_READONLY_FILE(pretbtt, 20, "%d TU", ar->global_pretbtt);
 822
 823void carl9170_debugfs_register(struct ar9170 *ar)
 824{
 825        ar->debug_dir = debugfs_create_dir(KBUILD_MODNAME,
 826                ar->hw->wiphy->debugfsdir);
 827
 828#define DEBUGFS_ADD(name)                                               \
 829        debugfs_create_file(#name, carl_debugfs_##name ##_ops.attr,     \
 830                            ar->debug_dir, ar,                          \
 831                            &carl_debugfs_##name ## _ops.fops);
 832
 833        DEBUGFS_ADD(usb_tx_anch_urbs);
 834        DEBUGFS_ADD(usb_rx_pool_urbs);
 835        DEBUGFS_ADD(usb_rx_anch_urbs);
 836        DEBUGFS_ADD(usb_rx_work_urbs);
 837
 838        DEBUGFS_ADD(tx_total_queued);
 839        DEBUGFS_ADD(tx_total_pending);
 840        DEBUGFS_ADD(tx_dropped);
 841        DEBUGFS_ADD(tx_stuck);
 842        DEBUGFS_ADD(tx_ampdu_upload);
 843        DEBUGFS_ADD(tx_ampdu_scheduler);
 844        DEBUGFS_ADD(tx_ampdu_list_len);
 845
 846        DEBUGFS_ADD(rx_dropped);
 847        DEBUGFS_ADD(sniffer_enabled);
 848        DEBUGFS_ADD(rx_software_decryption);
 849
 850        DEBUGFS_ADD(mem_usage);
 851        DEBUGFS_ADD(qos_stat);
 852        DEBUGFS_ADD(sta_psm);
 853        DEBUGFS_ADD(ampdu_state);
 854
 855        DEBUGFS_ADD(hw_tx_tally);
 856        DEBUGFS_ADD(hw_rx_tally);
 857        DEBUGFS_ADD(hw_phy_errors);
 858        DEBUGFS_ADD(phy_noise);
 859
 860        DEBUGFS_ADD(hw_wlan_queue);
 861        DEBUGFS_ADD(hw_pta_queue);
 862        DEBUGFS_ADD(hw_ampdu_info);
 863
 864        DEBUGFS_ADD(ampdu_density);
 865        DEBUGFS_ADD(ampdu_factor);
 866
 867        DEBUGFS_ADD(tx_janitor_last_run);
 868
 869        DEBUGFS_ADD(tx_status_0);
 870        DEBUGFS_ADD(tx_status_1);
 871        DEBUGFS_ADD(tx_status_2);
 872        DEBUGFS_ADD(tx_status_3);
 873
 874        DEBUGFS_ADD(tx_pending_0);
 875        DEBUGFS_ADD(tx_pending_1);
 876        DEBUGFS_ADD(tx_pending_2);
 877        DEBUGFS_ADD(tx_pending_3);
 878
 879        DEBUGFS_ADD(hw_ioread32);
 880        DEBUGFS_ADD(hw_iowrite32);
 881        DEBUGFS_ADD(bug);
 882
 883        DEBUGFS_ADD(erp);
 884
 885        DEBUGFS_ADD(vif_dump);
 886
 887        DEBUGFS_ADD(beacon_int);
 888        DEBUGFS_ADD(pretbtt);
 889
 890#undef DEBUGFS_ADD
 891}
 892
 893void carl9170_debugfs_unregister(struct ar9170 *ar)
 894{
 895        debugfs_remove_recursive(ar->debug_dir);
 896}
 897