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