]> Git Repo - J-linux.git/blob - drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / drivers / net / wireless / intel / iwlwifi / mvm / debugfs.c
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /*
3  * Copyright (C) 2012-2014, 2018-2023 Intel Corporation
4  * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
5  * Copyright (C) 2016-2017 Intel Deutschland GmbH
6  */
7 #include <linux/vmalloc.h>
8 #include <linux/err.h>
9 #include <linux/ieee80211.h>
10 #include <linux/netdevice.h>
11 #include <linux/dmi.h>
12
13 #include "mvm.h"
14 #include "sta.h"
15 #include "iwl-io.h"
16 #include "debugfs.h"
17 #include "iwl-modparams.h"
18 #include "iwl-drv.h"
19 #include "fw/error-dump.h"
20 #include "fw/api/phy-ctxt.h"
21
22 static ssize_t iwl_dbgfs_ctdp_budget_read(struct file *file,
23                                           char __user *user_buf,
24                                           size_t count, loff_t *ppos)
25 {
26         struct iwl_mvm *mvm = file->private_data;
27         char buf[16];
28         int pos, budget;
29
30         if (!iwl_mvm_is_ctdp_supported(mvm))
31                 return -EOPNOTSUPP;
32
33         if (!iwl_mvm_firmware_running(mvm) ||
34             mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR)
35                 return -EIO;
36
37         mutex_lock(&mvm->mutex);
38         budget = iwl_mvm_ctdp_command(mvm, CTDP_CMD_OPERATION_REPORT, 0);
39         mutex_unlock(&mvm->mutex);
40
41         if (budget < 0)
42                 return budget;
43
44         pos = scnprintf(buf, sizeof(buf), "%d\n", budget);
45
46         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
47 }
48
49 static ssize_t iwl_dbgfs_stop_ctdp_write(struct iwl_mvm *mvm, char *buf,
50                                          size_t count, loff_t *ppos)
51 {
52         int ret;
53         bool force;
54
55         if (!kstrtobool(buf, &force))
56                 IWL_DEBUG_INFO(mvm,
57                                "force start is %d [0=disabled, 1=enabled]\n",
58                                force);
59
60         /* we allow skipping cap support check and force stop ctdp
61          * statistics collection and with guerantee that it is
62          * safe to use.
63          */
64         if (!force && !iwl_mvm_is_ctdp_supported(mvm))
65                 return -EOPNOTSUPP;
66
67         if (!iwl_mvm_firmware_running(mvm) ||
68             mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR)
69                 return -EIO;
70
71         mutex_lock(&mvm->mutex);
72         ret = iwl_mvm_ctdp_command(mvm, CTDP_CMD_OPERATION_STOP, 0);
73         mutex_unlock(&mvm->mutex);
74
75         return ret ?: count;
76 }
77
78 static ssize_t iwl_dbgfs_start_ctdp_write(struct iwl_mvm *mvm,
79                                           char *buf, size_t count,
80                                           loff_t *ppos)
81 {
82         int ret;
83         bool force;
84
85         if (!kstrtobool(buf, &force))
86                 IWL_DEBUG_INFO(mvm,
87                                "force start is %d [0=disabled, 1=enabled]\n",
88                                force);
89
90         /* we allow skipping cap support check and force enable ctdp
91          * for statistics collection and with guerantee that it is
92          * safe to use.
93          */
94         if (!force && !iwl_mvm_is_ctdp_supported(mvm))
95                 return -EOPNOTSUPP;
96
97         if (!iwl_mvm_firmware_running(mvm) ||
98             mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR)
99                 return -EIO;
100
101         mutex_lock(&mvm->mutex);
102         ret = iwl_mvm_ctdp_command(mvm, CTDP_CMD_OPERATION_START, 0);
103         mutex_unlock(&mvm->mutex);
104
105         return ret ?: count;
106 }
107
108 static ssize_t iwl_dbgfs_force_ctkill_write(struct iwl_mvm *mvm, char *buf,
109                                             size_t count, loff_t *ppos)
110 {
111         if (!iwl_mvm_firmware_running(mvm) ||
112             mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR)
113                 return -EIO;
114
115         iwl_mvm_enter_ctkill(mvm);
116
117         return count;
118 }
119
120 static ssize_t iwl_dbgfs_tx_flush_write(struct iwl_mvm *mvm, char *buf,
121                                         size_t count, loff_t *ppos)
122 {
123         int ret;
124         u32 flush_arg;
125
126         if (!iwl_mvm_firmware_running(mvm) ||
127             mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR)
128                 return -EIO;
129
130         if (kstrtou32(buf, 0, &flush_arg))
131                 return -EINVAL;
132
133         if (iwl_mvm_has_new_tx_api(mvm)) {
134                 IWL_DEBUG_TX_QUEUES(mvm,
135                                     "FLUSHING all tids queues on sta_id = %d\n",
136                                     flush_arg);
137                 mutex_lock(&mvm->mutex);
138                 ret = iwl_mvm_flush_sta_tids(mvm, flush_arg, 0xFFFF)
139                         ? : count;
140                 mutex_unlock(&mvm->mutex);
141                 return ret;
142         }
143
144         IWL_DEBUG_TX_QUEUES(mvm, "FLUSHING queues mask to flush = 0x%x\n",
145                             flush_arg);
146
147         mutex_lock(&mvm->mutex);
148         ret =  iwl_mvm_flush_tx_path(mvm, flush_arg) ? : count;
149         mutex_unlock(&mvm->mutex);
150
151         return ret;
152 }
153
154 static ssize_t iwl_dbgfs_sram_read(struct file *file, char __user *user_buf,
155                                    size_t count, loff_t *ppos)
156 {
157         struct iwl_mvm *mvm = file->private_data;
158         const struct fw_img *img;
159         unsigned int ofs, len;
160         size_t ret;
161         u8 *ptr;
162
163         if (!iwl_mvm_firmware_running(mvm))
164                 return -EINVAL;
165
166         /* default is to dump the entire data segment */
167         img = &mvm->fw->img[mvm->fwrt.cur_fw_img];
168         ofs = img->sec[IWL_UCODE_SECTION_DATA].offset;
169         len = img->sec[IWL_UCODE_SECTION_DATA].len;
170
171         if (mvm->dbgfs_sram_len) {
172                 ofs = mvm->dbgfs_sram_offset;
173                 len = mvm->dbgfs_sram_len;
174         }
175
176         ptr = kzalloc(len, GFP_KERNEL);
177         if (!ptr)
178                 return -ENOMEM;
179
180         iwl_trans_read_mem_bytes(mvm->trans, ofs, ptr, len);
181
182         ret = simple_read_from_buffer(user_buf, count, ppos, ptr, len);
183
184         kfree(ptr);
185
186         return ret;
187 }
188
189 static ssize_t iwl_dbgfs_sram_write(struct iwl_mvm *mvm, char *buf,
190                                     size_t count, loff_t *ppos)
191 {
192         const struct fw_img *img;
193         u32 offset, len;
194         u32 img_offset, img_len;
195
196         if (!iwl_mvm_firmware_running(mvm))
197                 return -EINVAL;
198
199         img = &mvm->fw->img[mvm->fwrt.cur_fw_img];
200         img_offset = img->sec[IWL_UCODE_SECTION_DATA].offset;
201         img_len = img->sec[IWL_UCODE_SECTION_DATA].len;
202
203         if (sscanf(buf, "%x,%x", &offset, &len) == 2) {
204                 if ((offset & 0x3) || (len & 0x3))
205                         return -EINVAL;
206
207                 if (offset + len > img_offset + img_len)
208                         return -EINVAL;
209
210                 mvm->dbgfs_sram_offset = offset;
211                 mvm->dbgfs_sram_len = len;
212         } else {
213                 mvm->dbgfs_sram_offset = 0;
214                 mvm->dbgfs_sram_len = 0;
215         }
216
217         return count;
218 }
219
220 static ssize_t iwl_dbgfs_set_nic_temperature_read(struct file *file,
221                                                   char __user *user_buf,
222                                                   size_t count, loff_t *ppos)
223 {
224         struct iwl_mvm *mvm = file->private_data;
225         char buf[16];
226         int pos;
227
228         if (!mvm->temperature_test)
229                 pos = scnprintf(buf, sizeof(buf), "disabled\n");
230         else
231                 pos = scnprintf(buf, sizeof(buf), "%d\n", mvm->temperature);
232
233         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
234 }
235
236 /*
237  * Set NIC Temperature
238  * Cause the driver to ignore the actual NIC temperature reported by the FW
239  * Enable: any value between IWL_MVM_DEBUG_SET_TEMPERATURE_MIN -
240  * IWL_MVM_DEBUG_SET_TEMPERATURE_MAX
241  * Disable: IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE
242  */
243 static ssize_t iwl_dbgfs_set_nic_temperature_write(struct iwl_mvm *mvm,
244                                                    char *buf, size_t count,
245                                                    loff_t *ppos)
246 {
247         int temperature;
248
249         if (!iwl_mvm_firmware_running(mvm) && !mvm->temperature_test)
250                 return -EIO;
251
252         if (kstrtoint(buf, 10, &temperature))
253                 return -EINVAL;
254         /* not a legal temperature */
255         if ((temperature > IWL_MVM_DEBUG_SET_TEMPERATURE_MAX &&
256              temperature != IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE) ||
257             temperature < IWL_MVM_DEBUG_SET_TEMPERATURE_MIN)
258                 return -EINVAL;
259
260         mutex_lock(&mvm->mutex);
261         if (temperature == IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE) {
262                 if (!mvm->temperature_test)
263                         goto out;
264
265                 mvm->temperature_test = false;
266                 /* Since we can't read the temp while awake, just set
267                  * it to zero until we get the next RX stats from the
268                  * firmware.
269                  */
270                 mvm->temperature = 0;
271         } else {
272                 mvm->temperature_test = true;
273                 mvm->temperature = temperature;
274         }
275         IWL_DEBUG_TEMP(mvm, "%sabling debug set temperature (temp = %d)\n",
276                        mvm->temperature_test ? "En" : "Dis",
277                        mvm->temperature);
278         /* handle the temperature change */
279         iwl_mvm_tt_handler(mvm);
280
281 out:
282         mutex_unlock(&mvm->mutex);
283
284         return count;
285 }
286
287 static ssize_t iwl_dbgfs_nic_temp_read(struct file *file,
288                                        char __user *user_buf,
289                                        size_t count, loff_t *ppos)
290 {
291         struct iwl_mvm *mvm = file->private_data;
292         char buf[16];
293         int pos, ret;
294         s32 temp;
295
296         if (!iwl_mvm_firmware_running(mvm))
297                 return -EIO;
298
299         mutex_lock(&mvm->mutex);
300         ret = iwl_mvm_get_temp(mvm, &temp);
301         mutex_unlock(&mvm->mutex);
302
303         if (ret)
304                 return -EIO;
305
306         pos = scnprintf(buf, sizeof(buf), "%d\n", temp);
307
308         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
309 }
310
311 #ifdef CONFIG_ACPI
312 static ssize_t iwl_dbgfs_sar_geo_profile_read(struct file *file,
313                                               char __user *user_buf,
314                                               size_t count, loff_t *ppos)
315 {
316         struct iwl_mvm *mvm = file->private_data;
317         char buf[256];
318         int pos = 0;
319         int bufsz = sizeof(buf);
320         int tbl_idx;
321
322         if (!iwl_mvm_firmware_running(mvm))
323                 return -EIO;
324
325         mutex_lock(&mvm->mutex);
326         tbl_idx = iwl_mvm_get_sar_geo_profile(mvm);
327         if (tbl_idx < 0) {
328                 mutex_unlock(&mvm->mutex);
329                 return tbl_idx;
330         }
331
332         if (!tbl_idx) {
333                 pos = scnprintf(buf, bufsz,
334                                 "SAR geographic profile disabled\n");
335         } else {
336                 pos += scnprintf(buf + pos, bufsz - pos,
337                                  "Use geographic profile %d\n", tbl_idx);
338                 pos += scnprintf(buf + pos, bufsz - pos,
339                                  "2.4GHz:\n\tChain A offset: %u dBm\n\tChain B offset: %u dBm\n\tmax tx power: %u dBm\n",
340                                  mvm->fwrt.geo_profiles[tbl_idx - 1].bands[0].chains[0],
341                                  mvm->fwrt.geo_profiles[tbl_idx - 1].bands[0].chains[1],
342                                  mvm->fwrt.geo_profiles[tbl_idx - 1].bands[0].max);
343                 pos += scnprintf(buf + pos, bufsz - pos,
344                                  "5.2GHz:\n\tChain A offset: %u dBm\n\tChain B offset: %u dBm\n\tmax tx power: %u dBm\n",
345                                  mvm->fwrt.geo_profiles[tbl_idx - 1].bands[1].chains[0],
346                                  mvm->fwrt.geo_profiles[tbl_idx - 1].bands[1].chains[1],
347                                  mvm->fwrt.geo_profiles[tbl_idx - 1].bands[1].max);
348         }
349         mutex_unlock(&mvm->mutex);
350
351         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
352 }
353
354 static ssize_t iwl_dbgfs_wifi_6e_enable_read(struct file *file,
355                                              char __user *user_buf,
356                                              size_t count, loff_t *ppos)
357 {
358         struct iwl_mvm *mvm = file->private_data;
359         int err, pos;
360         char buf[12];
361         u32 value;
362
363         err = iwl_bios_get_dsm(&mvm->fwrt, DSM_FUNC_ENABLE_6E, &value);
364         if (err)
365                 return err;
366
367         pos = sprintf(buf, "0x%08x\n", value);
368
369         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
370 }
371 #endif
372
373 static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
374                                        size_t count, loff_t *ppos)
375 {
376         struct iwl_mvm *mvm = file->private_data;
377         struct ieee80211_sta *sta;
378         char buf[400];
379         int i, pos = 0, bufsz = sizeof(buf);
380
381         mutex_lock(&mvm->mutex);
382
383         for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) {
384                 pos += scnprintf(buf + pos, bufsz - pos, "%.2d: ", i);
385                 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
386                                                 lockdep_is_held(&mvm->mutex));
387                 if (!sta)
388                         pos += scnprintf(buf + pos, bufsz - pos, "N/A\n");
389                 else if (IS_ERR(sta))
390                         pos += scnprintf(buf + pos, bufsz - pos, "%ld\n",
391                                          PTR_ERR(sta));
392                 else
393                         pos += scnprintf(buf + pos, bufsz - pos, "%pM\n",
394                                          sta->addr);
395         }
396
397         mutex_unlock(&mvm->mutex);
398
399         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
400 }
401
402 static ssize_t iwl_dbgfs_rs_data_read(struct ieee80211_link_sta *link_sta,
403                                       struct iwl_mvm_sta *mvmsta,
404                                       struct iwl_mvm *mvm,
405                                       struct iwl_mvm_link_sta *mvm_link_sta,
406                                       char __user *user_buf,
407                                       size_t count, loff_t *ppos)
408 {
409         struct iwl_lq_sta_rs_fw *lq_sta = &mvm_link_sta->lq_sta.rs_fw;
410         static const size_t bufsz = 2048;
411         char *buff;
412         int desc = 0;
413         ssize_t ret;
414
415         buff = kmalloc(bufsz, GFP_KERNEL);
416         if (!buff)
417                 return -ENOMEM;
418
419         desc += scnprintf(buff + desc, bufsz - desc, "sta_id %d\n",
420                           lq_sta->pers.sta_id);
421         desc += scnprintf(buff + desc, bufsz - desc,
422                           "fixed rate 0x%X\n",
423                           lq_sta->pers.dbg_fixed_rate);
424         desc += scnprintf(buff + desc, bufsz - desc,
425                           "A-MPDU size limit %d\n",
426                           lq_sta->pers.dbg_agg_frame_count_lim);
427         desc += scnprintf(buff + desc, bufsz - desc,
428                           "valid_tx_ant %s%s\n",
429                 (iwl_mvm_get_valid_tx_ant(mvm) & ANT_A) ? "ANT_A," : "",
430                 (iwl_mvm_get_valid_tx_ant(mvm) & ANT_B) ? "ANT_B," : "");
431         desc += scnprintf(buff + desc, bufsz - desc,
432                           "last tx rate=0x%X ",
433                           lq_sta->last_rate_n_flags);
434
435         desc += rs_pretty_print_rate(buff + desc, bufsz - desc,
436                                      lq_sta->last_rate_n_flags);
437         if (desc < bufsz - 1)
438                 buff[desc++] = '\n';
439
440         ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
441         kfree(buff);
442         return ret;
443 }
444
445 static ssize_t iwl_dbgfs_amsdu_len_write(struct ieee80211_link_sta *link_sta,
446                                          struct iwl_mvm_sta *mvmsta,
447                                          struct iwl_mvm *mvm,
448                                          struct iwl_mvm_link_sta *mvm_link_sta,
449                                          char *buf, size_t count,
450                                          loff_t *ppos)
451 {
452         int i;
453         u16 amsdu_len;
454
455         if (kstrtou16(buf, 0, &amsdu_len))
456                 return -EINVAL;
457
458         /* only change from debug set <-> debug unset */
459         if (amsdu_len && mvm_link_sta->orig_amsdu_len)
460                 return -EBUSY;
461
462         if (amsdu_len) {
463                 mvm_link_sta->orig_amsdu_len = link_sta->agg.max_amsdu_len;
464                 link_sta->agg.max_amsdu_len = amsdu_len;
465                 link_sta->agg.max_amsdu_len = amsdu_len;
466                 for (i = 0; i < ARRAY_SIZE(link_sta->agg.max_tid_amsdu_len); i++)
467                         link_sta->agg.max_tid_amsdu_len[i] = amsdu_len;
468         } else {
469                 link_sta->agg.max_amsdu_len = mvm_link_sta->orig_amsdu_len;
470                 mvm_link_sta->orig_amsdu_len = 0;
471         }
472
473         ieee80211_sta_recalc_aggregates(link_sta->sta);
474
475         return count;
476 }
477
478 static ssize_t iwl_dbgfs_amsdu_len_read(struct ieee80211_link_sta *link_sta,
479                                         struct iwl_mvm_sta *mvmsta,
480                                         struct iwl_mvm *mvm,
481                                         struct iwl_mvm_link_sta *mvm_link_sta,
482                                         char __user *user_buf,
483                                         size_t count, loff_t *ppos)
484 {
485         char buf[32];
486         int pos;
487
488         pos = scnprintf(buf, sizeof(buf), "current %d ",
489                         link_sta->agg.max_amsdu_len);
490         pos += scnprintf(buf + pos, sizeof(buf) - pos, "stored %d\n",
491                          mvm_link_sta->orig_amsdu_len);
492
493         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
494 }
495
496 static ssize_t iwl_dbgfs_disable_power_off_read(struct file *file,
497                                                 char __user *user_buf,
498                                                 size_t count, loff_t *ppos)
499 {
500         struct iwl_mvm *mvm = file->private_data;
501         char buf[64];
502         int bufsz = sizeof(buf);
503         int pos = 0;
504
505         pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off_d0=%d\n",
506                          mvm->disable_power_off);
507         pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off_d3=%d\n",
508                          mvm->disable_power_off_d3);
509
510         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
511 }
512
513 static ssize_t iwl_dbgfs_disable_power_off_write(struct iwl_mvm *mvm, char *buf,
514                                                  size_t count, loff_t *ppos)
515 {
516         int ret, val;
517
518         if (!iwl_mvm_firmware_running(mvm))
519                 return -EIO;
520
521         if (!strncmp("disable_power_off_d0=", buf, 21)) {
522                 if (sscanf(buf + 21, "%d", &val) != 1)
523                         return -EINVAL;
524                 mvm->disable_power_off = val;
525         } else if (!strncmp("disable_power_off_d3=", buf, 21)) {
526                 if (sscanf(buf + 21, "%d", &val) != 1)
527                         return -EINVAL;
528                 mvm->disable_power_off_d3 = val;
529         } else {
530                 return -EINVAL;
531         }
532
533         mutex_lock(&mvm->mutex);
534         ret = iwl_mvm_power_update_device(mvm);
535         mutex_unlock(&mvm->mutex);
536
537         return ret ?: count;
538 }
539
540 static ssize_t iwl_dbgfs_fw_ver_read(struct file *file, char __user *user_buf,
541                                      size_t count, loff_t *ppos)
542 {
543         struct iwl_mvm *mvm = file->private_data;
544         char *buff, *pos, *endpos;
545         static const size_t bufsz = 1024;
546         int ret;
547
548         buff = kmalloc(bufsz, GFP_KERNEL);
549         if (!buff)
550                 return -ENOMEM;
551
552         pos = buff;
553         endpos = pos + bufsz;
554
555         pos += scnprintf(pos, endpos - pos, "FW id: %s\n",
556                          mvm->fwrt.fw->fw_version);
557         pos += scnprintf(pos, endpos - pos, "FW: %s\n",
558                          mvm->fwrt.fw->human_readable);
559         pos += scnprintf(pos, endpos - pos, "Device: %s\n",
560                          mvm->fwrt.trans->name);
561         pos += scnprintf(pos, endpos - pos, "Bus: %s\n",
562                          mvm->fwrt.dev->bus->name);
563
564         ret = simple_read_from_buffer(user_buf, count, ppos, buff, pos - buff);
565         kfree(buff);
566
567         return ret;
568 }
569
570 static ssize_t iwl_dbgfs_tas_get_status_read(struct file *file,
571                                              char __user *user_buf,
572                                              size_t count, loff_t *ppos)
573 {
574         struct iwl_mvm *mvm = file->private_data;
575         struct iwl_mvm_tas_status_resp tas_rsp;
576         struct iwl_mvm_tas_status_resp *rsp = &tas_rsp;
577         static const size_t bufsz = 1024;
578         char *buff, *pos, *endpos;
579         const char * const tas_dis_reason[TAS_DISABLED_REASON_MAX] = {
580                 [TAS_DISABLED_DUE_TO_BIOS] =
581                         "Due To BIOS",
582                 [TAS_DISABLED_DUE_TO_SAR_6DBM] =
583                         "Due To SAR Limit Less Than 6 dBm",
584                 [TAS_DISABLED_REASON_INVALID] =
585                         "N/A",
586         };
587         const char * const tas_current_status[TAS_DYNA_STATUS_MAX] = {
588                 [TAS_DYNA_INACTIVE] = "INACTIVE",
589                 [TAS_DYNA_INACTIVE_MVM_MODE] =
590                         "inactive due to mvm mode",
591                 [TAS_DYNA_INACTIVE_TRIGGER_MODE] =
592                         "inactive due to trigger mode",
593                 [TAS_DYNA_INACTIVE_BLOCK_LISTED] =
594                         "inactive due to block listed",
595                 [TAS_DYNA_INACTIVE_UHB_NON_US] =
596                         "inactive due to uhb non US",
597                 [TAS_DYNA_ACTIVE] = "ACTIVE",
598         };
599         struct iwl_host_cmd hcmd = {
600                 .id = WIDE_ID(DEBUG_GROUP, GET_TAS_STATUS),
601                 .flags = CMD_WANT_SKB,
602                 .len = { 0, },
603                 .data = { NULL, },
604         };
605         int ret, i, tmp;
606         bool tas_enabled = false;
607         unsigned long dyn_status;
608
609         if (!iwl_mvm_firmware_running(mvm))
610                 return -ENODEV;
611
612         mutex_lock(&mvm->mutex);
613         ret = iwl_mvm_send_cmd(mvm, &hcmd);
614         mutex_unlock(&mvm->mutex);
615         if (ret < 0)
616                 return ret;
617
618         buff = kzalloc(bufsz, GFP_KERNEL);
619         if (!buff)
620                 return -ENOMEM;
621         pos = buff;
622         endpos = pos + bufsz;
623
624         rsp = (void *)hcmd.resp_pkt->data;
625
626         pos += scnprintf(pos, endpos - pos, "TAS Conclusion:\n");
627         for (i = 0; i < rsp->in_dual_radio + 1; i++) {
628                 if (rsp->tas_status_mac[i].band != TAS_LMAC_BAND_INVALID &&
629                     rsp->tas_status_mac[i].dynamic_status & BIT(TAS_DYNA_ACTIVE)) {
630                         pos += scnprintf(pos, endpos - pos, "\tON for ");
631                         switch (rsp->tas_status_mac[i].band) {
632                         case TAS_LMAC_BAND_HB:
633                                 pos += scnprintf(pos, endpos - pos, "HB\n");
634                                 break;
635                         case TAS_LMAC_BAND_LB:
636                                 pos += scnprintf(pos, endpos - pos, "LB\n");
637                                 break;
638                         case TAS_LMAC_BAND_UHB:
639                                 pos += scnprintf(pos, endpos - pos, "UHB\n");
640                                 break;
641                         case TAS_LMAC_BAND_INVALID:
642                                 pos += scnprintf(pos, endpos - pos,
643                                                  "INVALID BAND\n");
644                                 break;
645                         default:
646                                 pos += scnprintf(pos, endpos - pos,
647                                                  "Unsupported band (%d)\n",
648                                                  rsp->tas_status_mac[i].band);
649                                 goto out;
650                         }
651                         tas_enabled = true;
652                 }
653         }
654         if (!tas_enabled)
655                 pos += scnprintf(pos, endpos - pos, "\tOFF\n");
656
657         pos += scnprintf(pos, endpos - pos, "TAS Report\n");
658         pos += scnprintf(pos, endpos - pos, "TAS FW version: %d\n",
659                          rsp->tas_fw_version);
660         pos += scnprintf(pos, endpos - pos, "Is UHB enabled for USA?: %s\n",
661                          rsp->is_uhb_for_usa_enable ? "True" : "False");
662         pos += scnprintf(pos, endpos - pos, "Current MCC: 0x%x\n",
663                          le16_to_cpu(rsp->curr_mcc));
664
665         pos += scnprintf(pos, endpos - pos, "Block list entries:");
666         for (i = 0; i < IWL_WTAS_BLACK_LIST_MAX; i++)
667                 pos += scnprintf(pos, endpos - pos, " 0x%x",
668                                  le16_to_cpu(rsp->block_list[i]));
669
670         pos += scnprintf(pos, endpos - pos, "\nOEM name: %s\n",
671                          dmi_get_system_info(DMI_SYS_VENDOR) ?: "<unknown>");
672         pos += scnprintf(pos, endpos - pos, "\tVendor In Approved List: %s\n",
673                          iwl_is_tas_approved() ? "YES" : "NO");
674         pos += scnprintf(pos, endpos - pos,
675                          "\tDo TAS Support Dual Radio?: %s\n",
676                          rsp->in_dual_radio ? "TRUE" : "FALSE");
677
678         for (i = 0; i < rsp->in_dual_radio + 1; i++) {
679                 if (rsp->tas_status_mac[i].static_status == 0) {
680                         pos += scnprintf(pos, endpos - pos,
681                                          "Static status: disabled\n");
682                         pos += scnprintf(pos, endpos - pos,
683                                          "Static disabled reason: %s (0)\n",
684                                          tas_dis_reason[0]);
685                         goto out;
686                 }
687
688                 pos += scnprintf(pos, endpos - pos, "TAS status for ");
689                 switch (rsp->tas_status_mac[i].band) {
690                 case TAS_LMAC_BAND_HB:
691                         pos += scnprintf(pos, endpos - pos, "High band\n");
692                         break;
693                 case TAS_LMAC_BAND_LB:
694                         pos += scnprintf(pos, endpos - pos, "Low band\n");
695                         break;
696                 case TAS_LMAC_BAND_UHB:
697                         pos += scnprintf(pos, endpos - pos,
698                                          "Ultra high band\n");
699                         break;
700                 case TAS_LMAC_BAND_INVALID:
701                         pos += scnprintf(pos, endpos - pos,
702                                          "INVALID band\n");
703                         break;
704                 default:
705                         pos += scnprintf(pos, endpos - pos,
706                                          "Unsupported band (%d)\n",
707                                          rsp->tas_status_mac[i].band);
708                         goto out;
709                 }
710                 pos += scnprintf(pos, endpos - pos, "Static status: %sabled\n",
711                                  rsp->tas_status_mac[i].static_status ?
712                                  "En" : "Dis");
713                 pos += scnprintf(pos, endpos - pos,
714                                  "\tStatic Disabled Reason: ");
715                 if (rsp->tas_status_mac[i].static_dis_reason < TAS_DISABLED_REASON_MAX)
716                         pos += scnprintf(pos, endpos - pos, "%s (%d)\n",
717                                          tas_dis_reason[rsp->tas_status_mac[i].static_dis_reason],
718                                          rsp->tas_status_mac[i].static_dis_reason);
719                 else
720                         pos += scnprintf(pos, endpos - pos,
721                                          "unsupported value (%d)\n",
722                                          rsp->tas_status_mac[i].static_dis_reason);
723
724                 pos += scnprintf(pos, endpos - pos, "Dynamic status:\n");
725                 dyn_status = (rsp->tas_status_mac[i].dynamic_status);
726                 for_each_set_bit(tmp, &dyn_status, sizeof(dyn_status)) {
727                         if (tmp >= 0 && tmp < TAS_DYNA_STATUS_MAX)
728                                 pos += scnprintf(pos, endpos - pos,
729                                                  "\t%s (%d)\n",
730                                                  tas_current_status[tmp], tmp);
731                 }
732
733                 pos += scnprintf(pos, endpos - pos,
734                                  "Is near disconnection?: %s\n",
735                                  rsp->tas_status_mac[i].near_disconnection ?
736                                  "True" : "False");
737                 tmp = le16_to_cpu(rsp->tas_status_mac[i].max_reg_pwr_limit);
738                 pos += scnprintf(pos, endpos - pos,
739                                  "Max. regulatory pwr limit (dBm): %d.%03d\n",
740                                  tmp / 8, 125 * (tmp % 8));
741                 tmp = le16_to_cpu(rsp->tas_status_mac[i].sar_limit);
742                 pos += scnprintf(pos, endpos - pos,
743                                  "SAR limit (dBm): %d.%03d\n",
744                                  tmp / 8, 125 * (tmp % 8));
745         }
746
747 out:
748         ret = simple_read_from_buffer(user_buf, count, ppos, buff, pos - buff);
749         kfree(buff);
750         iwl_free_resp(&hcmd);
751         return ret;
752 }
753
754 static ssize_t iwl_dbgfs_phy_integration_ver_read(struct file *file,
755                                                   char __user *user_buf,
756                                                   size_t count, loff_t *ppos)
757 {
758         struct iwl_mvm *mvm = file->private_data;
759         char *buf;
760         size_t bufsz;
761         int pos;
762         ssize_t ret;
763
764         bufsz = mvm->fw->phy_integration_ver_len + 2;
765         buf = kmalloc(bufsz, GFP_KERNEL);
766         if (!buf)
767                 return -ENOMEM;
768
769         pos = scnprintf(buf, bufsz, "%.*s\n", mvm->fw->phy_integration_ver_len,
770                         mvm->fw->phy_integration_ver);
771
772         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
773
774         kfree(buf);
775         return ret;
776 }
777
778 #define PRINT_STATS_LE32(_struct, _memb)                                \
779                          pos += scnprintf(buf + pos, bufsz - pos,       \
780                                           fmt_table, #_memb,            \
781                                           le32_to_cpu(_struct->_memb))
782
783 static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file,
784                                           char __user *user_buf, size_t count,
785                                           loff_t *ppos)
786 {
787         struct iwl_mvm *mvm = file->private_data;
788         static const char *fmt_table = "\t%-30s %10u\n";
789         static const char *fmt_header = "%-32s\n";
790         int pos = 0;
791         char *buf;
792         int ret;
793         size_t bufsz;
794         u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw,
795                                            WIDE_ID(SYSTEM_GROUP,
796                                                    SYSTEM_STATISTICS_CMD),
797                                            IWL_FW_CMD_VER_UNKNOWN);
798
799         if (cmd_ver != IWL_FW_CMD_VER_UNKNOWN)
800                 return -EOPNOTSUPP;
801
802         if (iwl_mvm_has_new_rx_stats_api(mvm))
803                 bufsz = ((sizeof(struct mvm_statistics_rx) /
804                           sizeof(__le32)) * 43) + (4 * 33) + 1;
805         else
806                 /* 43 = size of each data line; 33 = size of each header */
807                 bufsz = ((sizeof(struct mvm_statistics_rx_v3) /
808                           sizeof(__le32)) * 43) + (4 * 33) + 1;
809
810         buf = kzalloc(bufsz, GFP_KERNEL);
811         if (!buf)
812                 return -ENOMEM;
813
814         mutex_lock(&mvm->mutex);
815
816         if (iwl_mvm_firmware_running(mvm))
817                 iwl_mvm_request_statistics(mvm, false);
818
819         pos += scnprintf(buf + pos, bufsz - pos, fmt_header,
820                          "Statistics_Rx - OFDM");
821         if (!iwl_mvm_has_new_rx_stats_api(mvm)) {
822                 struct mvm_statistics_rx_phy_v2 *ofdm = &mvm->rx_stats_v3.ofdm;
823
824                 PRINT_STATS_LE32(ofdm, ina_cnt);
825                 PRINT_STATS_LE32(ofdm, fina_cnt);
826                 PRINT_STATS_LE32(ofdm, plcp_err);
827                 PRINT_STATS_LE32(ofdm, crc32_err);
828                 PRINT_STATS_LE32(ofdm, overrun_err);
829                 PRINT_STATS_LE32(ofdm, early_overrun_err);
830                 PRINT_STATS_LE32(ofdm, crc32_good);
831                 PRINT_STATS_LE32(ofdm, false_alarm_cnt);
832                 PRINT_STATS_LE32(ofdm, fina_sync_err_cnt);
833                 PRINT_STATS_LE32(ofdm, sfd_timeout);
834                 PRINT_STATS_LE32(ofdm, fina_timeout);
835                 PRINT_STATS_LE32(ofdm, unresponded_rts);
836                 PRINT_STATS_LE32(ofdm, rxe_frame_lmt_overrun);
837                 PRINT_STATS_LE32(ofdm, sent_ack_cnt);
838                 PRINT_STATS_LE32(ofdm, sent_cts_cnt);
839                 PRINT_STATS_LE32(ofdm, sent_ba_rsp_cnt);
840                 PRINT_STATS_LE32(ofdm, dsp_self_kill);
841                 PRINT_STATS_LE32(ofdm, mh_format_err);
842                 PRINT_STATS_LE32(ofdm, re_acq_main_rssi_sum);
843                 PRINT_STATS_LE32(ofdm, reserved);
844         } else {
845                 struct mvm_statistics_rx_phy *ofdm = &mvm->rx_stats.ofdm;
846
847                 PRINT_STATS_LE32(ofdm, unresponded_rts);
848                 PRINT_STATS_LE32(ofdm, rxe_frame_lmt_overrun);
849                 PRINT_STATS_LE32(ofdm, sent_ba_rsp_cnt);
850                 PRINT_STATS_LE32(ofdm, dsp_self_kill);
851                 PRINT_STATS_LE32(ofdm, reserved);
852         }
853
854         pos += scnprintf(buf + pos, bufsz - pos, fmt_header,
855                          "Statistics_Rx - CCK");
856         if (!iwl_mvm_has_new_rx_stats_api(mvm)) {
857                 struct mvm_statistics_rx_phy_v2 *cck = &mvm->rx_stats_v3.cck;
858
859                 PRINT_STATS_LE32(cck, ina_cnt);
860                 PRINT_STATS_LE32(cck, fina_cnt);
861                 PRINT_STATS_LE32(cck, plcp_err);
862                 PRINT_STATS_LE32(cck, crc32_err);
863                 PRINT_STATS_LE32(cck, overrun_err);
864                 PRINT_STATS_LE32(cck, early_overrun_err);
865                 PRINT_STATS_LE32(cck, crc32_good);
866                 PRINT_STATS_LE32(cck, false_alarm_cnt);
867                 PRINT_STATS_LE32(cck, fina_sync_err_cnt);
868                 PRINT_STATS_LE32(cck, sfd_timeout);
869                 PRINT_STATS_LE32(cck, fina_timeout);
870                 PRINT_STATS_LE32(cck, unresponded_rts);
871                 PRINT_STATS_LE32(cck, rxe_frame_lmt_overrun);
872                 PRINT_STATS_LE32(cck, sent_ack_cnt);
873                 PRINT_STATS_LE32(cck, sent_cts_cnt);
874                 PRINT_STATS_LE32(cck, sent_ba_rsp_cnt);
875                 PRINT_STATS_LE32(cck, dsp_self_kill);
876                 PRINT_STATS_LE32(cck, mh_format_err);
877                 PRINT_STATS_LE32(cck, re_acq_main_rssi_sum);
878                 PRINT_STATS_LE32(cck, reserved);
879         } else {
880                 struct mvm_statistics_rx_phy *cck = &mvm->rx_stats.cck;
881
882                 PRINT_STATS_LE32(cck, unresponded_rts);
883                 PRINT_STATS_LE32(cck, rxe_frame_lmt_overrun);
884                 PRINT_STATS_LE32(cck, sent_ba_rsp_cnt);
885                 PRINT_STATS_LE32(cck, dsp_self_kill);
886                 PRINT_STATS_LE32(cck, reserved);
887         }
888
889         pos += scnprintf(buf + pos, bufsz - pos, fmt_header,
890                          "Statistics_Rx - GENERAL");
891         if (!iwl_mvm_has_new_rx_stats_api(mvm)) {
892                 struct mvm_statistics_rx_non_phy_v3 *general =
893                         &mvm->rx_stats_v3.general;
894
895                 PRINT_STATS_LE32(general, bogus_cts);
896                 PRINT_STATS_LE32(general, bogus_ack);
897                 PRINT_STATS_LE32(general, non_bssid_frames);
898                 PRINT_STATS_LE32(general, filtered_frames);
899                 PRINT_STATS_LE32(general, non_channel_beacons);
900                 PRINT_STATS_LE32(general, channel_beacons);
901                 PRINT_STATS_LE32(general, num_missed_bcon);
902                 PRINT_STATS_LE32(general, adc_rx_saturation_time);
903                 PRINT_STATS_LE32(general, ina_detection_search_time);
904                 PRINT_STATS_LE32(general, beacon_silence_rssi_a);
905                 PRINT_STATS_LE32(general, beacon_silence_rssi_b);
906                 PRINT_STATS_LE32(general, beacon_silence_rssi_c);
907                 PRINT_STATS_LE32(general, interference_data_flag);
908                 PRINT_STATS_LE32(general, channel_load);
909                 PRINT_STATS_LE32(general, dsp_false_alarms);
910                 PRINT_STATS_LE32(general, beacon_rssi_a);
911                 PRINT_STATS_LE32(general, beacon_rssi_b);
912                 PRINT_STATS_LE32(general, beacon_rssi_c);
913                 PRINT_STATS_LE32(general, beacon_energy_a);
914                 PRINT_STATS_LE32(general, beacon_energy_b);
915                 PRINT_STATS_LE32(general, beacon_energy_c);
916                 PRINT_STATS_LE32(general, num_bt_kills);
917                 PRINT_STATS_LE32(general, mac_id);
918                 PRINT_STATS_LE32(general, directed_data_mpdu);
919         } else {
920                 struct mvm_statistics_rx_non_phy *general =
921                         &mvm->rx_stats.general;
922
923                 PRINT_STATS_LE32(general, bogus_cts);
924                 PRINT_STATS_LE32(general, bogus_ack);
925                 PRINT_STATS_LE32(general, non_channel_beacons);
926                 PRINT_STATS_LE32(general, channel_beacons);
927                 PRINT_STATS_LE32(general, num_missed_bcon);
928                 PRINT_STATS_LE32(general, adc_rx_saturation_time);
929                 PRINT_STATS_LE32(general, ina_detection_search_time);
930                 PRINT_STATS_LE32(general, beacon_silence_rssi_a);
931                 PRINT_STATS_LE32(general, beacon_silence_rssi_b);
932                 PRINT_STATS_LE32(general, beacon_silence_rssi_c);
933                 PRINT_STATS_LE32(general, interference_data_flag);
934                 PRINT_STATS_LE32(general, channel_load);
935                 PRINT_STATS_LE32(general, beacon_rssi_a);
936                 PRINT_STATS_LE32(general, beacon_rssi_b);
937                 PRINT_STATS_LE32(general, beacon_rssi_c);
938                 PRINT_STATS_LE32(general, beacon_energy_a);
939                 PRINT_STATS_LE32(general, beacon_energy_b);
940                 PRINT_STATS_LE32(general, beacon_energy_c);
941                 PRINT_STATS_LE32(general, num_bt_kills);
942                 PRINT_STATS_LE32(general, mac_id);
943         }
944
945         pos += scnprintf(buf + pos, bufsz - pos, fmt_header,
946                          "Statistics_Rx - HT");
947         if (!iwl_mvm_has_new_rx_stats_api(mvm)) {
948                 struct mvm_statistics_rx_ht_phy_v1 *ht =
949                         &mvm->rx_stats_v3.ofdm_ht;
950
951                 PRINT_STATS_LE32(ht, plcp_err);
952                 PRINT_STATS_LE32(ht, overrun_err);
953                 PRINT_STATS_LE32(ht, early_overrun_err);
954                 PRINT_STATS_LE32(ht, crc32_good);
955                 PRINT_STATS_LE32(ht, crc32_err);
956                 PRINT_STATS_LE32(ht, mh_format_err);
957                 PRINT_STATS_LE32(ht, agg_crc32_good);
958                 PRINT_STATS_LE32(ht, agg_mpdu_cnt);
959                 PRINT_STATS_LE32(ht, agg_cnt);
960                 PRINT_STATS_LE32(ht, unsupport_mcs);
961         } else {
962                 struct mvm_statistics_rx_ht_phy *ht =
963                         &mvm->rx_stats.ofdm_ht;
964
965                 PRINT_STATS_LE32(ht, mh_format_err);
966                 PRINT_STATS_LE32(ht, agg_mpdu_cnt);
967                 PRINT_STATS_LE32(ht, agg_cnt);
968                 PRINT_STATS_LE32(ht, unsupport_mcs);
969         }
970
971         mutex_unlock(&mvm->mutex);
972
973         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
974         kfree(buf);
975
976         return ret;
977 }
978 #undef PRINT_STAT_LE32
979
980 static ssize_t iwl_dbgfs_fw_system_stats_read(struct file *file,
981                                               char __user *user_buf,
982                                               size_t count, loff_t *ppos)
983 {
984         char *buff, *pos, *endpos;
985         int ret;
986         size_t bufsz;
987         int i;
988         struct iwl_mvm_vif *mvmvif;
989         struct ieee80211_vif *vif;
990         struct iwl_mvm *mvm = file->private_data;
991         u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw,
992                                            WIDE_ID(SYSTEM_GROUP,
993                                                    SYSTEM_STATISTICS_CMD),
994                                            IWL_FW_CMD_VER_UNKNOWN);
995
996         /* in case of a wrong cmd version, allocate buffer only for error msg */
997         bufsz = (cmd_ver == 1) ? 4096 : 64;
998
999         buff = kzalloc(bufsz, GFP_KERNEL);
1000         if (!buff)
1001                 return -ENOMEM;
1002
1003         pos = buff;
1004         endpos = pos + bufsz;
1005
1006         if (cmd_ver != 1) {
1007                 pos += scnprintf(pos, endpos - pos,
1008                                  "System stats not supported:%d\n", cmd_ver);
1009                 goto send_out;
1010         }
1011
1012         mutex_lock(&mvm->mutex);
1013         if (iwl_mvm_firmware_running(mvm))
1014                 iwl_mvm_request_statistics(mvm, false);
1015
1016         for (i = 0; i < NUM_MAC_INDEX_DRIVER; i++) {
1017                 vif = iwl_mvm_rcu_dereference_vif_id(mvm, i, false);
1018                 if (!vif)
1019                         continue;
1020
1021                 if (vif->type == NL80211_IFTYPE_STATION)
1022                         break;
1023         }
1024
1025         if (i == NUM_MAC_INDEX_DRIVER || !vif) {
1026                 pos += scnprintf(pos, endpos - pos, "vif is NULL\n");
1027                 goto release_send_out;
1028         }
1029
1030         mvmvif = iwl_mvm_vif_from_mac80211(vif);
1031         if (!mvmvif) {
1032                 pos += scnprintf(pos, endpos - pos, "mvmvif is NULL\n");
1033                 goto release_send_out;
1034         }
1035
1036         for_each_mvm_vif_valid_link(mvmvif, i) {
1037                 struct iwl_mvm_vif_link_info *link_info = mvmvif->link[i];
1038
1039                 pos += scnprintf(pos, endpos - pos,
1040                                  "link_id %d", i);
1041                 pos += scnprintf(pos, endpos - pos,
1042                                  " num_beacons %d",
1043                                  link_info->beacon_stats.num_beacons);
1044                 pos += scnprintf(pos, endpos - pos,
1045                                  " accu_num_beacons %d",
1046                                  link_info->beacon_stats.accu_num_beacons);
1047                 pos += scnprintf(pos, endpos - pos,
1048                                  " avg_signal %d\n",
1049                                  link_info->beacon_stats.avg_signal);
1050         }
1051
1052         pos += scnprintf(pos, endpos - pos,
1053                          "radio_stats.rx_time %lld\n",
1054                          mvm->radio_stats.rx_time);
1055         pos += scnprintf(pos, endpos - pos,
1056                          "radio_stats.tx_time %lld\n",
1057                          mvm->radio_stats.tx_time);
1058         pos += scnprintf(pos, endpos - pos,
1059                          "accu_radio_stats.rx_time %lld\n",
1060                          mvm->accu_radio_stats.rx_time);
1061         pos += scnprintf(pos, endpos - pos,
1062                          "accu_radio_stats.tx_time %lld\n",
1063                          mvm->accu_radio_stats.tx_time);
1064
1065 release_send_out:
1066         mutex_unlock(&mvm->mutex);
1067
1068 send_out:
1069         ret = simple_read_from_buffer(user_buf, count, ppos, buff, pos - buff);
1070         kfree(buff);
1071
1072         return ret;
1073 }
1074
1075 static ssize_t iwl_dbgfs_frame_stats_read(struct iwl_mvm *mvm,
1076                                           char __user *user_buf, size_t count,
1077                                           loff_t *ppos,
1078                                           struct iwl_mvm_frame_stats *stats)
1079 {
1080         char *buff, *pos, *endpos;
1081         int idx, i;
1082         int ret;
1083         static const size_t bufsz = 1024;
1084
1085         buff = kmalloc(bufsz, GFP_KERNEL);
1086         if (!buff)
1087                 return -ENOMEM;
1088
1089         spin_lock_bh(&mvm->drv_stats_lock);
1090
1091         pos = buff;
1092         endpos = pos + bufsz;
1093
1094         pos += scnprintf(pos, endpos - pos,
1095                          "Legacy/HT/VHT\t:\t%d/%d/%d\n",
1096                          stats->legacy_frames,
1097                          stats->ht_frames,
1098                          stats->vht_frames);
1099         pos += scnprintf(pos, endpos - pos, "20/40/80\t:\t%d/%d/%d\n",
1100                          stats->bw_20_frames,
1101                          stats->bw_40_frames,
1102                          stats->bw_80_frames);
1103         pos += scnprintf(pos, endpos - pos, "NGI/SGI\t\t:\t%d/%d\n",
1104                          stats->ngi_frames,
1105                          stats->sgi_frames);
1106         pos += scnprintf(pos, endpos - pos, "SISO/MIMO2\t:\t%d/%d\n",
1107                          stats->siso_frames,
1108                          stats->mimo2_frames);
1109         pos += scnprintf(pos, endpos - pos, "FAIL/SCSS\t:\t%d/%d\n",
1110                          stats->fail_frames,
1111                          stats->success_frames);
1112         pos += scnprintf(pos, endpos - pos, "MPDUs agg\t:\t%d\n",
1113                          stats->agg_frames);
1114         pos += scnprintf(pos, endpos - pos, "A-MPDUs\t\t:\t%d\n",
1115                          stats->ampdu_count);
1116         pos += scnprintf(pos, endpos - pos, "Avg MPDUs/A-MPDU:\t%d\n",
1117                          stats->ampdu_count > 0 ?
1118                          (stats->agg_frames / stats->ampdu_count) : 0);
1119
1120         pos += scnprintf(pos, endpos - pos, "Last Rates\n");
1121
1122         idx = stats->last_frame_idx - 1;
1123         for (i = 0; i < ARRAY_SIZE(stats->last_rates); i++) {
1124                 idx = (idx + 1) % ARRAY_SIZE(stats->last_rates);
1125                 if (stats->last_rates[idx] == 0)
1126                         continue;
1127                 pos += scnprintf(pos, endpos - pos, "Rate[%d]: ",
1128                                  (int)(ARRAY_SIZE(stats->last_rates) - i));
1129                 pos += rs_pretty_print_rate_v1(pos, endpos - pos,
1130                                                stats->last_rates[idx]);
1131                 if (pos < endpos - 1)
1132                         *pos++ = '\n';
1133         }
1134         spin_unlock_bh(&mvm->drv_stats_lock);
1135
1136         ret = simple_read_from_buffer(user_buf, count, ppos, buff, pos - buff);
1137         kfree(buff);
1138
1139         return ret;
1140 }
1141
1142 static ssize_t iwl_dbgfs_drv_rx_stats_read(struct file *file,
1143                                            char __user *user_buf, size_t count,
1144                                            loff_t *ppos)
1145 {
1146         struct iwl_mvm *mvm = file->private_data;
1147
1148         return iwl_dbgfs_frame_stats_read(mvm, user_buf, count, ppos,
1149                                           &mvm->drv_rx_stats);
1150 }
1151
1152 static ssize_t iwl_dbgfs_fw_restart_write(struct iwl_mvm *mvm, char *buf,
1153                                           size_t count, loff_t *ppos)
1154 {
1155         int __maybe_unused ret;
1156
1157         if (!iwl_mvm_firmware_running(mvm))
1158                 return -EIO;
1159
1160         mutex_lock(&mvm->mutex);
1161
1162         /* allow one more restart that we're provoking here */
1163         if (mvm->fw_restart >= 0)
1164                 mvm->fw_restart++;
1165
1166         if (count == 6 && !strcmp(buf, "nolog\n")) {
1167                 set_bit(IWL_MVM_STATUS_SUPPRESS_ERROR_LOG_ONCE, &mvm->status);
1168                 set_bit(STATUS_SUPPRESS_CMD_ERROR_ONCE, &mvm->trans->status);
1169         }
1170
1171         /* take the return value to make compiler happy - it will fail anyway */
1172         ret = iwl_mvm_send_cmd_pdu(mvm,
1173                                    WIDE_ID(LONG_GROUP, REPLY_ERROR),
1174                                    0, 0, NULL);
1175
1176         mutex_unlock(&mvm->mutex);
1177
1178         return count;
1179 }
1180
1181 static ssize_t iwl_dbgfs_fw_nmi_write(struct iwl_mvm *mvm, char *buf,
1182                                       size_t count, loff_t *ppos)
1183 {
1184         if (!iwl_mvm_firmware_running(mvm))
1185                 return -EIO;
1186
1187         IWL_ERR(mvm, "Triggering an NMI from debugfs\n");
1188
1189         if (count == 6 && !strcmp(buf, "nolog\n"))
1190                 set_bit(IWL_MVM_STATUS_SUPPRESS_ERROR_LOG_ONCE, &mvm->status);
1191
1192         iwl_force_nmi(mvm->trans);
1193
1194         return count;
1195 }
1196
1197 static ssize_t
1198 iwl_dbgfs_scan_ant_rxchain_read(struct file *file,
1199                                 char __user *user_buf,
1200                                 size_t count, loff_t *ppos)
1201 {
1202         struct iwl_mvm *mvm = file->private_data;
1203         int pos = 0;
1204         char buf[32];
1205         const size_t bufsz = sizeof(buf);
1206
1207         /* print which antennas were set for the scan command by the user */
1208         pos += scnprintf(buf + pos, bufsz - pos, "Antennas for scan: ");
1209         if (mvm->scan_rx_ant & ANT_A)
1210                 pos += scnprintf(buf + pos, bufsz - pos, "A");
1211         if (mvm->scan_rx_ant & ANT_B)
1212                 pos += scnprintf(buf + pos, bufsz - pos, "B");
1213         pos += scnprintf(buf + pos, bufsz - pos, " (%x)\n", mvm->scan_rx_ant);
1214
1215         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1216 }
1217
1218 static ssize_t
1219 iwl_dbgfs_scan_ant_rxchain_write(struct iwl_mvm *mvm, char *buf,
1220                                  size_t count, loff_t *ppos)
1221 {
1222         u8 scan_rx_ant;
1223
1224         if (!iwl_mvm_firmware_running(mvm))
1225                 return -EIO;
1226
1227         if (sscanf(buf, "%hhx", &scan_rx_ant) != 1)
1228                 return -EINVAL;
1229         if (scan_rx_ant > ANT_ABC)
1230                 return -EINVAL;
1231         if (scan_rx_ant & ~(iwl_mvm_get_valid_rx_ant(mvm)))
1232                 return -EINVAL;
1233
1234         if (mvm->scan_rx_ant != scan_rx_ant) {
1235                 mvm->scan_rx_ant = scan_rx_ant;
1236                 if (fw_has_capa(&mvm->fw->ucode_capa,
1237                                 IWL_UCODE_TLV_CAPA_UMAC_SCAN))
1238                         iwl_mvm_config_scan(mvm);
1239         }
1240
1241         return count;
1242 }
1243
1244 static ssize_t iwl_dbgfs_indirection_tbl_write(struct iwl_mvm *mvm,
1245                                                char *buf, size_t count,
1246                                                loff_t *ppos)
1247 {
1248         struct iwl_rss_config_cmd cmd = {
1249                 .flags = cpu_to_le32(IWL_RSS_ENABLE),
1250                 .hash_mask = IWL_RSS_HASH_TYPE_IPV4_TCP |
1251                              IWL_RSS_HASH_TYPE_IPV4_UDP |
1252                              IWL_RSS_HASH_TYPE_IPV4_PAYLOAD |
1253                              IWL_RSS_HASH_TYPE_IPV6_TCP |
1254                              IWL_RSS_HASH_TYPE_IPV6_UDP |
1255                              IWL_RSS_HASH_TYPE_IPV6_PAYLOAD,
1256         };
1257         int ret, i, num_repeats, nbytes = count / 2;
1258
1259         ret = hex2bin(cmd.indirection_table, buf, nbytes);
1260         if (ret)
1261                 return ret;
1262
1263         /*
1264          * The input is the redirection table, partial or full.
1265          * Repeat the pattern if needed.
1266          * For example, input of 01020F will be repeated 42 times,
1267          * indirecting RSS hash results to queues 1, 2, 15 (skipping
1268          * queues 3 - 14).
1269          */
1270         num_repeats = ARRAY_SIZE(cmd.indirection_table) / nbytes;
1271         for (i = 1; i < num_repeats; i++)
1272                 memcpy(&cmd.indirection_table[i * nbytes],
1273                        cmd.indirection_table, nbytes);
1274         /* handle cut in the middle pattern for the last places */
1275         memcpy(&cmd.indirection_table[i * nbytes], cmd.indirection_table,
1276                ARRAY_SIZE(cmd.indirection_table) % nbytes);
1277
1278         netdev_rss_key_fill(cmd.secret_key, sizeof(cmd.secret_key));
1279
1280         mutex_lock(&mvm->mutex);
1281         if (iwl_mvm_firmware_running(mvm))
1282                 ret = iwl_mvm_send_cmd_pdu(mvm, RSS_CONFIG_CMD, 0,
1283                                            sizeof(cmd), &cmd);
1284         else
1285                 ret = 0;
1286         mutex_unlock(&mvm->mutex);
1287
1288         return ret ?: count;
1289 }
1290
1291 static ssize_t iwl_dbgfs_inject_packet_write(struct iwl_mvm *mvm,
1292                                              char *buf, size_t count,
1293                                              loff_t *ppos)
1294 {
1295         struct iwl_op_mode *opmode = container_of((void *)mvm,
1296                                                   struct iwl_op_mode,
1297                                                   op_mode_specific);
1298         struct iwl_rx_cmd_buffer rxb = {
1299                 ._rx_page_order = 0,
1300                 .truesize = 0, /* not used */
1301                 ._offset = 0,
1302         };
1303         struct iwl_rx_packet *pkt;
1304         int bin_len = count / 2;
1305         int ret = -EINVAL;
1306
1307         if (!iwl_mvm_firmware_running(mvm))
1308                 return -EIO;
1309
1310         /* supporting only MQ RX */
1311         if (!mvm->trans->trans_cfg->mq_rx_supported)
1312                 return -EOPNOTSUPP;
1313
1314         rxb._page = alloc_pages(GFP_ATOMIC, 0);
1315         if (!rxb._page)
1316                 return -ENOMEM;
1317         pkt = rxb_addr(&rxb);
1318
1319         ret = hex2bin(page_address(rxb._page), buf, bin_len);
1320         if (ret)
1321                 goto out;
1322
1323         /* avoid invalid memory access and malformed packet */
1324         if (bin_len < sizeof(*pkt) ||
1325             bin_len != sizeof(*pkt) + iwl_rx_packet_payload_len(pkt))
1326                 goto out;
1327
1328         local_bh_disable();
1329         iwl_mvm_rx_mq(opmode, NULL, &rxb);
1330         local_bh_enable();
1331         ret = 0;
1332
1333 out:
1334         iwl_free_rxb(&rxb);
1335
1336         return ret ?: count;
1337 }
1338
1339 static int _iwl_dbgfs_inject_beacon_ie(struct iwl_mvm *mvm, char *bin, int len)
1340 {
1341         struct ieee80211_vif *vif;
1342         struct iwl_mvm_vif *mvmvif;
1343         struct sk_buff *beacon;
1344         struct ieee80211_tx_info *info;
1345         struct iwl_mac_beacon_cmd beacon_cmd = {};
1346         unsigned int link_id;
1347         u8 rate;
1348         int i;
1349
1350         len /= 2;
1351
1352         /* Element len should be represented by u8 */
1353         if (len >= U8_MAX)
1354                 return -EINVAL;
1355
1356         if (!iwl_mvm_firmware_running(mvm))
1357                 return -EIO;
1358
1359         if (!iwl_mvm_has_new_tx_api(mvm) &&
1360             !fw_has_api(&mvm->fw->ucode_capa,
1361                         IWL_UCODE_TLV_API_NEW_BEACON_TEMPLATE))
1362                 return -EINVAL;
1363
1364         mutex_lock(&mvm->mutex);
1365
1366         for (i = 0; i < NUM_MAC_INDEX_DRIVER; i++) {
1367                 vif = iwl_mvm_rcu_dereference_vif_id(mvm, i, false);
1368                 if (!vif)
1369                         continue;
1370
1371                 if (vif->type == NL80211_IFTYPE_AP)
1372                         break;
1373         }
1374
1375         if (i == NUM_MAC_INDEX_DRIVER || !vif)
1376                 goto out_err;
1377
1378         mvm->hw->extra_beacon_tailroom = len;
1379
1380         beacon = ieee80211_beacon_get_template(mvm->hw, vif, NULL, 0);
1381         if (!beacon)
1382                 goto out_err;
1383
1384         if (len && hex2bin(skb_put_zero(beacon, len), bin, len)) {
1385                 dev_kfree_skb(beacon);
1386                 goto out_err;
1387         }
1388
1389         mvm->beacon_inject_active = true;
1390
1391         mvmvif = iwl_mvm_vif_from_mac80211(vif);
1392         info = IEEE80211_SKB_CB(beacon);
1393         rate = iwl_mvm_mac_ctxt_get_beacon_rate(mvm, info, vif);
1394
1395         for_each_mvm_vif_valid_link(mvmvif, link_id) {
1396                 beacon_cmd.flags =
1397                         cpu_to_le16(iwl_mvm_mac_ctxt_get_beacon_flags(mvm->fw,
1398                                                                       rate));
1399                 beacon_cmd.byte_cnt = cpu_to_le16((u16)beacon->len);
1400                 if (iwl_fw_lookup_cmd_ver(mvm->fw, BEACON_TEMPLATE_CMD, 0) > 12)
1401                         beacon_cmd.link_id =
1402                                 cpu_to_le32(mvmvif->link[link_id]->fw_link_id);
1403                 else
1404                         beacon_cmd.link_id = cpu_to_le32((u32)mvmvif->id);
1405
1406                 iwl_mvm_mac_ctxt_set_tim(mvm, &beacon_cmd.tim_idx,
1407                                          &beacon_cmd.tim_size,
1408                                          beacon->data, beacon->len);
1409
1410                 if (iwl_fw_lookup_cmd_ver(mvm->fw,
1411                                           BEACON_TEMPLATE_CMD, 0) >= 14) {
1412                         u32 offset = iwl_mvm_find_ie_offset(beacon->data,
1413                                                             WLAN_EID_S1G_TWT,
1414                                                             beacon->len);
1415
1416                         beacon_cmd.btwt_offset = cpu_to_le32(offset);
1417                 }
1418
1419                 iwl_mvm_mac_ctxt_send_beacon_cmd(mvm, beacon, &beacon_cmd,
1420                                                  sizeof(beacon_cmd));
1421         }
1422         mutex_unlock(&mvm->mutex);
1423
1424         dev_kfree_skb(beacon);
1425
1426         return 0;
1427
1428 out_err:
1429         mutex_unlock(&mvm->mutex);
1430         return -EINVAL;
1431 }
1432
1433 static ssize_t iwl_dbgfs_inject_beacon_ie_write(struct iwl_mvm *mvm,
1434                                                 char *buf, size_t count,
1435                                                 loff_t *ppos)
1436 {
1437         int ret = _iwl_dbgfs_inject_beacon_ie(mvm, buf, count);
1438
1439         mvm->hw->extra_beacon_tailroom = 0;
1440         return ret ?: count;
1441 }
1442
1443 static ssize_t iwl_dbgfs_inject_beacon_ie_restore_write(struct iwl_mvm *mvm,
1444                                                         char *buf,
1445                                                         size_t count,
1446                                                         loff_t *ppos)
1447 {
1448         int ret = _iwl_dbgfs_inject_beacon_ie(mvm, NULL, 0);
1449
1450         mvm->hw->extra_beacon_tailroom = 0;
1451         mvm->beacon_inject_active = false;
1452         return ret ?: count;
1453 }
1454
1455 static ssize_t iwl_dbgfs_fw_dbg_conf_read(struct file *file,
1456                                           char __user *user_buf,
1457                                           size_t count, loff_t *ppos)
1458 {
1459         struct iwl_mvm *mvm = file->private_data;
1460         int conf;
1461         char buf[8];
1462         const size_t bufsz = sizeof(buf);
1463         int pos = 0;
1464
1465         mutex_lock(&mvm->mutex);
1466         conf = mvm->fwrt.dump.conf;
1467         mutex_unlock(&mvm->mutex);
1468
1469         pos += scnprintf(buf + pos, bufsz - pos, "%d\n", conf);
1470
1471         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1472 }
1473
1474 static ssize_t iwl_dbgfs_fw_dbg_conf_write(struct iwl_mvm *mvm,
1475                                            char *buf, size_t count,
1476                                            loff_t *ppos)
1477 {
1478         unsigned int conf_id;
1479         int ret;
1480
1481         if (!iwl_mvm_firmware_running(mvm))
1482                 return -EIO;
1483
1484         ret = kstrtouint(buf, 0, &conf_id);
1485         if (ret)
1486                 return ret;
1487
1488         if (WARN_ON(conf_id >= FW_DBG_CONF_MAX))
1489                 return -EINVAL;
1490
1491         mutex_lock(&mvm->mutex);
1492         ret = iwl_fw_start_dbg_conf(&mvm->fwrt, conf_id);
1493         mutex_unlock(&mvm->mutex);
1494
1495         return ret ?: count;
1496 }
1497
1498 static ssize_t iwl_dbgfs_fw_dbg_collect_write(struct iwl_mvm *mvm,
1499                                               char *buf, size_t count,
1500                                               loff_t *ppos)
1501 {
1502         if (count == 0)
1503                 return 0;
1504
1505         iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_POINT_USER_TRIGGER,
1506                                NULL);
1507
1508         iwl_fw_dbg_collect(&mvm->fwrt, FW_DBG_TRIGGER_USER, buf,
1509                            (count - 1), NULL);
1510
1511         return count;
1512 }
1513
1514 static ssize_t iwl_dbgfs_fw_dbg_clear_write(struct iwl_mvm *mvm,
1515                                             char *buf, size_t count,
1516                                             loff_t *ppos)
1517 {
1518         if (mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_9000)
1519                 return -EOPNOTSUPP;
1520
1521         mutex_lock(&mvm->mutex);
1522         iwl_fw_dbg_clear_monitor_buf(&mvm->fwrt);
1523         mutex_unlock(&mvm->mutex);
1524
1525         return count;
1526 }
1527
1528 static ssize_t iwl_dbgfs_dbg_time_point_write(struct iwl_mvm *mvm,
1529                                               char *buf, size_t count,
1530                                               loff_t *ppos)
1531 {
1532         u32 timepoint;
1533
1534         if (kstrtou32(buf, 0, &timepoint))
1535                 return -EINVAL;
1536
1537         if (timepoint == IWL_FW_INI_TIME_POINT_INVALID ||
1538             timepoint >= IWL_FW_INI_TIME_POINT_NUM)
1539                 return -EINVAL;
1540
1541         iwl_dbg_tlv_time_point(&mvm->fwrt, timepoint, NULL);
1542
1543         return count;
1544 }
1545
1546 #define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \
1547         _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm)
1548 #define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
1549         _MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm)
1550 #define MVM_DEBUGFS_ADD_FILE_ALIAS(alias, name, parent, mode) do {      \
1551                 debugfs_create_file(alias, mode, parent, mvm,           \
1552                                     &iwl_dbgfs_##name##_ops);           \
1553         } while (0)
1554 #define MVM_DEBUGFS_ADD_FILE(name, parent, mode) \
1555         MVM_DEBUGFS_ADD_FILE_ALIAS(#name, name, parent, mode)
1556
1557 static ssize_t
1558 _iwl_dbgfs_link_sta_wrap_write(ssize_t (*real)(struct ieee80211_link_sta *,
1559                                                struct iwl_mvm_sta *,
1560                                                struct iwl_mvm *,
1561                                                struct iwl_mvm_link_sta *,
1562                                                char *,
1563                                                size_t, loff_t *),
1564                            struct file *file,
1565                            char *buf, size_t buf_size, loff_t *ppos)
1566 {
1567         struct ieee80211_link_sta *link_sta = file->private_data;
1568         struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(link_sta->sta);
1569         struct iwl_mvm *mvm = iwl_mvm_vif_from_mac80211(mvmsta->vif)->mvm;
1570         struct iwl_mvm_link_sta *mvm_link_sta;
1571         ssize_t ret;
1572
1573         mutex_lock(&mvm->mutex);
1574
1575         mvm_link_sta = rcu_dereference_protected(mvmsta->link[link_sta->link_id],
1576                                                  lockdep_is_held(&mvm->mutex));
1577         if (WARN_ON(!mvm_link_sta)) {
1578                 mutex_unlock(&mvm->mutex);
1579                 return -ENODEV;
1580         }
1581
1582         ret = real(link_sta, mvmsta, mvm, mvm_link_sta, buf, buf_size, ppos);
1583
1584         mutex_unlock(&mvm->mutex);
1585
1586         return ret;
1587 }
1588
1589 static ssize_t
1590 _iwl_dbgfs_link_sta_wrap_read(ssize_t (*real)(struct ieee80211_link_sta *,
1591                                               struct iwl_mvm_sta *,
1592                                               struct iwl_mvm *,
1593                                               struct iwl_mvm_link_sta *,
1594                                               char __user *,
1595                                               size_t, loff_t *),
1596                            struct file *file,
1597                            char __user *user_buf, size_t count, loff_t *ppos)
1598 {
1599         struct ieee80211_link_sta *link_sta = file->private_data;
1600         struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(link_sta->sta);
1601         struct iwl_mvm *mvm = iwl_mvm_vif_from_mac80211(mvmsta->vif)->mvm;
1602         struct iwl_mvm_link_sta *mvm_link_sta;
1603         ssize_t ret;
1604
1605         mutex_lock(&mvm->mutex);
1606
1607         mvm_link_sta = rcu_dereference_protected(mvmsta->link[link_sta->link_id],
1608                                                  lockdep_is_held(&mvm->mutex));
1609         if (WARN_ON(!mvm_link_sta)) {
1610                 mutex_unlock(&mvm->mutex);
1611                 return -ENODEV;
1612         }
1613
1614         ret = real(link_sta, mvmsta, mvm, mvm_link_sta, user_buf, count, ppos);
1615
1616         mutex_unlock(&mvm->mutex);
1617
1618         return ret;
1619 }
1620
1621 #define MVM_DEBUGFS_LINK_STA_WRITE_WRAPPER(name, buflen)                \
1622 static ssize_t _iwl_dbgfs_link_sta_##name##_write(struct file *file,    \
1623                                          const char __user *user_buf,   \
1624                                          size_t count, loff_t *ppos)    \
1625 {                                                                       \
1626         char buf[buflen] = {};                                          \
1627         size_t buf_size = min(count, sizeof(buf) -  1);                 \
1628                                                                         \
1629         if (copy_from_user(buf, user_buf, buf_size))                    \
1630                 return -EFAULT;                                         \
1631                                                                         \
1632         return _iwl_dbgfs_link_sta_wrap_write(iwl_dbgfs_##name##_write, \
1633                                               file,                     \
1634                                               buf, buf_size, ppos);     \
1635 }                                                                       \
1636
1637 #define MVM_DEBUGFS_LINK_STA_READ_WRAPPER(name)         \
1638 static ssize_t _iwl_dbgfs_link_sta_##name##_read(struct file *file,     \
1639                                          char __user *user_buf,         \
1640                                          size_t count, loff_t *ppos)    \
1641 {                                                                       \
1642         return _iwl_dbgfs_link_sta_wrap_read(iwl_dbgfs_##name##_read,   \
1643                                              file,                      \
1644                                              user_buf, count, ppos);    \
1645 }                                                                       \
1646
1647 #define MVM_DEBUGFS_WRITE_LINK_STA_FILE_OPS(name, bufsz)                \
1648 MVM_DEBUGFS_LINK_STA_WRITE_WRAPPER(name, bufsz)                         \
1649 static const struct file_operations iwl_dbgfs_link_sta_##name##_ops = { \
1650         .write = _iwl_dbgfs_link_sta_##name##_write,                    \
1651         .open = simple_open,                                            \
1652         .llseek = generic_file_llseek,                                  \
1653 }
1654
1655 #define MVM_DEBUGFS_READ_LINK_STA_FILE_OPS(name)                        \
1656 MVM_DEBUGFS_LINK_STA_READ_WRAPPER(name)                                 \
1657 static const struct file_operations iwl_dbgfs_link_sta_##name##_ops = { \
1658         .read = _iwl_dbgfs_link_sta_##name##_read,                      \
1659         .open = simple_open,                                            \
1660         .llseek = generic_file_llseek,                                  \
1661 }
1662
1663 #define MVM_DEBUGFS_READ_WRITE_LINK_STA_FILE_OPS(name, bufsz)           \
1664 MVM_DEBUGFS_LINK_STA_READ_WRAPPER(name)                                 \
1665 MVM_DEBUGFS_LINK_STA_WRITE_WRAPPER(name, bufsz)                         \
1666 static const struct file_operations iwl_dbgfs_link_sta_##name##_ops = { \
1667         .read = _iwl_dbgfs_link_sta_##name##_read,                      \
1668         .write = _iwl_dbgfs_link_sta_##name##_write,                    \
1669         .open = simple_open,                                            \
1670         .llseek = generic_file_llseek,                                  \
1671 }
1672
1673 #define MVM_DEBUGFS_ADD_LINK_STA_FILE_ALIAS(alias, name, parent, mode)  \
1674                 debugfs_create_file(alias, mode, parent, link_sta,      \
1675                                     &iwl_dbgfs_link_sta_##name##_ops)
1676 #define MVM_DEBUGFS_ADD_LINK_STA_FILE(name, parent, mode) \
1677         MVM_DEBUGFS_ADD_LINK_STA_FILE_ALIAS(#name, name, parent, mode)
1678
1679 static ssize_t
1680 iwl_dbgfs_prph_reg_read(struct file *file,
1681                         char __user *user_buf,
1682                         size_t count, loff_t *ppos)
1683 {
1684         struct iwl_mvm *mvm = file->private_data;
1685         int pos = 0;
1686         char buf[32];
1687         const size_t bufsz = sizeof(buf);
1688
1689         if (!mvm->dbgfs_prph_reg_addr)
1690                 return -EINVAL;
1691
1692         pos += scnprintf(buf + pos, bufsz - pos, "Reg 0x%x: (0x%x)\n",
1693                 mvm->dbgfs_prph_reg_addr,
1694                 iwl_read_prph(mvm->trans, mvm->dbgfs_prph_reg_addr));
1695
1696         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1697 }
1698
1699 static ssize_t
1700 iwl_dbgfs_prph_reg_write(struct iwl_mvm *mvm, char *buf,
1701                          size_t count, loff_t *ppos)
1702 {
1703         u8 args;
1704         u32 value;
1705
1706         args = sscanf(buf, "%i %i", &mvm->dbgfs_prph_reg_addr, &value);
1707         /* if we only want to set the reg address - nothing more to do */
1708         if (args == 1)
1709                 goto out;
1710
1711         /* otherwise, make sure we have both address and value */
1712         if (args != 2)
1713                 return -EINVAL;
1714
1715         iwl_write_prph(mvm->trans, mvm->dbgfs_prph_reg_addr, value);
1716
1717 out:
1718         return count;
1719 }
1720
1721 static ssize_t
1722 iwl_dbgfs_send_echo_cmd_write(struct iwl_mvm *mvm, char *buf,
1723                               size_t count, loff_t *ppos)
1724 {
1725         int ret;
1726
1727         if (!iwl_mvm_firmware_running(mvm))
1728                 return -EIO;
1729
1730         mutex_lock(&mvm->mutex);
1731         ret = iwl_mvm_send_cmd_pdu(mvm, ECHO_CMD, 0, 0, NULL);
1732         mutex_unlock(&mvm->mutex);
1733
1734         return ret ?: count;
1735 }
1736
1737 struct iwl_mvm_sniffer_apply {
1738         struct iwl_mvm *mvm;
1739         u8 *bssid;
1740         u16 aid;
1741 };
1742
1743 static bool iwl_mvm_sniffer_apply(struct iwl_notif_wait_data *notif_data,
1744                                   struct iwl_rx_packet *pkt, void *data)
1745 {
1746         struct iwl_mvm_sniffer_apply *apply = data;
1747
1748         apply->mvm->cur_aid = cpu_to_le16(apply->aid);
1749         memcpy(apply->mvm->cur_bssid, apply->bssid,
1750                sizeof(apply->mvm->cur_bssid));
1751
1752         return true;
1753 }
1754
1755 static ssize_t
1756 iwl_dbgfs_he_sniffer_params_write(struct iwl_mvm *mvm, char *buf,
1757                                   size_t count, loff_t *ppos)
1758 {
1759         struct iwl_notification_wait wait;
1760         struct iwl_he_monitor_cmd he_mon_cmd = {};
1761         struct iwl_mvm_sniffer_apply apply = {
1762                 .mvm = mvm,
1763         };
1764         u16 wait_cmds[] = {
1765                 WIDE_ID(DATA_PATH_GROUP, HE_AIR_SNIFFER_CONFIG_CMD),
1766         };
1767         u32 aid;
1768         int ret;
1769
1770         if (!iwl_mvm_firmware_running(mvm))
1771                 return -EIO;
1772
1773         ret = sscanf(buf, "%x %2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx", &aid,
1774                      &he_mon_cmd.bssid[0], &he_mon_cmd.bssid[1],
1775                      &he_mon_cmd.bssid[2], &he_mon_cmd.bssid[3],
1776                      &he_mon_cmd.bssid[4], &he_mon_cmd.bssid[5]);
1777         if (ret != 7)
1778                 return -EINVAL;
1779
1780         he_mon_cmd.aid = cpu_to_le16(aid);
1781
1782         apply.aid = aid;
1783         apply.bssid = (void *)he_mon_cmd.bssid;
1784
1785         mutex_lock(&mvm->mutex);
1786
1787         /*
1788          * Use the notification waiter to get our function triggered
1789          * in sequence with other RX. This ensures that frames we get
1790          * on the RX queue _before_ the new configuration is applied
1791          * still have mvm->cur_aid pointing to the old AID, and that
1792          * frames on the RX queue _after_ the firmware processed the
1793          * new configuration (and sent the response, synchronously)
1794          * get mvm->cur_aid correctly set to the new AID.
1795          */
1796         iwl_init_notification_wait(&mvm->notif_wait, &wait,
1797                                    wait_cmds, ARRAY_SIZE(wait_cmds),
1798                                    iwl_mvm_sniffer_apply, &apply);
1799
1800         ret = iwl_mvm_send_cmd_pdu(mvm,
1801                                    WIDE_ID(DATA_PATH_GROUP, HE_AIR_SNIFFER_CONFIG_CMD),
1802                                    0,
1803                                    sizeof(he_mon_cmd), &he_mon_cmd);
1804
1805         /* no need to really wait, we already did anyway */
1806         iwl_remove_notification(&mvm->notif_wait, &wait);
1807
1808         mutex_unlock(&mvm->mutex);
1809
1810         return ret ?: count;
1811 }
1812
1813 static ssize_t
1814 iwl_dbgfs_he_sniffer_params_read(struct file *file, char __user *user_buf,
1815                                  size_t count, loff_t *ppos)
1816 {
1817         struct iwl_mvm *mvm = file->private_data;
1818         u8 buf[32];
1819         int len;
1820
1821         len = scnprintf(buf, sizeof(buf),
1822                         "%d %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n",
1823                         le16_to_cpu(mvm->cur_aid), mvm->cur_bssid[0],
1824                         mvm->cur_bssid[1], mvm->cur_bssid[2], mvm->cur_bssid[3],
1825                         mvm->cur_bssid[4], mvm->cur_bssid[5]);
1826
1827         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1828 }
1829
1830 static ssize_t
1831 iwl_dbgfs_uapsd_noagg_bssids_read(struct file *file, char __user *user_buf,
1832                                   size_t count, loff_t *ppos)
1833 {
1834         struct iwl_mvm *mvm = file->private_data;
1835         u8 buf[IWL_MVM_UAPSD_NOAGG_BSSIDS_NUM * ETH_ALEN * 3 + 1];
1836         unsigned int pos = 0;
1837         size_t bufsz = sizeof(buf);
1838         int i;
1839
1840         mutex_lock(&mvm->mutex);
1841
1842         for (i = 0; i < IWL_MVM_UAPSD_NOAGG_LIST_LEN; i++)
1843                 pos += scnprintf(buf + pos, bufsz - pos, "%pM\n",
1844                                  mvm->uapsd_noagg_bssids[i].addr);
1845
1846         mutex_unlock(&mvm->mutex);
1847
1848         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1849 }
1850
1851 static ssize_t
1852 iwl_dbgfs_ltr_config_write(struct iwl_mvm *mvm,
1853                            char *buf, size_t count, loff_t *ppos)
1854 {
1855         int ret;
1856         struct iwl_ltr_config_cmd ltr_config = {0};
1857
1858         if (!iwl_mvm_firmware_running(mvm))
1859                 return -EIO;
1860
1861         if (sscanf(buf, "%x,%x,%x,%x,%x,%x,%x",
1862                    &ltr_config.flags,
1863                    &ltr_config.static_long,
1864                    &ltr_config.static_short,
1865                    &ltr_config.ltr_cfg_values[0],
1866                    &ltr_config.ltr_cfg_values[1],
1867                    &ltr_config.ltr_cfg_values[2],
1868                    &ltr_config.ltr_cfg_values[3]) != 7) {
1869                 return -EINVAL;
1870         }
1871
1872         mutex_lock(&mvm->mutex);
1873         ret = iwl_mvm_send_cmd_pdu(mvm, LTR_CONFIG, 0, sizeof(ltr_config),
1874                                    &ltr_config);
1875         mutex_unlock(&mvm->mutex);
1876
1877         if (ret)
1878                 IWL_ERR(mvm, "failed to send ltr configuration cmd\n");
1879
1880         return ret ?: count;
1881 }
1882
1883 static ssize_t iwl_dbgfs_rfi_freq_table_write(struct iwl_mvm *mvm, char *buf,
1884                                               size_t count, loff_t *ppos)
1885 {
1886         int ret = 0;
1887         u16 op_id;
1888
1889         if (kstrtou16(buf, 10, &op_id))
1890                 return -EINVAL;
1891
1892         /* value zero triggers re-sending the default table to the device */
1893         if (!op_id) {
1894                 mutex_lock(&mvm->mutex);
1895                 ret = iwl_rfi_send_config_cmd(mvm, NULL);
1896                 mutex_unlock(&mvm->mutex);
1897         } else {
1898                 ret = -EOPNOTSUPP; /* in the future a new table will be added */
1899         }
1900
1901         return ret ?: count;
1902 }
1903
1904 /* The size computation is as follows:
1905  * each number needs at most 3 characters, number of rows is the size of
1906  * the table; So, need 5 chars for the "freq: " part and each tuple afterwards
1907  * needs 6 characters for numbers and 5 for the punctuation around.
1908  */
1909 #define IWL_RFI_BUF_SIZE (IWL_RFI_LUT_INSTALLED_SIZE *\
1910                                 (5 + IWL_RFI_LUT_ENTRY_CHANNELS_NUM * (6 + 5)))
1911
1912 static ssize_t iwl_dbgfs_rfi_freq_table_read(struct file *file,
1913                                              char __user *user_buf,
1914                                              size_t count, loff_t *ppos)
1915 {
1916         struct iwl_mvm *mvm = file->private_data;
1917         struct iwl_rfi_freq_table_resp_cmd *resp;
1918         u32 status;
1919         char buf[IWL_RFI_BUF_SIZE];
1920         int i, j, pos = 0;
1921
1922         resp = iwl_rfi_get_freq_table(mvm);
1923         if (IS_ERR(resp))
1924                 return PTR_ERR(resp);
1925
1926         status = le32_to_cpu(resp->status);
1927         if (status != RFI_FREQ_TABLE_OK) {
1928                 scnprintf(buf, IWL_RFI_BUF_SIZE, "status = %d\n", status);
1929                 goto out;
1930         }
1931
1932         for (i = 0; i < ARRAY_SIZE(resp->table); i++) {
1933                 pos += scnprintf(buf + pos, IWL_RFI_BUF_SIZE - pos, "%d: ",
1934                                  resp->table[i].freq);
1935
1936                 for (j = 0; j < ARRAY_SIZE(resp->table[i].channels); j++)
1937                         pos += scnprintf(buf + pos, IWL_RFI_BUF_SIZE - pos,
1938                                          "(%d, %d) ",
1939                                          resp->table[i].channels[j],
1940                                          resp->table[i].bands[j]);
1941                 pos += scnprintf(buf + pos, IWL_RFI_BUF_SIZE - pos, "\n");
1942         }
1943
1944 out:
1945         kfree(resp);
1946         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1947 }
1948
1949 MVM_DEBUGFS_READ_WRITE_FILE_OPS(prph_reg, 64);
1950
1951 /* Device wide debugfs entries */
1952 MVM_DEBUGFS_READ_FILE_OPS(ctdp_budget);
1953 MVM_DEBUGFS_WRITE_FILE_OPS(stop_ctdp, 8);
1954 MVM_DEBUGFS_WRITE_FILE_OPS(start_ctdp, 8);
1955 MVM_DEBUGFS_WRITE_FILE_OPS(force_ctkill, 8);
1956 MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush, 16);
1957 MVM_DEBUGFS_WRITE_FILE_OPS(send_echo_cmd, 8);
1958 MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram, 64);
1959 MVM_DEBUGFS_READ_WRITE_FILE_OPS(set_nic_temperature, 64);
1960 MVM_DEBUGFS_READ_FILE_OPS(nic_temp);
1961 MVM_DEBUGFS_READ_FILE_OPS(stations);
1962 MVM_DEBUGFS_READ_LINK_STA_FILE_OPS(rs_data);
1963 MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off, 64);
1964 MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats);
1965 MVM_DEBUGFS_READ_FILE_OPS(drv_rx_stats);
1966 MVM_DEBUGFS_READ_FILE_OPS(fw_system_stats);
1967 MVM_DEBUGFS_READ_FILE_OPS(fw_ver);
1968 MVM_DEBUGFS_READ_FILE_OPS(phy_integration_ver);
1969 MVM_DEBUGFS_READ_FILE_OPS(tas_get_status);
1970 MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart, 10);
1971 MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi, 10);
1972 MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8);
1973 MVM_DEBUGFS_READ_WRITE_FILE_OPS(fw_dbg_conf, 8);
1974 MVM_DEBUGFS_WRITE_FILE_OPS(fw_dbg_collect, 64);
1975 MVM_DEBUGFS_WRITE_FILE_OPS(fw_dbg_clear, 64);
1976 MVM_DEBUGFS_WRITE_FILE_OPS(dbg_time_point, 64);
1977 MVM_DEBUGFS_WRITE_FILE_OPS(indirection_tbl,
1978                            (IWL_RSS_INDIRECTION_TABLE_SIZE * 2));
1979 MVM_DEBUGFS_WRITE_FILE_OPS(inject_packet, 512);
1980 MVM_DEBUGFS_WRITE_FILE_OPS(inject_beacon_ie, 512);
1981 MVM_DEBUGFS_WRITE_FILE_OPS(inject_beacon_ie_restore, 512);
1982
1983 MVM_DEBUGFS_READ_FILE_OPS(uapsd_noagg_bssids);
1984
1985 #ifdef CONFIG_ACPI
1986 MVM_DEBUGFS_READ_FILE_OPS(sar_geo_profile);
1987 MVM_DEBUGFS_READ_FILE_OPS(wifi_6e_enable);
1988 #endif
1989
1990 MVM_DEBUGFS_READ_WRITE_LINK_STA_FILE_OPS(amsdu_len, 16);
1991
1992 MVM_DEBUGFS_READ_WRITE_FILE_OPS(he_sniffer_params, 32);
1993
1994 MVM_DEBUGFS_WRITE_FILE_OPS(ltr_config, 512);
1995 MVM_DEBUGFS_READ_WRITE_FILE_OPS(rfi_freq_table, 16);
1996
1997 static ssize_t iwl_dbgfs_mem_read(struct file *file, char __user *user_buf,
1998                                   size_t count, loff_t *ppos)
1999 {
2000         struct iwl_mvm *mvm = file->private_data;
2001         struct iwl_dbg_mem_access_cmd cmd = {};
2002         struct iwl_dbg_mem_access_rsp *rsp;
2003         struct iwl_host_cmd hcmd = {
2004                 .flags = CMD_WANT_SKB | CMD_SEND_IN_RFKILL,
2005                 .data = { &cmd, },
2006                 .len = { sizeof(cmd) },
2007         };
2008         size_t delta;
2009         ssize_t ret, len;
2010
2011         if (!iwl_mvm_firmware_running(mvm))
2012                 return -EIO;
2013
2014         hcmd.id = WIDE_ID(DEBUG_GROUP, *ppos >> 24 ? UMAC_RD_WR : LMAC_RD_WR);
2015         cmd.op = cpu_to_le32(DEBUG_MEM_OP_READ);
2016
2017         /* Take care of alignment of both the position and the length */
2018         delta = *ppos & 0x3;
2019         cmd.addr = cpu_to_le32(*ppos - delta);
2020         cmd.len = cpu_to_le32(min(ALIGN(count + delta, 4) / 4,
2021                                   (size_t)DEBUG_MEM_MAX_SIZE_DWORDS));
2022
2023         mutex_lock(&mvm->mutex);
2024         ret = iwl_mvm_send_cmd(mvm, &hcmd);
2025         mutex_unlock(&mvm->mutex);
2026
2027         if (ret < 0)
2028                 return ret;
2029
2030         if (iwl_rx_packet_payload_len(hcmd.resp_pkt) < sizeof(*rsp)) {
2031                 ret = -EIO;
2032                 goto out;
2033         }
2034
2035         rsp = (void *)hcmd.resp_pkt->data;
2036         if (le32_to_cpu(rsp->status) != DEBUG_MEM_STATUS_SUCCESS) {
2037                 ret = -ENXIO;
2038                 goto out;
2039         }
2040
2041         len = min((size_t)le32_to_cpu(rsp->len) << 2,
2042                   iwl_rx_packet_payload_len(hcmd.resp_pkt) - sizeof(*rsp));
2043         len = min(len - delta, count);
2044         if (len < 0) {
2045                 ret = -EFAULT;
2046                 goto out;
2047         }
2048
2049         ret = len - copy_to_user(user_buf, (u8 *)rsp->data + delta, len);
2050         *ppos += ret;
2051
2052 out:
2053         iwl_free_resp(&hcmd);
2054         return ret;
2055 }
2056
2057 static ssize_t iwl_dbgfs_mem_write(struct file *file,
2058                                    const char __user *user_buf, size_t count,
2059                                    loff_t *ppos)
2060 {
2061         struct iwl_mvm *mvm = file->private_data;
2062         struct iwl_dbg_mem_access_cmd *cmd;
2063         struct iwl_dbg_mem_access_rsp *rsp;
2064         struct iwl_host_cmd hcmd = {};
2065         size_t cmd_size;
2066         size_t data_size;
2067         u32 op, len;
2068         ssize_t ret;
2069
2070         if (!iwl_mvm_firmware_running(mvm))
2071                 return -EIO;
2072
2073         hcmd.id = WIDE_ID(DEBUG_GROUP, *ppos >> 24 ? UMAC_RD_WR : LMAC_RD_WR);
2074
2075         if (*ppos & 0x3 || count < 4) {
2076                 op = DEBUG_MEM_OP_WRITE_BYTES;
2077                 len = min(count, (size_t)(4 - (*ppos & 0x3)));
2078                 data_size = len;
2079         } else {
2080                 op = DEBUG_MEM_OP_WRITE;
2081                 len = min(count >> 2, (size_t)DEBUG_MEM_MAX_SIZE_DWORDS);
2082                 data_size = len << 2;
2083         }
2084
2085         cmd_size = sizeof(*cmd) + ALIGN(data_size, 4);
2086         cmd = kzalloc(cmd_size, GFP_KERNEL);
2087         if (!cmd)
2088                 return -ENOMEM;
2089
2090         cmd->op = cpu_to_le32(op);
2091         cmd->len = cpu_to_le32(len);
2092         cmd->addr = cpu_to_le32(*ppos);
2093         if (copy_from_user((void *)cmd->data, user_buf, data_size)) {
2094                 kfree(cmd);
2095                 return -EFAULT;
2096         }
2097
2098         hcmd.flags = CMD_WANT_SKB | CMD_SEND_IN_RFKILL,
2099         hcmd.data[0] = (void *)cmd;
2100         hcmd.len[0] = cmd_size;
2101
2102         mutex_lock(&mvm->mutex);
2103         ret = iwl_mvm_send_cmd(mvm, &hcmd);
2104         mutex_unlock(&mvm->mutex);
2105
2106         kfree(cmd);
2107
2108         if (ret < 0)
2109                 return ret;
2110
2111         if (iwl_rx_packet_payload_len(hcmd.resp_pkt) < sizeof(*rsp)) {
2112                 ret = -EIO;
2113                 goto out;
2114         }
2115
2116         rsp = (void *)hcmd.resp_pkt->data;
2117         if (rsp->status != DEBUG_MEM_STATUS_SUCCESS) {
2118                 ret = -ENXIO;
2119                 goto out;
2120         }
2121
2122         ret = data_size;
2123         *ppos += ret;
2124
2125 out:
2126         iwl_free_resp(&hcmd);
2127         return ret;
2128 }
2129
2130 static const struct file_operations iwl_dbgfs_mem_ops = {
2131         .read = iwl_dbgfs_mem_read,
2132         .write = iwl_dbgfs_mem_write,
2133         .open = simple_open,
2134         .llseek = default_llseek,
2135 };
2136
2137 void iwl_mvm_link_sta_add_debugfs(struct ieee80211_hw *hw,
2138                                   struct ieee80211_vif *vif,
2139                                   struct ieee80211_link_sta *link_sta,
2140                                   struct dentry *dir)
2141 {
2142         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2143
2144         if (iwl_mvm_has_tlc_offload(mvm)) {
2145                 MVM_DEBUGFS_ADD_LINK_STA_FILE(rs_data, dir, 0400);
2146         }
2147
2148         MVM_DEBUGFS_ADD_LINK_STA_FILE(amsdu_len, dir, 0600);
2149 }
2150
2151 void iwl_mvm_dbgfs_register(struct iwl_mvm *mvm)
2152 {
2153         struct dentry *bcast_dir __maybe_unused;
2154
2155         spin_lock_init(&mvm->drv_stats_lock);
2156
2157         MVM_DEBUGFS_ADD_FILE(tx_flush, mvm->debugfs_dir, 0200);
2158         MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, 0600);
2159         MVM_DEBUGFS_ADD_FILE(set_nic_temperature, mvm->debugfs_dir, 0600);
2160         MVM_DEBUGFS_ADD_FILE(nic_temp, mvm->debugfs_dir, 0400);
2161         MVM_DEBUGFS_ADD_FILE(ctdp_budget, mvm->debugfs_dir, 0400);
2162         MVM_DEBUGFS_ADD_FILE(stop_ctdp, mvm->debugfs_dir, 0200);
2163         MVM_DEBUGFS_ADD_FILE(start_ctdp, mvm->debugfs_dir, 0200);
2164         MVM_DEBUGFS_ADD_FILE(force_ctkill, mvm->debugfs_dir, 0200);
2165         MVM_DEBUGFS_ADD_FILE(stations, mvm->debugfs_dir, 0400);
2166         MVM_DEBUGFS_ADD_FILE(disable_power_off, mvm->debugfs_dir, 0600);
2167         MVM_DEBUGFS_ADD_FILE(fw_ver, mvm->debugfs_dir, 0400);
2168         MVM_DEBUGFS_ADD_FILE(fw_rx_stats, mvm->debugfs_dir, 0400);
2169         MVM_DEBUGFS_ADD_FILE(drv_rx_stats, mvm->debugfs_dir, 0400);
2170         MVM_DEBUGFS_ADD_FILE(fw_system_stats, mvm->debugfs_dir, 0400);
2171         MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, 0200);
2172         MVM_DEBUGFS_ADD_FILE(fw_nmi, mvm->debugfs_dir, 0200);
2173         MVM_DEBUGFS_ADD_FILE(scan_ant_rxchain, mvm->debugfs_dir, 0600);
2174         MVM_DEBUGFS_ADD_FILE(prph_reg, mvm->debugfs_dir, 0600);
2175         MVM_DEBUGFS_ADD_FILE(fw_dbg_conf, mvm->debugfs_dir, 0600);
2176         MVM_DEBUGFS_ADD_FILE(fw_dbg_collect, mvm->debugfs_dir, 0200);
2177         MVM_DEBUGFS_ADD_FILE(fw_dbg_clear, mvm->debugfs_dir, 0200);
2178         MVM_DEBUGFS_ADD_FILE(dbg_time_point, mvm->debugfs_dir, 0200);
2179         MVM_DEBUGFS_ADD_FILE(send_echo_cmd, mvm->debugfs_dir, 0200);
2180         MVM_DEBUGFS_ADD_FILE(indirection_tbl, mvm->debugfs_dir, 0200);
2181         MVM_DEBUGFS_ADD_FILE(inject_packet, mvm->debugfs_dir, 0200);
2182         MVM_DEBUGFS_ADD_FILE(inject_beacon_ie, mvm->debugfs_dir, 0200);
2183         MVM_DEBUGFS_ADD_FILE(inject_beacon_ie_restore, mvm->debugfs_dir, 0200);
2184         MVM_DEBUGFS_ADD_FILE(rfi_freq_table, mvm->debugfs_dir, 0600);
2185
2186         if (mvm->fw->phy_integration_ver)
2187                 MVM_DEBUGFS_ADD_FILE(phy_integration_ver, mvm->debugfs_dir, 0400);
2188         MVM_DEBUGFS_ADD_FILE(tas_get_status, mvm->debugfs_dir, 0400);
2189 #ifdef CONFIG_ACPI
2190         MVM_DEBUGFS_ADD_FILE(sar_geo_profile, mvm->debugfs_dir, 0400);
2191         MVM_DEBUGFS_ADD_FILE(wifi_6e_enable, mvm->debugfs_dir, 0400);
2192 #endif
2193         MVM_DEBUGFS_ADD_FILE(he_sniffer_params, mvm->debugfs_dir, 0600);
2194
2195         if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SET_LTR_GEN2))
2196                 MVM_DEBUGFS_ADD_FILE(ltr_config, mvm->debugfs_dir, 0200);
2197
2198         debugfs_create_bool("enable_scan_iteration_notif", 0600,
2199                             mvm->debugfs_dir, &mvm->scan_iter_notif_enabled);
2200         debugfs_create_bool("drop_bcn_ap_mode", 0600, mvm->debugfs_dir,
2201                             &mvm->drop_bcn_ap_mode);
2202
2203         MVM_DEBUGFS_ADD_FILE(uapsd_noagg_bssids, mvm->debugfs_dir, S_IRUSR);
2204
2205 #ifdef CONFIG_PM_SLEEP
2206         MVM_DEBUGFS_ADD_FILE(d3_test, mvm->debugfs_dir, 0400);
2207         debugfs_create_bool("d3_wake_sysassert", 0600, mvm->debugfs_dir,
2208                             &mvm->d3_wake_sysassert);
2209         debugfs_create_u32("last_netdetect_scans", 0400, mvm->debugfs_dir,
2210                            &mvm->last_netdetect_scans);
2211 #endif
2212
2213         debugfs_create_u8("ps_disabled", 0400, mvm->debugfs_dir,
2214                           &mvm->ps_disabled);
2215         debugfs_create_blob("nvm_hw", 0400, mvm->debugfs_dir,
2216                             &mvm->nvm_hw_blob);
2217         debugfs_create_blob("nvm_sw", 0400, mvm->debugfs_dir,
2218                             &mvm->nvm_sw_blob);
2219         debugfs_create_blob("nvm_calib", 0400, mvm->debugfs_dir,
2220                             &mvm->nvm_calib_blob);
2221         debugfs_create_blob("nvm_prod", 0400, mvm->debugfs_dir,
2222                             &mvm->nvm_prod_blob);
2223         debugfs_create_blob("nvm_phy_sku", 0400, mvm->debugfs_dir,
2224                             &mvm->nvm_phy_sku_blob);
2225         debugfs_create_blob("nvm_reg", S_IRUSR,
2226                             mvm->debugfs_dir, &mvm->nvm_reg_blob);
2227
2228         debugfs_create_file("mem", 0600, mvm->debugfs_dir, mvm,
2229                             &iwl_dbgfs_mem_ops);
2230
2231         debugfs_create_bool("rx_ts_ptp", 0600, mvm->debugfs_dir,
2232                             &mvm->rx_ts_ptp);
2233
2234         /*
2235          * Create a symlink with mac80211. It will be removed when mac80211
2236          * exists (before the opmode exists which removes the target.)
2237          */
2238         if (!IS_ERR(mvm->debugfs_dir)) {
2239                 char buf[100];
2240
2241                 snprintf(buf, 100, "../../%pd2", mvm->debugfs_dir->d_parent);
2242                 debugfs_create_symlink("iwlwifi", mvm->hw->wiphy->debugfsdir,
2243                                        buf);
2244         }
2245 }
This page took 0.156144 seconds and 4 git commands to generate.