root/net/mac80211/debugfs_netdev.c

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

DEFINITIONS

This source file includes following definitions.
  1. ieee80211_if_read
  2. ieee80211_if_write
  3. ieee80211_if_fmt_rc_rateidx_vht_mcs_mask_2ghz
  4. ieee80211_if_fmt_rc_rateidx_vht_mcs_mask_5ghz
  5. ieee80211_if_fmt_hw_queues
  6. ieee80211_set_smps
  7. ieee80211_if_fmt_smps
  8. ieee80211_if_parse_smps
  9. ieee80211_if_parse_tkip_mic_test
  10. ieee80211_if_parse_beacon_loss
  11. ieee80211_if_fmt_uapsd_queues
  12. ieee80211_if_parse_uapsd_queues
  13. ieee80211_if_fmt_uapsd_max_sp_len
  14. ieee80211_if_parse_uapsd_max_sp_len
  15. ieee80211_if_fmt_tdls_wider_bw
  16. ieee80211_if_parse_tdls_wider_bw
  17. ieee80211_if_fmt_num_buffered_multicast
  18. ieee80211_if_fmt_aqm
  19. ieee80211_if_fmt_tsf
  20. ieee80211_if_parse_tsf
  21. add_common_files
  22. add_sta_files
  23. add_ap_files
  24. add_vlan_files
  25. add_ibss_files
  26. add_wds_files
  27. add_mesh_files
  28. add_mesh_stats
  29. add_mesh_config
  30. add_files
  31. ieee80211_debugfs_add_netdev
  32. ieee80211_debugfs_remove_netdev
  33. ieee80211_debugfs_rename_netdev

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (c) 2006   Jiri Benc <jbenc@suse.cz>
   4  * Copyright 2007       Johannes Berg <johannes@sipsolutions.net>
   5  */
   6 
   7 #include <linux/kernel.h>
   8 #include <linux/device.h>
   9 #include <linux/if.h>
  10 #include <linux/if_ether.h>
  11 #include <linux/interrupt.h>
  12 #include <linux/netdevice.h>
  13 #include <linux/rtnetlink.h>
  14 #include <linux/slab.h>
  15 #include <linux/notifier.h>
  16 #include <net/mac80211.h>
  17 #include <net/cfg80211.h>
  18 #include "ieee80211_i.h"
  19 #include "rate.h"
  20 #include "debugfs.h"
  21 #include "debugfs_netdev.h"
  22 #include "driver-ops.h"
  23 
  24 static ssize_t ieee80211_if_read(
  25         struct ieee80211_sub_if_data *sdata,
  26         char __user *userbuf,
  27         size_t count, loff_t *ppos,
  28         ssize_t (*format)(const struct ieee80211_sub_if_data *, char *, int))
  29 {
  30         char buf[200];
  31         ssize_t ret = -EINVAL;
  32 
  33         read_lock(&dev_base_lock);
  34         ret = (*format)(sdata, buf, sizeof(buf));
  35         read_unlock(&dev_base_lock);
  36 
  37         if (ret >= 0)
  38                 ret = simple_read_from_buffer(userbuf, count, ppos, buf, ret);
  39 
  40         return ret;
  41 }
  42 
  43 static ssize_t ieee80211_if_write(
  44         struct ieee80211_sub_if_data *sdata,
  45         const char __user *userbuf,
  46         size_t count, loff_t *ppos,
  47         ssize_t (*write)(struct ieee80211_sub_if_data *, const char *, int))
  48 {
  49         char buf[64];
  50         ssize_t ret;
  51 
  52         if (count >= sizeof(buf))
  53                 return -E2BIG;
  54 
  55         if (copy_from_user(buf, userbuf, count))
  56                 return -EFAULT;
  57         buf[count] = '\0';
  58 
  59         ret = -ENODEV;
  60         rtnl_lock();
  61         ret = (*write)(sdata, buf, count);
  62         rtnl_unlock();
  63 
  64         return ret;
  65 }
  66 
  67 #define IEEE80211_IF_FMT(name, field, format_string)                    \
  68 static ssize_t ieee80211_if_fmt_##name(                                 \
  69         const struct ieee80211_sub_if_data *sdata, char *buf,           \
  70         int buflen)                                                     \
  71 {                                                                       \
  72         return scnprintf(buf, buflen, format_string, sdata->field);     \
  73 }
  74 #define IEEE80211_IF_FMT_DEC(name, field)                               \
  75                 IEEE80211_IF_FMT(name, field, "%d\n")
  76 #define IEEE80211_IF_FMT_HEX(name, field)                               \
  77                 IEEE80211_IF_FMT(name, field, "%#x\n")
  78 #define IEEE80211_IF_FMT_LHEX(name, field)                              \
  79                 IEEE80211_IF_FMT(name, field, "%#lx\n")
  80 #define IEEE80211_IF_FMT_SIZE(name, field)                              \
  81                 IEEE80211_IF_FMT(name, field, "%zd\n")
  82 
  83 #define IEEE80211_IF_FMT_HEXARRAY(name, field)                          \
  84 static ssize_t ieee80211_if_fmt_##name(                                 \
  85         const struct ieee80211_sub_if_data *sdata,                      \
  86         char *buf, int buflen)                                          \
  87 {                                                                       \
  88         char *p = buf;                                                  \
  89         int i;                                                          \
  90         for (i = 0; i < sizeof(sdata->field); i++) {                    \
  91                 p += scnprintf(p, buflen + buf - p, "%.2x ",            \
  92                                  sdata->field[i]);                      \
  93         }                                                               \
  94         p += scnprintf(p, buflen + buf - p, "\n");                      \
  95         return p - buf;                                                 \
  96 }
  97 
  98 #define IEEE80211_IF_FMT_ATOMIC(name, field)                            \
  99 static ssize_t ieee80211_if_fmt_##name(                                 \
 100         const struct ieee80211_sub_if_data *sdata,                      \
 101         char *buf, int buflen)                                          \
 102 {                                                                       \
 103         return scnprintf(buf, buflen, "%d\n", atomic_read(&sdata->field));\
 104 }
 105 
 106 #define IEEE80211_IF_FMT_MAC(name, field)                               \
 107 static ssize_t ieee80211_if_fmt_##name(                                 \
 108         const struct ieee80211_sub_if_data *sdata, char *buf,           \
 109         int buflen)                                                     \
 110 {                                                                       \
 111         return scnprintf(buf, buflen, "%pM\n", sdata->field);           \
 112 }
 113 
 114 #define IEEE80211_IF_FMT_JIFFIES_TO_MS(name, field)                     \
 115 static ssize_t ieee80211_if_fmt_##name(                                 \
 116         const struct ieee80211_sub_if_data *sdata,                      \
 117         char *buf, int buflen)                                          \
 118 {                                                                       \
 119         return scnprintf(buf, buflen, "%d\n",                           \
 120                          jiffies_to_msecs(sdata->field));               \
 121 }
 122 
 123 #define _IEEE80211_IF_FILE_OPS(name, _read, _write)                     \
 124 static const struct file_operations name##_ops = {                      \
 125         .read = (_read),                                                \
 126         .write = (_write),                                              \
 127         .open = simple_open,                                            \
 128         .llseek = generic_file_llseek,                                  \
 129 }
 130 
 131 #define _IEEE80211_IF_FILE_R_FN(name)                                   \
 132 static ssize_t ieee80211_if_read_##name(struct file *file,              \
 133                                         char __user *userbuf,           \
 134                                         size_t count, loff_t *ppos)     \
 135 {                                                                       \
 136         return ieee80211_if_read(file->private_data,                    \
 137                                  userbuf, count, ppos,                  \
 138                                  ieee80211_if_fmt_##name);              \
 139 }
 140 
 141 #define _IEEE80211_IF_FILE_W_FN(name)                                   \
 142 static ssize_t ieee80211_if_write_##name(struct file *file,             \
 143                                          const char __user *userbuf,    \
 144                                          size_t count, loff_t *ppos)    \
 145 {                                                                       \
 146         return ieee80211_if_write(file->private_data, userbuf, count,   \
 147                                   ppos, ieee80211_if_parse_##name);     \
 148 }
 149 
 150 #define IEEE80211_IF_FILE_R(name)                                       \
 151         _IEEE80211_IF_FILE_R_FN(name)                                   \
 152         _IEEE80211_IF_FILE_OPS(name, ieee80211_if_read_##name, NULL)
 153 
 154 #define IEEE80211_IF_FILE_W(name)                                       \
 155         _IEEE80211_IF_FILE_W_FN(name)                                   \
 156         _IEEE80211_IF_FILE_OPS(name, NULL, ieee80211_if_write_##name)
 157 
 158 #define IEEE80211_IF_FILE_RW(name)                                      \
 159         _IEEE80211_IF_FILE_R_FN(name)                                   \
 160         _IEEE80211_IF_FILE_W_FN(name)                                   \
 161         _IEEE80211_IF_FILE_OPS(name, ieee80211_if_read_##name,          \
 162                                ieee80211_if_write_##name)
 163 
 164 #define IEEE80211_IF_FILE(name, field, format)                          \
 165         IEEE80211_IF_FMT_##format(name, field)                          \
 166         IEEE80211_IF_FILE_R(name)
 167 
 168 /* common attributes */
 169 IEEE80211_IF_FILE(rc_rateidx_mask_2ghz, rc_rateidx_mask[NL80211_BAND_2GHZ],
 170                   HEX);
 171 IEEE80211_IF_FILE(rc_rateidx_mask_5ghz, rc_rateidx_mask[NL80211_BAND_5GHZ],
 172                   HEX);
 173 IEEE80211_IF_FILE(rc_rateidx_mcs_mask_2ghz,
 174                   rc_rateidx_mcs_mask[NL80211_BAND_2GHZ], HEXARRAY);
 175 IEEE80211_IF_FILE(rc_rateidx_mcs_mask_5ghz,
 176                   rc_rateidx_mcs_mask[NL80211_BAND_5GHZ], HEXARRAY);
 177 
 178 static ssize_t ieee80211_if_fmt_rc_rateidx_vht_mcs_mask_2ghz(
 179                                 const struct ieee80211_sub_if_data *sdata,
 180                                 char *buf, int buflen)
 181 {
 182         int i, len = 0;
 183         const u16 *mask = sdata->rc_rateidx_vht_mcs_mask[NL80211_BAND_2GHZ];
 184 
 185         for (i = 0; i < NL80211_VHT_NSS_MAX; i++)
 186                 len += scnprintf(buf + len, buflen - len, "%04x ", mask[i]);
 187         len += scnprintf(buf + len, buflen - len, "\n");
 188 
 189         return len;
 190 }
 191 
 192 IEEE80211_IF_FILE_R(rc_rateidx_vht_mcs_mask_2ghz);
 193 
 194 static ssize_t ieee80211_if_fmt_rc_rateidx_vht_mcs_mask_5ghz(
 195                                 const struct ieee80211_sub_if_data *sdata,
 196                                 char *buf, int buflen)
 197 {
 198         int i, len = 0;
 199         const u16 *mask = sdata->rc_rateidx_vht_mcs_mask[NL80211_BAND_5GHZ];
 200 
 201         for (i = 0; i < NL80211_VHT_NSS_MAX; i++)
 202                 len += scnprintf(buf + len, buflen - len, "%04x ", mask[i]);
 203         len += scnprintf(buf + len, buflen - len, "\n");
 204 
 205         return len;
 206 }
 207 
 208 IEEE80211_IF_FILE_R(rc_rateidx_vht_mcs_mask_5ghz);
 209 
 210 IEEE80211_IF_FILE(flags, flags, HEX);
 211 IEEE80211_IF_FILE(state, state, LHEX);
 212 IEEE80211_IF_FILE(txpower, vif.bss_conf.txpower, DEC);
 213 IEEE80211_IF_FILE(ap_power_level, ap_power_level, DEC);
 214 IEEE80211_IF_FILE(user_power_level, user_power_level, DEC);
 215 
 216 static ssize_t
 217 ieee80211_if_fmt_hw_queues(const struct ieee80211_sub_if_data *sdata,
 218                            char *buf, int buflen)
 219 {
 220         int len;
 221 
 222         len = scnprintf(buf, buflen, "AC queues: VO:%d VI:%d BE:%d BK:%d\n",
 223                         sdata->vif.hw_queue[IEEE80211_AC_VO],
 224                         sdata->vif.hw_queue[IEEE80211_AC_VI],
 225                         sdata->vif.hw_queue[IEEE80211_AC_BE],
 226                         sdata->vif.hw_queue[IEEE80211_AC_BK]);
 227 
 228         if (sdata->vif.type == NL80211_IFTYPE_AP)
 229                 len += scnprintf(buf + len, buflen - len, "cab queue: %d\n",
 230                                  sdata->vif.cab_queue);
 231 
 232         return len;
 233 }
 234 IEEE80211_IF_FILE_R(hw_queues);
 235 
 236 /* STA attributes */
 237 IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC);
 238 IEEE80211_IF_FILE(aid, u.mgd.aid, DEC);
 239 IEEE80211_IF_FILE(beacon_timeout, u.mgd.beacon_timeout, JIFFIES_TO_MS);
 240 
 241 static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata,
 242                               enum ieee80211_smps_mode smps_mode)
 243 {
 244         struct ieee80211_local *local = sdata->local;
 245         int err;
 246 
 247         if (!(local->hw.wiphy->features & NL80211_FEATURE_STATIC_SMPS) &&
 248             smps_mode == IEEE80211_SMPS_STATIC)
 249                 return -EINVAL;
 250 
 251         /* auto should be dynamic if in PS mode */
 252         if (!(local->hw.wiphy->features & NL80211_FEATURE_DYNAMIC_SMPS) &&
 253             (smps_mode == IEEE80211_SMPS_DYNAMIC ||
 254              smps_mode == IEEE80211_SMPS_AUTOMATIC))
 255                 return -EINVAL;
 256 
 257         if (sdata->vif.type != NL80211_IFTYPE_STATION &&
 258             sdata->vif.type != NL80211_IFTYPE_AP)
 259                 return -EOPNOTSUPP;
 260 
 261         sdata_lock(sdata);
 262         if (sdata->vif.type == NL80211_IFTYPE_STATION)
 263                 err = __ieee80211_request_smps_mgd(sdata, smps_mode);
 264         else
 265                 err = __ieee80211_request_smps_ap(sdata, smps_mode);
 266         sdata_unlock(sdata);
 267 
 268         return err;
 269 }
 270 
 271 static const char *smps_modes[IEEE80211_SMPS_NUM_MODES] = {
 272         [IEEE80211_SMPS_AUTOMATIC] = "auto",
 273         [IEEE80211_SMPS_OFF] = "off",
 274         [IEEE80211_SMPS_STATIC] = "static",
 275         [IEEE80211_SMPS_DYNAMIC] = "dynamic",
 276 };
 277 
 278 static ssize_t ieee80211_if_fmt_smps(const struct ieee80211_sub_if_data *sdata,
 279                                      char *buf, int buflen)
 280 {
 281         if (sdata->vif.type == NL80211_IFTYPE_STATION)
 282                 return snprintf(buf, buflen, "request: %s\nused: %s\n",
 283                                 smps_modes[sdata->u.mgd.req_smps],
 284                                 smps_modes[sdata->smps_mode]);
 285         if (sdata->vif.type == NL80211_IFTYPE_AP)
 286                 return snprintf(buf, buflen, "request: %s\nused: %s\n",
 287                                 smps_modes[sdata->u.ap.req_smps],
 288                                 smps_modes[sdata->smps_mode]);
 289         return -EINVAL;
 290 }
 291 
 292 static ssize_t ieee80211_if_parse_smps(struct ieee80211_sub_if_data *sdata,
 293                                        const char *buf, int buflen)
 294 {
 295         enum ieee80211_smps_mode mode;
 296 
 297         for (mode = 0; mode < IEEE80211_SMPS_NUM_MODES; mode++) {
 298                 if (strncmp(buf, smps_modes[mode], buflen) == 0) {
 299                         int err = ieee80211_set_smps(sdata, mode);
 300                         if (!err)
 301                                 return buflen;
 302                         return err;
 303                 }
 304         }
 305 
 306         return -EINVAL;
 307 }
 308 IEEE80211_IF_FILE_RW(smps);
 309 
 310 static ssize_t ieee80211_if_parse_tkip_mic_test(
 311         struct ieee80211_sub_if_data *sdata, const char *buf, int buflen)
 312 {
 313         struct ieee80211_local *local = sdata->local;
 314         u8 addr[ETH_ALEN];
 315         struct sk_buff *skb;
 316         struct ieee80211_hdr *hdr;
 317         __le16 fc;
 318 
 319         if (!mac_pton(buf, addr))
 320                 return -EINVAL;
 321 
 322         if (!ieee80211_sdata_running(sdata))
 323                 return -ENOTCONN;
 324 
 325         skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24 + 100);
 326         if (!skb)
 327                 return -ENOMEM;
 328         skb_reserve(skb, local->hw.extra_tx_headroom);
 329 
 330         hdr = skb_put_zero(skb, 24);
 331         fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA);
 332 
 333         switch (sdata->vif.type) {
 334         case NL80211_IFTYPE_AP:
 335                 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
 336                 /* DA BSSID SA */
 337                 memcpy(hdr->addr1, addr, ETH_ALEN);
 338                 memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN);
 339                 memcpy(hdr->addr3, sdata->vif.addr, ETH_ALEN);
 340                 break;
 341         case NL80211_IFTYPE_STATION:
 342                 fc |= cpu_to_le16(IEEE80211_FCTL_TODS);
 343                 /* BSSID SA DA */
 344                 sdata_lock(sdata);
 345                 if (!sdata->u.mgd.associated) {
 346                         sdata_unlock(sdata);
 347                         dev_kfree_skb(skb);
 348                         return -ENOTCONN;
 349                 }
 350                 memcpy(hdr->addr1, sdata->u.mgd.associated->bssid, ETH_ALEN);
 351                 memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN);
 352                 memcpy(hdr->addr3, addr, ETH_ALEN);
 353                 sdata_unlock(sdata);
 354                 break;
 355         default:
 356                 dev_kfree_skb(skb);
 357                 return -EOPNOTSUPP;
 358         }
 359         hdr->frame_control = fc;
 360 
 361         /*
 362          * Add some length to the test frame to make it look bit more valid.
 363          * The exact contents does not matter since the recipient is required
 364          * to drop this because of the Michael MIC failure.
 365          */
 366         skb_put_zero(skb, 50);
 367 
 368         IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_TKIP_MIC_FAILURE;
 369 
 370         ieee80211_tx_skb(sdata, skb);
 371 
 372         return buflen;
 373 }
 374 IEEE80211_IF_FILE_W(tkip_mic_test);
 375 
 376 static ssize_t ieee80211_if_parse_beacon_loss(
 377         struct ieee80211_sub_if_data *sdata, const char *buf, int buflen)
 378 {
 379         if (!ieee80211_sdata_running(sdata) || !sdata->vif.bss_conf.assoc)
 380                 return -ENOTCONN;
 381 
 382         ieee80211_beacon_loss(&sdata->vif);
 383 
 384         return buflen;
 385 }
 386 IEEE80211_IF_FILE_W(beacon_loss);
 387 
 388 static ssize_t ieee80211_if_fmt_uapsd_queues(
 389         const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
 390 {
 391         const struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 392 
 393         return snprintf(buf, buflen, "0x%x\n", ifmgd->uapsd_queues);
 394 }
 395 
 396 static ssize_t ieee80211_if_parse_uapsd_queues(
 397         struct ieee80211_sub_if_data *sdata, const char *buf, int buflen)
 398 {
 399         struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 400         u8 val;
 401         int ret;
 402 
 403         ret = kstrtou8(buf, 0, &val);
 404         if (ret)
 405                 return ret;
 406 
 407         if (val & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
 408                 return -ERANGE;
 409 
 410         ifmgd->uapsd_queues = val;
 411 
 412         return buflen;
 413 }
 414 IEEE80211_IF_FILE_RW(uapsd_queues);
 415 
 416 static ssize_t ieee80211_if_fmt_uapsd_max_sp_len(
 417         const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
 418 {
 419         const struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 420 
 421         return snprintf(buf, buflen, "0x%x\n", ifmgd->uapsd_max_sp_len);
 422 }
 423 
 424 static ssize_t ieee80211_if_parse_uapsd_max_sp_len(
 425         struct ieee80211_sub_if_data *sdata, const char *buf, int buflen)
 426 {
 427         struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 428         unsigned long val;
 429         int ret;
 430 
 431         ret = kstrtoul(buf, 0, &val);
 432         if (ret)
 433                 return -EINVAL;
 434 
 435         if (val & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK)
 436                 return -ERANGE;
 437 
 438         ifmgd->uapsd_max_sp_len = val;
 439 
 440         return buflen;
 441 }
 442 IEEE80211_IF_FILE_RW(uapsd_max_sp_len);
 443 
 444 static ssize_t ieee80211_if_fmt_tdls_wider_bw(
 445         const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
 446 {
 447         const struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 448         bool tdls_wider_bw;
 449 
 450         tdls_wider_bw = ieee80211_hw_check(&sdata->local->hw, TDLS_WIDER_BW) &&
 451                         !ifmgd->tdls_wider_bw_prohibited;
 452 
 453         return snprintf(buf, buflen, "%d\n", tdls_wider_bw);
 454 }
 455 
 456 static ssize_t ieee80211_if_parse_tdls_wider_bw(
 457         struct ieee80211_sub_if_data *sdata, const char *buf, int buflen)
 458 {
 459         struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 460         u8 val;
 461         int ret;
 462 
 463         ret = kstrtou8(buf, 0, &val);
 464         if (ret)
 465                 return ret;
 466 
 467         ifmgd->tdls_wider_bw_prohibited = !val;
 468         return buflen;
 469 }
 470 IEEE80211_IF_FILE_RW(tdls_wider_bw);
 471 
 472 /* AP attributes */
 473 IEEE80211_IF_FILE(num_mcast_sta, u.ap.num_mcast_sta, ATOMIC);
 474 IEEE80211_IF_FILE(num_sta_ps, u.ap.ps.num_sta_ps, ATOMIC);
 475 IEEE80211_IF_FILE(dtim_count, u.ap.ps.dtim_count, DEC);
 476 IEEE80211_IF_FILE(num_mcast_sta_vlan, u.vlan.num_mcast_sta, ATOMIC);
 477 
 478 static ssize_t ieee80211_if_fmt_num_buffered_multicast(
 479         const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
 480 {
 481         return scnprintf(buf, buflen, "%u\n",
 482                          skb_queue_len(&sdata->u.ap.ps.bc_buf));
 483 }
 484 IEEE80211_IF_FILE_R(num_buffered_multicast);
 485 
 486 static ssize_t ieee80211_if_fmt_aqm(
 487         const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
 488 {
 489         struct ieee80211_local *local = sdata->local;
 490         struct txq_info *txqi;
 491         int len;
 492 
 493         if (!sdata->vif.txq)
 494                 return 0;
 495 
 496         txqi = to_txq_info(sdata->vif.txq);
 497 
 498         spin_lock_bh(&local->fq.lock);
 499         rcu_read_lock();
 500 
 501         len = scnprintf(buf,
 502                         buflen,
 503                         "ac backlog-bytes backlog-packets new-flows drops marks overlimit collisions tx-bytes tx-packets\n"
 504                         "%u %u %u %u %u %u %u %u %u %u\n",
 505                         txqi->txq.ac,
 506                         txqi->tin.backlog_bytes,
 507                         txqi->tin.backlog_packets,
 508                         txqi->tin.flows,
 509                         txqi->cstats.drop_count,
 510                         txqi->cstats.ecn_mark,
 511                         txqi->tin.overlimit,
 512                         txqi->tin.collisions,
 513                         txqi->tin.tx_bytes,
 514                         txqi->tin.tx_packets);
 515 
 516         rcu_read_unlock();
 517         spin_unlock_bh(&local->fq.lock);
 518 
 519         return len;
 520 }
 521 IEEE80211_IF_FILE_R(aqm);
 522 
 523 IEEE80211_IF_FILE(multicast_to_unicast, u.ap.multicast_to_unicast, HEX);
 524 
 525 /* IBSS attributes */
 526 static ssize_t ieee80211_if_fmt_tsf(
 527         const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
 528 {
 529         struct ieee80211_local *local = sdata->local;
 530         u64 tsf;
 531 
 532         tsf = drv_get_tsf(local, (struct ieee80211_sub_if_data *)sdata);
 533 
 534         return scnprintf(buf, buflen, "0x%016llx\n", (unsigned long long) tsf);
 535 }
 536 
 537 static ssize_t ieee80211_if_parse_tsf(
 538         struct ieee80211_sub_if_data *sdata, const char *buf, int buflen)
 539 {
 540         struct ieee80211_local *local = sdata->local;
 541         unsigned long long tsf;
 542         int ret;
 543         int tsf_is_delta = 0;
 544 
 545         if (strncmp(buf, "reset", 5) == 0) {
 546                 if (local->ops->reset_tsf) {
 547                         drv_reset_tsf(local, sdata);
 548                         wiphy_info(local->hw.wiphy, "debugfs reset TSF\n");
 549                 }
 550         } else {
 551                 if (buflen > 10 && buf[1] == '=') {
 552                         if (buf[0] == '+')
 553                                 tsf_is_delta = 1;
 554                         else if (buf[0] == '-')
 555                                 tsf_is_delta = -1;
 556                         else
 557                                 return -EINVAL;
 558                         buf += 2;
 559                 }
 560                 ret = kstrtoull(buf, 10, &tsf);
 561                 if (ret < 0)
 562                         return ret;
 563                 if (tsf_is_delta && local->ops->offset_tsf) {
 564                         drv_offset_tsf(local, sdata, tsf_is_delta * tsf);
 565                         wiphy_info(local->hw.wiphy,
 566                                    "debugfs offset TSF by %018lld\n",
 567                                    tsf_is_delta * tsf);
 568                 } else if (local->ops->set_tsf) {
 569                         if (tsf_is_delta)
 570                                 tsf = drv_get_tsf(local, sdata) +
 571                                       tsf_is_delta * tsf;
 572                         drv_set_tsf(local, sdata, tsf);
 573                         wiphy_info(local->hw.wiphy,
 574                                    "debugfs set TSF to %#018llx\n", tsf);
 575                 }
 576         }
 577 
 578         ieee80211_recalc_dtim(local, sdata);
 579         return buflen;
 580 }
 581 IEEE80211_IF_FILE_RW(tsf);
 582 
 583 
 584 /* WDS attributes */
 585 IEEE80211_IF_FILE(peer, u.wds.remote_addr, MAC);
 586 
 587 #ifdef CONFIG_MAC80211_MESH
 588 IEEE80211_IF_FILE(estab_plinks, u.mesh.estab_plinks, ATOMIC);
 589 
 590 /* Mesh stats attributes */
 591 IEEE80211_IF_FILE(fwded_mcast, u.mesh.mshstats.fwded_mcast, DEC);
 592 IEEE80211_IF_FILE(fwded_unicast, u.mesh.mshstats.fwded_unicast, DEC);
 593 IEEE80211_IF_FILE(fwded_frames, u.mesh.mshstats.fwded_frames, DEC);
 594 IEEE80211_IF_FILE(dropped_frames_ttl, u.mesh.mshstats.dropped_frames_ttl, DEC);
 595 IEEE80211_IF_FILE(dropped_frames_congestion,
 596                   u.mesh.mshstats.dropped_frames_congestion, DEC);
 597 IEEE80211_IF_FILE(dropped_frames_no_route,
 598                   u.mesh.mshstats.dropped_frames_no_route, DEC);
 599 
 600 /* Mesh parameters */
 601 IEEE80211_IF_FILE(dot11MeshMaxRetries,
 602                   u.mesh.mshcfg.dot11MeshMaxRetries, DEC);
 603 IEEE80211_IF_FILE(dot11MeshRetryTimeout,
 604                   u.mesh.mshcfg.dot11MeshRetryTimeout, DEC);
 605 IEEE80211_IF_FILE(dot11MeshConfirmTimeout,
 606                   u.mesh.mshcfg.dot11MeshConfirmTimeout, DEC);
 607 IEEE80211_IF_FILE(dot11MeshHoldingTimeout,
 608                   u.mesh.mshcfg.dot11MeshHoldingTimeout, DEC);
 609 IEEE80211_IF_FILE(dot11MeshTTL, u.mesh.mshcfg.dot11MeshTTL, DEC);
 610 IEEE80211_IF_FILE(element_ttl, u.mesh.mshcfg.element_ttl, DEC);
 611 IEEE80211_IF_FILE(auto_open_plinks, u.mesh.mshcfg.auto_open_plinks, DEC);
 612 IEEE80211_IF_FILE(dot11MeshMaxPeerLinks,
 613                   u.mesh.mshcfg.dot11MeshMaxPeerLinks, DEC);
 614 IEEE80211_IF_FILE(dot11MeshHWMPactivePathTimeout,
 615                   u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout, DEC);
 616 IEEE80211_IF_FILE(dot11MeshHWMPpreqMinInterval,
 617                   u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval, DEC);
 618 IEEE80211_IF_FILE(dot11MeshHWMPperrMinInterval,
 619                   u.mesh.mshcfg.dot11MeshHWMPperrMinInterval, DEC);
 620 IEEE80211_IF_FILE(dot11MeshHWMPnetDiameterTraversalTime,
 621                   u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime, DEC);
 622 IEEE80211_IF_FILE(dot11MeshHWMPmaxPREQretries,
 623                   u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries, DEC);
 624 IEEE80211_IF_FILE(path_refresh_time,
 625                   u.mesh.mshcfg.path_refresh_time, DEC);
 626 IEEE80211_IF_FILE(min_discovery_timeout,
 627                   u.mesh.mshcfg.min_discovery_timeout, DEC);
 628 IEEE80211_IF_FILE(dot11MeshHWMPRootMode,
 629                   u.mesh.mshcfg.dot11MeshHWMPRootMode, DEC);
 630 IEEE80211_IF_FILE(dot11MeshGateAnnouncementProtocol,
 631                   u.mesh.mshcfg.dot11MeshGateAnnouncementProtocol, DEC);
 632 IEEE80211_IF_FILE(dot11MeshHWMPRannInterval,
 633                   u.mesh.mshcfg.dot11MeshHWMPRannInterval, DEC);
 634 IEEE80211_IF_FILE(dot11MeshForwarding, u.mesh.mshcfg.dot11MeshForwarding, DEC);
 635 IEEE80211_IF_FILE(rssi_threshold, u.mesh.mshcfg.rssi_threshold, DEC);
 636 IEEE80211_IF_FILE(ht_opmode, u.mesh.mshcfg.ht_opmode, DEC);
 637 IEEE80211_IF_FILE(dot11MeshHWMPactivePathToRootTimeout,
 638                   u.mesh.mshcfg.dot11MeshHWMPactivePathToRootTimeout, DEC);
 639 IEEE80211_IF_FILE(dot11MeshHWMProotInterval,
 640                   u.mesh.mshcfg.dot11MeshHWMProotInterval, DEC);
 641 IEEE80211_IF_FILE(dot11MeshHWMPconfirmationInterval,
 642                   u.mesh.mshcfg.dot11MeshHWMPconfirmationInterval, DEC);
 643 IEEE80211_IF_FILE(power_mode, u.mesh.mshcfg.power_mode, DEC);
 644 IEEE80211_IF_FILE(dot11MeshAwakeWindowDuration,
 645                   u.mesh.mshcfg.dot11MeshAwakeWindowDuration, DEC);
 646 IEEE80211_IF_FILE(dot11MeshConnectedToMeshGate,
 647                   u.mesh.mshcfg.dot11MeshConnectedToMeshGate, DEC);
 648 #endif
 649 
 650 #define DEBUGFS_ADD_MODE(name, mode) \
 651         debugfs_create_file(#name, mode, sdata->vif.debugfs_dir, \
 652                             sdata, &name##_ops);
 653 
 654 #define DEBUGFS_ADD(name) DEBUGFS_ADD_MODE(name, 0400)
 655 
 656 static void add_common_files(struct ieee80211_sub_if_data *sdata)
 657 {
 658         DEBUGFS_ADD(rc_rateidx_mask_2ghz);
 659         DEBUGFS_ADD(rc_rateidx_mask_5ghz);
 660         DEBUGFS_ADD(rc_rateidx_mcs_mask_2ghz);
 661         DEBUGFS_ADD(rc_rateidx_mcs_mask_5ghz);
 662         DEBUGFS_ADD(rc_rateidx_vht_mcs_mask_2ghz);
 663         DEBUGFS_ADD(rc_rateidx_vht_mcs_mask_5ghz);
 664         DEBUGFS_ADD(hw_queues);
 665 
 666         if (sdata->local->ops->wake_tx_queue &&
 667             sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE &&
 668             sdata->vif.type != NL80211_IFTYPE_NAN)
 669                 DEBUGFS_ADD(aqm);
 670 }
 671 
 672 static void add_sta_files(struct ieee80211_sub_if_data *sdata)
 673 {
 674         DEBUGFS_ADD(bssid);
 675         DEBUGFS_ADD(aid);
 676         DEBUGFS_ADD(beacon_timeout);
 677         DEBUGFS_ADD_MODE(smps, 0600);
 678         DEBUGFS_ADD_MODE(tkip_mic_test, 0200);
 679         DEBUGFS_ADD_MODE(beacon_loss, 0200);
 680         DEBUGFS_ADD_MODE(uapsd_queues, 0600);
 681         DEBUGFS_ADD_MODE(uapsd_max_sp_len, 0600);
 682         DEBUGFS_ADD_MODE(tdls_wider_bw, 0600);
 683 }
 684 
 685 static void add_ap_files(struct ieee80211_sub_if_data *sdata)
 686 {
 687         DEBUGFS_ADD(num_mcast_sta);
 688         DEBUGFS_ADD_MODE(smps, 0600);
 689         DEBUGFS_ADD(num_sta_ps);
 690         DEBUGFS_ADD(dtim_count);
 691         DEBUGFS_ADD(num_buffered_multicast);
 692         DEBUGFS_ADD_MODE(tkip_mic_test, 0200);
 693         DEBUGFS_ADD_MODE(multicast_to_unicast, 0600);
 694 }
 695 
 696 static void add_vlan_files(struct ieee80211_sub_if_data *sdata)
 697 {
 698         /* add num_mcast_sta_vlan using name num_mcast_sta */
 699         debugfs_create_file("num_mcast_sta", 0400, sdata->vif.debugfs_dir,
 700                             sdata, &num_mcast_sta_vlan_ops);
 701 }
 702 
 703 static void add_ibss_files(struct ieee80211_sub_if_data *sdata)
 704 {
 705         DEBUGFS_ADD_MODE(tsf, 0600);
 706 }
 707 
 708 static void add_wds_files(struct ieee80211_sub_if_data *sdata)
 709 {
 710         DEBUGFS_ADD(peer);
 711 }
 712 
 713 #ifdef CONFIG_MAC80211_MESH
 714 
 715 static void add_mesh_files(struct ieee80211_sub_if_data *sdata)
 716 {
 717         DEBUGFS_ADD_MODE(tsf, 0600);
 718         DEBUGFS_ADD_MODE(estab_plinks, 0400);
 719 }
 720 
 721 static void add_mesh_stats(struct ieee80211_sub_if_data *sdata)
 722 {
 723         struct dentry *dir = debugfs_create_dir("mesh_stats",
 724                                                 sdata->vif.debugfs_dir);
 725 #define MESHSTATS_ADD(name)\
 726         debugfs_create_file(#name, 0400, dir, sdata, &name##_ops);
 727 
 728         MESHSTATS_ADD(fwded_mcast);
 729         MESHSTATS_ADD(fwded_unicast);
 730         MESHSTATS_ADD(fwded_frames);
 731         MESHSTATS_ADD(dropped_frames_ttl);
 732         MESHSTATS_ADD(dropped_frames_no_route);
 733         MESHSTATS_ADD(dropped_frames_congestion);
 734 #undef MESHSTATS_ADD
 735 }
 736 
 737 static void add_mesh_config(struct ieee80211_sub_if_data *sdata)
 738 {
 739         struct dentry *dir = debugfs_create_dir("mesh_config",
 740                                                 sdata->vif.debugfs_dir);
 741 
 742 #define MESHPARAMS_ADD(name) \
 743         debugfs_create_file(#name, 0600, dir, sdata, &name##_ops);
 744 
 745         MESHPARAMS_ADD(dot11MeshMaxRetries);
 746         MESHPARAMS_ADD(dot11MeshRetryTimeout);
 747         MESHPARAMS_ADD(dot11MeshConfirmTimeout);
 748         MESHPARAMS_ADD(dot11MeshHoldingTimeout);
 749         MESHPARAMS_ADD(dot11MeshTTL);
 750         MESHPARAMS_ADD(element_ttl);
 751         MESHPARAMS_ADD(auto_open_plinks);
 752         MESHPARAMS_ADD(dot11MeshMaxPeerLinks);
 753         MESHPARAMS_ADD(dot11MeshHWMPactivePathTimeout);
 754         MESHPARAMS_ADD(dot11MeshHWMPpreqMinInterval);
 755         MESHPARAMS_ADD(dot11MeshHWMPperrMinInterval);
 756         MESHPARAMS_ADD(dot11MeshHWMPnetDiameterTraversalTime);
 757         MESHPARAMS_ADD(dot11MeshHWMPmaxPREQretries);
 758         MESHPARAMS_ADD(path_refresh_time);
 759         MESHPARAMS_ADD(min_discovery_timeout);
 760         MESHPARAMS_ADD(dot11MeshHWMPRootMode);
 761         MESHPARAMS_ADD(dot11MeshHWMPRannInterval);
 762         MESHPARAMS_ADD(dot11MeshForwarding);
 763         MESHPARAMS_ADD(dot11MeshGateAnnouncementProtocol);
 764         MESHPARAMS_ADD(rssi_threshold);
 765         MESHPARAMS_ADD(ht_opmode);
 766         MESHPARAMS_ADD(dot11MeshHWMPactivePathToRootTimeout);
 767         MESHPARAMS_ADD(dot11MeshHWMProotInterval);
 768         MESHPARAMS_ADD(dot11MeshHWMPconfirmationInterval);
 769         MESHPARAMS_ADD(power_mode);
 770         MESHPARAMS_ADD(dot11MeshAwakeWindowDuration);
 771         MESHPARAMS_ADD(dot11MeshConnectedToMeshGate);
 772 #undef MESHPARAMS_ADD
 773 }
 774 #endif
 775 
 776 static void add_files(struct ieee80211_sub_if_data *sdata)
 777 {
 778         if (!sdata->vif.debugfs_dir)
 779                 return;
 780 
 781         DEBUGFS_ADD(flags);
 782         DEBUGFS_ADD(state);
 783         DEBUGFS_ADD(txpower);
 784         DEBUGFS_ADD(user_power_level);
 785         DEBUGFS_ADD(ap_power_level);
 786 
 787         if (sdata->vif.type != NL80211_IFTYPE_MONITOR)
 788                 add_common_files(sdata);
 789 
 790         switch (sdata->vif.type) {
 791         case NL80211_IFTYPE_MESH_POINT:
 792 #ifdef CONFIG_MAC80211_MESH
 793                 add_mesh_files(sdata);
 794                 add_mesh_stats(sdata);
 795                 add_mesh_config(sdata);
 796 #endif
 797                 break;
 798         case NL80211_IFTYPE_STATION:
 799                 add_sta_files(sdata);
 800                 break;
 801         case NL80211_IFTYPE_ADHOC:
 802                 add_ibss_files(sdata);
 803                 break;
 804         case NL80211_IFTYPE_AP:
 805                 add_ap_files(sdata);
 806                 break;
 807         case NL80211_IFTYPE_AP_VLAN:
 808                 add_vlan_files(sdata);
 809                 break;
 810         case NL80211_IFTYPE_WDS:
 811                 add_wds_files(sdata);
 812                 break;
 813         default:
 814                 break;
 815         }
 816 }
 817 
 818 void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata)
 819 {
 820         char buf[10+IFNAMSIZ];
 821 
 822         sprintf(buf, "netdev:%s", sdata->name);
 823         sdata->vif.debugfs_dir = debugfs_create_dir(buf,
 824                 sdata->local->hw.wiphy->debugfsdir);
 825         sdata->debugfs.subdir_stations = debugfs_create_dir("stations",
 826                                                         sdata->vif.debugfs_dir);
 827         add_files(sdata);
 828 }
 829 
 830 void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata)
 831 {
 832         if (!sdata->vif.debugfs_dir)
 833                 return;
 834 
 835         debugfs_remove_recursive(sdata->vif.debugfs_dir);
 836         sdata->vif.debugfs_dir = NULL;
 837         sdata->debugfs.subdir_stations = NULL;
 838 }
 839 
 840 void ieee80211_debugfs_rename_netdev(struct ieee80211_sub_if_data *sdata)
 841 {
 842         struct dentry *dir;
 843         char buf[10 + IFNAMSIZ];
 844 
 845         dir = sdata->vif.debugfs_dir;
 846 
 847         if (IS_ERR_OR_NULL(dir))
 848                 return;
 849 
 850         sprintf(buf, "netdev:%s", sdata->name);
 851         debugfs_rename(dir->d_parent, dir, dir->d_parent, buf);
 852 }

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