linux/net/mac80211/debugfs.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * mac80211 debugfs for wireless PHYs
   4 *
   5 * Copyright 2007       Johannes Berg <johannes@sipsolutions.net>
   6 * Copyright 2013-2014  Intel Mobile Communications GmbH
   7 * Copyright (C) 2018 - 2019 Intel Corporation
   8 */
   9
  10#include <linux/debugfs.h>
  11#include <linux/rtnetlink.h>
  12#include <linux/vmalloc.h>
  13#include "ieee80211_i.h"
  14#include "driver-ops.h"
  15#include "rate.h"
  16#include "debugfs.h"
  17
  18#define DEBUGFS_FORMAT_BUFFER_SIZE 100
  19
  20int mac80211_format_buffer(char __user *userbuf, size_t count,
  21                                  loff_t *ppos, char *fmt, ...)
  22{
  23        va_list args;
  24        char buf[DEBUGFS_FORMAT_BUFFER_SIZE];
  25        int res;
  26
  27        va_start(args, fmt);
  28        res = vscnprintf(buf, sizeof(buf), fmt, args);
  29        va_end(args);
  30
  31        return simple_read_from_buffer(userbuf, count, ppos, buf, res);
  32}
  33
  34#define DEBUGFS_READONLY_FILE_FN(name, fmt, value...)                   \
  35static ssize_t name## _read(struct file *file, char __user *userbuf,    \
  36                            size_t count, loff_t *ppos)                 \
  37{                                                                       \
  38        struct ieee80211_local *local = file->private_data;             \
  39                                                                        \
  40        return mac80211_format_buffer(userbuf, count, ppos,             \
  41                                      fmt "\n", ##value);               \
  42}
  43
  44#define DEBUGFS_READONLY_FILE_OPS(name)                 \
  45static const struct file_operations name## _ops = {                     \
  46        .read = name## _read,                                           \
  47        .open = simple_open,                                            \
  48        .llseek = generic_file_llseek,                                  \
  49};
  50
  51#define DEBUGFS_READONLY_FILE(name, fmt, value...)              \
  52        DEBUGFS_READONLY_FILE_FN(name, fmt, value)              \
  53        DEBUGFS_READONLY_FILE_OPS(name)
  54
  55#define DEBUGFS_ADD(name)                                               \
  56        debugfs_create_file(#name, 0400, phyd, local, &name## _ops);
  57
  58#define DEBUGFS_ADD_MODE(name, mode)                                    \
  59        debugfs_create_file(#name, mode, phyd, local, &name## _ops);
  60
  61
  62DEBUGFS_READONLY_FILE(hw_conf, "%x",
  63                      local->hw.conf.flags);
  64DEBUGFS_READONLY_FILE(user_power, "%d",
  65                      local->user_power_level);
  66DEBUGFS_READONLY_FILE(power, "%d",
  67                      local->hw.conf.power_level);
  68DEBUGFS_READONLY_FILE(total_ps_buffered, "%d",
  69                      local->total_ps_buffered);
  70DEBUGFS_READONLY_FILE(wep_iv, "%#08x",
  71                      local->wep_iv & 0xffffff);
  72DEBUGFS_READONLY_FILE(rate_ctrl_alg, "%s",
  73        local->rate_ctrl ? local->rate_ctrl->ops->name : "hw/driver");
  74
  75static ssize_t aqm_read(struct file *file,
  76                        char __user *user_buf,
  77                        size_t count,
  78                        loff_t *ppos)
  79{
  80        struct ieee80211_local *local = file->private_data;
  81        struct fq *fq = &local->fq;
  82        char buf[200];
  83        int len = 0;
  84
  85        spin_lock_bh(&local->fq.lock);
  86        rcu_read_lock();
  87
  88        len = scnprintf(buf, sizeof(buf),
  89                        "access name value\n"
  90                        "R fq_flows_cnt %u\n"
  91                        "R fq_backlog %u\n"
  92                        "R fq_overlimit %u\n"
  93                        "R fq_overmemory %u\n"
  94                        "R fq_collisions %u\n"
  95                        "R fq_memory_usage %u\n"
  96                        "RW fq_memory_limit %u\n"
  97                        "RW fq_limit %u\n"
  98                        "RW fq_quantum %u\n",
  99                        fq->flows_cnt,
 100                        fq->backlog,
 101                        fq->overmemory,
 102                        fq->overlimit,
 103                        fq->collisions,
 104                        fq->memory_usage,
 105                        fq->memory_limit,
 106                        fq->limit,
 107                        fq->quantum);
 108
 109        rcu_read_unlock();
 110        spin_unlock_bh(&local->fq.lock);
 111
 112        return simple_read_from_buffer(user_buf, count, ppos,
 113                                       buf, len);
 114}
 115
 116static ssize_t aqm_write(struct file *file,
 117                         const char __user *user_buf,
 118                         size_t count,
 119                         loff_t *ppos)
 120{
 121        struct ieee80211_local *local = file->private_data;
 122        char buf[100];
 123        size_t len;
 124
 125        if (count > sizeof(buf))
 126                return -EINVAL;
 127
 128        if (copy_from_user(buf, user_buf, count))
 129                return -EFAULT;
 130
 131        buf[sizeof(buf) - 1] = '\0';
 132        len = strlen(buf);
 133        if (len > 0 && buf[len-1] == '\n')
 134                buf[len-1] = 0;
 135
 136        if (sscanf(buf, "fq_limit %u", &local->fq.limit) == 1)
 137                return count;
 138        else if (sscanf(buf, "fq_memory_limit %u", &local->fq.memory_limit) == 1)
 139                return count;
 140        else if (sscanf(buf, "fq_quantum %u", &local->fq.quantum) == 1)
 141                return count;
 142
 143        return -EINVAL;
 144}
 145
 146static const struct file_operations aqm_ops = {
 147        .write = aqm_write,
 148        .read = aqm_read,
 149        .open = simple_open,
 150        .llseek = default_llseek,
 151};
 152
 153static ssize_t airtime_flags_read(struct file *file,
 154                                  char __user *user_buf,
 155                                  size_t count, loff_t *ppos)
 156{
 157        struct ieee80211_local *local = file->private_data;
 158        char buf[128] = {}, *pos, *end;
 159
 160        pos = buf;
 161        end = pos + sizeof(buf) - 1;
 162
 163        if (local->airtime_flags & AIRTIME_USE_TX)
 164                pos += scnprintf(pos, end - pos, "AIRTIME_TX\t(%lx)\n",
 165                                 AIRTIME_USE_TX);
 166        if (local->airtime_flags & AIRTIME_USE_RX)
 167                pos += scnprintf(pos, end - pos, "AIRTIME_RX\t(%lx)\n",
 168                                 AIRTIME_USE_RX);
 169
 170        return simple_read_from_buffer(user_buf, count, ppos, buf,
 171                                       strlen(buf));
 172}
 173
 174static ssize_t airtime_flags_write(struct file *file,
 175                                   const char __user *user_buf,
 176                                   size_t count, loff_t *ppos)
 177{
 178        struct ieee80211_local *local = file->private_data;
 179        char buf[16];
 180        size_t len;
 181
 182        if (count > sizeof(buf))
 183                return -EINVAL;
 184
 185        if (copy_from_user(buf, user_buf, count))
 186                return -EFAULT;
 187
 188        buf[sizeof(buf) - 1] = 0;
 189        len = strlen(buf);
 190        if (len > 0 && buf[len - 1] == '\n')
 191                buf[len - 1] = 0;
 192
 193        if (kstrtou16(buf, 0, &local->airtime_flags))
 194                return -EINVAL;
 195
 196        return count;
 197}
 198
 199static const struct file_operations airtime_flags_ops = {
 200        .write = airtime_flags_write,
 201        .read = airtime_flags_read,
 202        .open = simple_open,
 203        .llseek = default_llseek,
 204};
 205
 206static ssize_t aql_txq_limit_read(struct file *file,
 207                                  char __user *user_buf,
 208                                  size_t count,
 209                                  loff_t *ppos)
 210{
 211        struct ieee80211_local *local = file->private_data;
 212        char buf[400];
 213        int len = 0;
 214
 215        len = scnprintf(buf, sizeof(buf),
 216                        "AC     AQL limit low   AQL limit high\n"
 217                        "VO     %u              %u\n"
 218                        "VI     %u              %u\n"
 219                        "BE     %u              %u\n"
 220                        "BK     %u              %u\n",
 221                        local->aql_txq_limit_low[IEEE80211_AC_VO],
 222                        local->aql_txq_limit_high[IEEE80211_AC_VO],
 223                        local->aql_txq_limit_low[IEEE80211_AC_VI],
 224                        local->aql_txq_limit_high[IEEE80211_AC_VI],
 225                        local->aql_txq_limit_low[IEEE80211_AC_BE],
 226                        local->aql_txq_limit_high[IEEE80211_AC_BE],
 227                        local->aql_txq_limit_low[IEEE80211_AC_BK],
 228                        local->aql_txq_limit_high[IEEE80211_AC_BK]);
 229        return simple_read_from_buffer(user_buf, count, ppos,
 230                                       buf, len);
 231}
 232
 233static ssize_t aql_txq_limit_write(struct file *file,
 234                                   const char __user *user_buf,
 235                                   size_t count,
 236                                   loff_t *ppos)
 237{
 238        struct ieee80211_local *local = file->private_data;
 239        char buf[100];
 240        size_t len;
 241        u32 ac, q_limit_low, q_limit_high, q_limit_low_old, q_limit_high_old;
 242        struct sta_info *sta;
 243
 244        if (count > sizeof(buf))
 245                return -EINVAL;
 246
 247        if (copy_from_user(buf, user_buf, count))
 248                return -EFAULT;
 249
 250        buf[sizeof(buf) - 1] = 0;
 251        len = strlen(buf);
 252        if (len > 0 && buf[len - 1] == '\n')
 253                buf[len - 1] = 0;
 254
 255        if (sscanf(buf, "%u %u %u", &ac, &q_limit_low, &q_limit_high) != 3)
 256                return -EINVAL;
 257
 258        if (ac >= IEEE80211_NUM_ACS)
 259                return -EINVAL;
 260
 261        q_limit_low_old = local->aql_txq_limit_low[ac];
 262        q_limit_high_old = local->aql_txq_limit_high[ac];
 263
 264        local->aql_txq_limit_low[ac] = q_limit_low;
 265        local->aql_txq_limit_high[ac] = q_limit_high;
 266
 267        mutex_lock(&local->sta_mtx);
 268        list_for_each_entry(sta, &local->sta_list, list) {
 269                /* If a sta has customized queue limits, keep it */
 270                if (sta->airtime[ac].aql_limit_low == q_limit_low_old &&
 271                    sta->airtime[ac].aql_limit_high == q_limit_high_old) {
 272                        sta->airtime[ac].aql_limit_low = q_limit_low;
 273                        sta->airtime[ac].aql_limit_high = q_limit_high;
 274                }
 275        }
 276        mutex_unlock(&local->sta_mtx);
 277        return count;
 278}
 279
 280static const struct file_operations aql_txq_limit_ops = {
 281        .write = aql_txq_limit_write,
 282        .read = aql_txq_limit_read,
 283        .open = simple_open,
 284        .llseek = default_llseek,
 285};
 286
 287static ssize_t force_tx_status_read(struct file *file,
 288                                    char __user *user_buf,
 289                                    size_t count,
 290                                    loff_t *ppos)
 291{
 292        struct ieee80211_local *local = file->private_data;
 293        char buf[3];
 294        int len = 0;
 295
 296        len = scnprintf(buf, sizeof(buf), "%d\n", (int)local->force_tx_status);
 297
 298        return simple_read_from_buffer(user_buf, count, ppos,
 299                                       buf, len);
 300}
 301
 302static ssize_t force_tx_status_write(struct file *file,
 303                                     const char __user *user_buf,
 304                                     size_t count,
 305                                     loff_t *ppos)
 306{
 307        struct ieee80211_local *local = file->private_data;
 308        char buf[3];
 309        size_t len;
 310
 311        if (count > sizeof(buf))
 312                return -EINVAL;
 313
 314        if (copy_from_user(buf, user_buf, count))
 315                return -EFAULT;
 316
 317        buf[sizeof(buf) - 1] = '\0';
 318        len = strlen(buf);
 319        if (len > 0 && buf[len - 1] == '\n')
 320                buf[len - 1] = 0;
 321
 322        if (buf[0] == '0' && buf[1] == '\0')
 323                local->force_tx_status = 0;
 324        else if (buf[0] == '1' && buf[1] == '\0')
 325                local->force_tx_status = 1;
 326        else
 327                return -EINVAL;
 328
 329        return count;
 330}
 331
 332static const struct file_operations force_tx_status_ops = {
 333        .write = force_tx_status_write,
 334        .read = force_tx_status_read,
 335        .open = simple_open,
 336        .llseek = default_llseek,
 337};
 338
 339#ifdef CONFIG_PM
 340static ssize_t reset_write(struct file *file, const char __user *user_buf,
 341                           size_t count, loff_t *ppos)
 342{
 343        struct ieee80211_local *local = file->private_data;
 344
 345        rtnl_lock();
 346        __ieee80211_suspend(&local->hw, NULL);
 347        __ieee80211_resume(&local->hw);
 348        rtnl_unlock();
 349
 350        return count;
 351}
 352
 353static const struct file_operations reset_ops = {
 354        .write = reset_write,
 355        .open = simple_open,
 356        .llseek = noop_llseek,
 357};
 358#endif
 359
 360static const char *hw_flag_names[] = {
 361#define FLAG(F) [IEEE80211_HW_##F] = #F
 362        FLAG(HAS_RATE_CONTROL),
 363        FLAG(RX_INCLUDES_FCS),
 364        FLAG(HOST_BROADCAST_PS_BUFFERING),
 365        FLAG(SIGNAL_UNSPEC),
 366        FLAG(SIGNAL_DBM),
 367        FLAG(NEED_DTIM_BEFORE_ASSOC),
 368        FLAG(SPECTRUM_MGMT),
 369        FLAG(AMPDU_AGGREGATION),
 370        FLAG(SUPPORTS_PS),
 371        FLAG(PS_NULLFUNC_STACK),
 372        FLAG(SUPPORTS_DYNAMIC_PS),
 373        FLAG(MFP_CAPABLE),
 374        FLAG(WANT_MONITOR_VIF),
 375        FLAG(NO_AUTO_VIF),
 376        FLAG(SW_CRYPTO_CONTROL),
 377        FLAG(SUPPORT_FAST_XMIT),
 378        FLAG(REPORTS_TX_ACK_STATUS),
 379        FLAG(CONNECTION_MONITOR),
 380        FLAG(QUEUE_CONTROL),
 381        FLAG(SUPPORTS_PER_STA_GTK),
 382        FLAG(AP_LINK_PS),
 383        FLAG(TX_AMPDU_SETUP_IN_HW),
 384        FLAG(SUPPORTS_RC_TABLE),
 385        FLAG(P2P_DEV_ADDR_FOR_INTF),
 386        FLAG(TIMING_BEACON_ONLY),
 387        FLAG(SUPPORTS_HT_CCK_RATES),
 388        FLAG(CHANCTX_STA_CSA),
 389        FLAG(SUPPORTS_CLONED_SKBS),
 390        FLAG(SINGLE_SCAN_ON_ALL_BANDS),
 391        FLAG(TDLS_WIDER_BW),
 392        FLAG(SUPPORTS_AMSDU_IN_AMPDU),
 393        FLAG(BEACON_TX_STATUS),
 394        FLAG(NEEDS_UNIQUE_STA_ADDR),
 395        FLAG(SUPPORTS_REORDERING_BUFFER),
 396        FLAG(USES_RSS),
 397        FLAG(TX_AMSDU),
 398        FLAG(TX_FRAG_LIST),
 399        FLAG(REPORTS_LOW_ACK),
 400        FLAG(SUPPORTS_TX_FRAG),
 401        FLAG(SUPPORTS_TDLS_BUFFER_STA),
 402        FLAG(DEAUTH_NEED_MGD_TX_PREP),
 403        FLAG(DOESNT_SUPPORT_QOS_NDP),
 404        FLAG(BUFF_MMPDU_TXQ),
 405        FLAG(SUPPORTS_VHT_EXT_NSS_BW),
 406        FLAG(STA_MMPDU_TXQ),
 407        FLAG(TX_STATUS_NO_AMPDU_LEN),
 408        FLAG(SUPPORTS_MULTI_BSSID),
 409        FLAG(SUPPORTS_ONLY_HE_MULTI_BSSID),
 410        FLAG(AMPDU_KEYBORDER_SUPPORT),
 411#undef FLAG
 412};
 413
 414static ssize_t hwflags_read(struct file *file, char __user *user_buf,
 415                            size_t count, loff_t *ppos)
 416{
 417        struct ieee80211_local *local = file->private_data;
 418        size_t bufsz = 30 * NUM_IEEE80211_HW_FLAGS;
 419        char *buf = kzalloc(bufsz, GFP_KERNEL);
 420        char *pos = buf, *end = buf + bufsz - 1;
 421        ssize_t rv;
 422        int i;
 423
 424        if (!buf)
 425                return -ENOMEM;
 426
 427        /* fail compilation if somebody adds or removes
 428         * a flag without updating the name array above
 429         */
 430        BUILD_BUG_ON(ARRAY_SIZE(hw_flag_names) != NUM_IEEE80211_HW_FLAGS);
 431
 432        for (i = 0; i < NUM_IEEE80211_HW_FLAGS; i++) {
 433                if (test_bit(i, local->hw.flags))
 434                        pos += scnprintf(pos, end - pos, "%s\n",
 435                                         hw_flag_names[i]);
 436        }
 437
 438        rv = simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
 439        kfree(buf);
 440        return rv;
 441}
 442
 443static ssize_t misc_read(struct file *file, char __user *user_buf,
 444                         size_t count, loff_t *ppos)
 445{
 446        struct ieee80211_local *local = file->private_data;
 447        /* Max len of each line is 16 characters, plus 9 for 'pending:\n' */
 448        size_t bufsz = IEEE80211_MAX_QUEUES * 16 + 9;
 449        char *buf;
 450        char *pos, *end;
 451        ssize_t rv;
 452        int i;
 453        int ln;
 454
 455        buf = kzalloc(bufsz, GFP_KERNEL);
 456        if (!buf)
 457                return -ENOMEM;
 458
 459        pos = buf;
 460        end = buf + bufsz - 1;
 461
 462        pos += scnprintf(pos, end - pos, "pending:\n");
 463
 464        for (i = 0; i < IEEE80211_MAX_QUEUES; i++) {
 465                ln = skb_queue_len(&local->pending[i]);
 466                pos += scnprintf(pos, end - pos, "[%i] %d\n",
 467                                 i, ln);
 468        }
 469
 470        rv = simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
 471        kfree(buf);
 472        return rv;
 473}
 474
 475static ssize_t queues_read(struct file *file, char __user *user_buf,
 476                           size_t count, loff_t *ppos)
 477{
 478        struct ieee80211_local *local = file->private_data;
 479        unsigned long flags;
 480        char buf[IEEE80211_MAX_QUEUES * 20];
 481        int q, res = 0;
 482
 483        spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
 484        for (q = 0; q < local->hw.queues; q++)
 485                res += sprintf(buf + res, "%02d: %#.8lx/%d\n", q,
 486                                local->queue_stop_reasons[q],
 487                                skb_queue_len(&local->pending[q]));
 488        spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
 489
 490        return simple_read_from_buffer(user_buf, count, ppos, buf, res);
 491}
 492
 493DEBUGFS_READONLY_FILE_OPS(hwflags);
 494DEBUGFS_READONLY_FILE_OPS(queues);
 495DEBUGFS_READONLY_FILE_OPS(misc);
 496
 497/* statistics stuff */
 498
 499static ssize_t format_devstat_counter(struct ieee80211_local *local,
 500        char __user *userbuf,
 501        size_t count, loff_t *ppos,
 502        int (*printvalue)(struct ieee80211_low_level_stats *stats, char *buf,
 503                          int buflen))
 504{
 505        struct ieee80211_low_level_stats stats;
 506        char buf[20];
 507        int res;
 508
 509        rtnl_lock();
 510        res = drv_get_stats(local, &stats);
 511        rtnl_unlock();
 512        if (res)
 513                return res;
 514        res = printvalue(&stats, buf, sizeof(buf));
 515        return simple_read_from_buffer(userbuf, count, ppos, buf, res);
 516}
 517
 518#define DEBUGFS_DEVSTATS_FILE(name)                                     \
 519static int print_devstats_##name(struct ieee80211_low_level_stats *stats,\
 520                                 char *buf, int buflen)                 \
 521{                                                                       \
 522        return scnprintf(buf, buflen, "%u\n", stats->name);             \
 523}                                                                       \
 524static ssize_t stats_ ##name## _read(struct file *file,                 \
 525                                     char __user *userbuf,              \
 526                                     size_t count, loff_t *ppos)        \
 527{                                                                       \
 528        return format_devstat_counter(file->private_data,               \
 529                                      userbuf,                          \
 530                                      count,                            \
 531                                      ppos,                             \
 532                                      print_devstats_##name);           \
 533}                                                                       \
 534                                                                        \
 535static const struct file_operations stats_ ##name## _ops = {            \
 536        .read = stats_ ##name## _read,                                  \
 537        .open = simple_open,                                            \
 538        .llseek = generic_file_llseek,                                  \
 539};
 540
 541#define DEBUGFS_STATS_ADD(name)                                 \
 542        debugfs_create_u32(#name, 0400, statsd, &local->name);
 543#define DEBUGFS_DEVSTATS_ADD(name)                                      \
 544        debugfs_create_file(#name, 0400, statsd, local, &stats_ ##name## _ops);
 545
 546DEBUGFS_DEVSTATS_FILE(dot11ACKFailureCount);
 547DEBUGFS_DEVSTATS_FILE(dot11RTSFailureCount);
 548DEBUGFS_DEVSTATS_FILE(dot11FCSErrorCount);
 549DEBUGFS_DEVSTATS_FILE(dot11RTSSuccessCount);
 550
 551void debugfs_hw_add(struct ieee80211_local *local)
 552{
 553        struct dentry *phyd = local->hw.wiphy->debugfsdir;
 554        struct dentry *statsd;
 555
 556        if (!phyd)
 557                return;
 558
 559        local->debugfs.keys = debugfs_create_dir("keys", phyd);
 560
 561        DEBUGFS_ADD(total_ps_buffered);
 562        DEBUGFS_ADD(wep_iv);
 563        DEBUGFS_ADD(rate_ctrl_alg);
 564        DEBUGFS_ADD(queues);
 565        DEBUGFS_ADD(misc);
 566#ifdef CONFIG_PM
 567        DEBUGFS_ADD_MODE(reset, 0200);
 568#endif
 569        DEBUGFS_ADD(hwflags);
 570        DEBUGFS_ADD(user_power);
 571        DEBUGFS_ADD(power);
 572        DEBUGFS_ADD(hw_conf);
 573        DEBUGFS_ADD_MODE(force_tx_status, 0600);
 574
 575        if (local->ops->wake_tx_queue)
 576                DEBUGFS_ADD_MODE(aqm, 0600);
 577
 578        DEBUGFS_ADD_MODE(airtime_flags, 0600);
 579
 580        DEBUGFS_ADD(aql_txq_limit);
 581        debugfs_create_u32("aql_threshold", 0600,
 582                           phyd, &local->aql_threshold);
 583
 584        statsd = debugfs_create_dir("statistics", phyd);
 585
 586        /* if the dir failed, don't put all the other things into the root! */
 587        if (!statsd)
 588                return;
 589
 590#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
 591        DEBUGFS_STATS_ADD(dot11TransmittedFragmentCount);
 592        DEBUGFS_STATS_ADD(dot11MulticastTransmittedFrameCount);
 593        DEBUGFS_STATS_ADD(dot11FailedCount);
 594        DEBUGFS_STATS_ADD(dot11RetryCount);
 595        DEBUGFS_STATS_ADD(dot11MultipleRetryCount);
 596        DEBUGFS_STATS_ADD(dot11FrameDuplicateCount);
 597        DEBUGFS_STATS_ADD(dot11ReceivedFragmentCount);
 598        DEBUGFS_STATS_ADD(dot11MulticastReceivedFrameCount);
 599        DEBUGFS_STATS_ADD(dot11TransmittedFrameCount);
 600        DEBUGFS_STATS_ADD(tx_handlers_drop);
 601        DEBUGFS_STATS_ADD(tx_handlers_queued);
 602        DEBUGFS_STATS_ADD(tx_handlers_drop_wep);
 603        DEBUGFS_STATS_ADD(tx_handlers_drop_not_assoc);
 604        DEBUGFS_STATS_ADD(tx_handlers_drop_unauth_port);
 605        DEBUGFS_STATS_ADD(rx_handlers_drop);
 606        DEBUGFS_STATS_ADD(rx_handlers_queued);
 607        DEBUGFS_STATS_ADD(rx_handlers_drop_nullfunc);
 608        DEBUGFS_STATS_ADD(rx_handlers_drop_defrag);
 609        DEBUGFS_STATS_ADD(tx_expand_skb_head);
 610        DEBUGFS_STATS_ADD(tx_expand_skb_head_cloned);
 611        DEBUGFS_STATS_ADD(rx_expand_skb_head_defrag);
 612        DEBUGFS_STATS_ADD(rx_handlers_fragments);
 613        DEBUGFS_STATS_ADD(tx_status_drop);
 614#endif
 615        DEBUGFS_DEVSTATS_ADD(dot11ACKFailureCount);
 616        DEBUGFS_DEVSTATS_ADD(dot11RTSFailureCount);
 617        DEBUGFS_DEVSTATS_ADD(dot11FCSErrorCount);
 618        DEBUGFS_DEVSTATS_ADD(dot11RTSSuccessCount);
 619}
 620