LCOV - code coverage report
Current view: top level - net/mac80211 - debugfs_netdev.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 44 306 14.4 %
Date: 2022-03-28 13:20:08 Functions: 4 79 5.1 %
Branches: 6 109 5.5 %

           Branch data     Line data    Source code
       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                 :          0 : 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                 :          0 :         char buf[200];
      31                 :          0 :         ssize_t ret = -EINVAL;
      32                 :            : 
      33                 :          0 :         read_lock(&dev_base_lock);
      34                 :          0 :         ret = (*format)(sdata, buf, sizeof(buf));
      35                 :          0 :         read_unlock(&dev_base_lock);
      36                 :            : 
      37         [ #  # ]:          0 :         if (ret >= 0)
      38                 :          0 :                 ret = simple_read_from_buffer(userbuf, count, ppos, buf, ret);
      39                 :            : 
      40                 :          0 :         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                 :          0 : IEEE80211_IF_FILE(rc_rateidx_mask_2ghz, rc_rateidx_mask[NL80211_BAND_2GHZ],
     170                 :            :                   HEX);
     171                 :          0 : IEEE80211_IF_FILE(rc_rateidx_mask_5ghz, rc_rateidx_mask[NL80211_BAND_5GHZ],
     172                 :            :                   HEX);
     173         [ #  # ]:          0 : IEEE80211_IF_FILE(rc_rateidx_mcs_mask_2ghz,
     174                 :            :                   rc_rateidx_mcs_mask[NL80211_BAND_2GHZ], HEXARRAY);
     175         [ #  # ]:          0 : IEEE80211_IF_FILE(rc_rateidx_mcs_mask_5ghz,
     176                 :            :                   rc_rateidx_mcs_mask[NL80211_BAND_5GHZ], HEXARRAY);
     177                 :            : 
     178                 :          0 : 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                 :          0 :         int i, len = 0;
     183                 :          0 :         const u16 *mask = sdata->rc_rateidx_vht_mcs_mask[NL80211_BAND_2GHZ];
     184                 :            : 
     185         [ #  # ]:          0 :         for (i = 0; i < NL80211_VHT_NSS_MAX; i++)
     186                 :          0 :                 len += scnprintf(buf + len, buflen - len, "%04x ", mask[i]);
     187                 :          0 :         len += scnprintf(buf + len, buflen - len, "\n");
     188                 :            : 
     189                 :          0 :         return len;
     190                 :            : }
     191                 :            : 
     192                 :          0 : IEEE80211_IF_FILE_R(rc_rateidx_vht_mcs_mask_2ghz);
     193                 :            : 
     194                 :          0 : 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                 :          0 :         int i, len = 0;
     199                 :          0 :         const u16 *mask = sdata->rc_rateidx_vht_mcs_mask[NL80211_BAND_5GHZ];
     200                 :            : 
     201         [ #  # ]:          0 :         for (i = 0; i < NL80211_VHT_NSS_MAX; i++)
     202                 :          0 :                 len += scnprintf(buf + len, buflen - len, "%04x ", mask[i]);
     203                 :          0 :         len += scnprintf(buf + len, buflen - len, "\n");
     204                 :            : 
     205                 :          0 :         return len;
     206                 :            : }
     207                 :            : 
     208                 :          0 : IEEE80211_IF_FILE_R(rc_rateidx_vht_mcs_mask_5ghz);
     209                 :            : 
     210                 :          0 : IEEE80211_IF_FILE(flags, flags, HEX);
     211                 :          0 : IEEE80211_IF_FILE(state, state, LHEX);
     212                 :          0 : IEEE80211_IF_FILE(txpower, vif.bss_conf.txpower, DEC);
     213                 :          0 : IEEE80211_IF_FILE(ap_power_level, ap_power_level, DEC);
     214                 :          0 : IEEE80211_IF_FILE(user_power_level, user_power_level, DEC);
     215                 :            : 
     216                 :            : static ssize_t
     217                 :          0 : ieee80211_if_fmt_hw_queues(const struct ieee80211_sub_if_data *sdata,
     218                 :            :                            char *buf, int buflen)
     219                 :            : {
     220                 :          0 :         int len;
     221                 :            : 
     222                 :          0 :         len = scnprintf(buf, buflen, "AC queues: VO:%d VI:%d BE:%d BK:%d\n",
     223                 :          0 :                         sdata->vif.hw_queue[IEEE80211_AC_VO],
     224                 :          0 :                         sdata->vif.hw_queue[IEEE80211_AC_VI],
     225                 :          0 :                         sdata->vif.hw_queue[IEEE80211_AC_BE],
     226                 :          0 :                         sdata->vif.hw_queue[IEEE80211_AC_BK]);
     227                 :            : 
     228         [ #  # ]:          0 :         if (sdata->vif.type == NL80211_IFTYPE_AP)
     229                 :          0 :                 len += scnprintf(buf + len, buflen - len, "cab queue: %d\n",
     230                 :          0 :                                  sdata->vif.cab_queue);
     231                 :            : 
     232                 :          0 :         return len;
     233                 :            : }
     234                 :          0 : IEEE80211_IF_FILE_R(hw_queues);
     235                 :            : 
     236                 :            : /* STA attributes */
     237                 :          0 : IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC);
     238                 :          0 : IEEE80211_IF_FILE(aid, u.mgd.aid, DEC);
     239                 :          0 : IEEE80211_IF_FILE(beacon_timeout, u.mgd.beacon_timeout, JIFFIES_TO_MS);
     240                 :            : 
     241                 :          0 : static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata,
     242                 :            :                               enum ieee80211_smps_mode smps_mode)
     243                 :            : {
     244                 :          0 :         struct ieee80211_local *local = sdata->local;
     245                 :          0 :         int err;
     246                 :            : 
     247   [ #  #  #  # ]:          0 :         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         [ #  # ]:          0 :         if (!(local->hw.wiphy->features & NL80211_FEATURE_DYNAMIC_SMPS) &&
     253                 :          0 :             (smps_mode == IEEE80211_SMPS_DYNAMIC ||
     254         [ #  # ]:          0 :              smps_mode == IEEE80211_SMPS_AUTOMATIC))
     255                 :            :                 return -EINVAL;
     256                 :            : 
     257         [ #  # ]:          0 :         if (sdata->vif.type != NL80211_IFTYPE_STATION &&
     258                 :            :             sdata->vif.type != NL80211_IFTYPE_AP)
     259                 :            :                 return -EOPNOTSUPP;
     260                 :            : 
     261                 :          0 :         sdata_lock(sdata);
     262         [ #  # ]:          0 :         if (sdata->vif.type == NL80211_IFTYPE_STATION)
     263                 :          0 :                 err = __ieee80211_request_smps_mgd(sdata, smps_mode);
     264                 :            :         else
     265                 :          0 :                 err = __ieee80211_request_smps_ap(sdata, smps_mode);
     266                 :          0 :         sdata_unlock(sdata);
     267                 :            : 
     268                 :          0 :         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                 :          0 : static ssize_t ieee80211_if_fmt_smps(const struct ieee80211_sub_if_data *sdata,
     279                 :            :                                      char *buf, int buflen)
     280                 :            : {
     281         [ #  # ]:          0 :         if (sdata->vif.type == NL80211_IFTYPE_STATION)
     282                 :          0 :                 return snprintf(buf, buflen, "request: %s\nused: %s\n",
     283                 :          0 :                                 smps_modes[sdata->u.mgd.req_smps],
     284                 :          0 :                                 smps_modes[sdata->smps_mode]);
     285         [ #  # ]:          0 :         if (sdata->vif.type == NL80211_IFTYPE_AP)
     286                 :          0 :                 return snprintf(buf, buflen, "request: %s\nused: %s\n",
     287                 :          0 :                                 smps_modes[sdata->u.ap.req_smps],
     288                 :          0 :                                 smps_modes[sdata->smps_mode]);
     289                 :            :         return -EINVAL;
     290                 :            : }
     291                 :            : 
     292                 :          0 : static ssize_t ieee80211_if_parse_smps(struct ieee80211_sub_if_data *sdata,
     293                 :            :                                        const char *buf, int buflen)
     294                 :            : {
     295                 :          0 :         enum ieee80211_smps_mode mode;
     296                 :            : 
     297         [ #  # ]:          0 :         for (mode = 0; mode < IEEE80211_SMPS_NUM_MODES; mode++) {
     298         [ #  # ]:          0 :                 if (strncmp(buf, smps_modes[mode], buflen) == 0) {
     299                 :          0 :                         int err = ieee80211_set_smps(sdata, mode);
     300         [ #  # ]:          0 :                         if (!err)
     301                 :          0 :                                 return buflen;
     302                 :          0 :                         return err;
     303                 :            :                 }
     304                 :            :         }
     305                 :            : 
     306                 :            :         return -EINVAL;
     307                 :            : }
     308                 :          0 : IEEE80211_IF_FILE_RW(smps);
     309                 :            : 
     310                 :          0 : static ssize_t ieee80211_if_parse_tkip_mic_test(
     311                 :            :         struct ieee80211_sub_if_data *sdata, const char *buf, int buflen)
     312                 :            : {
     313                 :          0 :         struct ieee80211_local *local = sdata->local;
     314                 :          0 :         u8 addr[ETH_ALEN];
     315                 :          0 :         struct sk_buff *skb;
     316                 :          0 :         struct ieee80211_hdr *hdr;
     317                 :          0 :         __le16 fc;
     318                 :            : 
     319         [ #  # ]:          0 :         if (!mac_pton(buf, addr))
     320                 :            :                 return -EINVAL;
     321                 :            : 
     322         [ #  # ]:          0 :         if (!ieee80211_sdata_running(sdata))
     323                 :            :                 return -ENOTCONN;
     324                 :            : 
     325                 :          0 :         skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24 + 100);
     326         [ #  # ]:          0 :         if (!skb)
     327                 :            :                 return -ENOMEM;
     328                 :          0 :         skb_reserve(skb, local->hw.extra_tx_headroom);
     329                 :            : 
     330                 :          0 :         hdr = skb_put_zero(skb, 24);
     331                 :          0 :         fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA);
     332                 :            : 
     333      [ #  #  # ]:          0 :         switch (sdata->vif.type) {
     334                 :          0 :         case NL80211_IFTYPE_AP:
     335                 :          0 :                 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
     336                 :            :                 /* DA BSSID SA */
     337                 :          0 :                 memcpy(hdr->addr1, addr, ETH_ALEN);
     338                 :          0 :                 memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN);
     339                 :          0 :                 memcpy(hdr->addr3, sdata->vif.addr, ETH_ALEN);
     340                 :          0 :                 break;
     341                 :          0 :         case NL80211_IFTYPE_STATION:
     342                 :          0 :                 fc |= cpu_to_le16(IEEE80211_FCTL_TODS);
     343                 :            :                 /* BSSID SA DA */
     344                 :          0 :                 sdata_lock(sdata);
     345         [ #  # ]:          0 :                 if (!sdata->u.mgd.associated) {
     346                 :          0 :                         sdata_unlock(sdata);
     347                 :          0 :                         dev_kfree_skb(skb);
     348                 :          0 :                         return -ENOTCONN;
     349                 :            :                 }
     350                 :          0 :                 memcpy(hdr->addr1, sdata->u.mgd.associated->bssid, ETH_ALEN);
     351                 :          0 :                 memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN);
     352                 :          0 :                 memcpy(hdr->addr3, addr, ETH_ALEN);
     353                 :          0 :                 sdata_unlock(sdata);
     354                 :            :                 break;
     355                 :          0 :         default:
     356                 :          0 :                 dev_kfree_skb(skb);
     357                 :          0 :                 return -EOPNOTSUPP;
     358                 :            :         }
     359                 :          0 :         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                 :          0 :         skb_put_zero(skb, 50);
     367                 :            : 
     368                 :          0 :         IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_TKIP_MIC_FAILURE;
     369                 :            : 
     370                 :          0 :         ieee80211_tx_skb(sdata, skb);
     371                 :            : 
     372                 :          0 :         return buflen;
     373                 :            : }
     374                 :          0 : IEEE80211_IF_FILE_W(tkip_mic_test);
     375                 :            : 
     376                 :          0 : static ssize_t ieee80211_if_parse_beacon_loss(
     377                 :            :         struct ieee80211_sub_if_data *sdata, const char *buf, int buflen)
     378                 :            : {
     379   [ #  #  #  # ]:          0 :         if (!ieee80211_sdata_running(sdata) || !sdata->vif.bss_conf.assoc)
     380                 :            :                 return -ENOTCONN;
     381                 :            : 
     382                 :          0 :         ieee80211_beacon_loss(&sdata->vif);
     383                 :            : 
     384                 :          0 :         return buflen;
     385                 :            : }
     386                 :          0 : IEEE80211_IF_FILE_W(beacon_loss);
     387                 :            : 
     388                 :          0 : static ssize_t ieee80211_if_fmt_uapsd_queues(
     389                 :            :         const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
     390                 :            : {
     391                 :          0 :         const struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
     392                 :            : 
     393                 :          0 :         return snprintf(buf, buflen, "0x%x\n", ifmgd->uapsd_queues);
     394                 :            : }
     395                 :            : 
     396                 :          0 : static ssize_t ieee80211_if_parse_uapsd_queues(
     397                 :            :         struct ieee80211_sub_if_data *sdata, const char *buf, int buflen)
     398                 :            : {
     399                 :          0 :         struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
     400                 :          0 :         u8 val;
     401                 :          0 :         int ret;
     402                 :            : 
     403                 :          0 :         ret = kstrtou8(buf, 0, &val);
     404         [ #  # ]:          0 :         if (ret)
     405                 :          0 :                 return ret;
     406                 :            : 
     407         [ #  # ]:          0 :         if (val & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
     408                 :            :                 return -ERANGE;
     409                 :            : 
     410                 :          0 :         ifmgd->uapsd_queues = val;
     411                 :            : 
     412                 :          0 :         return buflen;
     413                 :            : }
     414                 :          0 : IEEE80211_IF_FILE_RW(uapsd_queues);
     415                 :            : 
     416                 :          0 : static ssize_t ieee80211_if_fmt_uapsd_max_sp_len(
     417                 :            :         const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
     418                 :            : {
     419                 :          0 :         const struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
     420                 :            : 
     421                 :          0 :         return snprintf(buf, buflen, "0x%x\n", ifmgd->uapsd_max_sp_len);
     422                 :            : }
     423                 :            : 
     424                 :          0 : static ssize_t ieee80211_if_parse_uapsd_max_sp_len(
     425                 :            :         struct ieee80211_sub_if_data *sdata, const char *buf, int buflen)
     426                 :            : {
     427                 :          0 :         struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
     428                 :          0 :         unsigned long val;
     429                 :          0 :         int ret;
     430                 :            : 
     431                 :          0 :         ret = kstrtoul(buf, 0, &val);
     432         [ #  # ]:          0 :         if (ret)
     433                 :            :                 return -EINVAL;
     434                 :            : 
     435         [ #  # ]:          0 :         if (val & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK)
     436                 :            :                 return -ERANGE;
     437                 :            : 
     438                 :          0 :         ifmgd->uapsd_max_sp_len = val;
     439                 :            : 
     440                 :          0 :         return buflen;
     441                 :            : }
     442                 :          0 : IEEE80211_IF_FILE_RW(uapsd_max_sp_len);
     443                 :            : 
     444                 :          0 : static ssize_t ieee80211_if_fmt_tdls_wider_bw(
     445                 :            :         const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
     446                 :            : {
     447                 :          0 :         const struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
     448                 :          0 :         bool tdls_wider_bw;
     449                 :            : 
     450         [ #  # ]:          0 :         tdls_wider_bw = ieee80211_hw_check(&sdata->local->hw, TDLS_WIDER_BW) &&
     451         [ #  # ]:          0 :                         !ifmgd->tdls_wider_bw_prohibited;
     452                 :            : 
     453                 :          0 :         return snprintf(buf, buflen, "%d\n", tdls_wider_bw);
     454                 :            : }
     455                 :            : 
     456                 :          0 : static ssize_t ieee80211_if_parse_tdls_wider_bw(
     457                 :            :         struct ieee80211_sub_if_data *sdata, const char *buf, int buflen)
     458                 :            : {
     459                 :          0 :         struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
     460                 :          0 :         u8 val;
     461                 :          0 :         int ret;
     462                 :            : 
     463                 :          0 :         ret = kstrtou8(buf, 0, &val);
     464         [ #  # ]:          0 :         if (ret)
     465                 :          0 :                 return ret;
     466                 :            : 
     467                 :          0 :         ifmgd->tdls_wider_bw_prohibited = !val;
     468                 :          0 :         return buflen;
     469                 :            : }
     470                 :          0 : IEEE80211_IF_FILE_RW(tdls_wider_bw);
     471                 :            : 
     472                 :            : /* AP attributes */
     473                 :          0 : IEEE80211_IF_FILE(num_mcast_sta, u.ap.num_mcast_sta, ATOMIC);
     474                 :          0 : IEEE80211_IF_FILE(num_sta_ps, u.ap.ps.num_sta_ps, ATOMIC);
     475                 :          0 : IEEE80211_IF_FILE(dtim_count, u.ap.ps.dtim_count, DEC);
     476                 :          0 : IEEE80211_IF_FILE(num_mcast_sta_vlan, u.vlan.num_mcast_sta, ATOMIC);
     477                 :            : 
     478                 :          0 : static ssize_t ieee80211_if_fmt_num_buffered_multicast(
     479                 :            :         const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
     480                 :            : {
     481                 :          0 :         return scnprintf(buf, buflen, "%u\n",
     482                 :            :                          skb_queue_len(&sdata->u.ap.ps.bc_buf));
     483                 :            : }
     484                 :          0 : IEEE80211_IF_FILE_R(num_buffered_multicast);
     485                 :            : 
     486                 :          0 : static ssize_t ieee80211_if_fmt_aqm(
     487                 :            :         const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
     488                 :            : {
     489                 :          0 :         struct ieee80211_local *local = sdata->local;
     490                 :          0 :         struct txq_info *txqi;
     491                 :          0 :         int len;
     492                 :            : 
     493         [ #  # ]:          0 :         if (!sdata->vif.txq)
     494                 :            :                 return 0;
     495                 :            : 
     496                 :          0 :         txqi = to_txq_info(sdata->vif.txq);
     497                 :            : 
     498                 :          0 :         spin_lock_bh(&local->fq.lock);
     499                 :          0 :         rcu_read_lock();
     500                 :            : 
     501                 :          0 :         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                 :          0 :                         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                 :          0 :         rcu_read_unlock();
     517                 :          0 :         spin_unlock_bh(&local->fq.lock);
     518                 :            : 
     519                 :          0 :         return len;
     520                 :            : }
     521                 :          0 : IEEE80211_IF_FILE_R(aqm);
     522                 :            : 
     523                 :          0 : IEEE80211_IF_FILE(multicast_to_unicast, u.ap.multicast_to_unicast, HEX);
     524                 :            : 
     525                 :            : /* IBSS attributes */
     526                 :          0 : static ssize_t ieee80211_if_fmt_tsf(
     527                 :            :         const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
     528                 :            : {
     529                 :          0 :         struct ieee80211_local *local = sdata->local;
     530                 :          0 :         u64 tsf;
     531                 :            : 
     532                 :          0 :         tsf = drv_get_tsf(local, (struct ieee80211_sub_if_data *)sdata);
     533                 :            : 
     534                 :          0 :         return scnprintf(buf, buflen, "0x%016llx\n", (unsigned long long) tsf);
     535                 :            : }
     536                 :            : 
     537                 :          0 : static ssize_t ieee80211_if_parse_tsf(
     538                 :            :         struct ieee80211_sub_if_data *sdata, const char *buf, int buflen)
     539                 :            : {
     540                 :          0 :         struct ieee80211_local *local = sdata->local;
     541                 :          0 :         unsigned long long tsf;
     542                 :          0 :         int ret;
     543                 :          0 :         int tsf_is_delta = 0;
     544                 :            : 
     545         [ #  # ]:          0 :         if (strncmp(buf, "reset", 5) == 0) {
     546         [ #  # ]:          0 :                 if (local->ops->reset_tsf) {
     547                 :          0 :                         drv_reset_tsf(local, sdata);
     548                 :          0 :                         wiphy_info(local->hw.wiphy, "debugfs reset TSF\n");
     549                 :            :                 }
     550                 :            :         } else {
     551   [ #  #  #  # ]:          0 :                 if (buflen > 10 && buf[1] == '=') {
     552         [ #  # ]:          0 :                         if (buf[0] == '+')
     553                 :            :                                 tsf_is_delta = 1;
     554         [ #  # ]:          0 :                         else if (buf[0] == '-')
     555                 :            :                                 tsf_is_delta = -1;
     556                 :            :                         else
     557                 :            :                                 return -EINVAL;
     558                 :          0 :                         buf += 2;
     559                 :            :                 }
     560                 :          0 :                 ret = kstrtoull(buf, 10, &tsf);
     561         [ #  # ]:          0 :                 if (ret < 0)
     562                 :          0 :                         return ret;
     563   [ #  #  #  # ]:          0 :                 if (tsf_is_delta && local->ops->offset_tsf) {
     564                 :          0 :                         drv_offset_tsf(local, sdata, tsf_is_delta * tsf);
     565                 :          0 :                         wiphy_info(local->hw.wiphy,
     566                 :            :                                    "debugfs offset TSF by %018lld\n",
     567                 :            :                                    tsf_is_delta * tsf);
     568         [ #  # ]:          0 :                 } else if (local->ops->set_tsf) {
     569         [ #  # ]:          0 :                         if (tsf_is_delta)
     570                 :          0 :                                 tsf = drv_get_tsf(local, sdata) +
     571                 :          0 :                                       tsf_is_delta * tsf;
     572                 :          0 :                         drv_set_tsf(local, sdata, tsf);
     573                 :          0 :                         wiphy_info(local->hw.wiphy,
     574                 :            :                                    "debugfs set TSF to %#018llx\n", tsf);
     575                 :            :                 }
     576                 :            :         }
     577                 :            : 
     578                 :          0 :         ieee80211_recalc_dtim(local, sdata);
     579                 :          0 :         return buflen;
     580                 :            : }
     581                 :          0 : IEEE80211_IF_FILE_RW(tsf);
     582                 :            : 
     583                 :            : 
     584                 :            : /* WDS attributes */
     585                 :          0 : 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                 :          6 : static void add_common_files(struct ieee80211_sub_if_data *sdata)
     657                 :            : {
     658                 :          6 :         DEBUGFS_ADD(rc_rateidx_mask_2ghz);
     659                 :          6 :         DEBUGFS_ADD(rc_rateidx_mask_5ghz);
     660                 :          6 :         DEBUGFS_ADD(rc_rateidx_mcs_mask_2ghz);
     661                 :          6 :         DEBUGFS_ADD(rc_rateidx_mcs_mask_5ghz);
     662                 :          6 :         DEBUGFS_ADD(rc_rateidx_vht_mcs_mask_2ghz);
     663                 :          6 :         DEBUGFS_ADD(rc_rateidx_vht_mcs_mask_5ghz);
     664                 :          6 :         DEBUGFS_ADD(hw_queues);
     665                 :            : 
     666         [ +  - ]:          6 :         if (sdata->local->ops->wake_tx_queue &&
     667   [ +  -  +  - ]:          6 :             sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE &&
     668                 :            :             sdata->vif.type != NL80211_IFTYPE_NAN)
     669                 :          6 :                 DEBUGFS_ADD(aqm);
     670                 :          6 : }
     671                 :            : 
     672                 :          6 : static void add_sta_files(struct ieee80211_sub_if_data *sdata)
     673                 :            : {
     674                 :          6 :         DEBUGFS_ADD(bssid);
     675                 :          6 :         DEBUGFS_ADD(aid);
     676                 :          6 :         DEBUGFS_ADD(beacon_timeout);
     677                 :          6 :         DEBUGFS_ADD_MODE(smps, 0600);
     678                 :          6 :         DEBUGFS_ADD_MODE(tkip_mic_test, 0200);
     679                 :          6 :         DEBUGFS_ADD_MODE(beacon_loss, 0200);
     680                 :          6 :         DEBUGFS_ADD_MODE(uapsd_queues, 0600);
     681                 :          6 :         DEBUGFS_ADD_MODE(uapsd_max_sp_len, 0600);
     682                 :          6 :         DEBUGFS_ADD_MODE(tdls_wider_bw, 0600);
     683                 :          6 : }
     684                 :            : 
     685                 :          0 : static void add_ap_files(struct ieee80211_sub_if_data *sdata)
     686                 :            : {
     687                 :          0 :         DEBUGFS_ADD(num_mcast_sta);
     688                 :          0 :         DEBUGFS_ADD_MODE(smps, 0600);
     689                 :          0 :         DEBUGFS_ADD(num_sta_ps);
     690                 :          0 :         DEBUGFS_ADD(dtim_count);
     691                 :          0 :         DEBUGFS_ADD(num_buffered_multicast);
     692                 :          0 :         DEBUGFS_ADD_MODE(tkip_mic_test, 0200);
     693                 :          0 :         DEBUGFS_ADD_MODE(multicast_to_unicast, 0600);
     694                 :          0 : }
     695                 :            : 
     696                 :          0 : static void add_vlan_files(struct ieee80211_sub_if_data *sdata)
     697                 :            : {
     698                 :            :         /* add num_mcast_sta_vlan using name num_mcast_sta */
     699                 :          0 :         debugfs_create_file("num_mcast_sta", 0400, sdata->vif.debugfs_dir,
     700                 :            :                             sdata, &num_mcast_sta_vlan_ops);
     701                 :          0 : }
     702                 :            : 
     703                 :          0 : static void add_ibss_files(struct ieee80211_sub_if_data *sdata)
     704                 :            : {
     705                 :          0 :         DEBUGFS_ADD_MODE(tsf, 0600);
     706                 :          0 : }
     707                 :            : 
     708                 :          0 : static void add_wds_files(struct ieee80211_sub_if_data *sdata)
     709                 :            : {
     710                 :          0 :         DEBUGFS_ADD(peer);
     711                 :          0 : }
     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                 :          6 : static void add_files(struct ieee80211_sub_if_data *sdata)
     777                 :            : {
     778         [ +  - ]:          6 :         if (!sdata->vif.debugfs_dir)
     779                 :            :                 return;
     780                 :            : 
     781                 :          6 :         DEBUGFS_ADD(flags);
     782                 :          6 :         DEBUGFS_ADD(state);
     783                 :          6 :         DEBUGFS_ADD(txpower);
     784                 :          6 :         DEBUGFS_ADD(user_power_level);
     785                 :          6 :         DEBUGFS_ADD(ap_power_level);
     786                 :            : 
     787         [ +  - ]:          6 :         if (sdata->vif.type != NL80211_IFTYPE_MONITOR)
     788                 :          6 :                 add_common_files(sdata);
     789                 :            : 
     790   [ +  -  -  -  :          6 :         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                 :          6 :         case NL80211_IFTYPE_STATION:
     799                 :          6 :                 add_sta_files(sdata);
     800                 :          6 :                 break;
     801                 :            :         case NL80211_IFTYPE_ADHOC:
     802                 :          0 :                 add_ibss_files(sdata);
     803                 :            :                 break;
     804                 :          0 :         case NL80211_IFTYPE_AP:
     805                 :          0 :                 add_ap_files(sdata);
     806                 :          0 :                 break;
     807                 :            :         case NL80211_IFTYPE_AP_VLAN:
     808                 :          0 :                 add_vlan_files(sdata);
     809                 :            :                 break;
     810                 :            :         case NL80211_IFTYPE_WDS:
     811                 :          0 :                 add_wds_files(sdata);
     812                 :            :                 break;
     813                 :            :         default:
     814                 :            :                 break;
     815                 :            :         }
     816                 :            : }
     817                 :            : 
     818                 :          6 : void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata)
     819                 :            : {
     820                 :          6 :         char buf[10+IFNAMSIZ];
     821                 :            : 
     822                 :          6 :         sprintf(buf, "netdev:%s", sdata->name);
     823                 :         12 :         sdata->vif.debugfs_dir = debugfs_create_dir(buf,
     824                 :          6 :                 sdata->local->hw.wiphy->debugfsdir);
     825                 :          6 :         sdata->debugfs.subdir_stations = debugfs_create_dir("stations",
     826                 :            :                                                         sdata->vif.debugfs_dir);
     827                 :          6 :         add_files(sdata);
     828                 :          6 : }
     829                 :            : 
     830                 :          0 : void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata)
     831                 :            : {
     832         [ #  # ]:          0 :         if (!sdata->vif.debugfs_dir)
     833                 :            :                 return;
     834                 :            : 
     835                 :          0 :         debugfs_remove_recursive(sdata->vif.debugfs_dir);
     836                 :          0 :         sdata->vif.debugfs_dir = NULL;
     837                 :          0 :         sdata->debugfs.subdir_stations = NULL;
     838                 :            : }
     839                 :            : 
     840                 :          0 : void ieee80211_debugfs_rename_netdev(struct ieee80211_sub_if_data *sdata)
     841                 :            : {
     842                 :          0 :         struct dentry *dir;
     843                 :          0 :         char buf[10 + IFNAMSIZ];
     844                 :            : 
     845                 :          0 :         dir = sdata->vif.debugfs_dir;
     846                 :            : 
     847   [ #  #  #  # ]:          0 :         if (IS_ERR_OR_NULL(dir))
     848                 :          0 :                 return;
     849                 :            : 
     850                 :          0 :         sprintf(buf, "netdev:%s", sdata->name);
     851                 :          0 :         debugfs_rename(dir->d_parent, dir, dir->d_parent, buf);
     852                 :            : }

Generated by: LCOV version 1.14