root/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c

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

DEFINITIONS

This source file includes following definitions.
  1. iwl_dbgfs_ctdp_budget_read
  2. iwl_dbgfs_stop_ctdp_write
  3. iwl_dbgfs_force_ctkill_write
  4. iwl_dbgfs_tx_flush_write
  5. iwl_dbgfs_sta_drain_write
  6. iwl_dbgfs_sram_read
  7. iwl_dbgfs_sram_write
  8. iwl_dbgfs_set_nic_temperature_read
  9. iwl_dbgfs_set_nic_temperature_write
  10. iwl_dbgfs_nic_temp_read
  11. iwl_dbgfs_sar_geo_profile_read
  12. iwl_dbgfs_stations_read
  13. iwl_dbgfs_rs_data_read
  14. iwl_dbgfs_amsdu_len_write
  15. iwl_dbgfs_amsdu_len_read
  16. iwl_dbgfs_disable_power_off_read
  17. iwl_dbgfs_disable_power_off_write
  18. iwl_mvm_coex_dump_mbox
  19. iwl_dbgfs_bt_notif_read
  20. iwl_dbgfs_bt_cmd_read
  21. iwl_dbgfs_bt_tx_prio_write
  22. iwl_dbgfs_bt_force_ant_write
  23. iwl_dbgfs_fw_ver_read
  24. iwl_dbgfs_fw_rx_stats_read
  25. iwl_dbgfs_frame_stats_read
  26. iwl_dbgfs_drv_rx_stats_read
  27. iwl_dbgfs_fw_restart_write
  28. iwl_dbgfs_fw_nmi_write
  29. iwl_dbgfs_scan_ant_rxchain_read
  30. iwl_dbgfs_scan_ant_rxchain_write
  31. iwl_dbgfs_indirection_tbl_write
  32. iwl_dbgfs_inject_packet_write
  33. _iwl_dbgfs_inject_beacon_ie
  34. iwl_dbgfs_inject_beacon_ie_write
  35. iwl_dbgfs_inject_beacon_ie_restore_write
  36. iwl_dbgfs_fw_dbg_conf_read
  37. iwl_dbgfs_fw_dbg_conf_write
  38. iwl_dbgfs_fw_dbg_collect_write
  39. iwl_dbgfs_bcast_filters_read
  40. iwl_dbgfs_bcast_filters_write
  41. iwl_dbgfs_bcast_filters_macs_read
  42. iwl_dbgfs_bcast_filters_macs_write
  43. iwl_dbgfs_prph_reg_read
  44. iwl_dbgfs_prph_reg_write
  45. iwl_dbgfs_send_echo_cmd_write
  46. iwl_mvm_sniffer_apply
  47. iwl_dbgfs_he_sniffer_params_write
  48. iwl_dbgfs_he_sniffer_params_read
  49. iwl_dbgfs_uapsd_noagg_bssids_read
  50. iwl_dbgfs_ltr_config_write
  51. iwl_dbgfs_mem_read
  52. iwl_dbgfs_mem_write
  53. iwl_mvm_sta_add_debugfs
  54. iwl_mvm_dbgfs_register

   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 
  75 static 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 
 102 static 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 
 121 static 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 
 133 static 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 
 166 static 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 
 197 static 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 
 232 static 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 
 263 static 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  */
 286 static 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 
 324 out:
 325         mutex_unlock(&mvm->mutex);
 326 
 327         return count;
 328 }
 329 
 330 static 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
 355 static 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 
 397 static 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 
 426 static 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 
 470 static 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 
 493 static 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 
 510 static 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 
 527 static 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 
 554 static
 555 int 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 
 614 static 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 
 658 static 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 
 682 static ssize_t
 683 iwl_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 
 698 static ssize_t
 699 iwl_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 
 729 out:
 730         mutex_unlock(&mvm->mutex);
 731         return ret ?: count;
 732 }
 733 
 734 static 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 
 769 static 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 
 959 static 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 
