The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/dev/iwlwifi/mvm/debugfs-vif.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
    2 /*
    3  * Copyright (C) 2012-2014, 2018-2021 Intel Corporation
    4  * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
    5  * Copyright (C) 2016-2017 Intel Deutschland GmbH
    6  */
    7 #include "mvm.h"
    8 #include "debugfs.h"
    9 #if defined(__FreeBSD__)
   10 #include <linux/math64.h>
   11 #endif
   12 
   13 static void iwl_dbgfs_update_pm(struct iwl_mvm *mvm,
   14                                  struct ieee80211_vif *vif,
   15                                  enum iwl_dbgfs_pm_mask param, int val)
   16 {
   17         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
   18         struct iwl_dbgfs_pm *dbgfs_pm = &mvmvif->dbgfs_pm;
   19 
   20         dbgfs_pm->mask |= param;
   21 
   22         switch (param) {
   23         case MVM_DEBUGFS_PM_KEEP_ALIVE: {
   24                 int dtimper = vif->bss_conf.dtim_period ?: 1;
   25                 int dtimper_msec = dtimper * vif->bss_conf.beacon_int;
   26 
   27                 IWL_DEBUG_POWER(mvm, "debugfs: set keep_alive= %d sec\n", val);
   28                 if (val * MSEC_PER_SEC < 3 * dtimper_msec)
   29                         IWL_WARN(mvm,
   30                                  "debugfs: keep alive period (%ld msec) is less than minimum required (%d msec)\n",
   31                                  val * MSEC_PER_SEC, 3 * dtimper_msec);
   32                 dbgfs_pm->keep_alive_seconds = val;
   33                 break;
   34         }
   35         case MVM_DEBUGFS_PM_SKIP_OVER_DTIM:
   36                 IWL_DEBUG_POWER(mvm, "skip_over_dtim %s\n",
   37                                 val ? "enabled" : "disabled");
   38                 dbgfs_pm->skip_over_dtim = val;
   39                 break;
   40         case MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS:
   41                 IWL_DEBUG_POWER(mvm, "skip_dtim_periods=%d\n", val);
   42                 dbgfs_pm->skip_dtim_periods = val;
   43                 break;
   44         case MVM_DEBUGFS_PM_RX_DATA_TIMEOUT:
   45                 IWL_DEBUG_POWER(mvm, "rx_data_timeout=%d\n", val);
   46                 dbgfs_pm->rx_data_timeout = val;
   47                 break;
   48         case MVM_DEBUGFS_PM_TX_DATA_TIMEOUT:
   49                 IWL_DEBUG_POWER(mvm, "tx_data_timeout=%d\n", val);
   50                 dbgfs_pm->tx_data_timeout = val;
   51                 break;
   52         case MVM_DEBUGFS_PM_LPRX_ENA:
   53                 IWL_DEBUG_POWER(mvm, "lprx %s\n", val ? "enabled" : "disabled");
   54                 dbgfs_pm->lprx_ena = val;
   55                 break;
   56         case MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD:
   57                 IWL_DEBUG_POWER(mvm, "lprx_rssi_threshold=%d\n", val);
   58                 dbgfs_pm->lprx_rssi_threshold = val;
   59                 break;
   60         case MVM_DEBUGFS_PM_SNOOZE_ENABLE:
   61                 IWL_DEBUG_POWER(mvm, "snooze_enable=%d\n", val);
   62                 dbgfs_pm->snooze_ena = val;
   63                 break;
   64         case MVM_DEBUGFS_PM_UAPSD_MISBEHAVING:
   65                 IWL_DEBUG_POWER(mvm, "uapsd_misbehaving_enable=%d\n", val);
   66                 dbgfs_pm->uapsd_misbehaving = val;
   67                 break;
   68         case MVM_DEBUGFS_PM_USE_PS_POLL:
   69                 IWL_DEBUG_POWER(mvm, "use_ps_poll=%d\n", val);
   70                 dbgfs_pm->use_ps_poll = val;
   71                 break;
   72         }
   73 }
   74 
   75 static ssize_t iwl_dbgfs_pm_params_write(struct ieee80211_vif *vif, char *buf,
   76                                          size_t count, loff_t *ppos)
   77 {
   78         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
   79         struct iwl_mvm *mvm = mvmvif->mvm;
   80         enum iwl_dbgfs_pm_mask param;
   81         int val, ret;
   82 
   83         if (!strncmp("keep_alive=", buf, 11)) {
   84                 if (sscanf(buf + 11, "%d", &val) != 1)
   85                         return -EINVAL;
   86                 param = MVM_DEBUGFS_PM_KEEP_ALIVE;
   87         } else if (!strncmp("skip_over_dtim=", buf, 15)) {
   88                 if (sscanf(buf + 15, "%d", &val) != 1)
   89                         return -EINVAL;
   90                 param = MVM_DEBUGFS_PM_SKIP_OVER_DTIM;
   91         } else if (!strncmp("skip_dtim_periods=", buf, 18)) {
   92                 if (sscanf(buf + 18, "%d", &val) != 1)
   93                         return -EINVAL;
   94                 param = MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS;
   95         } else if (!strncmp("rx_data_timeout=", buf, 16)) {
   96                 if (sscanf(buf + 16, "%d", &val) != 1)
   97                         return -EINVAL;
   98                 param = MVM_DEBUGFS_PM_RX_DATA_TIMEOUT;
   99         } else if (!strncmp("tx_data_timeout=", buf, 16)) {
  100                 if (sscanf(buf + 16, "%d", &val) != 1)
  101                         return -EINVAL;
  102                 param = MVM_DEBUGFS_PM_TX_DATA_TIMEOUT;
  103         } else if (!strncmp("lprx=", buf, 5)) {
  104                 if (sscanf(buf + 5, "%d", &val) != 1)
  105                         return -EINVAL;
  106                 param = MVM_DEBUGFS_PM_LPRX_ENA;
  107         } else if (!strncmp("lprx_rssi_threshold=", buf, 20)) {
  108                 if (sscanf(buf + 20, "%d", &val) != 1)
  109                         return -EINVAL;
  110                 if (val > POWER_LPRX_RSSI_THRESHOLD_MAX || val <
  111                     POWER_LPRX_RSSI_THRESHOLD_MIN)
  112                         return -EINVAL;
  113                 param = MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD;
  114         } else if (!strncmp("snooze_enable=", buf, 14)) {
  115                 if (sscanf(buf + 14, "%d", &val) != 1)
  116                         return -EINVAL;
  117                 param = MVM_DEBUGFS_PM_SNOOZE_ENABLE;
  118         } else if (!strncmp("uapsd_misbehaving=", buf, 18)) {
  119                 if (sscanf(buf + 18, "%d", &val) != 1)
  120                         return -EINVAL;
  121                 param = MVM_DEBUGFS_PM_UAPSD_MISBEHAVING;
  122         } else if (!strncmp("use_ps_poll=", buf, 12)) {
  123                 if (sscanf(buf + 12, "%d", &val) != 1)
  124                         return -EINVAL;
  125                 param = MVM_DEBUGFS_PM_USE_PS_POLL;
  126         } else {
  127                 return -EINVAL;
  128         }
  129 
  130         mutex_lock(&mvm->mutex);
  131         iwl_dbgfs_update_pm(mvm, vif, param, val);
  132         ret = iwl_mvm_power_update_mac(mvm);
  133         mutex_unlock(&mvm->mutex);
  134 
  135         return ret ?: count;
  136 }
  137 
  138 static ssize_t iwl_dbgfs_tx_pwr_lmt_read(struct file *file,
  139                                          char __user *user_buf,
  140                                          size_t count, loff_t *ppos)
  141 {
  142         struct ieee80211_vif *vif = file->private_data;
  143         char buf[64];
  144         int bufsz = sizeof(buf);
  145         int pos;
  146 
  147         pos = scnprintf(buf, bufsz, "bss limit = %d\n",
  148                         vif->bss_conf.txpower);
  149 
  150         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
  151 }
  152 
  153 static ssize_t iwl_dbgfs_pm_params_read(struct file *file,
  154                                         char __user *user_buf,
  155                                         size_t count, loff_t *ppos)
  156 {
  157         struct ieee80211_vif *vif = file->private_data;
  158         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
  159         struct iwl_mvm *mvm = mvmvif->mvm;
  160         char buf[512];
  161         int bufsz = sizeof(buf);
  162         int pos;
  163 
  164         pos = iwl_mvm_power_mac_dbgfs_read(mvm, vif, buf, bufsz);
  165 
  166         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
  167 }
  168 
  169 static ssize_t iwl_dbgfs_mac_params_read(struct file *file,
  170                                          char __user *user_buf,
  171                                          size_t count, loff_t *ppos)
  172 {
  173         struct ieee80211_vif *vif = file->private_data;
  174         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
  175         struct iwl_mvm *mvm = mvmvif->mvm;
  176         u8 ap_sta_id;
  177         struct ieee80211_chanctx_conf *chanctx_conf;
  178         char buf[512];
  179         int bufsz = sizeof(buf);
  180         int pos = 0;
  181         int i;
  182 
  183         mutex_lock(&mvm->mutex);
  184 
  185         ap_sta_id = mvmvif->ap_sta_id;
  186 
  187         switch (ieee80211_vif_type_p2p(vif)) {
  188         case NL80211_IFTYPE_ADHOC:
  189                 pos += scnprintf(buf+pos, bufsz-pos, "type: ibss\n");
  190                 break;
  191         case NL80211_IFTYPE_STATION:
  192                 pos += scnprintf(buf+pos, bufsz-pos, "type: bss\n");
  193                 break;
  194         case NL80211_IFTYPE_AP:
  195                 pos += scnprintf(buf+pos, bufsz-pos, "type: ap\n");
  196                 break;
  197         case NL80211_IFTYPE_P2P_CLIENT:
  198                 pos += scnprintf(buf+pos, bufsz-pos, "type: p2p client\n");
  199                 break;
  200         case NL80211_IFTYPE_P2P_GO:
  201                 pos += scnprintf(buf+pos, bufsz-pos, "type: p2p go\n");
  202                 break;
  203         case NL80211_IFTYPE_P2P_DEVICE:
  204                 pos += scnprintf(buf+pos, bufsz-pos, "type: p2p dev\n");
  205                 break;
  206         default:
  207                 break;
  208         }
  209 
  210         pos += scnprintf(buf+pos, bufsz-pos, "mac id/color: %d / %d\n",
  211                          mvmvif->id, mvmvif->color);
  212         pos += scnprintf(buf+pos, bufsz-pos, "bssid: %pM\n",
  213                          vif->bss_conf.bssid);
  214         pos += scnprintf(buf+pos, bufsz-pos, "Load: %d\n",
  215                          mvm->tcm.result.load[mvmvif->id]);
  216         pos += scnprintf(buf+pos, bufsz-pos, "QoS:\n");
  217         for (i = 0; i < ARRAY_SIZE(mvmvif->queue_params); i++)
  218                 pos += scnprintf(buf+pos, bufsz-pos,
  219                                  "\t%d: txop:%d - cw_min:%d - cw_max = %d - aifs = %d upasd = %d\n",
  220                                  i, mvmvif->queue_params[i].txop,
  221                                  mvmvif->queue_params[i].cw_min,
  222                                  mvmvif->queue_params[i].cw_max,
  223                                  mvmvif->queue_params[i].aifs,
  224                                  mvmvif->queue_params[i].uapsd);
  225 
  226         if (vif->type == NL80211_IFTYPE_STATION &&
  227             ap_sta_id != IWL_MVM_INVALID_STA) {
  228                 struct iwl_mvm_sta *mvm_sta;
  229 
  230                 mvm_sta = iwl_mvm_sta_from_staid_protected(mvm, ap_sta_id);
  231                 if (mvm_sta) {
  232                         pos += scnprintf(buf+pos, bufsz-pos,
  233                                          "ap_sta_id %d - reduced Tx power %d\n",
  234                                          ap_sta_id,
  235                                          mvm_sta->bt_reduced_txpower);
  236                 }
  237         }
  238 
  239         rcu_read_lock();
  240         chanctx_conf = rcu_dereference(vif->bss_conf.chanctx_conf);
  241         if (chanctx_conf)
  242                 pos += scnprintf(buf+pos, bufsz-pos,
  243                                  "idle rx chains %d, active rx chains: %d\n",
  244                                  chanctx_conf->rx_chains_static,
  245                                  chanctx_conf->rx_chains_dynamic);
  246         rcu_read_unlock();
  247 
  248         mutex_unlock(&mvm->mutex);
  249 
  250         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
  251 }
  252 
  253 static void iwl_dbgfs_update_bf(struct ieee80211_vif *vif,
  254                                 enum iwl_dbgfs_bf_mask param, int value)
  255 {
  256         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
  257         struct iwl_dbgfs_bf *dbgfs_bf = &mvmvif->dbgfs_bf;
  258 
  259         dbgfs_bf->mask |= param;
  260 
  261         switch (param) {
  262         case MVM_DEBUGFS_BF_ENERGY_DELTA:
  263                 dbgfs_bf->bf_energy_delta = value;
  264                 break;
  265         case MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA:
  266                 dbgfs_bf->bf_roaming_energy_delta = value;
  267                 break;
  268         case MVM_DEBUGFS_BF_ROAMING_STATE:
  269                 dbgfs_bf->bf_roaming_state = value;
  270                 break;
  271         case MVM_DEBUGFS_BF_TEMP_THRESHOLD:
  272                 dbgfs_bf->bf_temp_threshold = value;
  273                 break;
  274         case MVM_DEBUGFS_BF_TEMP_FAST_FILTER:
  275                 dbgfs_bf->bf_temp_fast_filter = value;
  276                 break;
  277         case MVM_DEBUGFS_BF_TEMP_SLOW_FILTER:
  278                 dbgfs_bf->bf_temp_slow_filter = value;
  279                 break;
  280         case MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER:
  281                 dbgfs_bf->bf_enable_beacon_filter = value;
  282                 break;
  283         case MVM_DEBUGFS_BF_DEBUG_FLAG:
  284                 dbgfs_bf->bf_debug_flag = value;
  285                 break;
  286         case MVM_DEBUGFS_BF_ESCAPE_TIMER:
  287                 dbgfs_bf->bf_escape_timer = value;
  288                 break;
  289         case MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT:
  290                 dbgfs_bf->ba_enable_beacon_abort = value;
  291                 break;
  292         case MVM_DEBUGFS_BA_ESCAPE_TIMER:
  293                 dbgfs_bf->ba_escape_timer = value;
  294                 break;
  295         }
  296 }
  297 
  298 static ssize_t iwl_dbgfs_bf_params_write(struct ieee80211_vif *vif, char *buf,
  299                                          size_t count, loff_t *ppos)
  300 {
  301         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
  302         struct iwl_mvm *mvm = mvmvif->mvm;
  303         enum iwl_dbgfs_bf_mask param;
  304         int value, ret = 0;
  305 
  306         if (!strncmp("bf_energy_delta=", buf, 16)) {
  307                 if (sscanf(buf+16, "%d", &value) != 1)
  308                         return -EINVAL;
  309                 if (value < IWL_BF_ENERGY_DELTA_MIN ||
  310                     value > IWL_BF_ENERGY_DELTA_MAX)
  311                         return -EINVAL;
  312                 param = MVM_DEBUGFS_BF_ENERGY_DELTA;
  313         } else if (!strncmp("bf_roaming_energy_delta=", buf, 24)) {
  314                 if (sscanf(buf+24, "%d", &value) != 1)
  315                         return -EINVAL;
  316                 if (value < IWL_BF_ROAMING_ENERGY_DELTA_MIN ||
  317                     value > IWL_BF_ROAMING_ENERGY_DELTA_MAX)
  318                         return -EINVAL;
  319                 param = MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA;
  320         } else if (!strncmp("bf_roaming_state=", buf, 17)) {
  321                 if (sscanf(buf+17, "%d", &value) != 1)
  322                         return -EINVAL;
  323                 if (value < IWL_BF_ROAMING_STATE_MIN ||
  324                     value > IWL_BF_ROAMING_STATE_MAX)
  325                         return -EINVAL;
  326                 param = MVM_DEBUGFS_BF_ROAMING_STATE;
  327         } else if (!strncmp("bf_temp_threshold=", buf, 18)) {
  328                 if (sscanf(buf+18, "%d", &value) != 1)
  329                         return -EINVAL;
  330                 if (value < IWL_BF_TEMP_THRESHOLD_MIN ||
  331                     value > IWL_BF_TEMP_THRESHOLD_MAX)
  332                         return -EINVAL;
  333                 param = MVM_DEBUGFS_BF_TEMP_THRESHOLD;
  334         } else if (!strncmp("bf_temp_fast_filter=", buf, 20)) {
  335                 if (sscanf(buf+20, "%d", &value) != 1)
  336                         return -EINVAL;
  337                 if (value < IWL_BF_TEMP_FAST_FILTER_MIN ||
  338                     value > IWL_BF_TEMP_FAST_FILTER_MAX)
  339                         return -EINVAL;
  340                 param = MVM_DEBUGFS_BF_TEMP_FAST_FILTER;
  341         } else if (!strncmp("bf_temp_slow_filter=", buf, 20)) {
  342                 if (sscanf(buf+20, "%d", &value) != 1)
  343                         return -EINVAL;
  344                 if (value < IWL_BF_TEMP_SLOW_FILTER_MIN ||
  345                     value > IWL_BF_TEMP_SLOW_FILTER_MAX)
  346                         return -EINVAL;
  347                 param = MVM_DEBUGFS_BF_TEMP_SLOW_FILTER;
  348         } else if (!strncmp("bf_enable_beacon_filter=", buf, 24)) {
  349                 if (sscanf(buf+24, "%d", &value) != 1)
  350                         return -EINVAL;
  351                 if (value < 0 || value > 1)
  352                         return -EINVAL;
  353                 param = MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER;
  354         } else if (!strncmp("bf_debug_flag=", buf, 14)) {
  355                 if (sscanf(buf+14, "%d", &value) != 1)
  356                         return -EINVAL;
  357                 if (value < 0 || value > 1)
  358                         return -EINVAL;
  359                 param = MVM_DEBUGFS_BF_DEBUG_FLAG;
  360         } else if (!strncmp("bf_escape_timer=", buf, 16)) {
  361                 if (sscanf(buf+16, "%d", &value) != 1)
  362                         return -EINVAL;
  363                 if (value < IWL_BF_ESCAPE_TIMER_MIN ||
  364                     value > IWL_BF_ESCAPE_TIMER_MAX)
  365                         return -EINVAL;
  366                 param = MVM_DEBUGFS_BF_ESCAPE_TIMER;
  367         } else if (!strncmp("ba_escape_timer=", buf, 16)) {
  368                 if (sscanf(buf+16, "%d", &value) != 1)
  369                         return -EINVAL;
  370                 if (value < IWL_BA_ESCAPE_TIMER_MIN ||
  371                     value > IWL_BA_ESCAPE_TIMER_MAX)
  372                         return -EINVAL;
  373                 param = MVM_DEBUGFS_BA_ESCAPE_TIMER;
  374         } else if (!strncmp("ba_enable_beacon_abort=", buf, 23)) {
  375                 if (sscanf(buf+23, "%d", &value) != 1)
  376                         return -EINVAL;
  377                 if (value < 0 || value > 1)
  378                         return -EINVAL;
  379                 param = MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT;
  380         } else {
  381                 return -EINVAL;
  382         }
  383 
  384         mutex_lock(&mvm->mutex);
  385         iwl_dbgfs_update_bf(vif, param, value);
  386         if (param == MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER && !value)
  387                 ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0);
  388         else
  389                 ret = iwl_mvm_enable_beacon_filter(mvm, vif, 0);
  390         mutex_unlock(&mvm->mutex);
  391 
  392         return ret ?: count;
  393 }
  394 
  395 static ssize_t iwl_dbgfs_bf_params_read(struct file *file,
  396                                         char __user *user_buf,
  397                                         size_t count, loff_t *ppos)
  398 {
  399         struct ieee80211_vif *vif = file->private_data;
  400         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
  401         char buf[256];
  402         int pos = 0;
  403         const size_t bufsz = sizeof(buf);
  404         struct iwl_beacon_filter_cmd cmd = {
  405                 IWL_BF_CMD_CONFIG_DEFAULTS,
  406                 .bf_enable_beacon_filter =
  407                         cpu_to_le32(IWL_BF_ENABLE_BEACON_FILTER_DEFAULT),
  408                 .ba_enable_beacon_abort =
  409                         cpu_to_le32(IWL_BA_ENABLE_BEACON_ABORT_DEFAULT),
  410         };
  411 
  412         iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd);
  413         if (mvmvif->bf_data.bf_enabled)
  414                 cmd.bf_enable_beacon_filter = cpu_to_le32(1);
  415         else
  416                 cmd.bf_enable_beacon_filter = 0;
  417 
  418         pos += scnprintf(buf+pos, bufsz-pos, "bf_energy_delta = %d\n",
  419                          le32_to_cpu(cmd.bf_energy_delta));
  420         pos += scnprintf(buf+pos, bufsz-pos, "bf_roaming_energy_delta = %d\n",
  421                          le32_to_cpu(cmd.bf_roaming_energy_delta));
  422         pos += scnprintf(buf+pos, bufsz-pos, "bf_roaming_state = %d\n",
  423                          le32_to_cpu(cmd.bf_roaming_state));
  424         pos += scnprintf(buf+pos, bufsz-pos, "bf_temp_threshold = %d\n",
  425                          le32_to_cpu(cmd.bf_temp_threshold));
  426         pos += scnprintf(buf+pos, bufsz-pos, "bf_temp_fast_filter = %d\n",
  427                          le32_to_cpu(cmd.bf_temp_fast_filter));
  428         pos += scnprintf(buf+pos, bufsz-pos, "bf_temp_slow_filter = %d\n",
  429                          le32_to_cpu(cmd.bf_temp_slow_filter));
  430         pos += scnprintf(buf+pos, bufsz-pos, "bf_enable_beacon_filter = %d\n",
  431                          le32_to_cpu(cmd.bf_enable_beacon_filter));
  432         pos += scnprintf(buf+pos, bufsz-pos, "bf_debug_flag = %d\n",
  433                          le32_to_cpu(cmd.bf_debug_flag));
  434         pos += scnprintf(buf+pos, bufsz-pos, "bf_escape_timer = %d\n",
  435                          le32_to_cpu(cmd.bf_escape_timer));
  436         pos += scnprintf(buf+pos, bufsz-pos, "ba_escape_timer = %d\n",
  437                          le32_to_cpu(cmd.ba_escape_timer));
  438         pos += scnprintf(buf+pos, bufsz-pos, "ba_enable_beacon_abort = %d\n",
  439                          le32_to_cpu(cmd.ba_enable_beacon_abort));
  440 
  441         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
  442 }
  443 
  444 #if defined(__linux__)
  445 static inline char *iwl_dbgfs_is_match(char *name, char *buf)
  446 {
  447         int len = strlen(name);
  448 
  449         return !strncmp(name, buf, len) ? buf + len : NULL;
  450 }
  451 #endif
  452 
  453 static ssize_t iwl_dbgfs_os_device_timediff_read(struct file *file,
  454                                                  char __user *user_buf,
  455                                                  size_t count, loff_t *ppos)
  456 {
  457         struct ieee80211_vif *vif = file->private_data;
  458         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
  459         struct iwl_mvm *mvm = mvmvif->mvm;
  460         u32 curr_gp2;
  461         u64 curr_os;
  462         s64 diff;
  463         char buf[64];
  464         const size_t bufsz = sizeof(buf);
  465         int pos = 0;
  466 
  467         mutex_lock(&mvm->mutex);
  468         iwl_mvm_get_sync_time(mvm, CLOCK_BOOTTIME, &curr_gp2, &curr_os, NULL);
  469         mutex_unlock(&mvm->mutex);
  470 
  471         do_div(curr_os, NSEC_PER_USEC);
  472         diff = curr_os - curr_gp2;
  473         pos += scnprintf(buf + pos, bufsz - pos, "diff=%lld\n", diff);
  474 
  475         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
  476 }
  477 
  478 static ssize_t iwl_dbgfs_low_latency_write(struct ieee80211_vif *vif, char *buf,
  479                                            size_t count, loff_t *ppos)
  480 {
  481         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
  482         struct iwl_mvm *mvm = mvmvif->mvm;
  483         u8 value;
  484         int ret;
  485 
  486         ret = kstrtou8(buf, 0, &value);
  487         if (ret)
  488                 return ret;
  489         if (value > 1)
  490                 return -EINVAL;
  491 
  492         mutex_lock(&mvm->mutex);
  493         iwl_mvm_update_low_latency(mvm, vif, value, LOW_LATENCY_DEBUGFS);
  494         mutex_unlock(&mvm->mutex);
  495 
  496         return count;
  497 }
  498 
  499 static ssize_t
  500 iwl_dbgfs_low_latency_force_write(struct ieee80211_vif *vif, char *buf,
  501                                   size_t count, loff_t *ppos)
  502 {
  503         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
  504         struct iwl_mvm *mvm = mvmvif->mvm;
  505         u8 value;
  506         int ret;
  507 
  508         ret = kstrtou8(buf, 0, &value);
  509         if (ret)
  510                 return ret;
  511 
  512         if (value > NUM_LOW_LATENCY_FORCE)
  513                 return -EINVAL;
  514 
  515         mutex_lock(&mvm->mutex);
  516         if (value == LOW_LATENCY_FORCE_UNSET) {
  517                 iwl_mvm_update_low_latency(mvm, vif, false,
  518                                            LOW_LATENCY_DEBUGFS_FORCE);
  519                 iwl_mvm_update_low_latency(mvm, vif, false,
  520                                            LOW_LATENCY_DEBUGFS_FORCE_ENABLE);
  521         } else {
  522                 iwl_mvm_update_low_latency(mvm, vif,
  523                                            value == LOW_LATENCY_FORCE_ON,
  524                                            LOW_LATENCY_DEBUGFS_FORCE);
  525                 iwl_mvm_update_low_latency(mvm, vif, true,
  526                                            LOW_LATENCY_DEBUGFS_FORCE_ENABLE);
  527         }
  528         mutex_unlock(&mvm->mutex);
  529         return count;
  530 }
  531 
  532 static ssize_t iwl_dbgfs_low_latency_read(struct file *file,
  533                                           char __user *user_buf,
  534                                           size_t count, loff_t *ppos)
  535 {
  536         struct ieee80211_vif *vif = file->private_data;
  537         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
  538         char format[] = "traffic=%d\ndbgfs=%d\nvcmd=%d\nvif_type=%d\n"
  539                         "dbgfs_force_enable=%d\ndbgfs_force=%d\nactual=%d\n";
  540 
  541         /*
  542          * all values in format are boolean so the size of format is enough
  543          * for holding the result string
  544          */
  545         char buf[sizeof(format) + 1] = {};
  546         int len;
  547 
  548         len = scnprintf(buf, sizeof(buf) - 1, format,
  549                         !!(mvmvif->low_latency & LOW_LATENCY_TRAFFIC),
  550                         !!(mvmvif->low_latency & LOW_LATENCY_DEBUGFS),
  551                         !!(mvmvif->low_latency & LOW_LATENCY_VCMD),
  552                         !!(mvmvif->low_latency & LOW_LATENCY_VIF_TYPE),
  553                         !!(mvmvif->low_latency &
  554                            LOW_LATENCY_DEBUGFS_FORCE_ENABLE),
  555                         !!(mvmvif->low_latency & LOW_LATENCY_DEBUGFS_FORCE),
  556                         !!(mvmvif->low_latency_actual));
  557         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
  558 }
  559 
  560 static ssize_t iwl_dbgfs_uapsd_misbehaving_read(struct file *file,
  561                                                 char __user *user_buf,
  562                                                 size_t count, loff_t *ppos)
  563 {
  564         struct ieee80211_vif *vif = file->private_data;
  565         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
  566         char buf[20];
  567         int len;
  568 
  569 #if defined(__linux__)
  570         len = sprintf(buf, "%pM\n", mvmvif->uapsd_misbehaving_bssid);
  571 #elif defined(__FreeBSD__)
  572         len = sprintf(buf, "%6D\n", mvmvif->uapsd_misbehaving_bssid, ":");
  573 #endif
  574         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
  575 }
  576 
  577 static ssize_t iwl_dbgfs_uapsd_misbehaving_write(struct ieee80211_vif *vif,
  578                                                  char *buf, size_t count,
  579                                                  loff_t *ppos)
  580 {
  581         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
  582         struct iwl_mvm *mvm = mvmvif->mvm;
  583         bool ret;
  584 
  585         mutex_lock(&mvm->mutex);
  586         ret = mac_pton(buf, mvmvif->uapsd_misbehaving_bssid);
  587         mutex_unlock(&mvm->mutex);
  588 
  589         return ret ? count : -EINVAL;
  590 }
  591 
  592 static ssize_t iwl_dbgfs_rx_phyinfo_write(struct ieee80211_vif *vif, char *buf,
  593                                           size_t count, loff_t *ppos)
  594 {
  595         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
  596         struct iwl_mvm *mvm = mvmvif->mvm;
  597         struct ieee80211_chanctx_conf *chanctx_conf;
  598         struct iwl_mvm_phy_ctxt *phy_ctxt;
  599         u16 value;
  600         int ret;
  601 
  602         ret = kstrtou16(buf, 0, &value);
  603         if (ret)
  604                 return ret;
  605 
  606         mutex_lock(&mvm->mutex);
  607         rcu_read_lock();
  608 
  609         chanctx_conf = rcu_dereference(vif->bss_conf.chanctx_conf);
  610         /* make sure the channel context is assigned */
  611         if (!chanctx_conf) {
  612                 rcu_read_unlock();
  613                 mutex_unlock(&mvm->mutex);
  614                 return -EINVAL;
  615         }
  616 
  617         phy_ctxt = &mvm->phy_ctxts[*(u16 *)chanctx_conf->drv_priv];
  618         rcu_read_unlock();
  619 
  620         mvm->dbgfs_rx_phyinfo = value;
  621 
  622         ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &chanctx_conf->min_def,
  623                                        chanctx_conf->rx_chains_static,
  624                                        chanctx_conf->rx_chains_dynamic);
  625         mutex_unlock(&mvm->mutex);
  626 
  627         return ret ?: count;
  628 }
  629 
  630 static ssize_t iwl_dbgfs_rx_phyinfo_read(struct file *file,
  631                                          char __user *user_buf,
  632                                          size_t count, loff_t *ppos)
  633 {
  634         struct ieee80211_vif *vif = file->private_data;
  635         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
  636         char buf[8];
  637         int len;
  638 
  639         len = scnprintf(buf, sizeof(buf), "0x%04x\n",
  640                         mvmvif->mvm->dbgfs_rx_phyinfo);
  641 
  642         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
  643 }
  644 
  645 static void iwl_dbgfs_quota_check(void *data, u8 *mac,
  646                                   struct ieee80211_vif *vif)
  647 {
  648         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
  649         int *ret = data;
  650 
  651         if (mvmvif->dbgfs_quota_min)
  652                 *ret = -EINVAL;
  653 }
  654 
  655 static ssize_t iwl_dbgfs_quota_min_write(struct ieee80211_vif *vif, char *buf,
  656                                          size_t count, loff_t *ppos)
  657 {
  658         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
  659         struct iwl_mvm *mvm = mvmvif->mvm;
  660         u16 value;
  661         int ret;
  662 
  663         ret = kstrtou16(buf, 0, &value);
  664         if (ret)
  665                 return ret;
  666 
  667         if (value > 95)
  668                 return -EINVAL;
  669 
  670         mutex_lock(&mvm->mutex);
  671 
  672         mvmvif->dbgfs_quota_min = 0;
  673         ieee80211_iterate_interfaces(mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
  674                                      iwl_dbgfs_quota_check, &ret);
  675         if (ret == 0) {
  676                 mvmvif->dbgfs_quota_min = value;
  677                 iwl_mvm_update_quotas(mvm, false, NULL);
  678         }
  679         mutex_unlock(&mvm->mutex);
  680 
  681         return ret ?: count;
  682 }
  683 
  684 static ssize_t iwl_dbgfs_quota_min_read(struct file *file,
  685                                         char __user *user_buf,
  686                                         size_t count, loff_t *ppos)
  687 {
  688         struct ieee80211_vif *vif = file->private_data;
  689         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
  690         char buf[10];
  691         int len;
  692 
  693         len = scnprintf(buf, sizeof(buf), "%d\n", mvmvif->dbgfs_quota_min);
  694 
  695         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
  696 }
  697 
  698 #define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \
  699         _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct ieee80211_vif)
  700 #define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
  701         _MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct ieee80211_vif)
  702 #define MVM_DEBUGFS_ADD_FILE_VIF(name, parent, mode) do {               \
  703                 debugfs_create_file(#name, mode, parent, vif,           \
  704                                     &iwl_dbgfs_##name##_ops);           \
  705         } while (0)
  706 
  707 MVM_DEBUGFS_READ_FILE_OPS(mac_params);
  708 MVM_DEBUGFS_READ_FILE_OPS(tx_pwr_lmt);
  709 MVM_DEBUGFS_READ_WRITE_FILE_OPS(pm_params, 32);
  710 MVM_DEBUGFS_READ_WRITE_FILE_OPS(bf_params, 256);
  711 MVM_DEBUGFS_READ_WRITE_FILE_OPS(low_latency, 10);
  712 MVM_DEBUGFS_WRITE_FILE_OPS(low_latency_force, 10);
  713 MVM_DEBUGFS_READ_WRITE_FILE_OPS(uapsd_misbehaving, 20);
  714 MVM_DEBUGFS_READ_WRITE_FILE_OPS(rx_phyinfo, 10);
  715 MVM_DEBUGFS_READ_WRITE_FILE_OPS(quota_min, 32);
  716 MVM_DEBUGFS_READ_FILE_OPS(os_device_timediff);
  717 
  718 
  719 void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
  720 {
  721         struct dentry *dbgfs_dir = vif->debugfs_dir;
  722         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
  723 #if defined(__linux__)
  724         char buf[100];
  725 #endif
  726 
  727         /*
  728          * Check if debugfs directory already exist before creating it.
  729          * This may happen when, for example, resetting hw or suspend-resume
  730          */
  731         if (!dbgfs_dir || mvmvif->dbgfs_dir)
  732                 return;
  733 
  734         mvmvif->dbgfs_dir = debugfs_create_dir("iwlmvm", dbgfs_dir);
  735         if (IS_ERR_OR_NULL(mvmvif->dbgfs_dir)) {
  736                 IWL_ERR(mvm, "Failed to create debugfs directory under %pd\n",
  737                         dbgfs_dir);
  738                 return;
  739         }
  740 
  741         if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM &&
  742             ((vif->type == NL80211_IFTYPE_STATION && !vif->p2p) ||
  743              (vif->type == NL80211_IFTYPE_STATION && vif->p2p)))
  744                 MVM_DEBUGFS_ADD_FILE_VIF(pm_params, mvmvif->dbgfs_dir, 0600);
  745 
  746         MVM_DEBUGFS_ADD_FILE_VIF(tx_pwr_lmt, mvmvif->dbgfs_dir, 0400);
  747         MVM_DEBUGFS_ADD_FILE_VIF(mac_params, mvmvif->dbgfs_dir, 0400);
  748         MVM_DEBUGFS_ADD_FILE_VIF(low_latency, mvmvif->dbgfs_dir, 0600);
  749         MVM_DEBUGFS_ADD_FILE_VIF(low_latency_force, mvmvif->dbgfs_dir, 0600);
  750         MVM_DEBUGFS_ADD_FILE_VIF(uapsd_misbehaving, mvmvif->dbgfs_dir, 0600);
  751         MVM_DEBUGFS_ADD_FILE_VIF(rx_phyinfo, mvmvif->dbgfs_dir, 0600);
  752         MVM_DEBUGFS_ADD_FILE_VIF(quota_min, mvmvif->dbgfs_dir, 0600);
  753         MVM_DEBUGFS_ADD_FILE_VIF(os_device_timediff, mvmvif->dbgfs_dir, 0400);
  754 
  755         if (vif->type == NL80211_IFTYPE_STATION && !vif->p2p &&
  756             mvmvif == mvm->bf_allowed_vif)
  757                 MVM_DEBUGFS_ADD_FILE_VIF(bf_params, mvmvif->dbgfs_dir, 0600);
  758 
  759 #if defined(__linux__)
  760         /*
  761          * Create symlink for convenience pointing to interface specific
  762          * debugfs entries for the driver. For example, under
  763          * /sys/kernel/debug/iwlwifi/0000\:02\:00.0/iwlmvm/
  764          * find
  765          * netdev:wlan0 -> ../../../ieee80211/phy0/netdev:wlan0/iwlmvm/
  766          */
  767         snprintf(buf, 100, "../../../%pd3/%pd",
  768                  dbgfs_dir,
  769                  mvmvif->dbgfs_dir);
  770 
  771         mvmvif->dbgfs_slink = debugfs_create_symlink(dbgfs_dir->d_name.name,
  772                                                      mvm->debugfs_dir, buf);
  773 #endif
  774 }
  775 
  776 void iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
  777 {
  778         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
  779 
  780         debugfs_remove(mvmvif->dbgfs_slink);
  781         mvmvif->dbgfs_slink = NULL;
  782 
  783         debugfs_remove_recursive(mvmvif->dbgfs_dir);
  784         mvmvif->dbgfs_dir = NULL;
  785 }

Cache object: 79e159276692bc7b299cf78a4ada597e


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.