linux/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * This file is provided under a dual BSD/GPLv2 license.  When using or
   4 * redistributing this file, you may do so under either license.
   5 *
   6 * GPL LICENSE SUMMARY
   7 *
   8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
   9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
  11 * Copyright(c) 2018 - 2019 Intel Corporation
  12 *
  13 * This program is free software; you can redistribute it and/or modify
  14 * it under the terms of version 2 of the GNU General Public License as
  15 * published by the Free Software Foundation.
  16 *
  17 * This program is distributed in the hope that it will be useful, but
  18 * WITHOUT ANY WARRANTY; without even the implied warranty of
  19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  20 * General Public License for more details.
  21 *
  22 * The full GNU General Public License is included in this distribution
  23 * in the file called COPYING.
  24 *
  25 * Contact Information:
  26 *  Intel Linux Wireless <linuxwifi@intel.com>
  27 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  28 *
  29 * BSD LICENSE
  30 *
  31 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
  34 * Copyright(c) 2018 - 2019 Intel Corporation
  35 * All rights reserved.
  36 *
  37 * Redistribution and use in source and binary forms, with or without
  38 * modification, are permitted provided that the following conditions
  39 * are met:
  40 *
  41 *  * Redistributions of source code must retain the above copyright
  42 *    notice, this list of conditions and the following disclaimer.
  43 *  * Redistributions in binary form must reproduce the above copyright
  44 *    notice, this list of conditions and the following disclaimer in
  45 *    the documentation and/or other materials provided with the
  46 *    distribution.
  47 *  * Neither the name Intel Corporation nor the names of its
  48 *    contributors may be used to endorse or promote products derived
  49 *    from this software without specific prior written permission.
  50 *
  51 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  52 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  53 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  54 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  55 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  56 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  57 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  58 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  59 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  60 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  61 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  62 *
  63 *****************************************************************************/
  64#include <linux/vmalloc.h>
  65#include <linux/ieee80211.h>
  66#include <linux/netdevice.h>
  67
  68#include "mvm.h"
  69#include "sta.h"
  70#include "iwl-io.h"
  71#include "debugfs.h"
  72#include "iwl-modparams.h"
  73#include "fw/error-dump.h"
  74
  75static ssize_t iwl_dbgfs_ctdp_budget_read(struct file *file,
  76                                          char __user *user_buf,
  77                                          size_t count, loff_t *ppos)
  78{
  79        struct iwl_mvm *mvm = file->private_data;
  80        char buf[16];
  81        int pos, budget;
  82
  83        if (!iwl_mvm_is_ctdp_supported(mvm))
  84                return -EOPNOTSUPP;
  85
  86        if (!iwl_mvm_firmware_running(mvm) ||
  87            mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR)
  88                return -EIO;
  89
  90        mutex_lock(&mvm->mutex);
  91        budget = iwl_mvm_ctdp_command(mvm, CTDP_CMD_OPERATION_REPORT, 0);
  92        mutex_unlock(&mvm->mutex);
  93
  94        if (budget < 0)
  95                return budget;
  96
  97        pos = scnprintf(buf, sizeof(buf), "%d\n", budget);
  98
  99        return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 100}
 101
 102static ssize_t iwl_dbgfs_stop_ctdp_write(struct iwl_mvm *mvm, char *buf,
 103                                         size_t count, loff_t *ppos)
 104{
 105        int ret;
 106
 107        if (!iwl_mvm_is_ctdp_supported(mvm))
 108                return -EOPNOTSUPP;
 109
 110        if (!iwl_mvm_firmware_running(mvm) ||
 111            mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR)
 112                return -EIO;
 113
 114        mutex_lock(&mvm->mutex);
 115        ret = iwl_mvm_ctdp_command(mvm, CTDP_CMD_OPERATION_STOP, 0);
 116        mutex_unlock(&mvm->mutex);
 117
 118        return ret ?: count;
 119}
 120
 121static ssize_t iwl_dbgfs_force_ctkill_write(struct iwl_mvm *mvm, char *buf,
 122                                            size_t count, loff_t *ppos)
 123{
 124        if (!iwl_mvm_firmware_running(mvm) ||
 125            mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR)
 126                return -EIO;
 127
 128        iwl_mvm_enter_ctkill(mvm);
 129
 130        return count;
 131}
 132
 133static ssize_t iwl_dbgfs_tx_flush_write(struct iwl_mvm *mvm, char *buf,
 134                                        size_t count, loff_t *ppos)
 135{
 136        int ret;
 137        u32 flush_arg;
 138
 139        if (!iwl_mvm_firmware_running(mvm) ||
 140            mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR)
 141                return -EIO;
 142
 143        if (kstrtou32(buf, 0, &flush_arg))
 144                return -EINVAL;
 145
 146        if (iwl_mvm_has_new_tx_api(mvm)) {
 147                IWL_DEBUG_TX_QUEUES(mvm,
 148                                    "FLUSHING all tids queues on sta_id = %d\n",
 149                                    flush_arg);
 150                mutex_lock(&mvm->mutex);
 151                ret = iwl_mvm_flush_sta_tids(mvm, flush_arg, 0xFF, 0) ? : count;
 152                mutex_unlock(&mvm->mutex);
 153                return ret;
 154        }
 155
 156        IWL_DEBUG_TX_QUEUES(mvm, "FLUSHING queues mask to flush = 0x%x\n",
 157                            flush_arg);
 158
 159        mutex_lock(&mvm->mutex);
 160        ret =  iwl_mvm_flush_tx_path(mvm, flush_arg, 0) ? : count;
 161        mutex_unlock(&mvm->mutex);
 162
 163        return ret;
 164}
 165
 166static ssize_t iwl_dbgfs_sta_drain_write(struct iwl_mvm *mvm, char *buf,
 167                                         size_t count, loff_t *ppos)
 168{
 169        struct iwl_mvm_sta *mvmsta;
 170        int sta_id, drain, ret;
 171
 172        if (!iwl_mvm_firmware_running(mvm) ||
 173            mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR)
 174                return -EIO;
 175
 176        if (sscanf(buf, "%d %d", &sta_id, &drain) != 2)
 177                return -EINVAL;
 178        if (sta_id < 0 || sta_id >= IWL_MVM_STATION_COUNT)
 179                return -EINVAL;
 180        if (drain < 0 || drain > 1)
 181                return -EINVAL;
 182
 183        mutex_lock(&mvm->mutex);
 184
 185        mvmsta = iwl_mvm_sta_from_staid_protected(mvm, sta_id);
 186
 187        if (!mvmsta)
 188                ret = -ENOENT;
 189        else
 190                ret = iwl_mvm_drain_sta(mvm, mvmsta, drain) ? : count;
 191
 192        mutex_unlock(&mvm->mutex);
 193
 194        return ret;
 195}
 196
 197static ssize_t iwl_dbgfs_sram_read(struct file *file, char __user *user_buf,
 198                                   size_t count, loff_t *ppos)
 199{
 200        struct iwl_mvm *mvm = file->private_data;
 201        const struct fw_img *img;
 202        unsigned int ofs, len;
 203        size_t ret;
 204        u8 *ptr;
 205
 206        if (!iwl_mvm_firmware_running(mvm))
 207                return -EINVAL;
 208
 209        /* default is to dump the entire data segment */
 210        img = &mvm->fw->img[mvm->fwrt.cur_fw_img];
 211        ofs = img->sec[IWL_UCODE_SECTION_DATA].offset;
 212        len = img->sec[IWL_UCODE_SECTION_DATA].len;
 213
 214        if (mvm->dbgfs_sram_len) {
 215                ofs = mvm->dbgfs_sram_offset;
 216                len = mvm->dbgfs_sram_len;
 217        }
 218
 219        ptr = kzalloc(len, GFP_KERNEL);
 220        if (!ptr)
 221                return -ENOMEM;
 222
 223        iwl_trans_read_mem_bytes(mvm->trans, ofs, ptr, len);
 224
 225        ret = simple_read_from_buffer(user_buf, count, ppos, ptr, len);
 226
 227        kfree(ptr);
 228
 229        return ret;
 230}
 231
 232static ssize_t iwl_dbgfs_sram_write(struct iwl_mvm *mvm, char *buf,
 233                                    size_t count, loff_t *ppos)
 234{
 235        const struct fw_img *img;
 236        u32 offset, len;
 237        u32 img_offset, img_len;
 238
 239        if (!iwl_mvm_firmware_running(mvm))
 240                return -EINVAL;
 241
 242        img = &mvm->fw->img[mvm->fwrt.cur_fw_img];
 243        img_offset = img->sec[IWL_UCODE_SECTION_DATA].offset;
 244        img_len = img->sec[IWL_UCODE_SECTION_DATA].len;
 245
 246        if (sscanf(buf, "%x,%x", &offset, &len) == 2) {
 247                if ((offset & 0x3) || (len & 0x3))
 248                        return -EINVAL;
 249
 250                if (offset + len > img_offset + img_len)
 251                        return -EINVAL;
 252
 253                mvm->dbgfs_sram_offset = offset;
 254                mvm->dbgfs_sram_len = len;
 255        } else {
 256                mvm->dbgfs_sram_offset = 0;
 257                mvm->dbgfs_sram_len = 0;
 258        }
 259
 260        return count;
 261}
 262
 263static ssize_t iwl_dbgfs_set_nic_temperature_read(struct file *file,
 264                                                  char __user *user_buf,
 265                                                  size_t count, loff_t *ppos)
 266{
 267        struct iwl_mvm *mvm = file->private_data;
 268        char buf[16];
 269        int pos;
 270
 271        if (!mvm->temperature_test)
 272                pos = scnprintf(buf , sizeof(buf), "disabled\n");
 273        else
 274                pos = scnprintf(buf , sizeof(buf), "%d\n", mvm->temperature);
 275
 276        return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 277}
 278
 279/*
 280 * Set NIC Temperature
 281 * Cause the driver to ignore the actual NIC temperature reported by the FW
 282 * Enable: any value between IWL_MVM_DEBUG_SET_TEMPERATURE_MIN -
 283 * IWL_MVM_DEBUG_SET_TEMPERATURE_MAX
 284 * Disable: IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE
 285 */
 286static ssize_t iwl_dbgfs_set_nic_temperature_write(struct iwl_mvm *mvm,
 287                                                   char *buf, size_t count,
 288                                                   loff_t *ppos)
 289{
 290        int temperature;
 291
 292        if (!iwl_mvm_firmware_running(mvm) && !mvm->temperature_test)
 293                return -EIO;
 294
 295        if (kstrtoint(buf, 10, &temperature))
 296                return -EINVAL;
 297        /* not a legal temperature */
 298        if ((temperature > IWL_MVM_DEBUG_SET_TEMPERATURE_MAX &&
 299             temperature != IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE) ||
 300            temperature < IWL_MVM_DEBUG_SET_TEMPERATURE_MIN)
 301                return -EINVAL;
 302
 303        mutex_lock(&mvm->mutex);
 304        if (temperature == IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE) {
 305                if (!mvm->temperature_test)
 306                        goto out;
 307
 308                mvm->temperature_test = false;
 309                /* Since we can't read the temp while awake, just set
 310                 * it to zero until we get the next RX stats from the
 311                 * firmware.
 312                 */
 313                mvm->temperature = 0;
 314        } else {
 315                mvm->temperature_test = true;
 316                mvm->temperature = temperature;
 317        }
 318        IWL_DEBUG_TEMP(mvm, "%sabling debug set temperature (temp = %d)\n",
 319                       mvm->temperature_test ? "En" : "Dis" ,
 320                       mvm->temperature);
 321        /* handle the temperature change */
 322        iwl_mvm_tt_handler(mvm);
 323
 324out:
 325        mutex_unlock(&mvm->mutex);
 326
 327        return count;
 328}
 329
 330static ssize_t iwl_dbgfs_nic_temp_read(struct file *file,
 331                                       char __user *user_buf,
 332                                       size_t count, loff_t *ppos)
 333{
 334        struct iwl_mvm *mvm = file->private_data;
 335        char buf[16];
 336        int pos, ret;
 337        s32 temp;
 338
 339        if (!iwl_mvm_firmware_running(mvm))
 340                return -EIO;
 341
 342        mutex_lock(&mvm->mutex);
 343        ret = iwl_mvm_get_temp(mvm, &temp);
 344        mutex_unlock(&mvm->mutex);
 345
 346        if (ret)
 347                return -EIO;
 348
 349        pos = scnprintf(buf , sizeof(buf), "%d\n", temp);
 350
 351        return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 352}
 353
 354#ifdef CONFIG_ACPI
 355static ssize_t iwl_dbgfs_sar_geo_profile_read(struct file *file,
 356                                              char __user *user_buf,
 357                                              size_t count, loff_t *ppos)
 358{
 359        struct iwl_mvm *mvm = file->private_data;
 360        char buf[256];
 361        int pos = 0;
 362        int bufsz = sizeof(buf);
 363        int tbl_idx;
 364        u8 *value;
 365
 366        if (!iwl_mvm_firmware_running(mvm))
 367                return -EIO;
 368
 369        mutex_lock(&mvm->mutex);
 370        tbl_idx = iwl_mvm_get_sar_geo_profile(mvm);
 371        if (tbl_idx < 0) {
 372                mutex_unlock(&mvm->mutex);
 373                return tbl_idx;
 374        }
 375
 376        if (!tbl_idx) {
 377                pos = scnprintf(buf, bufsz,
 378                                "SAR geographic profile disabled\n");
 379        } else {
 380                value = &mvm->geo_profiles[tbl_idx - 1].values[0];
 381
 382                pos += scnprintf(buf + pos, bufsz - pos,
 383                                 "Use geographic profile %d\n", tbl_idx);
 384                pos += scnprintf(buf + pos, bufsz - pos,
 385                                 "2.4GHz:\n\tChain A offset: %hhd dBm\n\tChain B offset: %hhd dBm\n\tmax tx power: %hhd dBm\n",
 386                                 value[1], value[2], value[0]);
 387                pos += scnprintf(buf + pos, bufsz - pos,
 388                                 "5.2GHz:\n\tChain A offset: %hhd dBm\n\tChain B offset: %hhd dBm\n\tmax tx power: %hhd dBm\n",
 389                                 value[4], value[5], value[3]);
 390        }
 391        mutex_unlock(&mvm->mutex);
 392
 393        return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 394}
 395#endif
 396
 397static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
 398                                       size_t count, loff_t *ppos)
 399{
 400        struct iwl_mvm *mvm = file->private_data;
 401        struct ieee80211_sta *sta;
 402        char buf[400];
 403        int i, pos = 0, bufsz = sizeof(buf);
 404
 405        mutex_lock(&mvm->mutex);
 406
 407        for (i = 0; i < ARRAY_SIZE(mvm->fw_id_to_mac_id); i++) {
 408                pos += scnprintf(buf + pos, bufsz - pos, "%.2d: ", i);
 409                sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
 410                                                lockdep_is_held(&mvm->mutex));
 411                if (!sta)
 412                        pos += scnprintf(buf + pos, bufsz - pos, "N/A\n");
 413                else if (IS_ERR(sta))
 414                        pos += scnprintf(buf + pos, bufsz - pos, "%ld\n",
 415                                         PTR_ERR(sta));
 416                else
 417                        pos += scnprintf(buf + pos, bufsz - pos, "%pM\n",
 418                                         sta->addr);
 419        }
 420
 421        mutex_unlock(&mvm->mutex);
 422
 423        return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 424}
 425
 426static ssize_t iwl_dbgfs_rs_data_read(struct file *file, char __user *user_buf,
 427                                      size_t count, loff_t *ppos)
 428{
 429        struct ieee80211_sta *sta = file->private_data;
 430        struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
 431        struct iwl_lq_sta_rs_fw *lq_sta = &mvmsta->lq_sta.rs_fw;
 432        struct iwl_mvm *mvm = lq_sta->pers.drv;
 433        static const size_t bufsz = 2048;
 434        char *buff;
 435        int desc = 0;
 436        ssize_t ret;
 437
 438        buff = kmalloc(bufsz, GFP_KERNEL);
 439        if (!buff)
 440                return -ENOMEM;
 441
 442        mutex_lock(&mvm->mutex);
 443
 444        desc += scnprintf(buff + desc, bufsz - desc, "sta_id %d\n",
 445                          lq_sta->pers.sta_id);
 446        desc += scnprintf(buff + desc, bufsz - desc,
 447                          "fixed rate 0x%X\n",
 448                          lq_sta->pers.dbg_fixed_rate);
 449        desc += scnprintf(buff + desc, bufsz - desc,
 450                          "A-MPDU size limit %d\n",
 451                          lq_sta->pers.dbg_agg_frame_count_lim);
 452        desc += scnprintf(buff + desc, bufsz - desc,
 453                          "valid_tx_ant %s%s%s\n",
 454                (iwl_mvm_get_valid_tx_ant(mvm) & ANT_A) ? "ANT_A," : "",
 455                (iwl_mvm_get_valid_tx_ant(mvm) & ANT_B) ? "ANT_B," : "",
 456                (iwl_mvm_get_valid_tx_ant(mvm) & ANT_C) ? "ANT_C" : "");
 457        desc += scnprintf(buff + desc, bufsz - desc,
 458                          "last tx rate=0x%X ",
 459                          lq_sta->last_rate_n_flags);
 460
 461        desc += rs_pretty_print_rate(buff + desc, bufsz - desc,
 462                                     lq_sta->last_rate_n_flags);
 463        mutex_unlock(&mvm->mutex);
 464
 465        ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
 466        kfree(buff);
 467        return ret;
 468}
 469
 470static ssize_t iwl_dbgfs_amsdu_len_write(struct ieee80211_sta *sta,
 471                                         char *buf, size_t count,
 472                                         loff_t *ppos)
 473{
 474        struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
 475        int i;
 476        u16 amsdu_len;
 477
 478        if (kstrtou16(buf, 0, &amsdu_len))
 479                return -EINVAL;
 480
 481        if (amsdu_len) {
 482                mvmsta->orig_amsdu_len = sta->max_amsdu_len;
 483                sta->max_amsdu_len = amsdu_len;
 484                for (i = 0; i < ARRAY_SIZE(sta->max_tid_amsdu_len); i++)
 485                        sta->max_tid_amsdu_len[i] = amsdu_len;
 486        } else {
 487                sta->max_amsdu_len = mvmsta->orig_amsdu_len;
 488                mvmsta->orig_amsdu_len = 0;
 489        }
 490        return count;
 491}
 492
 493static ssize_t iwl_dbgfs_amsdu_len_read(struct file *file,
 494                                        char __user *user_buf,
 495                                        size_t count, loff_t *ppos)
 496{
 497        struct ieee80211_sta *sta = file->private_data;
 498        struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
 499
 500        char buf[32];
 501        int pos;
 502
 503        pos = scnprintf(buf, sizeof(buf), "current %d ", sta->max_amsdu_len);
 504        pos += scnprintf(buf + pos, sizeof(buf) - pos, "stored %d\n",
 505                         mvmsta->orig_amsdu_len);
 506
 507        return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 508}
 509
 510static ssize_t iwl_dbgfs_disable_power_off_read(struct file *file,
 511                                                char __user *user_buf,
 512                                                size_t count, loff_t *ppos)
 513{
 514        struct iwl_mvm *mvm = file->private_data;
 515        char buf[64];
 516        int bufsz = sizeof(buf);
 517        int pos = 0;
 518
 519        pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off_d0=%d\n",
 520                         mvm->disable_power_off);
 521        pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off_d3=%d\n",
 522                         mvm->disable_power_off_d3);
 523
 524        return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 525}
 526
 527static ssize_t iwl_dbgfs_disable_power_off_write(struct iwl_mvm *mvm, char *buf,
 528                                                 size_t count, loff_t *ppos)
 529{
 530        int ret, val;
 531
 532        if (!iwl_mvm_firmware_running(mvm))
 533                return -EIO;
 534
 535        if (!strncmp("disable_power_off_d0=", buf, 21)) {
 536                if (sscanf(buf + 21, "%d", &val) != 1)
 537                        return -EINVAL;
 538                mvm->disable_power_off = val;
 539        } else if (!strncmp("disable_power_off_d3=", buf, 21)) {
 540                if (sscanf(buf + 21, "%d", &val) != 1)
 541                        return -EINVAL;
 542                mvm->disable_power_off_d3 = val;
 543        } else {
 544                return -EINVAL;
 545        }
 546
 547        mutex_lock(&mvm->mutex);
 548        ret = iwl_mvm_power_update_device(mvm);
 549        mutex_unlock(&mvm->mutex);
 550
 551        return ret ?: count;
 552}
 553
 554static
 555int iwl_mvm_coex_dump_mbox(struct iwl_bt_coex_profile_notif *notif, char *buf,
 556                           int pos, int bufsz)
 557{
 558        pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw0:\n");
 559
 560        BT_MBOX_PRINT(0, LE_SLAVE_LAT, false);
 561        BT_MBOX_PRINT(0, LE_PROF1, false);
 562        BT_MBOX_PRINT(0, LE_PROF2, false);
 563        BT_MBOX_PRINT(0, LE_PROF_OTHER, false);
 564        BT_MBOX_PRINT(0, CHL_SEQ_N, false);
 565        BT_MBOX_PRINT(0, INBAND_S, false);
 566        BT_MBOX_PRINT(0, LE_MIN_RSSI, false);
 567        BT_MBOX_PRINT(0, LE_SCAN, false);
 568        BT_MBOX_PRINT(0, LE_ADV, false);
 569        BT_MBOX_PRINT(0, LE_MAX_TX_POWER, false);
 570        BT_MBOX_PRINT(0, OPEN_CON_1, true);
 571
 572        pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw1:\n");
 573
 574        BT_MBOX_PRINT(1, BR_MAX_TX_POWER, false);
 575        BT_MBOX_PRINT(1, IP_SR, false);
 576        BT_MBOX_PRINT(1, LE_MSTR, false);
 577        BT_MBOX_PRINT(1, AGGR_TRFC_LD, false);
 578        BT_MBOX_PRINT(1, MSG_TYPE, false);
 579        BT_MBOX_PRINT(1, SSN, true);
 580
 581        pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw2:\n");
 582
 583        BT_MBOX_PRINT(2, SNIFF_ACT, false);
 584        BT_MBOX_PRINT(2, PAG, false);
 585        BT_MBOX_PRINT(2, INQUIRY, false);
 586        BT_MBOX_PRINT(2, CONN, false);
 587        BT_MBOX_PRINT(2, SNIFF_INTERVAL, false);
 588        BT_MBOX_PRINT(2, DISC, false);
 589        BT_MBOX_PRINT(2, SCO_TX_ACT, false);
 590        BT_MBOX_PRINT(2, SCO_RX_ACT, false);
 591        BT_MBOX_PRINT(2, ESCO_RE_TX, false);
 592        BT_MBOX_PRINT(2, SCO_DURATION, true);
 593
 594        pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw3:\n");
 595
 596        BT_MBOX_PRINT(3, SCO_STATE, false);
 597        BT_MBOX_PRINT(3, SNIFF_STATE, false);
 598        BT_MBOX_PRINT(3, A2DP_STATE, false);
 599        BT_MBOX_PRINT(3, A2DP_SRC, false);
 600        BT_MBOX_PRINT(3, ACL_STATE, false);
 601        BT_MBOX_PRINT(3, MSTR_STATE, false);
 602        BT_MBOX_PRINT(3, OBX_STATE, false);
 603        BT_MBOX_PRINT(3, OPEN_CON_2, false);
 604        BT_MBOX_PRINT(3, TRAFFIC_LOAD, false);
 605        BT_MBOX_PRINT(3, CHL_SEQN_LSB, false);
 606        BT_MBOX_PRINT(3, INBAND_P, false);
 607        BT_MBOX_PRINT(3, MSG_TYPE_2, false);
 608        BT_MBOX_PRINT(3, SSN_2, false);
 609        BT_MBOX_PRINT(3, UPDATE_REQUEST, true);
 610
 611        return pos;
 612}
 613
 614static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf,
 615                                       size_t count, loff_t *ppos)
 616{
 617        struct iwl_mvm *mvm = file->private_data;
 618        struct iwl_bt_coex_profile_notif *notif = &mvm->last_bt_notif;
 619        char *buf;
 620        int ret, pos = 0, bufsz = sizeof(char) * 1024;
 621
 622        buf = kmalloc(bufsz, GFP_KERNEL);
 623        if (!buf)
 624                return -ENOMEM;
 625
 626        mutex_lock(&mvm->mutex);
 627
 628        pos += iwl_mvm_coex_dump_mbox(notif, buf, pos, bufsz);
 629
 630        pos += scnprintf(buf + pos, bufsz - pos, "bt_ci_compliance = %d\n",
 631                         notif->bt_ci_compliance);
 632        pos += scnprintf(buf + pos, bufsz - pos, "primary_ch_lut = %d\n",
 633                         le32_to_cpu(notif->primary_ch_lut));
 634        pos += scnprintf(buf + pos, bufsz - pos, "secondary_ch_lut = %d\n",
 635                         le32_to_cpu(notif->secondary_ch_lut));
 636        pos += scnprintf(buf + pos,
 637                         bufsz - pos, "bt_activity_grading = %d\n",
 638                         le32_to_cpu(notif->bt_activity_grading));
 639        pos += scnprintf(buf + pos, bufsz - pos, "bt_rrc = %d\n",
 640                         notif->rrc_status & 0xF);
 641        pos += scnprintf(buf + pos, bufsz - pos, "bt_ttc = %d\n",
 642                         notif->ttc_status & 0xF);
 643
 644        pos += scnprintf(buf + pos, bufsz - pos, "sync_sco = %d\n",
 645                         IWL_MVM_BT_COEX_SYNC2SCO);
 646        pos += scnprintf(buf + pos, bufsz - pos, "mplut = %d\n",
 647                         IWL_MVM_BT_COEX_MPLUT);
 648
 649        mutex_unlock(&mvm->mutex);
 650
 651        ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 652        kfree(buf);
 653
 654        return ret;
 655}
 656#undef BT_MBOX_PRINT
 657
 658static ssize_t iwl_dbgfs_bt_cmd_read(struct file *file, char __user *user_buf,
 659                                     size_t count, loff_t *ppos)
 660{
 661        struct iwl_mvm *mvm = file->private_data;
 662        struct iwl_bt_coex_ci_cmd *cmd = &mvm->last_bt_ci_cmd;
 663        char buf[256];
 664        int bufsz = sizeof(buf);
 665        int pos = 0;
 666
 667        mutex_lock(&mvm->mutex);
 668
 669        pos += scnprintf(buf + pos, bufsz - pos, "Channel inhibition CMD\n");
 670        pos += scnprintf(buf + pos, bufsz - pos,
 671                         "\tPrimary Channel Bitmap 0x%016llx\n",
 672                         le64_to_cpu(cmd->bt_primary_ci));
 673        pos += scnprintf(buf + pos, bufsz - pos,
 674                         "\tSecondary Channel Bitmap 0x%016llx\n",
 675                         le64_to_cpu(cmd->bt_secondary_ci));
 676
 677        mutex_unlock(&mvm->mutex);
 678
 679        return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 680}
 681
 682static ssize_t
 683iwl_dbgfs_bt_tx_prio_write(struct iwl_mvm *mvm, char *buf,
 684                           size_t count, loff_t *ppos)
 685{
 686        u32 bt_tx_prio;
 687
 688        if (sscanf(buf, "%u", &bt_tx_prio) != 1)
 689                return -EINVAL;
 690        if (bt_tx_prio > 4)
 691                return -EINVAL;
 692
 693        mvm->bt_tx_prio = bt_tx_prio;
 694
 695        return count;
 696}
 697
 698static ssize_t
 699iwl_dbgfs_bt_force_ant_write(struct iwl_mvm *mvm, char *buf,
 700                             size_t count, loff_t *ppos)
 701{
 702        static const char * const modes_str[BT_FORCE_ANT_MAX] = {
 703                [BT_FORCE_ANT_DIS] = "dis",
 704                [BT_FORCE_ANT_AUTO] = "auto",
 705                [BT_FORCE_ANT_BT] = "bt",
 706                [BT_FORCE_ANT_WIFI] = "wifi",
 707        };
 708        int ret, bt_force_ant_mode;
 709
 710        ret = match_string(modes_str, ARRAY_SIZE(modes_str), buf);
 711        if (ret < 0)
 712                return ret;
 713
 714        bt_force_ant_mode = ret;
 715        ret = 0;
 716        mutex_lock(&mvm->mutex);
 717        if (mvm->bt_force_ant_mode == bt_force_ant_mode)
 718                goto out;
 719
 720        mvm->bt_force_ant_mode = bt_force_ant_mode;
 721        IWL_DEBUG_COEX(mvm, "Force mode: %s\n",
 722                       modes_str[mvm->bt_force_ant_mode]);
 723
 724        if (iwl_mvm_firmware_running(mvm))
 725                ret = iwl_mvm_send_bt_init_conf(mvm);
 726        else
 727                ret = 0;
 728
 729out:
 730        mutex_unlock(&mvm->mutex);
 731        return ret ?: count;
 732}
 733
 734static ssize_t iwl_dbgfs_fw_ver_read(struct file *file, char __user *user_buf,
 735                                     size_t count, loff_t *ppos)
 736{
 737        struct iwl_mvm *mvm = file->private_data;
 738        char *buff, *pos, *endpos;
 739        static const size_t bufsz = 1024;
 740        int ret;
 741
 742        buff = kmalloc(bufsz, GFP_KERNEL);
 743        if (!buff)
 744                return -ENOMEM;
 745
 746        pos = buff;
 747        endpos = pos + bufsz;
 748
 749        pos += scnprintf(pos, endpos - pos, "FW prefix: %s\n",
 750                         mvm->trans->cfg->fw_name_pre);
 751        pos += scnprintf(pos, endpos - pos, "FW: %s\n",
 752                         mvm->fwrt.fw->human_readable);
 753        pos += scnprintf(pos, endpos - pos, "Device: %s\n",
 754                         mvm->fwrt.trans->cfg->name);
 755        pos += scnprintf(pos, endpos - pos, "Bus: %s\n",
 756                         mvm->fwrt.dev->bus->name);
 757
 758        ret = simple_read_from_buffer(user_buf, count, ppos, buff, pos - buff);
 759        kfree(buff);
 760
 761        return ret;
 762}
 763
 764#define PRINT_STATS_LE32(_struct, _memb)                                \
 765                         pos += scnprintf(buf + pos, bufsz - pos,       \
 766                                          fmt_table, #_memb,            \
 767                                          le32_to_cpu(_struct->_memb))
 768
 769static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file,
 770                                          char __user *user_buf, size_t count,
 771                                          loff_t *ppos)
 772{
 773        struct iwl_mvm *mvm = file->private_data;
 774        static const char *fmt_table = "\t%-30s %10u\n";
 775        static const char *fmt_header = "%-32s\n";
 776        int pos = 0;
 777        char *buf;
 778        int ret;
 779        size_t bufsz;
 780
 781        if (iwl_mvm_has_new_rx_stats_api(mvm))
 782                bufsz = ((sizeof(struct mvm_statistics_rx) /
 783                          sizeof(__le32)) * 43) + (4 * 33) + 1;
 784        else
 785                /* 43 = size of each data line; 33 = size of each header */
 786                bufsz = ((sizeof(struct mvm_statistics_rx_v3) /
 787                          sizeof(__le32)) * 43) + (4 * 33) + 1;
 788
 789        buf = kzalloc(bufsz, GFP_KERNEL);
 790        if (!buf)
 791                return -ENOMEM;
 792
 793        mutex_lock(&mvm->mutex);
 794
 795        if (iwl_mvm_firmware_running(mvm))
 796                iwl_mvm_request_statistics(mvm, false);
 797
 798        pos += scnprintf(buf + pos, bufsz - pos, fmt_header,
 799                         "Statistics_Rx - OFDM");
 800        if (!iwl_mvm_has_new_rx_stats_api(mvm)) {
 801                struct mvm_statistics_rx_phy_v2 *ofdm = &mvm->rx_stats_v3.ofdm;
 802
 803                PRINT_STATS_LE32(ofdm, ina_cnt);
 804                PRINT_STATS_LE32(ofdm, fina_cnt);
 805                PRINT_STATS_LE32(ofdm, plcp_err);
 806                PRINT_STATS_LE32(ofdm, crc32_err);
 807                PRINT_STATS_LE32(ofdm, overrun_err);
 808                PRINT_STATS_LE32(ofdm, early_overrun_err);
 809                PRINT_STATS_LE32(ofdm, crc32_good);
 810                PRINT_STATS_LE32(ofdm, false_alarm_cnt);
 811                PRINT_STATS_LE32(ofdm, fina_sync_err_cnt);
 812                PRINT_STATS_LE32(ofdm, sfd_timeout);
 813                PRINT_STATS_LE32(ofdm, fina_timeout);
 814                PRINT_STATS_LE32(ofdm, unresponded_rts);
 815                PRINT_STATS_LE32(ofdm, rxe_frame_lmt_overrun);
 816                PRINT_STATS_LE32(ofdm, sent_ack_cnt);
 817                PRINT_STATS_LE32(ofdm, sent_cts_cnt);
 818                PRINT_STATS_LE32(ofdm, sent_ba_rsp_cnt);
 819                PRINT_STATS_LE32(ofdm, dsp_self_kill);
 820                PRINT_STATS_LE32(ofdm, mh_format_err);
 821                PRINT_STATS_LE32(ofdm, re_acq_main_rssi_sum);
 822                PRINT_STATS_LE32(ofdm, reserved);
 823        } else {
 824                struct mvm_statistics_rx_phy *ofdm = &mvm->rx_stats.ofdm;
 825
 826                PRINT_STATS_LE32(ofdm, unresponded_rts);
 827                PRINT_STATS_LE32(ofdm, rxe_frame_lmt_overrun);
 828                PRINT_STATS_LE32(ofdm, sent_ba_rsp_cnt);
 829                PRINT_STATS_LE32(ofdm, dsp_self_kill);
 830                PRINT_STATS_LE32(ofdm, reserved);
 831        }
 832
 833        pos += scnprintf(buf + pos, bufsz - pos, fmt_header,
 834                         "Statistics_Rx - CCK");
 835        if (!iwl_mvm_has_new_rx_stats_api(mvm)) {
 836                struct mvm_statistics_rx_phy_v2 *cck = &mvm->rx_stats_v3.cck;
 837
 838                PRINT_STATS_LE32(cck, ina_cnt);
 839                PRINT_STATS_LE32(cck, fina_cnt);
 840                PRINT_STATS_LE32(cck, plcp_err);
 841                PRINT_STATS_LE32(cck, crc32_err);
 842                PRINT_STATS_LE32(cck, overrun_err);
 843                PRINT_STATS_LE32(cck, early_overrun_err);
 844                PRINT_STATS_LE32(cck, crc32_good);
 845                PRINT_STATS_LE32(cck, false_alarm_cnt);
 846                PRINT_STATS_LE32(cck, fina_sync_err_cnt);
 847                PRINT_STATS_LE32(cck, sfd_timeout);
 848                PRINT_STATS_LE32(cck, fina_timeout);
 849                PRINT_STATS_LE32(cck, unresponded_rts);
 850                PRINT_STATS_LE32(cck, rxe_frame_lmt_overrun);
 851                PRINT_STATS_LE32(cck, sent_ack_cnt);
 852                PRINT_STATS_LE32(cck, sent_cts_cnt);
 853                PRINT_STATS_LE32(cck, sent_ba_rsp_cnt);
 854                PRINT_STATS_LE32(cck, dsp_self_kill);
 855                PRINT_STATS_LE32(cck, mh_format_err);
 856                PRINT_STATS_LE32(cck, re_acq_main_rssi_sum);
 857                PRINT_STATS_LE32(cck, reserved);
 858        } else {
 859                struct mvm_statistics_rx_phy *cck = &mvm->rx_stats.cck;
 860
 861                PRINT_STATS_LE32(cck, unresponded_rts);
 862                PRINT_STATS_LE32(cck, rxe_frame_lmt_overrun);
 863                PRINT_STATS_LE32(cck, sent_ba_rsp_cnt);
 864                PRINT_STATS_LE32(cck, dsp_self_kill);
 865                PRINT_STATS_LE32(cck, reserved);
 866        }
 867
 868        pos += scnprintf(buf + pos, bufsz - pos, fmt_header,
 869                         "Statistics_Rx - GENERAL");
 870        if (!iwl_mvm_has_new_rx_stats_api(mvm)) {
 871                struct mvm_statistics_rx_non_phy_v3 *general =
 872                        &mvm->rx_stats_v3.general;
 873
 874                PRINT_STATS_LE32(general, bogus_cts);
 875                PRINT_STATS_LE32(general, bogus_ack);
 876                PRINT_STATS_LE32(general, non_bssid_frames);
 877                PRINT_STATS_LE32(general, filtered_frames);
 878                PRINT_STATS_LE32(general, non_channel_beacons);
 879                PRINT_STATS_LE32(general, channel_beacons);
 880                PRINT_STATS_LE32(general, num_missed_bcon);
 881                PRINT_STATS_LE32(general, adc_rx_saturation_time);
 882                PRINT_STATS_LE32(general, ina_detection_search_time);
 883                PRINT_STATS_LE32(general, beacon_silence_rssi_a);
 884                PRINT_STATS_LE32(general, beacon_silence_rssi_b);
 885                PRINT_STATS_LE32(general, beacon_silence_rssi_c);
 886                PRINT_STATS_LE32(general, interference_data_flag);
 887                PRINT_STATS_LE32(general, channel_load);
 888                PRINT_STATS_LE32(general, dsp_false_alarms);
 889                PRINT_STATS_LE32(general, beacon_rssi_a);
 890                PRINT_STATS_LE32(general, beacon_rssi_b);
 891                PRINT_STATS_LE32(general, beacon_rssi_c);
 892                PRINT_STATS_LE32(general, beacon_energy_a);
 893                PRINT_STATS_LE32(general, beacon_energy_b);
 894                PRINT_STATS_LE32(general, beacon_energy_c);
 895                PRINT_STATS_LE32(general, num_bt_kills);
 896                PRINT_STATS_LE32(general, mac_id);
 897                PRINT_STATS_LE32(general, directed_data_mpdu);
 898        } else {
 899                struct mvm_statistics_rx_non_phy *general =
 900                        &mvm->rx_stats.general;
 901
 902                PRINT_STATS_LE32(general, bogus_cts);
 903                PRINT_STATS_LE32(general, bogus_ack);
 904                PRINT_STATS_LE32(general, non_channel_beacons);
 905                PRINT_STATS_LE32(general, channel_beacons);
 906                PRINT_STATS_LE32(general, num_missed_bcon);
 907                PRINT_STATS_LE32(general, adc_rx_saturation_time);
 908                PRINT_STATS_LE32(general, ina_detection_search_time);
 909                PRINT_STATS_LE32(general, beacon_silence_rssi_a);
 910                PRINT_STATS_LE32(general, beacon_silence_rssi_b);
 911                PRINT_STATS_LE32(general, beacon_silence_rssi_c);
 912                PRINT_STATS_LE32(general, interference_data_flag);
 913                PRINT_STATS_LE32(general, channel_load);
 914                PRINT_STATS_LE32(general, beacon_rssi_a);
 915                PRINT_STATS_LE32(general, beacon_rssi_b);
 916                PRINT_STATS_LE32(general, beacon_rssi_c);
 917                PRINT_STATS_LE32(general, beacon_energy_a);
 918                PRINT_STATS_LE32(general, beacon_energy_b);
 919                PRINT_STATS_LE32(general, beacon_energy_c);
 920                PRINT_STATS_LE32(general, num_bt_kills);
 921                PRINT_STATS_LE32(general, mac_id);
 922        }
 923
 924        pos += scnprintf(buf + pos, bufsz - pos, fmt_header,
 925                         "Statistics_Rx - HT");
 926        if (!iwl_mvm_has_new_rx_stats_api(mvm)) {
 927                struct mvm_statistics_rx_ht_phy_v1 *ht =
 928                        &mvm->rx_stats_v3.ofdm_ht;
 929
 930                PRINT_STATS_LE32(ht, plcp_err);
 931                PRINT_STATS_LE32(ht, overrun_err);
 932                PRINT_STATS_LE32(ht, early_overrun_err);
 933                PRINT_STATS_LE32(ht, crc32_good);
 934                PRINT_STATS_LE32(ht, crc32_err);
 935                PRINT_STATS_LE32(ht, mh_format_err);
 936                PRINT_STATS_LE32(ht, agg_crc32_good);
 937                PRINT_STATS_LE32(ht, agg_mpdu_cnt);
 938                PRINT_STATS_LE32(ht, agg_cnt);
 939                PRINT_STATS_LE32(ht, unsupport_mcs);
 940        } else {
 941                struct mvm_statistics_rx_ht_phy *ht =
 942                        &mvm->rx_stats.ofdm_ht;
 943
 944                PRINT_STATS_LE32(ht, mh_format_err);
 945                PRINT_STATS_LE32(ht, agg_mpdu_cnt);
 946                PRINT_STATS_LE32(ht, agg_cnt);
 947                PRINT_STATS_LE32(ht, unsupport_mcs);
 948        }
 949
 950        mutex_unlock(&mvm->mutex);
 951
 952        ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 953        kfree(buf);
 954
 955        return ret;
 956}
 957#undef PRINT_STAT_LE32
 958
 959static ssize_t iwl_dbgfs_frame_stats_read(struct iwl_mvm *mvm,
 960                                          char __user *user_buf, size_t count,
 961                                          loff_t *ppos,
 962                                          struct iwl_mvm_frame_stats *stats)
 963{
 964        char *buff, *pos, *endpos;
 965        int idx, i;
 966        int ret;
 967        static const size_t bufsz = 1024;
 968
 969        buff = kmalloc(bufsz, GFP_KERNEL);
 970        if (!buff)
 971                return -ENOMEM;
 972
 973        spin_lock_bh(&mvm->drv_stats_lock);
 974
 975        pos = buff;
 976        endpos = pos + bufsz;
 977
 978        pos += scnprintf(pos, endpos - pos,
 979                         "Legacy/HT/VHT\t:\t%d/%d/%d\n",
 980                         stats->legacy_frames,
 981                         stats->ht_frames,
 982                         stats->vht_frames);
 983        pos += scnprintf(pos, endpos - pos, "20/40/80\t:\t%d/%d/%d\n",
 984                         stats->bw_20_frames,
 985                         stats->bw_40_frames,
 986                         stats->bw_80_frames);
 987        pos += scnprintf(pos, endpos - pos, "NGI/SGI\t\t:\t%d/%d\n",
 988                         stats->ngi_frames,
 989                         stats->sgi_frames);
 990        pos += scnprintf(pos, endpos - pos, "SISO/MIMO2\t:\t%d/%d\n",
 991                         stats->siso_frames,
 992                         stats->mimo2_frames);
 993        pos += scnprintf(pos, endpos - pos, "FAIL/SCSS\t:\t%d/%d\n",
 994                         stats->fail_frames,
 995                         stats->success_frames);
 996        pos += scnprintf(pos, endpos - pos, "MPDUs agg\t:\t%d\n",
 997                         stats->agg_frames);
 998        pos += scnprintf(pos, endpos - pos, "A-MPDUs\t\t:\t%d\n",
 999                         stats->ampdu_count);
1000        pos += scnprintf(pos, endpos - pos, "Avg MPDUs/A-MPDU:\t%d\n",
1001                         stats->ampdu_count > 0 ?
1002                         (stats->agg_frames / stats->ampdu_count) : 0);
1003
1004        pos += scnprintf(pos, endpos - pos, "Last Rates\n");
1005
1006        idx = stats->last_frame_idx - 1;
1007        for (i = 0; i < ARRAY_SIZE(stats->last_rates); i++) {
1008                idx = (idx + 1) % ARRAY_SIZE(stats->last_rates);
1009                if (stats->last_rates[idx] == 0)
1010                        continue;
1011                pos += scnprintf(pos, endpos - pos, "Rate[%d]: ",
1012                                 (int)(ARRAY_SIZE(stats->last_rates) - i));
1013                pos += rs_pretty_print_rate(pos, endpos - pos,
1014                                            stats->last_rates[idx]);
1015        }
1016        spin_unlock_bh(&mvm->drv_stats_lock);
1017
1018        ret = simple_read_from_buffer(user_buf, count, ppos, buff, pos - buff);
1019        kfree(buff);
1020
1021        return ret;
1022}
1023
1024static ssize_t iwl_dbgfs_drv_rx_stats_read(struct file *file,
1025                                           char __user *user_buf, size_t count,
1026                                           loff_t *ppos)
1027{
1028        struct iwl_mvm *mvm = file->private_data;
1029
1030        return iwl_dbgfs_frame_stats_read(mvm, user_buf, count, ppos,
1031                                          &mvm->drv_rx_stats);
1032}
1033
1034static ssize_t iwl_dbgfs_fw_restart_write(struct iwl_mvm *mvm, char *buf,
1035                                          size_t count, loff_t *ppos)
1036{
1037        int __maybe_unused ret;
1038
1039        if (!iwl_mvm_firmware_running(mvm))
1040                return -EIO;
1041
1042        mutex_lock(&mvm->mutex);
1043
1044        /* allow one more restart that we're provoking here */
1045        if (mvm->fw_restart >= 0)
1046                mvm->fw_restart++;
1047
1048        /* take the return value to make compiler happy - it will fail anyway */
1049        ret = iwl_mvm_send_cmd_pdu(mvm, REPLY_ERROR, 0, 0, NULL);
1050
1051        mutex_unlock(&mvm->mutex);
1052
1053        return count;
1054}
1055
1056static ssize_t iwl_dbgfs_fw_nmi_write(struct iwl_mvm *mvm, char *buf,
1057                                      size_t count, loff_t *ppos)
1058{
1059        int ret;
1060
1061        if (!iwl_mvm_firmware_running(mvm))
1062                return -EIO;
1063
1064        ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_NMI);
1065        if (ret)
1066                return ret;
1067
1068        iwl_force_nmi(mvm->trans);
1069
1070        iwl_mvm_unref(mvm, IWL_MVM_REF_NMI);
1071
1072        return count;
1073}
1074
1075static ssize_t
1076iwl_dbgfs_scan_ant_rxchain_read(struct file *file,
1077                                char __user *user_buf,
1078                                size_t count, loff_t *ppos)
1079{
1080        struct iwl_mvm *mvm = file->private_data;
1081        int pos = 0;
1082        char buf[32];
1083        const size_t bufsz = sizeof(buf);
1084
1085        /* print which antennas were set for the scan command by the user */
1086        pos += scnprintf(buf + pos, bufsz - pos, "Antennas for scan: ");
1087        if (mvm->scan_rx_ant & ANT_A)
1088                pos += scnprintf(buf + pos, bufsz - pos, "A");
1089        if (mvm->scan_rx_ant & ANT_B)
1090                pos += scnprintf(buf + pos, bufsz - pos, "B");
1091        if (mvm->scan_rx_ant & ANT_C)
1092                pos += scnprintf(buf + pos, bufsz - pos, "C");
1093        pos += scnprintf(buf + pos, bufsz - pos, " (%hhx)\n", mvm->scan_rx_ant);
1094
1095        return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1096}
1097
1098static ssize_t
1099iwl_dbgfs_scan_ant_rxchain_write(struct iwl_mvm *mvm, char *buf,
1100                                 size_t count, loff_t *ppos)
1101{
1102        u8 scan_rx_ant;
1103
1104        if (!iwl_mvm_firmware_running(mvm))
1105                return -EIO;
1106
1107        if (sscanf(buf, "%hhx", &scan_rx_ant) != 1)
1108                return -EINVAL;
1109        if (scan_rx_ant > ANT_ABC)
1110                return -EINVAL;
1111        if (scan_rx_ant & ~(iwl_mvm_get_valid_rx_ant(mvm)))
1112                return -EINVAL;
1113
1114        if (mvm->scan_rx_ant != scan_rx_ant) {
1115                mvm->scan_rx_ant = scan_rx_ant;
1116                if (fw_has_capa(&mvm->fw->ucode_capa,
1117                                IWL_UCODE_TLV_CAPA_UMAC_SCAN))
1118                        iwl_mvm_config_scan(mvm);
1119        }
1120
1121        return count;
1122}
1123
1124static ssize_t iwl_dbgfs_indirection_tbl_write(struct iwl_mvm *mvm,
1125                                               char *buf, size_t count,
1126                                               loff_t *ppos)
1127{
1128        struct iwl_rss_config_cmd cmd = {
1129                .flags = cpu_to_le32(IWL_RSS_ENABLE),
1130                .hash_mask = IWL_RSS_HASH_TYPE_IPV4_TCP |
1131                             IWL_RSS_HASH_TYPE_IPV4_UDP |
1132                             IWL_RSS_HASH_TYPE_IPV4_PAYLOAD |
1133                             IWL_RSS_HASH_TYPE_IPV6_TCP |
1134                             IWL_RSS_HASH_TYPE_IPV6_UDP |
1135                             IWL_RSS_HASH_TYPE_IPV6_PAYLOAD,
1136        };
1137        int ret, i, num_repeats, nbytes = count / 2;
1138
1139        ret = hex2bin(cmd.indirection_table, buf, nbytes);
1140        if (ret)
1141                return ret;
1142
1143        /*
1144         * The input is the redirection table, partial or full.
1145         * Repeat the pattern if needed.
1146         * For example, input of 01020F will be repeated 42 times,
1147         * indirecting RSS hash results to queues 1, 2, 15 (skipping
1148         * queues 3 - 14).
1149         */
1150        num_repeats = ARRAY_SIZE(cmd.indirection_table) / nbytes;
1151        for (i = 1; i < num_repeats; i++)
1152                memcpy(&cmd.indirection_table[i * nbytes],
1153                       cmd.indirection_table, nbytes);
1154        /* handle cut in the middle pattern for the last places */
1155        memcpy(&cmd.indirection_table[i * nbytes], cmd.indirection_table,
1156               ARRAY_SIZE(cmd.indirection_table) % nbytes);
1157
1158        netdev_rss_key_fill(cmd.secret_key, sizeof(cmd.secret_key));
1159
1160        mutex_lock(&mvm->mutex);
1161        if (iwl_mvm_firmware_running(mvm))
1162                ret = iwl_mvm_send_cmd_pdu(mvm, RSS_CONFIG_CMD, 0,
1163                                           sizeof(cmd), &cmd);
1164        else
1165                ret = 0;
1166        mutex_unlock(&mvm->mutex);
1167
1168        return ret ?: count;
1169}
1170
1171static ssize_t iwl_dbgfs_inject_packet_write(struct iwl_mvm *mvm,
1172                                             char *buf, size_t count,
1173                                             loff_t *ppos)
1174{
1175        struct iwl_rx_cmd_buffer rxb = {
1176                ._rx_page_order = 0,
1177                .truesize = 0, /* not used */
1178                ._offset = 0,
1179        };
1180        struct iwl_rx_packet *pkt;
1181        struct iwl_rx_mpdu_desc *desc;
1182        int bin_len = count / 2;
1183        int ret = -EINVAL;
1184        size_t mpdu_cmd_hdr_size =
1185                (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) ?
1186                sizeof(struct iwl_rx_mpdu_desc) :
1187                IWL_RX_DESC_SIZE_V1;
1188
1189        if (!iwl_mvm_firmware_running(mvm))
1190                return -EIO;
1191
1192        /* supporting only 9000 descriptor */
1193        if (!mvm->trans->cfg->mq_rx_supported)
1194                return -ENOTSUPP;
1195
1196        rxb._page = alloc_pages(GFP_ATOMIC, 0);
1197        if (!rxb._page)
1198                return -ENOMEM;
1199        pkt = rxb_addr(&rxb);
1200
1201        ret = hex2bin(page_address(rxb._page), buf, bin_len);
1202        if (ret)
1203                goto out;
1204
1205        /* avoid invalid memory access */
1206        if (bin_len < sizeof(*pkt) + mpdu_cmd_hdr_size)
1207                goto out;
1208
1209        /* check this is RX packet */
1210        if (WIDE_ID(pkt->hdr.group_id, pkt->hdr.cmd) !=
1211            WIDE_ID(LEGACY_GROUP, REPLY_RX_MPDU_CMD))
1212                goto out;
1213
1214        /* check the length in metadata matches actual received length */
1215        desc = (void *)pkt->data;
1216        if (le16_to_cpu(desc->mpdu_len) !=
1217            (bin_len - mpdu_cmd_hdr_size - sizeof(*pkt)))
1218                goto out;
1219
1220        local_bh_disable();
1221        iwl_mvm_rx_mpdu_mq(mvm, NULL, &rxb, 0);
1222        local_bh_enable();
1223        ret = 0;
1224
1225out:
1226        iwl_free_rxb(&rxb);
1227
1228        return ret ?: count;
1229}
1230
1231static int _iwl_dbgfs_inject_beacon_ie(struct iwl_mvm *mvm, char *bin, int len)
1232{
1233        struct ieee80211_vif *vif;
1234        struct iwl_mvm_vif *mvmvif;
1235        struct sk_buff *beacon;
1236        struct ieee80211_tx_info *info;
1237        struct iwl_mac_beacon_cmd beacon_cmd = {};
1238        u8 rate;
1239        u16 flags;
1240        int i;
1241
1242        len /= 2;
1243
1244        /* Element len should be represented by u8 */
1245        if (len >= U8_MAX)
1246                return -EINVAL;
1247
1248        if (!iwl_mvm_firmware_running(mvm))
1249                return -EIO;
1250
1251        if (!iwl_mvm_has_new_tx_api(mvm) &&
1252            !fw_has_api(&mvm->fw->ucode_capa,
1253                        IWL_UCODE_TLV_API_NEW_BEACON_TEMPLATE))
1254                return -EINVAL;
1255
1256        rcu_read_lock();
1257
1258        for (i = 0; i < NUM_MAC_INDEX_DRIVER; i++) {
1259                vif = iwl_mvm_rcu_dereference_vif_id(mvm, i, true);
1260                if (!vif)
1261                        continue;
1262
1263                if (vif->type == NL80211_IFTYPE_AP)
1264                        break;
1265        }
1266
1267        if (i == NUM_MAC_INDEX_DRIVER || !vif)
1268                goto out_err;
1269
1270        mvm->hw->extra_beacon_tailroom = len;
1271
1272        beacon = ieee80211_beacon_get_template(mvm->hw, vif, NULL);
1273        if (!beacon)
1274                goto out_err;
1275
1276        if (len && hex2bin(skb_put_zero(beacon, len), bin, len)) {
1277                dev_kfree_skb(beacon);
1278                goto out_err;
1279        }
1280
1281        mvm->beacon_inject_active = true;
1282
1283        mvmvif = iwl_mvm_vif_from_mac80211(vif);
1284        info = IEEE80211_SKB_CB(beacon);
1285        rate = iwl_mvm_mac_ctxt_get_lowest_rate(info, vif);
1286        flags = iwl_mvm_mac80211_idx_to_hwrate(rate);
1287
1288        if (rate == IWL_FIRST_CCK_RATE)
1289                flags |= IWL_MAC_BEACON_CCK;
1290
1291        beacon_cmd.flags = cpu_to_le16(flags);
1292        beacon_cmd.byte_cnt = cpu_to_le16((u16)beacon->len);
1293        beacon_cmd.template_id = cpu_to_le32((u32)mvmvif->id);
1294
1295        iwl_mvm_mac_ctxt_set_tim(mvm, &beacon_cmd.tim_idx,
1296                                 &beacon_cmd.tim_size,
1297                                 beacon->data, beacon->len);
1298
1299        mutex_lock(&mvm->mutex);
1300        iwl_mvm_mac_ctxt_send_beacon_cmd(mvm, beacon, &beacon_cmd,
1301                                         sizeof(beacon_cmd));
1302        mutex_unlock(&mvm->mutex);
1303
1304        dev_kfree_skb(beacon);
1305
1306        rcu_read_unlock();
1307        return 0;
1308
1309out_err:
1310        rcu_read_unlock();
1311        return -EINVAL;
1312}
1313
1314static ssize_t iwl_dbgfs_inject_beacon_ie_write(struct iwl_mvm *mvm,
1315                                                char *buf, size_t count,
1316                                                loff_t *ppos)
1317{
1318        int ret = _iwl_dbgfs_inject_beacon_ie(mvm, buf, count);
1319
1320        mvm->hw->extra_beacon_tailroom = 0;
1321        return ret ?: count;
1322}
1323
1324static ssize_t iwl_dbgfs_inject_beacon_ie_restore_write(struct iwl_mvm *mvm,
1325                                                        char *buf,
1326                                                        size_t count,
1327                                                        loff_t *ppos)
1328{
1329        int ret = _iwl_dbgfs_inject_beacon_ie(mvm, NULL, 0);
1330
1331        mvm->hw->extra_beacon_tailroom = 0;
1332        mvm->beacon_inject_active = false;
1333        return ret ?: count;
1334}
1335
1336static ssize_t iwl_dbgfs_fw_dbg_conf_read(struct file *file,
1337                                          char __user *user_buf,
1338                                          size_t count, loff_t *ppos)
1339{
1340        struct iwl_mvm *mvm = file->private_data;
1341        int conf;
1342        char buf[8];
1343        const size_t bufsz = sizeof(buf);
1344        int pos = 0;
1345
1346        mutex_lock(&mvm->mutex);
1347        conf = mvm->fwrt.dump.conf;
1348        mutex_unlock(&mvm->mutex);
1349
1350        pos += scnprintf(buf + pos, bufsz - pos, "%d\n", conf);
1351
1352        return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1353}
1354
1355static ssize_t iwl_dbgfs_fw_dbg_conf_write(struct iwl_mvm *mvm,
1356                                           char *buf, size_t count,
1357                                           loff_t *ppos)
1358{
1359        unsigned int conf_id;
1360        int ret;
1361
1362        if (!iwl_mvm_firmware_running(mvm))
1363                return -EIO;
1364
1365        ret = kstrtouint(buf, 0, &conf_id);
1366        if (ret)
1367                return ret;
1368
1369        if (WARN_ON(conf_id >= FW_DBG_CONF_MAX))
1370                return -EINVAL;
1371
1372        mutex_lock(&mvm->mutex);
1373        ret = iwl_fw_start_dbg_conf(&mvm->fwrt, conf_id);
1374        mutex_unlock(&mvm->mutex);
1375
1376        return ret ?: count;
1377}
1378
1379static ssize_t iwl_dbgfs_fw_dbg_collect_write(struct iwl_mvm *mvm,
1380                                              char *buf, size_t count,
1381                                              loff_t *ppos)
1382{
1383        int ret;
1384
1385        ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PRPH_WRITE);
1386        if (ret)
1387                return ret;
1388        if (count == 0)
1389                return 0;
1390
1391        iwl_fw_dbg_collect(&mvm->fwrt, FW_DBG_TRIGGER_USER, buf,
1392                           (count - 1), NULL);
1393
1394        iwl_mvm_unref(mvm, IWL_MVM_REF_PRPH_WRITE);
1395
1396        return count;
1397}
1398
1399#define ADD_TEXT(...) pos += scnprintf(buf + pos, bufsz - pos, __VA_ARGS__)
1400#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
1401static ssize_t iwl_dbgfs_bcast_filters_read(struct file *file,
1402                                            char __user *user_buf,
1403                                            size_t count, loff_t *ppos)
1404{
1405        struct iwl_mvm *mvm = file->private_data;
1406        struct iwl_bcast_filter_cmd cmd;
1407        const struct iwl_fw_bcast_filter *filter;
1408        char *buf;
1409        int bufsz = 1024;
1410        int i, j, pos = 0;
1411        ssize_t ret;
1412
1413        buf = kzalloc(bufsz, GFP_KERNEL);
1414        if (!buf)
1415                return -ENOMEM;
1416
1417        mutex_lock(&mvm->mutex);
1418        if (!iwl_mvm_bcast_filter_build_cmd(mvm, &cmd)) {
1419                ADD_TEXT("None\n");
1420                mutex_unlock(&mvm->mutex);
1421                goto out;
1422        }
1423        mutex_unlock(&mvm->mutex);
1424
1425        for (i = 0; cmd.filters[i].attrs[0].mask; i++) {
1426                filter = &cmd.filters[i];
1427
1428                ADD_TEXT("Filter [%d]:\n", i);
1429                ADD_TEXT("\tDiscard=%d\n", filter->discard);
1430                ADD_TEXT("\tFrame Type: %s\n",
1431                         filter->frame_type ? "IPv4" : "Generic");
1432
1433                for (j = 0; j < ARRAY_SIZE(filter->attrs); j++) {
1434                        const struct iwl_fw_bcast_filter_attr *attr;
1435
1436                        attr = &filter->attrs[j];
1437                        if (!attr->mask)
1438                                break;
1439
1440                        ADD_TEXT("\tAttr [%d]: offset=%d (from %s), mask=0x%x, value=0x%x reserved=0x%x\n",
1441                                 j, attr->offset,
1442                                 attr->offset_type ? "IP End" :
1443                                                     "Payload Start",
1444                                 be32_to_cpu(attr->mask),
1445                                 be32_to_cpu(attr->val),
1446                                 le16_to_cpu(attr->reserved1));
1447                }
1448        }
1449out:
1450        ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1451        kfree(buf);
1452        return ret;
1453}
1454
1455static ssize_t iwl_dbgfs_bcast_filters_write(struct iwl_mvm *mvm, char *buf,
1456                                             size_t count, loff_t *ppos)
1457{
1458        int pos, next_pos;
1459        struct iwl_fw_bcast_filter filter = {};
1460        struct iwl_bcast_filter_cmd cmd;
1461        u32 filter_id, attr_id, mask, value;
1462        int err = 0;
1463
1464        if (sscanf(buf, "%d %hhi %hhi %n", &filter_id, &filter.discard,
1465                   &filter.frame_type, &pos) != 3)
1466                return -EINVAL;
1467
1468        if (filter_id >= ARRAY_SIZE(mvm->dbgfs_bcast_filtering.cmd.filters) ||
1469            filter.frame_type > BCAST_FILTER_FRAME_TYPE_IPV4)
1470                return -EINVAL;
1471
1472        for (attr_id = 0; attr_id < ARRAY_SIZE(filter.attrs);
1473             attr_id++) {
1474                struct iwl_fw_bcast_filter_attr *attr =
1475                                &filter.attrs[attr_id];
1476
1477                if (pos >= count)
1478                        break;
1479
1480                if (sscanf(&buf[pos], "%hhi %hhi %i %i %n",
1481                           &attr->offset, &attr->offset_type,
1482                           &mask, &value, &next_pos) != 4)
1483                        return -EINVAL;
1484
1485                attr->mask = cpu_to_be32(mask);
1486                attr->val = cpu_to_be32(value);
1487                if (mask)
1488                        filter.num_attrs++;
1489
1490                pos += next_pos;
1491        }
1492
1493        mutex_lock(&mvm->mutex);
1494        memcpy(&mvm->dbgfs_bcast_filtering.cmd.filters[filter_id],
1495               &filter, sizeof(filter));
1496
1497        /* send updated bcast filtering configuration */
1498        if (iwl_mvm_firmware_running(mvm) &&
1499            mvm->dbgfs_bcast_filtering.override &&
1500            iwl_mvm_bcast_filter_build_cmd(mvm, &cmd))
1501                err = iwl_mvm_send_cmd_pdu(mvm, BCAST_FILTER_CMD, 0,
1502                                           sizeof(cmd), &cmd);
1503        mutex_unlock(&mvm->mutex);
1504
1505        return err ?: count;
1506}
1507
1508static ssize_t iwl_dbgfs_bcast_filters_macs_read(struct file *file,
1509                                                 char __user *user_buf,
1510                                                 size_t count, loff_t *ppos)
1511{
1512        struct iwl_mvm *mvm = file->private_data;
1513        struct iwl_bcast_filter_cmd cmd;
1514        char *buf;
1515        int bufsz = 1024;
1516        int i, pos = 0;
1517        ssize_t ret;
1518
1519        buf = kzalloc(bufsz, GFP_KERNEL);
1520        if (!buf)
1521                return -ENOMEM;
1522
1523        mutex_lock(&mvm->mutex);
1524        if (!iwl_mvm_bcast_filter_build_cmd(mvm, &cmd)) {
1525                ADD_TEXT("None\n");
1526                mutex_unlock(&mvm->mutex);
1527                goto out;
1528        }
1529        mutex_unlock(&mvm->mutex);
1530
1531        for (i = 0; i < ARRAY_SIZE(cmd.macs); i++) {
1532                const struct iwl_fw_bcast_mac *mac = &cmd.macs[i];
1533
1534                ADD_TEXT("Mac [%d]: discard=%d attached_filters=0x%x\n",
1535                         i, mac->default_discard, mac->attached_filters);
1536        }
1537out:
1538        ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1539        kfree(buf);
1540        return ret;
1541}
1542
1543static ssize_t iwl_dbgfs_bcast_filters_macs_write(struct iwl_mvm *mvm,
1544                                                  char *buf, size_t count,
1545                                                  loff_t *ppos)
1546{
1547        struct iwl_bcast_filter_cmd cmd;
1548        struct iwl_fw_bcast_mac mac = {};
1549        u32 mac_id, attached_filters;
1550        int err = 0;
1551
1552        if (!mvm->bcast_filters)
1553                return -ENOENT;
1554
1555        if (sscanf(buf, "%d %hhi %i", &mac_id, &mac.default_discard,
1556                   &attached_filters) != 3)
1557                return -EINVAL;
1558
1559        if (mac_id >= ARRAY_SIZE(cmd.macs) ||
1560            mac.default_discard > 1 ||
1561            attached_filters >= BIT(ARRAY_SIZE(cmd.filters)))
1562                return -EINVAL;
1563
1564        mac.attached_filters = cpu_to_le16(attached_filters);
1565
1566        mutex_lock(&mvm->mutex);
1567        memcpy(&mvm->dbgfs_bcast_filtering.cmd.macs[mac_id],
1568               &mac, sizeof(mac));
1569
1570        /* send updated bcast filtering configuration */
1571        if (iwl_mvm_firmware_running(mvm) &&
1572            mvm->dbgfs_bcast_filtering.override &&
1573            iwl_mvm_bcast_filter_build_cmd(mvm, &cmd))
1574                err = iwl_mvm_send_cmd_pdu(mvm, BCAST_FILTER_CMD, 0,
1575                                           sizeof(cmd), &cmd);
1576        mutex_unlock(&mvm->mutex);
1577
1578        return err ?: count;
1579}
1580#endif
1581
1582#define PRINT_MVM_REF(ref) do {                                         \
1583        if (mvm->refs[ref])                                             \
1584                pos += scnprintf(buf + pos, bufsz - pos,                \
1585                                 "\t(0x%lx): %d %s\n",                  \
1586                                 BIT(ref), mvm->refs[ref], #ref);       \
1587} while (0)
1588
1589static ssize_t iwl_dbgfs_d0i3_refs_read(struct file *file,
1590                                        char __user *user_buf,
1591                                        size_t count, loff_t *ppos)
1592{
1593        struct iwl_mvm *mvm = file->private_data;
1594        int i, pos = 0;
1595        char buf[256];
1596        const size_t bufsz = sizeof(buf);
1597        u32 refs = 0;
1598
1599        for (i = 0; i < IWL_MVM_REF_COUNT; i++)
1600                if (mvm->refs[i])
1601                        refs |= BIT(i);
1602
1603        pos += scnprintf(buf + pos, bufsz - pos, "taken mvm refs: 0x%x\n",
1604                         refs);
1605
1606        PRINT_MVM_REF(IWL_MVM_REF_UCODE_DOWN);
1607        PRINT_MVM_REF(IWL_MVM_REF_SCAN);
1608        PRINT_MVM_REF(IWL_MVM_REF_ROC);
1609        PRINT_MVM_REF(IWL_MVM_REF_ROC_AUX);
1610        PRINT_MVM_REF(IWL_MVM_REF_P2P_CLIENT);
1611        PRINT_MVM_REF(IWL_MVM_REF_AP_IBSS);
1612        PRINT_MVM_REF(IWL_MVM_REF_USER);
1613        PRINT_MVM_REF(IWL_MVM_REF_TX);
1614        PRINT_MVM_REF(IWL_MVM_REF_TX_AGG);
1615        PRINT_MVM_REF(IWL_MVM_REF_ADD_IF);
1616        PRINT_MVM_REF(IWL_MVM_REF_START_AP);
1617        PRINT_MVM_REF(IWL_MVM_REF_BSS_CHANGED);
1618        PRINT_MVM_REF(IWL_MVM_REF_PREPARE_TX);
1619        PRINT_MVM_REF(IWL_MVM_REF_PROTECT_TDLS);
1620        PRINT_MVM_REF(IWL_MVM_REF_CHECK_CTKILL);
1621        PRINT_MVM_REF(IWL_MVM_REF_PRPH_READ);
1622        PRINT_MVM_REF(IWL_MVM_REF_PRPH_WRITE);
1623        PRINT_MVM_REF(IWL_MVM_REF_NMI);
1624        PRINT_MVM_REF(IWL_MVM_REF_TM_CMD);
1625        PRINT_MVM_REF(IWL_MVM_REF_EXIT_WORK);
1626        PRINT_MVM_REF(IWL_MVM_REF_PROTECT_CSA);
1627        PRINT_MVM_REF(IWL_MVM_REF_FW_DBG_COLLECT);
1628        PRINT_MVM_REF(IWL_MVM_REF_INIT_UCODE);
1629        PRINT_MVM_REF(IWL_MVM_REF_SENDING_CMD);
1630        PRINT_MVM_REF(IWL_MVM_REF_RX);
1631
1632        return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1633}
1634
1635static ssize_t iwl_dbgfs_d0i3_refs_write(struct iwl_mvm *mvm, char *buf,
1636                                         size_t count, loff_t *ppos)
1637{
1638        unsigned long value;
1639        int ret;
1640        bool taken;
1641
1642        ret = kstrtoul(buf, 10, &value);
1643        if (ret < 0)
1644                return ret;
1645
1646        mutex_lock(&mvm->mutex);
1647
1648        taken = mvm->refs[IWL_MVM_REF_USER];
1649        if (value == 1 && !taken)
1650                iwl_mvm_ref(mvm, IWL_MVM_REF_USER);
1651        else if (value == 0 && taken)
1652                iwl_mvm_unref(mvm, IWL_MVM_REF_USER);
1653        else
1654                ret = -EINVAL;
1655
1656        mutex_unlock(&mvm->mutex);
1657
1658        if (ret < 0)
1659                return ret;
1660        return count;
1661}
1662
1663#define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \
1664        _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm)
1665#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
1666        _MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm)
1667#define MVM_DEBUGFS_ADD_FILE_ALIAS(alias, name, parent, mode) do {      \
1668                debugfs_create_file(alias, mode, parent, mvm,           \
1669                                    &iwl_dbgfs_##name##_ops);           \
1670        } while (0)
1671#define MVM_DEBUGFS_ADD_FILE(name, parent, mode) \
1672        MVM_DEBUGFS_ADD_FILE_ALIAS(#name, name, parent, mode)
1673
1674#define MVM_DEBUGFS_WRITE_STA_FILE_OPS(name, bufsz) \
1675        _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct ieee80211_sta)
1676#define MVM_DEBUGFS_READ_WRITE_STA_FILE_OPS(name, bufsz) \
1677        _MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct ieee80211_sta)
1678
1679#define MVM_DEBUGFS_ADD_STA_FILE_ALIAS(alias, name, parent, mode) do {  \
1680                debugfs_create_file(alias, mode, parent, sta,           \
1681                                    &iwl_dbgfs_##name##_ops);           \
1682        } while (0)
1683#define MVM_DEBUGFS_ADD_STA_FILE(name, parent, mode) \
1684        MVM_DEBUGFS_ADD_STA_FILE_ALIAS(#name, name, parent, mode)
1685
1686static ssize_t
1687iwl_dbgfs_prph_reg_read(struct file *file,
1688                        char __user *user_buf,
1689                        size_t count, loff_t *ppos)
1690{
1691        struct iwl_mvm *mvm = file->private_data;
1692        int pos = 0;
1693        char buf[32];
1694        const size_t bufsz = sizeof(buf);
1695        int ret;
1696
1697        if (!mvm->dbgfs_prph_reg_addr)
1698                return -EINVAL;
1699
1700        ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PRPH_READ);
1701        if (ret)
1702                return ret;
1703
1704        pos += scnprintf(buf + pos, bufsz - pos, "Reg 0x%x: (0x%x)\n",
1705                mvm->dbgfs_prph_reg_addr,
1706                iwl_read_prph(mvm->trans, mvm->dbgfs_prph_reg_addr));
1707
1708        iwl_mvm_unref(mvm, IWL_MVM_REF_PRPH_READ);
1709
1710        return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1711}
1712
1713static ssize_t
1714iwl_dbgfs_prph_reg_write(struct iwl_mvm *mvm, char *buf,
1715                         size_t count, loff_t *ppos)
1716{
1717        u8 args;
1718        u32 value;
1719        int ret;
1720
1721        args = sscanf(buf, "%i %i", &mvm->dbgfs_prph_reg_addr, &value);
1722        /* if we only want to set the reg address - nothing more to do */
1723        if (args == 1)
1724                goto out;
1725
1726        /* otherwise, make sure we have both address and value */
1727        if (args != 2)
1728                return -EINVAL;
1729
1730        ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PRPH_WRITE);
1731        if (ret)
1732                return ret;
1733
1734        iwl_write_prph(mvm->trans, mvm->dbgfs_prph_reg_addr, value);
1735
1736        iwl_mvm_unref(mvm, IWL_MVM_REF_PRPH_WRITE);
1737out:
1738        return count;
1739}
1740
1741static ssize_t
1742iwl_dbgfs_send_echo_cmd_write(struct iwl_mvm *mvm, char *buf,
1743                              size_t count, loff_t *ppos)
1744{
1745        int ret;
1746
1747        if (!iwl_mvm_firmware_running(mvm))
1748                return -EIO;
1749
1750        mutex_lock(&mvm->mutex);
1751        ret = iwl_mvm_send_cmd_pdu(mvm, ECHO_CMD, 0, 0, NULL);
1752        mutex_unlock(&mvm->mutex);
1753
1754        return ret ?: count;
1755}
1756
1757struct iwl_mvm_sniffer_apply {
1758        struct iwl_mvm *mvm;
1759        u8 *bssid;
1760        u16 aid;
1761};
1762
1763static bool iwl_mvm_sniffer_apply(struct iwl_notif_wait_data *notif_data,
1764                                  struct iwl_rx_packet *pkt, void *data)
1765{
1766        struct iwl_mvm_sniffer_apply *apply = data;
1767
1768        apply->mvm->cur_aid = cpu_to_le16(apply->aid);
1769        memcpy(apply->mvm->cur_bssid, apply->bssid,
1770               sizeof(apply->mvm->cur_bssid));
1771
1772        return true;
1773}
1774
1775static ssize_t
1776iwl_dbgfs_he_sniffer_params_write(struct iwl_mvm *mvm, char *buf,
1777                                  size_t count, loff_t *ppos)
1778{
1779        struct iwl_notification_wait wait;
1780        struct iwl_he_monitor_cmd he_mon_cmd = {};
1781        struct iwl_mvm_sniffer_apply apply = {
1782                .mvm = mvm,
1783        };
1784        u16 wait_cmds[] = {
1785                iwl_cmd_id(HE_AIR_SNIFFER_CONFIG_CMD, DATA_PATH_GROUP, 0),
1786        };
1787        u32 aid;
1788        int ret;
1789
1790        if (!iwl_mvm_firmware_running(mvm))
1791                return -EIO;
1792
1793        ret = sscanf(buf, "%x %2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx", &aid,
1794                     &he_mon_cmd.bssid[0], &he_mon_cmd.bssid[1],
1795                     &he_mon_cmd.bssid[2], &he_mon_cmd.bssid[3],
1796                     &he_mon_cmd.bssid[4], &he_mon_cmd.bssid[5]);
1797        if (ret != 7)
1798                return -EINVAL;
1799
1800        he_mon_cmd.aid = cpu_to_le16(aid);
1801
1802        apply.aid = aid;
1803        apply.bssid = (void *)he_mon_cmd.bssid;
1804
1805        mutex_lock(&mvm->mutex);
1806
1807        /*
1808         * Use the notification waiter to get our function triggered
1809         * in sequence with other RX. This ensures that frames we get
1810         * on the RX queue _before_ the new configuration is applied
1811         * still have mvm->cur_aid pointing to the old AID, and that
1812         * frames on the RX queue _after_ the firmware processed the
1813         * new configuration (and sent the response, synchronously)
1814         * get mvm->cur_aid correctly set to the new AID.
1815         */
1816        iwl_init_notification_wait(&mvm->notif_wait, &wait,
1817                                   wait_cmds, ARRAY_SIZE(wait_cmds),
1818                                   iwl_mvm_sniffer_apply, &apply);
1819
1820        ret = iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(HE_AIR_SNIFFER_CONFIG_CMD,
1821                                                   DATA_PATH_GROUP, 0), 0,
1822                                   sizeof(he_mon_cmd), &he_mon_cmd);
1823
1824        /* no need to really wait, we already did anyway */
1825        iwl_remove_notification(&mvm->notif_wait, &wait);
1826
1827        mutex_unlock(&mvm->mutex);
1828
1829        return ret ?: count;
1830}
1831
1832static ssize_t
1833iwl_dbgfs_he_sniffer_params_read(struct file *file, char __user *user_buf,
1834                                 size_t count, loff_t *ppos)
1835{
1836        struct iwl_mvm *mvm = file->private_data;
1837        u8 buf[32];
1838        int len;
1839
1840        len = scnprintf(buf, sizeof(buf),
1841                        "%d %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n",
1842                        le16_to_cpu(mvm->cur_aid), mvm->cur_bssid[0],
1843                        mvm->cur_bssid[1], mvm->cur_bssid[2], mvm->cur_bssid[3],
1844                        mvm->cur_bssid[4], mvm->cur_bssid[5]);
1845
1846        return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1847}
1848
1849static ssize_t
1850iwl_dbgfs_uapsd_noagg_bssids_read(struct file *file, char __user *user_buf,
1851                                  size_t count, loff_t *ppos)
1852{
1853        struct iwl_mvm *mvm = file->private_data;
1854        u8 buf[IWL_MVM_UAPSD_NOAGG_BSSIDS_NUM * ETH_ALEN * 3 + 1];
1855        unsigned int pos = 0;
1856        size_t bufsz = sizeof(buf);
1857        int i;
1858
1859        mutex_lock(&mvm->mutex);
1860
1861        for (i = 0; i < IWL_MVM_UAPSD_NOAGG_LIST_LEN; i++)
1862                pos += scnprintf(buf + pos, bufsz - pos, "%pM\n",
1863                                 mvm->uapsd_noagg_bssids[i].addr);
1864
1865        mutex_unlock(&mvm->mutex);
1866
1867        return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1868}
1869
1870MVM_DEBUGFS_READ_WRITE_FILE_OPS(prph_reg, 64);
1871
1872/* Device wide debugfs entries */
1873MVM_DEBUGFS_READ_FILE_OPS(ctdp_budget);
1874MVM_DEBUGFS_WRITE_FILE_OPS(stop_ctdp, 8);
1875MVM_DEBUGFS_WRITE_FILE_OPS(force_ctkill, 8);
1876MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush, 16);
1877MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain, 8);
1878MVM_DEBUGFS_WRITE_FILE_OPS(send_echo_cmd, 8);
1879MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram, 64);
1880MVM_DEBUGFS_READ_WRITE_FILE_OPS(set_nic_temperature, 64);
1881MVM_DEBUGFS_READ_FILE_OPS(nic_temp);
1882MVM_DEBUGFS_READ_FILE_OPS(stations);
1883MVM_DEBUGFS_READ_FILE_OPS(rs_data);
1884MVM_DEBUGFS_READ_FILE_OPS(bt_notif);
1885MVM_DEBUGFS_READ_FILE_OPS(bt_cmd);
1886MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off, 64);
1887MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats);
1888MVM_DEBUGFS_READ_FILE_OPS(drv_rx_stats);
1889MVM_DEBUGFS_READ_FILE_OPS(fw_ver);
1890MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart, 10);
1891MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi, 10);
1892MVM_DEBUGFS_WRITE_FILE_OPS(bt_tx_prio, 10);
1893MVM_DEBUGFS_WRITE_FILE_OPS(bt_force_ant, 10);
1894MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8);
1895MVM_DEBUGFS_READ_WRITE_FILE_OPS(d0i3_refs, 8);
1896MVM_DEBUGFS_READ_WRITE_FILE_OPS(fw_dbg_conf, 8);
1897MVM_DEBUGFS_WRITE_FILE_OPS(fw_dbg_collect, 64);
1898MVM_DEBUGFS_WRITE_FILE_OPS(indirection_tbl,
1899                           (IWL_RSS_INDIRECTION_TABLE_SIZE * 2));
1900MVM_DEBUGFS_WRITE_FILE_OPS(inject_packet, 512);
1901MVM_DEBUGFS_WRITE_FILE_OPS(inject_beacon_ie, 512);
1902MVM_DEBUGFS_WRITE_FILE_OPS(inject_beacon_ie_restore, 512);
1903
1904MVM_DEBUGFS_READ_FILE_OPS(uapsd_noagg_bssids);
1905
1906#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
1907MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters, 256);
1908MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters_macs, 256);
1909#endif
1910
1911#ifdef CONFIG_ACPI
1912MVM_DEBUGFS_READ_FILE_OPS(sar_geo_profile);
1913#endif
1914
1915MVM_DEBUGFS_READ_WRITE_STA_FILE_OPS(amsdu_len, 16);
1916
1917MVM_DEBUGFS_READ_WRITE_FILE_OPS(he_sniffer_params, 32);
1918
1919static ssize_t iwl_dbgfs_mem_read(struct file *file, char __user *user_buf,
1920                                  size_t count, loff_t *ppos)
1921{
1922        struct iwl_mvm *mvm = file->private_data;
1923        struct iwl_dbg_mem_access_cmd cmd = {};
1924        struct iwl_dbg_mem_access_rsp *rsp;
1925        struct iwl_host_cmd hcmd = {
1926                .flags = CMD_WANT_SKB | CMD_SEND_IN_RFKILL,
1927                .data = { &cmd, },
1928                .len = { sizeof(cmd) },
1929        };
1930        size_t delta;
1931        ssize_t ret, len;
1932
1933        if (!iwl_mvm_firmware_running(mvm))
1934                return -EIO;
1935
1936        hcmd.id = iwl_cmd_id(*ppos >> 24 ? UMAC_RD_WR : LMAC_RD_WR,
1937                             DEBUG_GROUP, 0);
1938        cmd.op = cpu_to_le32(DEBUG_MEM_OP_READ);
1939
1940        /* Take care of alignment of both the position and the length */
1941        delta = *ppos & 0x3;
1942        cmd.addr = cpu_to_le32(*ppos - delta);
1943        cmd.len = cpu_to_le32(min(ALIGN(count + delta, 4) / 4,
1944                                  (size_t)DEBUG_MEM_MAX_SIZE_DWORDS));
1945
1946        mutex_lock(&mvm->mutex);
1947        ret = iwl_mvm_send_cmd(mvm, &hcmd);
1948        mutex_unlock(&mvm->mutex);
1949
1950        if (ret < 0)
1951                return ret;
1952
1953        rsp = (void *)hcmd.resp_pkt->data;
1954        if (le32_to_cpu(rsp->status) != DEBUG_MEM_STATUS_SUCCESS) {
1955                ret = -ENXIO;
1956                goto out;
1957        }
1958
1959        len = min((size_t)le32_to_cpu(rsp->len) << 2,
1960                  iwl_rx_packet_payload_len(hcmd.resp_pkt) - sizeof(*rsp));
1961        len = min(len - delta, count);
1962        if (len < 0) {
1963                ret = -EFAULT;
1964                goto out;
1965        }
1966
1967        ret = len - copy_to_user(user_buf, (void *)rsp->data + delta, len);
1968        *ppos += ret;
1969
1970out:
1971        iwl_free_resp(&hcmd);
1972        return ret;
1973}
1974
1975static ssize_t iwl_dbgfs_mem_write(struct file *file,
1976                                   const char __user *user_buf, size_t count,
1977                                   loff_t *ppos)
1978{
1979        struct iwl_mvm *mvm = file->private_data;
1980        struct iwl_dbg_mem_access_cmd *cmd;
1981        struct iwl_dbg_mem_access_rsp *rsp;
1982        struct iwl_host_cmd hcmd = {};
1983        size_t cmd_size;
1984        size_t data_size;
1985        u32 op, len;
1986        ssize_t ret;
1987
1988        if (!iwl_mvm_firmware_running(mvm))
1989                return -EIO;
1990
1991        hcmd.id = iwl_cmd_id(*ppos >> 24 ? UMAC_RD_WR : LMAC_RD_WR,
1992                             DEBUG_GROUP, 0);
1993
1994        if (*ppos & 0x3 || count < 4) {
1995                op = DEBUG_MEM_OP_WRITE_BYTES;
1996                len = min(count, (size_t)(4 - (*ppos & 0x3)));
1997                data_size = len;
1998        } else {
1999                op = DEBUG_MEM_OP_WRITE;
2000                len = min(count >> 2, (size_t)DEBUG_MEM_MAX_SIZE_DWORDS);
2001                data_size = len << 2;
2002        }
2003
2004        cmd_size = sizeof(*cmd) + ALIGN(data_size, 4);
2005        cmd = kzalloc(cmd_size, GFP_KERNEL);
2006        if (!cmd)
2007                return -ENOMEM;
2008
2009        cmd->op = cpu_to_le32(op);
2010        cmd->len = cpu_to_le32(len);
2011        cmd->addr = cpu_to_le32(*ppos);
2012        if (copy_from_user((void *)cmd->data, user_buf, data_size)) {
2013                kfree(cmd);
2014                return -EFAULT;
2015        }
2016
2017        hcmd.flags = CMD_WANT_SKB | CMD_SEND_IN_RFKILL,
2018        hcmd.data[0] = (void *)cmd;
2019        hcmd.len[0] = cmd_size;
2020
2021        mutex_lock(&mvm->mutex);
2022        ret = iwl_mvm_send_cmd(mvm, &hcmd);
2023        mutex_unlock(&mvm->mutex);
2024
2025        kfree(cmd);
2026
2027        if (ret < 0)
2028                return ret;
2029
2030        rsp = (void *)hcmd.resp_pkt->data;
2031        if (rsp->status != DEBUG_MEM_STATUS_SUCCESS) {
2032                ret = -ENXIO;
2033                goto out;
2034        }
2035
2036        ret = data_size;
2037        *ppos += ret;
2038
2039out:
2040        iwl_free_resp(&hcmd);
2041        return ret;
2042}
2043
2044static const struct file_operations iwl_dbgfs_mem_ops = {
2045        .read = iwl_dbgfs_mem_read,
2046        .write = iwl_dbgfs_mem_write,
2047        .open = simple_open,
2048        .llseek = default_llseek,
2049};
2050
2051void iwl_mvm_sta_add_debugfs(struct ieee80211_hw *hw,
2052                             struct ieee80211_vif *vif,
2053                             struct ieee80211_sta *sta,
2054                             struct dentry *dir)
2055{
2056        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2057
2058        if (iwl_mvm_has_tlc_offload(mvm)) {
2059                MVM_DEBUGFS_ADD_STA_FILE(rs_data, dir, 0400);
2060        }
2061        MVM_DEBUGFS_ADD_STA_FILE(amsdu_len, dir, 0600);
2062}
2063
2064void iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
2065{
2066        struct dentry *bcast_dir __maybe_unused;
2067        char buf[100];
2068
2069        spin_lock_init(&mvm->drv_stats_lock);
2070
2071        mvm->debugfs_dir = dbgfs_dir;
2072
2073        MVM_DEBUGFS_ADD_FILE(tx_flush, mvm->debugfs_dir, 0200);
2074        MVM_DEBUGFS_ADD_FILE(sta_drain, mvm->debugfs_dir, 0200);
2075        MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, 0600);
2076        MVM_DEBUGFS_ADD_FILE(set_nic_temperature, mvm->debugfs_dir, 0600);
2077        MVM_DEBUGFS_ADD_FILE(nic_temp, dbgfs_dir, 0400);
2078        MVM_DEBUGFS_ADD_FILE(ctdp_budget, dbgfs_dir, 0400);
2079        MVM_DEBUGFS_ADD_FILE(stop_ctdp, dbgfs_dir, 0200);
2080        MVM_DEBUGFS_ADD_FILE(force_ctkill, dbgfs_dir, 0200);
2081        MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, 0400);
2082        MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, 0400);
2083        MVM_DEBUGFS_ADD_FILE(bt_cmd, dbgfs_dir, 0400);
2084        MVM_DEBUGFS_ADD_FILE(disable_power_off, mvm->debugfs_dir, 0600);
2085        MVM_DEBUGFS_ADD_FILE(fw_ver, mvm->debugfs_dir, 0400);
2086        MVM_DEBUGFS_ADD_FILE(fw_rx_stats, mvm->debugfs_dir, 0400);
2087        MVM_DEBUGFS_ADD_FILE(drv_rx_stats, mvm->debugfs_dir, 0400);
2088        MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, 0200);
2089        MVM_DEBUGFS_ADD_FILE(fw_nmi, mvm->debugfs_dir, 0200);
2090        MVM_DEBUGFS_ADD_FILE(bt_tx_prio, mvm->debugfs_dir, 0200);
2091        MVM_DEBUGFS_ADD_FILE(bt_force_ant, mvm->debugfs_dir, 0200);
2092        MVM_DEBUGFS_ADD_FILE(scan_ant_rxchain, mvm->debugfs_dir, 0600);
2093        MVM_DEBUGFS_ADD_FILE(prph_reg, mvm->debugfs_dir, 0600);
2094        MVM_DEBUGFS_ADD_FILE(d0i3_refs, mvm->debugfs_dir, 0600);
2095        MVM_DEBUGFS_ADD_FILE(fw_dbg_conf, mvm->debugfs_dir, 0600);
2096        MVM_DEBUGFS_ADD_FILE(fw_dbg_collect, mvm->debugfs_dir, 0200);
2097        MVM_DEBUGFS_ADD_FILE(send_echo_cmd, mvm->debugfs_dir, 0200);
2098        MVM_DEBUGFS_ADD_FILE(indirection_tbl, mvm->debugfs_dir, 0200);
2099        MVM_DEBUGFS_ADD_FILE(inject_packet, mvm->debugfs_dir, 0200);
2100        MVM_DEBUGFS_ADD_FILE(inject_beacon_ie, mvm->debugfs_dir, 0200);
2101        MVM_DEBUGFS_ADD_FILE(inject_beacon_ie_restore, mvm->debugfs_dir, 0200);
2102#ifdef CONFIG_ACPI
2103        MVM_DEBUGFS_ADD_FILE(sar_geo_profile, dbgfs_dir, 0400);
2104#endif
2105        MVM_DEBUGFS_ADD_FILE(he_sniffer_params, mvm->debugfs_dir, 0600);
2106
2107        debugfs_create_bool("enable_scan_iteration_notif", 0600,
2108                            mvm->debugfs_dir, &mvm->scan_iter_notif_enabled);
2109        debugfs_create_bool("drop_bcn_ap_mode", 0600, mvm->debugfs_dir,
2110                            &mvm->drop_bcn_ap_mode);
2111
2112        MVM_DEBUGFS_ADD_FILE(uapsd_noagg_bssids, mvm->debugfs_dir, S_IRUSR);
2113
2114#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
2115        if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BCAST_FILTERING) {
2116                bcast_dir = debugfs_create_dir("bcast_filtering",
2117                                               mvm->debugfs_dir);
2118
2119                debugfs_create_bool("override", 0600, bcast_dir,
2120                                    &mvm->dbgfs_bcast_filtering.override);
2121
2122                MVM_DEBUGFS_ADD_FILE_ALIAS("filters", bcast_filters,
2123                                           bcast_dir, 0600);
2124                MVM_DEBUGFS_ADD_FILE_ALIAS("macs", bcast_filters_macs,
2125                                           bcast_dir, 0600);
2126        }
2127#endif
2128
2129#ifdef CONFIG_PM_SLEEP
2130        MVM_DEBUGFS_ADD_FILE(d3_test, mvm->debugfs_dir, 0400);
2131        debugfs_create_bool("d3_wake_sysassert", 0600, mvm->debugfs_dir,
2132                            &mvm->d3_wake_sysassert);
2133        debugfs_create_u32("last_netdetect_scans", 0400, mvm->debugfs_dir,
2134                           &mvm->last_netdetect_scans);
2135#endif
2136
2137        debugfs_create_u8("ps_disabled", 0400, mvm->debugfs_dir,
2138                          &mvm->ps_disabled);
2139        debugfs_create_blob("nvm_hw", 0400, mvm->debugfs_dir,
2140                            &mvm->nvm_hw_blob);
2141        debugfs_create_blob("nvm_sw", 0400, mvm->debugfs_dir,
2142                            &mvm->nvm_sw_blob);
2143        debugfs_create_blob("nvm_calib", 0400, mvm->debugfs_dir,
2144                            &mvm->nvm_calib_blob);
2145        debugfs_create_blob("nvm_prod", 0400, mvm->debugfs_dir,
2146                            &mvm->nvm_prod_blob);
2147        debugfs_create_blob("nvm_phy_sku", 0400, mvm->debugfs_dir,
2148                            &mvm->nvm_phy_sku_blob);
2149        debugfs_create_blob("nvm_reg", S_IRUSR,
2150                            mvm->debugfs_dir, &mvm->nvm_reg_blob);
2151
2152        debugfs_create_file("mem", 0600, dbgfs_dir, mvm, &iwl_dbgfs_mem_ops);
2153
2154        /*
2155         * Create a symlink with mac80211. It will be removed when mac80211
2156         * exists (before the opmode exists which removes the target.)
2157         */
2158        snprintf(buf, 100, "../../%pd2", dbgfs_dir->d_parent);
2159        debugfs_create_symlink("iwlwifi", mvm->hw->wiphy->debugfsdir, buf);
2160}
2161