1024 static 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 
1034 static 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 
1056 static ssize_t iwl_dbgfs_fw_nmi_write(struct iwl_mvm *mvm, char *buf,
1057                                       size_t count, loff_t *ppos)
1058 {
1059         if (!iwl_mvm_firmware_running(mvm))
1060                 return -EIO;
1061 
1062         iwl_force_nmi(mvm->trans);
1063 
1064         return count;
1065 }
1066 
1067 static ssize_t
1068 iwl_dbgfs_scan_ant_rxchain_read(struct file *file,
1069                                 char __user *user_buf,
1070                                 size_t count, loff_t *ppos)
1071 {
1072         struct iwl_mvm *mvm = file->private_data;
1073         int pos = 0;
1074         char buf[32];
1075         const size_t bufsz = sizeof(buf);
1076 
1077         /* print which antennas were set for the scan command by the user */
1078         pos += scnprintf(buf + pos, bufsz - pos, "Antennas for scan: ");
1079         if (mvm->scan_rx_ant & ANT_A)
1080                 pos += scnprintf(buf + pos, bufsz - pos, "A");
1081         if (mvm->scan_rx_ant & ANT_B)
1082                 pos += scnprintf(buf + pos, bufsz - pos, "B");
1083         if (mvm->scan_rx_ant & ANT_C)
1084                 pos += scnprintf(buf + pos, bufsz - pos, "C");
1085         pos += scnprintf(buf + pos, bufsz - pos, " (%hhx)\n", mvm->scan_rx_ant);
1086 
1087         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1088 }
1089 
1090 static ssize_t
1091 iwl_dbgfs_scan_ant_rxchain_write(struct iwl_mvm *mvm, char *buf,
1092                                  size_t count, loff_t *ppos)
1093 {
1094         u8 scan_rx_ant;
1095 
1096         if (!iwl_mvm_firmware_running(mvm))
1097                 return -EIO;
1098 
1099         if (sscanf(buf, "%hhx", &scan_rx_ant) != 1)
1100                 return -EINVAL;
1101         if (scan_rx_ant > ANT_ABC)
1102                 return -EINVAL;
1103         if (scan_rx_ant & ~(iwl_mvm_get_valid_rx_ant(mvm)))
1104                 return -EINVAL;
1105 
1106         if (mvm->scan_rx_ant != scan_rx_ant) {
1107                 mvm->scan_rx_ant = scan_rx_ant;
1108                 if (fw_has_capa(&mvm->fw->ucode_capa,
1109                                 IWL_UCODE_TLV_CAPA_UMAC_SCAN))
1110                         iwl_mvm_config_scan(mvm);
1111         }
1112 
1113         return count;
1114 }
1115 
1116 static ssize_t iwl_dbgfs_indirection_tbl_write(struct iwl_mvm *mvm,
1117                                                char *buf, size_t count,
1118                                                loff_t *ppos)
1119 {
1120         struct iwl_rss_config_cmd cmd = {
1121                 .flags = cpu_to_le32(IWL_RSS_ENABLE),
1122                 .hash_mask = IWL_RSS_HASH_TYPE_IPV4_TCP |
1123                              IWL_RSS_HASH_TYPE_IPV4_UDP |
1124                              IWL_RSS_HASH_TYPE_IPV4_PAYLOAD |
1125                              IWL_RSS_HASH_TYPE_IPV6_TCP |
1126                              IWL_RSS_HASH_TYPE_IPV6_UDP |
1127                              IWL_RSS_HASH_TYPE_IPV6_PAYLOAD,
1128         };
1129         int ret, i, num_repeats, nbytes = count / 2;
1130 
1131         ret = hex2bin(cmd.indirection_table, buf, nbytes);
1132         if (ret)
1133                 return ret;
1134 
1135         /*
1136          * The input is the redirection table, partial or full.
1137          * Repeat the pattern if needed.
1138          * For example, input of 01020F will be repeated 42 times,
1139          * indirecting RSS hash results to queues 1, 2, 15 (skipping
1140          * queues 3 - 14).
1141          */
1142         num_repeats = ARRAY_SIZE(cmd.indirection_table) / nbytes;
1143         for (i = 1; i < num_repeats; i++)
1144                 memcpy(&cmd.indirection_table[i * nbytes],
1145                        cmd.indirection_table, nbytes);
1146         /* handle cut in the middle pattern for the last places */
1147         memcpy(&cmd.indirection_table[i * nbytes], cmd.indirection_table,
1148                ARRAY_SIZE(cmd.indirection_table) % nbytes);
1149 
1150         netdev_rss_key_fill(cmd.secret_key, sizeof(cmd.secret_key));
1151 
1152         mutex_lock(&mvm->mutex);
1153         if (iwl_mvm_firmware_running(mvm))
1154                 ret = iwl_mvm_send_cmd_pdu(mvm, RSS_CONFIG_CMD, 0,
1155                                            sizeof(cmd), &cmd);
1156         else
1157                 ret = 0;
1158         mutex_unlock(&mvm->mutex);
1159 
1160         return ret ?: count;
1161 }
1162 
1163 static ssize_t iwl_dbgfs_inject_packet_write(struct iwl_mvm *mvm,
1164                                              char *buf, size_t count,
1165                                              loff_t *ppos)
1166 {
1167         struct iwl_rx_cmd_buffer rxb = {
1168                 ._rx_page_order = 0,
1169                 .truesize = 0, /* not used */
1170                 ._offset = 0,
1171         };
1172         struct iwl_rx_packet *pkt;
1173         struct iwl_rx_mpdu_desc *desc;
1174         int bin_len = count / 2;
1175         int ret = -EINVAL;
1176         size_t mpdu_cmd_hdr_size = (mvm->trans->trans_cfg->device_family >=
1177                                     IWL_DEVICE_FAMILY_22560) ?
1178                 sizeof(struct iwl_rx_mpdu_desc) :
1179                 IWL_RX_DESC_SIZE_V1;
1180 
1181         if (!iwl_mvm_firmware_running(mvm))
1182                 return -EIO;
1183 
1184         /* supporting only 9000 descriptor */
1185         if (!mvm->trans->trans_cfg->mq_rx_supported)
1186                 return -ENOTSUPP;
1187 
1188         rxb._page = alloc_pages(GFP_ATOMIC, 0);
1189         if (!rxb._page)
1190                 return -ENOMEM;
1191         pkt = rxb_addr(&rxb);
1192 
1193         ret = hex2bin(page_address(rxb._page), buf, bin_len);
1194         if (ret)
1195                 goto out;
1196 
1197         /* avoid invalid memory access */
1198         if (bin_len < sizeof(*pkt) + mpdu_cmd_hdr_size)
1199                 goto out;
1200 
1201         /* check this is RX packet */
1202         if (WIDE_ID(pkt->hdr.group_id, pkt->hdr.cmd) !=
1203             WIDE_ID(LEGACY_GROUP, REPLY_RX_MPDU_CMD))
1204                 goto out;
1205 
1206         /* check the length in metadata matches actual received length */
1207         desc = (void *)pkt->data;
1208         if (le16_to_cpu(desc->mpdu_len) !=
1209             (bin_len - mpdu_cmd_hdr_size - sizeof(*pkt)))
1210                 goto out;
1211 
1212         local_bh_disable();
1213         iwl_mvm_rx_mpdu_mq(mvm, NULL, &rxb, 0);
1214         local_bh_enable();
1215         ret = 0;
1216 
1217 out:
1218         iwl_free_rxb(&rxb);
1219 
1220         return ret ?: count;
1221 }
1222 
1223 static int _iwl_dbgfs_inject_beacon_ie(struct iwl_mvm *mvm, char *bin, int len)
1224 {
1225         struct ieee80211_vif *vif;
1226         struct iwl_mvm_vif *mvmvif;
1227         struct sk_buff *beacon;
1228         struct ieee80211_tx_info *info;
1229         struct iwl_mac_beacon_cmd beacon_cmd = {};
1230         u8 rate;
1231         u16 flags;
1232         int i;
1233 
1234         len /= 2;
1235 
1236         /* Element len should be represented by u8 */
1237         if (len >= U8_MAX)
1238                 return -EINVAL;
1239 
1240         if (!iwl_mvm_firmware_running(mvm))
1241                 return -EIO;
1242 
1243         if (!iwl_mvm_has_new_tx_api(mvm) &&
1244             !fw_has_api(&mvm->fw->ucode_capa,
1245                         IWL_UCODE_TLV_API_NEW_BEACON_TEMPLATE))
1246                 return -EINVAL;
1247 
1248         rcu_read_lock();
1249 
1250         for (i = 0; i < NUM_MAC_INDEX_DRIVER; i++) {
1251                 vif = iwl_mvm_rcu_dereference_vif_id(mvm, i, true);
1252                 if (!vif)
1253                         continue;
1254 
1255                 if (vif->type == NL80211_IFTYPE_AP)
1256                         break;
1257         }
1258 
1259         if (i == NUM_MAC_INDEX_DRIVER || !vif)
1260                 goto out_err;
1261 
1262         mvm->hw->extra_beacon_tailroom = len;
1263 
1264         beacon = ieee80211_beacon_get_template(mvm->hw, vif, NULL);
1265         if (!beacon)
1266                 goto out_err;
1267 
1268         if (len && hex2bin(skb_put_zero(beacon, len), bin, len)) {
1269                 dev_kfree_skb(beacon);
1270                 goto out_err;
1271         }
1272 
1273         mvm->beacon_inject_active = true;
1274 
1275         mvmvif = iwl_mvm_vif_from_mac80211(vif);
1276         info = IEEE80211_SKB_CB(beacon);
1277         rate = iwl_mvm_mac_ctxt_get_lowest_rate(info, vif);
1278         flags = iwl_mvm_mac80211_idx_to_hwrate(rate);
1279 
1280         if (rate == IWL_FIRST_CCK_RATE)
1281                 flags |= IWL_MAC_BEACON_CCK;
1282 
1283         beacon_cmd.flags = cpu_to_le16(flags);
1284         beacon_cmd.byte_cnt = cpu_to_le16((u16)beacon->len);
1285         beacon_cmd.template_id = cpu_to_le32((u32)mvmvif->id);
1286 
1287         iwl_mvm_mac_ctxt_set_tim(mvm, &beacon_cmd.tim_idx,
1288                                  &beacon_cmd.tim_size,
1289                                  beacon->data, beacon->len);
1290 
1291         mutex_lock(&mvm->mutex);
1292         iwl_mvm_mac_ctxt_send_beacon_cmd(mvm, beacon, &beacon_cmd,
1293                                          sizeof(beacon_cmd));
1294         mutex_unlock(&mvm->mutex);
1295 
1296         dev_kfree_skb(beacon);
1297 
1298         rcu_read_unlock();
1299         return 0;
1300 
1301 out_err:
1302         rcu_read_unlock();
1303         return -EINVAL;
1304 }
1305 
1306 static ssize_t iwl_dbgfs_inject_beacon_ie_write(struct iwl_mvm *mvm,
1307                                                 char *buf, size_t count,
1308                                                 loff_t *ppos)
1309 {
1310         int ret = _iwl_dbgfs_inject_beacon_ie(mvm, buf, count);
1311 
1312         mvm->hw->extra_beacon_tailroom = 0;
1313         return ret ?: count;
1314 }
1315 
1316 static ssize_t iwl_dbgfs_inject_beacon_ie_restore_write(struct iwl_mvm *mvm,
1317                                                         char *buf,
1318                                                         size_t count,
1319                                                         loff_t *ppos)
1320 {
1321         int ret = _iwl_dbgfs_inject_beacon_ie(mvm, NULL, 0);
1322 
1323         mvm->hw->extra_beacon_tailroom = 0;
1324         mvm->beacon_inject_active = false;
1325         return ret ?: count;
1326 }
1327 
1328 static ssize_t iwl_dbgfs_fw_dbg_conf_read(struct file *file,
1329                                           char __user *user_buf,
1330                                           size_t count, loff_t *ppos)
1331 {
1332         struct iwl_mvm *mvm = file->private_data;
1333         int conf;
1334         char buf[8];
1335         const size_t bufsz = sizeof(buf);
1336         int pos = 0;
1337 
1338         mutex_lock(&mvm->mutex);
1339         conf = mvm->fwrt.dump.conf;
1340         mutex_unlock(&mvm->mutex);
1341 
1342         pos += scnprintf(buf + pos, bufsz - pos, "%d\n", conf);
1343 
1344         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1345 }
1346 
1347 static ssize_t iwl_dbgfs_fw_dbg_conf_write(struct iwl_mvm *mvm,
1348                                            char *buf, size_t count,
1349                                            loff_t *ppos)
1350 {
1351         unsigned int conf_id;
1352         int ret;
1353 
1354         if (!iwl_mvm_firmware_running(mvm))
1355                 return -EIO;
1356 
1357         ret = kstrtouint(buf, 0, &conf_id);
1358         if (ret)
1359                 return ret;
1360 
1361         if (WARN_ON(conf_id >= FW_DBG_CONF_MAX))
1362                 return -EINVAL;
1363 
1364         mutex_lock(&mvm->mutex);
1365         ret = iwl_fw_start_dbg_conf(&mvm->fwrt, conf_id);
1366         mutex_unlock(&mvm->mutex);
1367 
1368         return ret ?: count;
1369 }
1370 
1371 static ssize_t iwl_dbgfs_fw_dbg_collect_write(struct iwl_mvm *mvm,
1372                                               char *buf, size_t count,
1373                                               loff_t *ppos)
1374 {
1375         if (count == 0)
1376                 return 0;
1377 
1378         iwl_fw_dbg_collect(&mvm->fwrt, FW_DBG_TRIGGER_USER, buf,
1379                            (count - 1), NULL);
1380 
1381         return count;
1382 }
1383 
1384 #define ADD_TEXT(...) pos += scnprintf(buf + pos, bufsz - pos, __VA_ARGS__)
1385 #ifdef CONFIG_IWLWIFI_BCAST_FILTERING
1386 static ssize_t iwl_dbgfs_bcast_filters_read(struct file *file,
1387                                             char __user *user_buf,
1388                                             size_t count, loff_t *ppos)
1389 {
1390         struct iwl_mvm *mvm = file->private_data;
1391         struct iwl_bcast_filter_cmd cmd;
1392         const struct iwl_fw_bcast_filter *filter;
1393         char *buf;
1394         int bufsz = 1024;
1395         int i, j, pos = 0;
1396         ssize_t ret;
1397 
1398         buf = kzalloc(bufsz, GFP_KERNEL);
1399         if (!buf)
1400                 return -ENOMEM;
1401 
1402         mutex_lock(&mvm->mutex);
1403         if (!iwl_mvm_bcast_filter_build_cmd(mvm, &cmd)) {
1404                 ADD_TEXT("None\n");
1405                 mutex_unlock(&mvm->mutex);
1406                 goto out;
1407         }
1408         mutex_unlock(&mvm->mutex);
1409 
1410         for (i = 0; cmd.filters[i].attrs[0].mask; i++) {
1411                 filter = &cmd.filters[i];
1412 
1413                 ADD_TEXT("Filter [%d]:\n", i);
1414                 ADD_TEXT("\tDiscard=%d\n", filter->discard);
1415                 ADD_TEXT("\tFrame Type: %s\n",
1416                          filter->frame_type ? "IPv4" : "Generic");
1417 
1418                 for (j = 0; j < ARRAY_SIZE(filter->attrs); j++) {
1419                         const struct iwl_fw_bcast_filter_attr *attr;
1420 
1421                         attr = &filter->attrs[j];
1422                         if (!attr->mask)
1423                                 break;
1424 
1425                         ADD_TEXT("\tAttr [%d]: offset=%d (from %s), mask=0x%x, value=0x%x reserved=0x%x\n",
1426                                  j, attr->offset,
1427                                  attr->offset_type ? "IP End" :
1428                                                      "Payload Start",
1429                                  be32_to_cpu(attr->mask),
1430                                  be32_to_cpu(attr->val),
1431                                  le16_to_cpu(attr->reserved1));
1432                 }
1433         }
1434 out:
1435         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1436         kfree(buf);
1437         return ret;
1438 }
1439 
1440 static ssize_t iwl_dbgfs_bcast_filters_write(struct iwl_mvm *mvm, char *buf,
1441                                              size_t count, loff_t *ppos)
1442 {
1443         int pos, next_pos;
1444         struct iwl_fw_bcast_filter filter = {};
1445         struct iwl_bcast_filter_cmd cmd;
1446         u32 filter_id, attr_id, mask, value;
1447         int err = 0;
1448 
1449         if (sscanf(buf, "%d %hhi %hhi %n", &filter_id, &filter.discard,
1450                    &filter.frame_type, &pos) != 3)
1451                 return -EINVAL;
1452 
1453         if (filter_id >= ARRAY_SIZE(mvm->dbgfs_bcast_filtering.cmd.filters) ||
1454             filter.frame_type > BCAST_FILTER_FRAME_TYPE_IPV4)
1455                 return -EINVAL;
1456 
1457         for (attr_id = 0; attr_id < ARRAY_SIZE(filter.attrs);
1458              attr_id++) {
1459                 struct iwl_fw_bcast_filter_attr *attr =
1460                                 &filter.attrs[attr_id];
1461 
1462                 if (pos >= count)
1463                         break;
1464 
1465                 if (sscanf(&buf[pos], "%hhi %hhi %i %i %n",
1466                            &attr->offset, &attr->offset_type,
1467                            &mask, &value, &next_pos) != 4)
1468                         return -EINVAL;
1469 
1470                 attr->mask = cpu_to_be32(mask);
1471                 attr->val = cpu_to_be32(value);
1472                 if (mask)
1473                         filter.num_attrs++;
1474 
1475                 pos += next_pos;
1476         }
1477 
1478         mutex_lock(&mvm->mutex);
1479         memcpy(&mvm->dbgfs_bcast_filtering.cmd.filters[filter_id],
1480                &filter, sizeof(filter));
1481 
1482         /* send updated bcast filtering configuration */
1483         if (iwl_mvm_firmware_running(mvm) &&
1484             mvm->dbgfs_bcast_filtering.override &&
1485             iwl_mvm_bcast_filter_build_cmd(mvm, &cmd))
1486                 err = iwl_mvm_send_cmd_pdu(mvm, BCAST_FILTER_CMD, 0,
1487                                            sizeof(cmd), &cmd);
1488         mutex_unlock(&mvm->mutex);
1489 
1490         return err ?: count;
1491 }
1492 
1493 static ssize_t iwl_dbgfs_bcast_filters_macs_read(struct file *file,
1494                                                  char __user *user_buf,
1495                                                  size_t count, loff_t *ppos)
1496 {
1497         struct iwl_mvm *mvm = file->private_data;
1498         struct iwl_bcast_filter_cmd cmd;
1499         char *buf;
1500         int bufsz = 1024;
1501         int i, pos = 0;
1502         ssize_t ret;
1503 
1504         buf = kzalloc(bufsz, GFP_KERNEL);
1505         if (!buf)
1506                 return -ENOMEM;
1507 
1508         mutex_lock(&mvm->mutex);
1509         if (!iwl_mvm_bcast_filter_build_cmd(mvm, &cmd)) {
1510                 ADD_TEXT("None\n");
1511                 mutex_unlock(&mvm->mutex);
1512                 goto out;
1513         }
1514         mutex_unlock(&mvm->mutex);
1515 
1516         for (i = 0; i < ARRAY_SIZE(cmd.macs); i++) {
1517                 const struct iwl_fw_bcast_mac *mac = &cmd.macs[i];
1518 
1519                 ADD_TEXT("Mac [%d]: discard=%d attached_filters=0x%x\n",
1520                          i, mac->default_discard, mac->attached_filters);
1521         }
1522 out:
1523         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1524         kfree(buf);
1525         return ret;
1526 }
1527 
1528 static ssize_t iwl_dbgfs_bcast_filters_macs_write(struct iwl_mvm *mvm,
1529                                                   char *buf, size_t count,
1530                                                   loff_t *ppos)
1531 {
1532         struct iwl_bcast_filter_cmd cmd;
1533         struct iwl_fw_bcast_mac mac = {};
1534         u32 mac_id, attached_filters;
1535         int err = 0;
1536 
1537         if (!mvm->bcast_filters)
1538                 return -ENOENT;
1539 
1540         if (sscanf(buf, "%d %hhi %i", &mac_id, &mac.default_discard,
1541                    &attached_filters) != 3)
1542                 return -EINVAL;
1543 
1544         if (mac_id >= ARRAY_SIZE(cmd.macs) ||
1545             mac.default_discard > 1 ||
1546             attached_filters >= BIT(ARRAY_SIZE(cmd.filters)))
1547                 return -EINVAL;
1548 
1549         mac.attached_filters = cpu_to_le16(attached_filters);
1550 
1551         mutex_lock(&mvm->mutex);
1552         memcpy(&mvm->dbgfs_bcast_filtering.cmd.macs[mac_id],
1553                &mac, sizeof(mac));
1554 
1555         /* send updated bcast filtering configuration */
1556         if (iwl_mvm_firmware_running(mvm) &&
1557             mvm->dbgfs_bcast_filtering.override &&
1558             iwl_mvm_bcast_filter_build_cmd(mvm, &cmd))
1559                 err = iwl_mvm_send_cmd_pdu(mvm, BCAST_FILTER_CMD, 0,
1560                                            sizeof(cmd), &cmd);
1561         mutex_unlock(&mvm->mutex);
1562 
1563         return err ?: count;
1564 }
1565 #endif
1566 
1567 #define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \
1568         _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm)
1569 #define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
1570         _MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm)
1571 #define MVM_DEBUGFS_ADD_FILE_ALIAS(alias, name, parent, mode) do {      \
1572                 debugfs_create_file(alias, mode, parent, mvm,           \
1573                                     &iwl_dbgfs_##name##_ops);           \
1574         } while (0)
1575 #define MVM_DEBUGFS_ADD_FILE(name, parent, mode) \
1576         MVM_DEBUGFS_ADD_FILE_ALIAS(#name, name, parent, mode)
1577 
1578 #define MVM_DEBUGFS_WRITE_STA_FILE_OPS(name, bufsz) \
1579         _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct ieee80211_sta)
1580 #define MVM_DEBUGFS_READ_WRITE_STA_FILE_OPS(name, bufsz) \
1581         _MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct ieee80211_sta)
1582 
1583 #define MVM_DEBUGFS_ADD_STA_FILE_ALIAS(alias, name, parent, mode) do {  \
1584                 debugfs_create_file(alias, mode, parent, sta,           \
1585                                     &iwl_dbgfs_##name##_ops);           \
1586         } while (0)
1587 #define MVM_DEBUGFS_ADD_STA_FILE(name, parent, mode) \
1588         MVM_DEBUGFS_ADD_STA_FILE_ALIAS(#name, name, parent, mode)
1589 
1590 static ssize_t
1591 iwl_dbgfs_prph_reg_read(struct file *file,
1592                         char __user *user_buf,
1593                         size_t count, loff_t *ppos)
1594 {
1595         struct iwl_mvm *mvm = file->private_data;
1596         int pos = 0;
1597         char buf[32];
1598         const size_t bufsz = sizeof(buf);
1599 
1600         if (!mvm->dbgfs_prph_reg_addr)
1601                 return -EINVAL;
1602 
1603         pos += scnprintf(buf + pos, bufsz - pos, "Reg 0x%x: (0x%x)\n",
1604                 mvm->dbgfs_prph_reg_addr,
1605                 iwl_read_prph(mvm->trans, mvm->dbgfs_prph_reg_addr));
1606 
1607         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1608 }
1609 
1610 static ssize_t
1611 iwl_dbgfs_prph_reg_write(struct iwl_mvm *mvm, char *buf,
1612                          size_t count, loff_t *ppos)
1613 {
1614         u8 args;
1615         u32 value;
1616 
1617         args = sscanf(buf, "%i %i", &mvm->dbgfs_prph_reg_addr, &value);
1618         /* if we only want to set the reg address - nothing more to do */
1619         if (args == 1)
1620                 goto out;
1621 
1622         /* otherwise, make sure we have both address and value */
1623         if (args != 2)
1624                 return -EINVAL;
1625 
1626         iwl_write_prph(mvm->trans, mvm->dbgfs_prph_reg_addr, value);
1627 
1628 out:
1629         return count;
1630 }
1631 
1632 static ssize_t
1633 iwl_dbgfs_send_echo_cmd_write(struct iwl_mvm *mvm, char *buf,
1634                               size_t count, loff_t *ppos)
1635 {
1636         int ret;
1637 
1638         if (!iwl_mvm_firmware_running(mvm))
1639                 return -EIO;
1640 
1641         mutex_lock(&mvm->mutex);
1642         ret = iwl_mvm_send_cmd_pdu(mvm, ECHO_CMD, 0, 0, NULL);
1643         mutex_unlock(&mvm->mutex);
1644 
1645         return ret ?: count;
1646 }
1647 
1648 struct iwl_mvm_sniffer_apply {
1649         struct iwl_mvm *mvm;
1650         u8 *bssid;
1651         u16 aid;
1652 };
1653 
1654 static bool iwl_mvm_sniffer_apply(struct iwl_notif_wait_data *notif_data,
1655                                   struct iwl_rx_packet *pkt, void *data)
1656 {
1657         struct iwl_mvm_sniffer_apply *apply = data;
1658 
1659         apply->mvm->cur_aid = cpu_to_le16(apply->aid);
1660         memcpy(apply->mvm->cur_bssid, apply->bssid,
1661                sizeof(apply->mvm->cur_bssid));
1662 
1663         return true;
1664 }
1665 
1666 static ssize_t
1667 iwl_dbgfs_he_sniffer_params_write(struct iwl_mvm *mvm, char *buf,
1668                                   size_t count, loff_t *ppos)
1669 {
1670         struct iwl_notification_wait wait;
1671         struct iwl_he_monitor_cmd he_mon_cmd = {};
1672         struct iwl_mvm_sniffer_apply apply = {
1673                 .mvm = mvm,
1674         };
1675         u16 wait_cmds[] = {
1676                 iwl_cmd_id(HE_AIR_SNIFFER_CONFIG_CMD, DATA_PATH_GROUP, 0),
1677         };
1678         u32 aid;
1679         int ret;
1680 
1681         if (!iwl_mvm_firmware_running(mvm))
1682                 return -EIO;
1683 
1684         ret = sscanf(buf, "%x %2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx", &aid,
1685                      &he_mon_cmd.bssid[0], &he_mon_cmd.bssid[1],
1686                      &he_mon_cmd.bssid[2], &he_mon_cmd.bssid[3],
1687                      &he_mon_cmd.bssid[4], &he_mon_cmd.bssid[5]);
1688         if (ret != 7)
1689                 return -EINVAL;
1690 
1691         he_mon_cmd.aid = cpu_to_le16(aid);
1692 
1693         apply.aid = aid;
1694         apply.bssid = (void *)he_mon_cmd.bssid;
1695 
1696         mutex_lock(&mvm->mutex);
1697 
1698         /*
1699          * Use the notification waiter to get our function triggered
1700          * in sequence with other RX. This ensures that frames we get
1701          * on the RX queue _before_ the new configuration is applied
1702          * still have mvm->cur_aid pointing to the old AID, and that
1703          * frames on the RX queue _after_ the firmware processed the
1704          * new configuration (and sent the response, synchronously)
1705          * get mvm->cur_aid correctly set to the new AID.
1706          */
1707         iwl_init_notification_wait(&mvm->notif_wait, &wait,
1708                                    wait_cmds, ARRAY_SIZE(wait_cmds),
1709                                    iwl_mvm_sniffer_apply, &apply);
1710 
1711         ret = iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(HE_AIR_SNIFFER_CONFIG_CMD,
1712                                                    DATA_PATH_GROUP, 0), 0,
1713                                    sizeof(he_mon_cmd), &he_mon_cmd);
1714 
1715         /* no need to really wait, we already did anyway */
1716         iwl_remove_notification(&mvm->notif_wait, &wait);
1717 
1718         mutex_unlock(&mvm->mutex);
1719 
1720         return ret ?: count;
1721 }
1722 
1723 static ssize_t
1724 iwl_dbgfs_he_sniffer_params_read(struct file *file, char __user *user_buf,
1725                                  size_t count, loff_t *ppos)
1726 {
1727         struct iwl_mvm *mvm = file->private_data;
1728         u8 buf[32];
1729         int len;
1730 
1731         len = scnprintf(buf, sizeof(buf),
1732                         "%d %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n",
1733                         le16_to_cpu(mvm->cur_aid), mvm->cur_bssid[0],
1734                         mvm->cur_bssid[1], mvm->cur_bssid[2], mvm->cur_bssid[3],
1735                         mvm->cur_bssid[4], mvm->cur_bssid[5]);
1736 
1737         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1738 }
1739 
1740 static ssize_t
1741 iwl_dbgfs_uapsd_noagg_bssids_read(struct file *file, char __user *user_buf,
1742                                   size_t count, loff_t *ppos)
1743 {
1744         struct iwl_mvm *mvm = file->private_data;
1745         u8 buf[IWL_MVM_UAPSD_NOAGG_BSSIDS_NUM * ETH_ALEN * 3 + 1];
1746         unsigned int pos = 0;
1747         size_t bufsz = sizeof(buf);
1748         int i;
1749 
1750         mutex_lock(&mvm->mutex);
1751 
1752         for (i = 0; i < IWL_MVM_UAPSD_NOAGG_LIST_LEN; i++)
1753                 pos += scnprintf(buf + pos, bufsz - pos, "%pM\n",
1754                                  mvm->uapsd_noagg_bssids[i].addr);
1755 
1756         mutex_unlock(&mvm->mutex);
1757 
1758         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1759 }
1760 
1761 static ssize_t
1762 iwl_dbgfs_ltr_config_write(struct iwl_mvm *mvm,
1763                            char *buf, size_t count, loff_t *ppos)
1764 {
1765         int ret;
1766         struct iwl_ltr_config_cmd ltr_config = {0};
1767 
1768         if (!iwl_mvm_firmware_running(mvm))
1769                 return -EIO;
1770 
1771         if (sscanf(buf, "%x,%x,%x,%x,%x,%x,%x",
1772                    &ltr_config.flags,
1773                    &ltr_config.static_long,
1774                    &ltr_config.static_short,
1775                    &ltr_config.ltr_cfg_values[0],
1776                    &ltr_config.ltr_cfg_values[1],
1777                    &ltr_config.ltr_cfg_values[2],
1778                    &ltr_config.ltr_cfg_values[3]) != 7) {
1779                 return -EINVAL;
1780         }
1781 
1782         mutex_lock(&mvm->mutex);
1783         ret = iwl_mvm_send_cmd_pdu(mvm, LTR_CONFIG, 0, sizeof(ltr_config),
1784                                    &ltr_config);
1785         mutex_unlock(&mvm->mutex);
1786 
1787         if (ret)
1788                 IWL_ERR(mvm, "failed to send ltr configuration cmd\n");
1789 
1790         return ret ?: count;
1791 }
1792 
1793 MVM_DEBUGFS_READ_WRITE_FILE_OPS(prph_reg, 64);
1794 
1795 /* Device wide debugfs entries */
1796 MVM_DEBUGFS_READ_FILE_OPS(ctdp_budget);
1797 MVM_DEBUGFS_WRITE_FILE_OPS(stop_ctdp, 8);
1798 MVM_DEBUGFS_WRITE_FILE_OPS(force_ctkill, 8);
1799 MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush, 16);
1800 MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain, 8);
1801 MVM_DEBUGFS_WRITE_FILE_OPS(send_echo_cmd, 8);
1802 MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram, 64);
1803 MVM_DEBUGFS_READ_WRITE_FILE_OPS(set_nic_temperature, 64);
1804 MVM_DEBUGFS_READ_FILE_OPS(nic_temp);
1805 MVM_DEBUGFS_READ_FILE_OPS(stations);
1806 MVM_DEBUGFS_READ_FILE_OPS(rs_data);
1807 MVM_DEBUGFS_READ_FILE_OPS(bt_notif);
1808 MVM_DEBUGFS_READ_FILE_OPS(bt_cmd);
1809 MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off, 64);
1810 MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats);
1811 MVM_DEBUGFS_READ_FILE_OPS(drv_rx_stats);
1812 MVM_DEBUGFS_READ_FILE_OPS(fw_ver);
1813 MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart, 10);
1814 MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi, 10);
1815 MVM_DEBUGFS_WRITE_FILE_OPS(bt_tx_prio, 10);
1816 MVM_DEBUGFS_WRITE_FILE_OPS(bt_force_ant, 10);
1817 MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8);
1818 MVM_DEBUGFS_READ_WRITE_FILE_OPS(fw_dbg_conf, 8);
1819 MVM_DEBUGFS_WRITE_FILE_OPS(fw_dbg_collect, 64);
1820 MVM_DEBUGFS_WRITE_FILE_OPS(indirection_tbl,
1821                            (IWL_RSS_INDIRECTION_TABLE_SIZE * 2));
1822 MVM_DEBUGFS_WRITE_FILE_OPS(inject_packet, 512);
1823 MVM_DEBUGFS_WRITE_FILE_OPS(inject_beacon_ie, 512);
1824 MVM_DEBUGFS_WRITE_FILE_OPS(inject_beacon_ie_restore, 512);
1825 
1826 MVM_DEBUGFS_READ_FILE_OPS(uapsd_noagg_bssids);
1827 
1828 #ifdef CONFIG_IWLWIFI_BCAST_FILTERING
1829 MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters, 256);
1830 MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters_macs, 256);
1831 #endif
1832 
1833 #ifdef CONFIG_ACPI
1834 MVM_DEBUGFS_READ_FILE_OPS(sar_geo_profile);
1835 #endif
1836 
1837 MVM_DEBUGFS_READ_WRITE_STA_FILE_OPS(amsdu_len, 16);
1838 
1839 MVM_DEBUGFS_READ_WRITE_FILE_OPS(he_sniffer_params, 32);
1840 
1841 MVM_DEBUGFS_WRITE_FILE_OPS(ltr_config, 512);
1842 
1843 static ssize_t iwl_dbgfs_mem_read(struct file *file, char __user *user_buf,
1844                                   size_t count, loff_t *ppos)
1845 {
1846         struct iwl_mvm *mvm = file->private_data;
1847         struct iwl_dbg_mem_access_cmd cmd = {};
1848         struct iwl_dbg_mem_access_rsp *rsp;
1849         struct iwl_host_cmd hcmd = {
1850                 .flags = CMD_WANT_SKB | CMD_SEND_IN_RFKILL,
1851                 .data = { &cmd, },
1852                 .len = { sizeof(cmd) },
1853         };
1854         size_t delta;
1855         ssize_t ret, len;
1856 
1857         if (!iwl_mvm_firmware_running(mvm))
1858                 return -EIO;
1859 
1860         hcmd.id = iwl_cmd_id(*ppos >> 24 ? UMAC_RD_WR : LMAC_RD_WR,
1861                              DEBUG_GROUP, 0);
1862         cmd.op = cpu_to_le32(DEBUG_MEM_OP_READ);
1863 
1864         /* Take care of alignment of both the position and the length */
1865         delta = *ppos & 0x3;
1866         cmd.addr = cpu_to_le32(*ppos - delta);
1867         cmd.len = cpu_to_le32(min(ALIGN(count + delta, 4) / 4,
1868                                   (size_t)DEBUG_MEM_MAX_SIZE_DWORDS));
1869 
1870         mutex_lock(&mvm->mutex);
1871         ret = iwl_mvm_send_cmd(mvm, &hcmd);
1872         mutex_unlock(&mvm->mutex);
1873 
1874         if (ret < 0)
1875                 return ret;
1876 
1877         rsp = (void *)hcmd.resp_pkt->data;
1878         if (le32_to_cpu(rsp->status) != DEBUG_MEM_STATUS_SUCCESS) {
1879                 ret = -ENXIO;
1880                 goto out;
1881         }
1882 
1883         len = min((size_t)le32_to_cpu(rsp->len) << 2,
1884                   iwl_rx_packet_payload_len(hcmd.resp_pkt) - sizeof(*rsp));
1885         len = min(len - delta, count);
1886         if (len < 0) {
1887                 ret = -EFAULT;
1888                 goto out;
1889         }
1890 
1891         ret = len - copy_to_user(user_buf, (void *)rsp->data + delta, len);
1892         *ppos += ret;
1893 
1894 out:
1895         iwl_free_resp(&hcmd);
1896         return ret;
1897 }
1898 
1899 static ssize_t iwl_dbgfs_mem_write(struct file *file,
1900                                    const char __user *user_buf, size_t count,
1901                                    loff_t *ppos)
1902 {
1903         struct iwl_mvm *mvm = file->private_data;
1904         struct iwl_dbg_mem_access_cmd *cmd;
1905         struct iwl_dbg_mem_access_rsp *rsp;
1906         struct iwl_host_cmd hcmd = {};
1907         size_t cmd_size;
1908         size_t data_size;
1909         u32 op, len;
1910         ssize_t ret;
1911 
1912         if (!iwl_mvm_firmware_running(mvm))
1913                 return -EIO;
1914 
1915         hcmd.id = iwl_cmd_id(*ppos >> 24 ? UMAC_RD_WR : LMAC_RD_WR,
1916                              DEBUG_GROUP, 0);
1917 
1918         if (*ppos & 0x3 || count < 4) {
1919                 op = DEBUG_MEM_OP_WRITE_BYTES;
1920                 len = min(count, (size_t)(4 - (*ppos & 0x3)));
1921                 data_size = len;
1922         } else {
1923                 op = DEBUG_MEM_OP_WRITE;
1924                 len = min(count >> 2, (size_t)DEBUG_MEM_MAX_SIZE_DWORDS);
1925                 data_size = len << 2;
1926         }
1927 
1928         cmd_size = sizeof(*cmd) + ALIGN(data_size, 4);
1929         cmd = kzalloc(cmd_size, GFP_KERNEL);
1930         if (!cmd)
1931                 return -ENOMEM;
1932 
1933         cmd->op = cpu_to_le32(op);
1934         cmd->len = cpu_to_le32(len);
1935         cmd->addr = cpu_to_le32(*ppos);
1936         if (copy_from_user((void *)cmd->data, user_buf, data_size)) {
1937                 kfree(cmd);
1938                 return -EFAULT;
1939         }
1940 
1941         hcmd.flags = CMD_WANT_SKB | CMD_SEND_IN_RFKILL,
1942         hcmd.data[0] = (void *)cmd;
1943         hcmd.len[0] = cmd_size;
1944 
1945         mutex_lock(&mvm->mutex);
1946         ret = iwl_mvm_send_cmd(mvm, &hcmd);
1947         mutex_unlock(&mvm->mutex);
1948 
1949         kfree(cmd);
1950 
1951         if (ret < 0)
1952                 return ret;
1953 
1954         rsp = (void *)hcmd.resp_pkt->data;
1955         if (rsp->status != DEBUG_MEM_STATUS_SUCCESS) {
1956                 ret = -ENXIO;
1957                 goto out;
1958         }
1959 
1960         ret = data_size;
1961         *ppos += ret;
1962 
1963 out:
1964         iwl_free_resp(&hcmd);
1965         return ret;
1966 }
1967 
1968 static const struct file_operations iwl_dbgfs_mem_ops = {
1969         .read = iwl_dbgfs_mem_read,
1970         .write = iwl_dbgfs_mem_write,
1971         .open = simple_open,
1972         .llseek = default_llseek,
1973 };
1974 
1975 void iwl_mvm_sta_add_debugfs(struct ieee80211_hw *hw,
1976                              struct ieee80211_vif *vif,
1977                              struct ieee80211_sta *sta,
1978                              struct dentry *dir)
1979 {
1980         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1981 
1982         if (iwl_mvm_has_tlc_offload(mvm)) {
1983                 MVM_DEBUGFS_ADD_STA_FILE(rs_data, dir, 0400);
1984         }
1985         MVM_DEBUGFS_ADD_STA_FILE(amsdu_len, dir, 0600);
1986 }
1987 
1988 void iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
1989 {
1990         struct dentry *bcast_dir __maybe_unused;
1991         char buf[100];
1992 
1993         spin_lock_init(&mvm->drv_stats_lock);
1994 
1995         mvm->debugfs_dir = dbgfs_dir;
1996 
1997         MVM_DEBUGFS_ADD_FILE(tx_flush, mvm->debugfs_dir, 0200);
1998         MVM_DEBUGFS_ADD_FILE(sta_drain, mvm->debugfs_dir, 0200);
1999         MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, 0600);
2000         MVM_DEBUGFS_ADD_FILE(set_nic_temperature, mvm->debugfs_dir, 0600);
2001         MVM_DEBUGFS_ADD_FILE(nic_temp, dbgfs_dir, 0400);
2002         MVM_DEBUGFS_ADD_FILE(ctdp_budget, dbgfs_dir, 0400);
2003         MVM_DEBUGFS_ADD_FILE(stop_ctdp, dbgfs_dir, 0200);
2004         MVM_DEBUGFS_ADD_FILE(force_ctkill, dbgfs_dir, 0200);
2005         MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, 0400);
2006         MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, 0400);
2007         MVM_DEBUGFS_ADD_FILE(bt_cmd, dbgfs_dir, 0400);
2008         MVM_DEBUGFS_ADD_FILE(disable_power_off, mvm->debugfs_dir, 0600);
2009         MVM_DEBUGFS_ADD_FILE(fw_ver, mvm->debugfs_dir, 0400);
2010         MVM_DEBUGFS_ADD_FILE(fw_rx_stats, mvm->debugfs_dir, 0400);
2011         MVM_DEBUGFS_ADD_FILE(drv_rx_stats, mvm->debugfs_dir, 0400);
2012         MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, 0200);
2013         MVM_DEBUGFS_ADD_FILE(fw_nmi, mvm->debugfs_dir, 0200);
2014         MVM_DEBUGFS_ADD_FILE(bt_tx_prio, mvm->debugfs_dir, 0200);
2015         MVM_DEBUGFS_ADD_FILE(bt_force_ant, mvm->debugfs_dir, 0200);
2016         MVM_DEBUGFS_ADD_FILE(scan_ant_rxchain, mvm->debugfs_dir, 0600);
2017         MVM_DEBUGFS_ADD_FILE(prph_reg, mvm->debugfs_dir, 0600);
2018         MVM_DEBUGFS_ADD_FILE(fw_dbg_conf, mvm->debugfs_dir, 0600);
2019         MVM_DEBUGFS_ADD_FILE(fw_dbg_collect, mvm->debugfs_dir, 0200);
2020         MVM_DEBUGFS_ADD_FILE(send_echo_cmd, mvm->debugfs_dir, 0200);
2021         MVM_DEBUGFS_ADD_FILE(indirection_tbl, mvm->debugfs_dir, 0200);
2022         MVM_DEBUGFS_ADD_FILE(inject_packet, mvm->debugfs_dir, 0200);
2023         MVM_DEBUGFS_ADD_FILE(inject_beacon_ie, mvm->debugfs_dir, 0200);
2024         MVM_DEBUGFS_ADD_FILE(inject_beacon_ie_restore, mvm->debugfs_dir, 0200);
2025 #ifdef CONFIG_ACPI
2026         MVM_DEBUGFS_ADD_FILE(sar_geo_profile, dbgfs_dir, 0400);
2027 #endif
2028         MVM_DEBUGFS_ADD_FILE(he_sniffer_params, mvm->debugfs_dir, 0600);
2029 
2030         if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SET_LTR_GEN2))
2031                 MVM_DEBUGFS_ADD_FILE(ltr_config, mvm->debugfs_dir, 0200);
2032 
2033         debugfs_create_bool("enable_scan_iteration_notif", 0600,
2034                             mvm->debugfs_dir, &mvm->scan_iter_notif_enabled);
2035         debugfs_create_bool("drop_bcn_ap_mode", 0600, mvm->debugfs_dir,
2036                             &mvm->drop_bcn_ap_mode);
2037 
2038         MVM_DEBUGFS_ADD_FILE(uapsd_noagg_bssids, mvm->debugfs_dir, S_IRUSR);
2039 
2040 #ifdef CONFIG_IWLWIFI_BCAST_FILTERING
2041         if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BCAST_FILTERING) {
2042                 bcast_dir = debugfs_create_dir("bcast_filtering",
2043                                                mvm->debugfs_dir);
2044 
2045                 debugfs_create_bool("override", 0600, bcast_dir,
2046                                     &mvm->dbgfs_bcast_filtering.override);
2047 
2048                 MVM_DEBUGFS_ADD_FILE_ALIAS("filters", bcast_filters,
2049                                            bcast_dir, 0600);
2050                 MVM_DEBUGFS_ADD_FILE_ALIAS("macs", bcast_filters_macs,
2051                                            bcast_dir, 0600);
2052         }
2053 #endif
2054 
2055 #ifdef CONFIG_PM_SLEEP
2056         MVM_DEBUGFS_ADD_FILE(d3_test, mvm->debugfs_dir, 0400);
2057         debugfs_create_bool("d3_wake_sysassert", 0600, mvm->debugfs_dir,
2058                             &mvm->d3_wake_sysassert);
2059         debugfs_create_u32("last_netdetect_scans", 0400, mvm->debugfs_dir,
2060                            &mvm->last_netdetect_scans);
2061 #endif
2062 
2063         debugfs_create_u8("ps_disabled", 0400, mvm->debugfs_dir,
2064                           &mvm->ps_disabled);
2065         debugfs_create_blob("nvm_hw", 0400, mvm->debugfs_dir,
2066                             &mvm->nvm_hw_blob);
2067         debugfs_create_blob("nvm_sw", 0400, mvm->debugfs_dir,
2068                             &mvm->nvm_sw_blob);
2069         debugfs_create_blob("nvm_calib", 0400, mvm->debugfs_dir,
2070                             &mvm->nvm_calib_blob);
2071         debugfs_create_blob("nvm_prod", 0400, mvm->debugfs_dir,
2072                             &mvm->nvm_prod_blob);
2073         debugfs_create_blob("nvm_phy_sku", 0400, mvm->debugfs_dir,
2074                             &mvm->nvm_phy_sku_blob);
2075         debugfs_create_blob("nvm_reg", S_IRUSR,
2076                             mvm->debugfs_dir, &mvm->nvm_reg_blob);
2077 
2078         debugfs_create_file("mem", 0600, dbgfs_dir, mvm, &iwl_dbgfs_mem_ops);
2079 
2080         /*
2081          * Create a symlink with mac80211. It will be removed when mac80211
2082          * exists (before the opmode exists which removes the target.)
2083          */
2084         snprintf(buf, 100, "../../%pd2", dbgfs_dir->d_parent);
2085         debugfs_create_symlink("iwlwifi", mvm->hw->wiphy->debugfsdir, buf);
2086 }

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