1 /******************************************************************************
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.
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
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.
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.
22 * The full GNU General Public License is included in this distribution
23 * in the file called COPYING.
25 * Contact Information:
26 * Intel Linux Wireless <linuxwifi@intel.com>
27 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
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.
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
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
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.
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.
63 *****************************************************************************/
64 #include <linux/vmalloc.h>
65 #include <linux/ieee80211.h>
66 #include <linux/netdevice.h>
72 #include "iwl-modparams.h"
73 #include "fw/error-dump.h"
75 static ssize_t
iwl_dbgfs_ctdp_budget_read(struct file
*file
,
76 char __user
*user_buf
,
77 size_t count
, loff_t
*ppos
)
79 struct iwl_mvm
*mvm
= file
->private_data
;
83 if (!iwl_mvm_is_ctdp_supported(mvm
))
86 if (!iwl_mvm_firmware_running(mvm
) ||
87 mvm
->fwrt
.cur_fw_img
!= IWL_UCODE_REGULAR
)
90 mutex_lock(&mvm
->mutex
);
91 budget
= iwl_mvm_ctdp_command(mvm
, CTDP_CMD_OPERATION_REPORT
, 0);
92 mutex_unlock(&mvm
->mutex
);
97 pos
= scnprintf(buf
, sizeof(buf
), "%d\n", budget
);
99 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
102 static ssize_t
iwl_dbgfs_stop_ctdp_write(struct iwl_mvm
*mvm
, char *buf
,
103 size_t count
, loff_t
*ppos
)
107 if (!iwl_mvm_is_ctdp_supported(mvm
))
110 if (!iwl_mvm_firmware_running(mvm
) ||
111 mvm
->fwrt
.cur_fw_img
!= IWL_UCODE_REGULAR
)
114 mutex_lock(&mvm
->mutex
);
115 ret
= iwl_mvm_ctdp_command(mvm
, CTDP_CMD_OPERATION_STOP
, 0);
116 mutex_unlock(&mvm
->mutex
);
121 static ssize_t
iwl_dbgfs_force_ctkill_write(struct iwl_mvm
*mvm
, char *buf
,
122 size_t count
, loff_t
*ppos
)
124 if (!iwl_mvm_firmware_running(mvm
) ||
125 mvm
->fwrt
.cur_fw_img
!= IWL_UCODE_REGULAR
)
128 iwl_mvm_enter_ctkill(mvm
);
133 static ssize_t
iwl_dbgfs_tx_flush_write(struct iwl_mvm
*mvm
, char *buf
,
134 size_t count
, loff_t
*ppos
)
139 if (!iwl_mvm_firmware_running(mvm
) ||
140 mvm
->fwrt
.cur_fw_img
!= IWL_UCODE_REGULAR
)
143 if (kstrtou32(buf
, 0, &flush_arg
))
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",
150 mutex_lock(&mvm
->mutex
);
151 ret
= iwl_mvm_flush_sta_tids(mvm
, flush_arg
, 0xFFFF, 0)
153 mutex_unlock(&mvm
->mutex
);
157 IWL_DEBUG_TX_QUEUES(mvm
, "FLUSHING queues mask to flush = 0x%x\n",
160 mutex_lock(&mvm
->mutex
);
161 ret
= iwl_mvm_flush_tx_path(mvm
, flush_arg
, 0) ? : count
;
162 mutex_unlock(&mvm
->mutex
);
167 static ssize_t
iwl_dbgfs_sta_drain_write(struct iwl_mvm
*mvm
, char *buf
,
168 size_t count
, loff_t
*ppos
)
170 struct iwl_mvm_sta
*mvmsta
;
171 int sta_id
, drain
, ret
;
173 if (!iwl_mvm_firmware_running(mvm
) ||
174 mvm
->fwrt
.cur_fw_img
!= IWL_UCODE_REGULAR
)
177 if (sscanf(buf
, "%d %d", &sta_id
, &drain
) != 2)
179 if (sta_id
< 0 || sta_id
>= IWL_MVM_STATION_COUNT
)
181 if (drain
< 0 || drain
> 1)
184 mutex_lock(&mvm
->mutex
);
186 mvmsta
= iwl_mvm_sta_from_staid_protected(mvm
, sta_id
);
191 ret
= iwl_mvm_drain_sta(mvm
, mvmsta
, drain
) ? : count
;
193 mutex_unlock(&mvm
->mutex
);
198 static ssize_t
iwl_dbgfs_sram_read(struct file
*file
, char __user
*user_buf
,
199 size_t count
, loff_t
*ppos
)
201 struct iwl_mvm
*mvm
= file
->private_data
;
202 const struct fw_img
*img
;
203 unsigned int ofs
, len
;
207 if (!iwl_mvm_firmware_running(mvm
))
210 /* default is to dump the entire data segment */
211 img
= &mvm
->fw
->img
[mvm
->fwrt
.cur_fw_img
];
212 ofs
= img
->sec
[IWL_UCODE_SECTION_DATA
].offset
;
213 len
= img
->sec
[IWL_UCODE_SECTION_DATA
].len
;
215 if (mvm
->dbgfs_sram_len
) {
216 ofs
= mvm
->dbgfs_sram_offset
;
217 len
= mvm
->dbgfs_sram_len
;
220 ptr
= kzalloc(len
, GFP_KERNEL
);
224 iwl_trans_read_mem_bytes(mvm
->trans
, ofs
, ptr
, len
);
226 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, ptr
, len
);
233 static ssize_t
iwl_dbgfs_sram_write(struct iwl_mvm
*mvm
, char *buf
,
234 size_t count
, loff_t
*ppos
)
236 const struct fw_img
*img
;
238 u32 img_offset
, img_len
;
240 if (!iwl_mvm_firmware_running(mvm
))
243 img
= &mvm
->fw
->img
[mvm
->fwrt
.cur_fw_img
];
244 img_offset
= img
->sec
[IWL_UCODE_SECTION_DATA
].offset
;
245 img_len
= img
->sec
[IWL_UCODE_SECTION_DATA
].len
;
247 if (sscanf(buf
, "%x,%x", &offset
, &len
) == 2) {
248 if ((offset
& 0x3) || (len
& 0x3))
251 if (offset
+ len
> img_offset
+ img_len
)
254 mvm
->dbgfs_sram_offset
= offset
;
255 mvm
->dbgfs_sram_len
= len
;
257 mvm
->dbgfs_sram_offset
= 0;
258 mvm
->dbgfs_sram_len
= 0;
264 static ssize_t
iwl_dbgfs_set_nic_temperature_read(struct file
*file
,
265 char __user
*user_buf
,
266 size_t count
, loff_t
*ppos
)
268 struct iwl_mvm
*mvm
= file
->private_data
;
272 if (!mvm
->temperature_test
)
273 pos
= scnprintf(buf
, sizeof(buf
), "disabled\n");
275 pos
= scnprintf(buf
, sizeof(buf
), "%d\n", mvm
->temperature
);
277 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
281 * Set NIC Temperature
282 * Cause the driver to ignore the actual NIC temperature reported by the FW
283 * Enable: any value between IWL_MVM_DEBUG_SET_TEMPERATURE_MIN -
284 * IWL_MVM_DEBUG_SET_TEMPERATURE_MAX
285 * Disable: IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE
287 static ssize_t
iwl_dbgfs_set_nic_temperature_write(struct iwl_mvm
*mvm
,
288 char *buf
, size_t count
,
293 if (!iwl_mvm_firmware_running(mvm
) && !mvm
->temperature_test
)
296 if (kstrtoint(buf
, 10, &temperature
))
298 /* not a legal temperature */
299 if ((temperature
> IWL_MVM_DEBUG_SET_TEMPERATURE_MAX
&&
300 temperature
!= IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE
) ||
301 temperature
< IWL_MVM_DEBUG_SET_TEMPERATURE_MIN
)
304 mutex_lock(&mvm
->mutex
);
305 if (temperature
== IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE
) {
306 if (!mvm
->temperature_test
)
309 mvm
->temperature_test
= false;
310 /* Since we can't read the temp while awake, just set
311 * it to zero until we get the next RX stats from the
314 mvm
->temperature
= 0;
316 mvm
->temperature_test
= true;
317 mvm
->temperature
= temperature
;
319 IWL_DEBUG_TEMP(mvm
, "%sabling debug set temperature (temp = %d)\n",
320 mvm
->temperature_test
? "En" : "Dis" ,
322 /* handle the temperature change */
323 iwl_mvm_tt_handler(mvm
);
326 mutex_unlock(&mvm
->mutex
);
331 static ssize_t
iwl_dbgfs_nic_temp_read(struct file
*file
,
332 char __user
*user_buf
,
333 size_t count
, loff_t
*ppos
)
335 struct iwl_mvm
*mvm
= file
->private_data
;
340 if (!iwl_mvm_firmware_running(mvm
))
343 mutex_lock(&mvm
->mutex
);
344 ret
= iwl_mvm_get_temp(mvm
, &temp
);
345 mutex_unlock(&mvm
->mutex
);
350 pos
= scnprintf(buf
, sizeof(buf
), "%d\n", temp
);
352 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
356 static ssize_t
iwl_dbgfs_sar_geo_profile_read(struct file
*file
,
357 char __user
*user_buf
,
358 size_t count
, loff_t
*ppos
)
360 struct iwl_mvm
*mvm
= file
->private_data
;
363 int bufsz
= sizeof(buf
);
367 if (!iwl_mvm_firmware_running(mvm
))
370 mutex_lock(&mvm
->mutex
);
371 tbl_idx
= iwl_mvm_get_sar_geo_profile(mvm
);
373 mutex_unlock(&mvm
->mutex
);
378 pos
= scnprintf(buf
, bufsz
,
379 "SAR geographic profile disabled\n");
381 value
= &mvm
->fwrt
.geo_profiles
[tbl_idx
- 1].values
[0];
383 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
384 "Use geographic profile %d\n", tbl_idx
);
385 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
386 "2.4GHz:\n\tChain A offset: %hhd dBm\n\tChain B offset: %hhd dBm\n\tmax tx power: %hhd dBm\n",
387 value
[1], value
[2], value
[0]);
388 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
389 "5.2GHz:\n\tChain A offset: %hhd dBm\n\tChain B offset: %hhd dBm\n\tmax tx power: %hhd dBm\n",
390 value
[4], value
[5], value
[3]);
392 mutex_unlock(&mvm
->mutex
);
394 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
398 static ssize_t
iwl_dbgfs_stations_read(struct file
*file
, char __user
*user_buf
,
399 size_t count
, loff_t
*ppos
)
401 struct iwl_mvm
*mvm
= file
->private_data
;
402 struct ieee80211_sta
*sta
;
404 int i
, pos
= 0, bufsz
= sizeof(buf
);
406 mutex_lock(&mvm
->mutex
);
408 for (i
= 0; i
< ARRAY_SIZE(mvm
->fw_id_to_mac_id
); i
++) {
409 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "%.2d: ", i
);
410 sta
= rcu_dereference_protected(mvm
->fw_id_to_mac_id
[i
],
411 lockdep_is_held(&mvm
->mutex
));
413 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "N/A\n");
414 else if (IS_ERR(sta
))
415 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "%ld\n",
418 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "%pM\n",
422 mutex_unlock(&mvm
->mutex
);
424 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
427 static ssize_t
iwl_dbgfs_rs_data_read(struct file
*file
, char __user
*user_buf
,
428 size_t count
, loff_t
*ppos
)
430 struct ieee80211_sta
*sta
= file
->private_data
;
431 struct iwl_mvm_sta
*mvmsta
= iwl_mvm_sta_from_mac80211(sta
);
432 struct iwl_lq_sta_rs_fw
*lq_sta
= &mvmsta
->lq_sta
.rs_fw
;
433 struct iwl_mvm
*mvm
= lq_sta
->pers
.drv
;
434 static const size_t bufsz
= 2048;
439 buff
= kmalloc(bufsz
, GFP_KERNEL
);
443 mutex_lock(&mvm
->mutex
);
445 desc
+= scnprintf(buff
+ desc
, bufsz
- desc
, "sta_id %d\n",
446 lq_sta
->pers
.sta_id
);
447 desc
+= scnprintf(buff
+ desc
, bufsz
- desc
,
449 lq_sta
->pers
.dbg_fixed_rate
);
450 desc
+= scnprintf(buff
+ desc
, bufsz
- desc
,
451 "A-MPDU size limit %d\n",
452 lq_sta
->pers
.dbg_agg_frame_count_lim
);
453 desc
+= scnprintf(buff
+ desc
, bufsz
- desc
,
454 "valid_tx_ant %s%s%s\n",
455 (iwl_mvm_get_valid_tx_ant(mvm
) & ANT_A
) ? "ANT_A," : "",
456 (iwl_mvm_get_valid_tx_ant(mvm
) & ANT_B
) ? "ANT_B," : "",
457 (iwl_mvm_get_valid_tx_ant(mvm
) & ANT_C
) ? "ANT_C" : "");
458 desc
+= scnprintf(buff
+ desc
, bufsz
- desc
,
459 "last tx rate=0x%X ",
460 lq_sta
->last_rate_n_flags
);
462 desc
+= rs_pretty_print_rate(buff
+ desc
, bufsz
- desc
,
463 lq_sta
->last_rate_n_flags
);
464 mutex_unlock(&mvm
->mutex
);
466 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buff
, desc
);
471 static ssize_t
iwl_dbgfs_amsdu_len_write(struct ieee80211_sta
*sta
,
472 char *buf
, size_t count
,
475 struct iwl_mvm_sta
*mvmsta
= iwl_mvm_sta_from_mac80211(sta
);
479 if (kstrtou16(buf
, 0, &amsdu_len
))
483 mvmsta
->orig_amsdu_len
= sta
->max_amsdu_len
;
484 sta
->max_amsdu_len
= amsdu_len
;
485 for (i
= 0; i
< ARRAY_SIZE(sta
->max_tid_amsdu_len
); i
++)
486 sta
->max_tid_amsdu_len
[i
] = amsdu_len
;
488 sta
->max_amsdu_len
= mvmsta
->orig_amsdu_len
;
489 mvmsta
->orig_amsdu_len
= 0;
494 static ssize_t
iwl_dbgfs_amsdu_len_read(struct file
*file
,
495 char __user
*user_buf
,
496 size_t count
, loff_t
*ppos
)
498 struct ieee80211_sta
*sta
= file
->private_data
;
499 struct iwl_mvm_sta
*mvmsta
= iwl_mvm_sta_from_mac80211(sta
);
504 pos
= scnprintf(buf
, sizeof(buf
), "current %d ", sta
->max_amsdu_len
);
505 pos
+= scnprintf(buf
+ pos
, sizeof(buf
) - pos
, "stored %d\n",
506 mvmsta
->orig_amsdu_len
);
508 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
511 static ssize_t
iwl_dbgfs_disable_power_off_read(struct file
*file
,
512 char __user
*user_buf
,
513 size_t count
, loff_t
*ppos
)
515 struct iwl_mvm
*mvm
= file
->private_data
;
517 int bufsz
= sizeof(buf
);
520 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "disable_power_off_d0=%d\n",
521 mvm
->disable_power_off
);
522 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "disable_power_off_d3=%d\n",
523 mvm
->disable_power_off_d3
);
525 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
528 static ssize_t
iwl_dbgfs_disable_power_off_write(struct iwl_mvm
*mvm
, char *buf
,
529 size_t count
, loff_t
*ppos
)
533 if (!iwl_mvm_firmware_running(mvm
))
536 if (!strncmp("disable_power_off_d0=", buf
, 21)) {
537 if (sscanf(buf
+ 21, "%d", &val
) != 1)
539 mvm
->disable_power_off
= val
;
540 } else if (!strncmp("disable_power_off_d3=", buf
, 21)) {
541 if (sscanf(buf
+ 21, "%d", &val
) != 1)
543 mvm
->disable_power_off_d3
= val
;
548 mutex_lock(&mvm
->mutex
);
549 ret
= iwl_mvm_power_update_device(mvm
);
550 mutex_unlock(&mvm
->mutex
);
556 int iwl_mvm_coex_dump_mbox(struct iwl_bt_coex_profile_notif
*notif
, char *buf
,
559 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "MBOX dw0:\n");
561 BT_MBOX_PRINT(0, LE_SLAVE_LAT
, false);
562 BT_MBOX_PRINT(0, LE_PROF1
, false);
563 BT_MBOX_PRINT(0, LE_PROF2
, false);
564 BT_MBOX_PRINT(0, LE_PROF_OTHER
, false);
565 BT_MBOX_PRINT(0, CHL_SEQ_N
, false);
566 BT_MBOX_PRINT(0, INBAND_S
, false);
567 BT_MBOX_PRINT(0, LE_MIN_RSSI
, false);
568 BT_MBOX_PRINT(0, LE_SCAN
, false);
569 BT_MBOX_PRINT(0, LE_ADV
, false);
570 BT_MBOX_PRINT(0, LE_MAX_TX_POWER
, false);
571 BT_MBOX_PRINT(0, OPEN_CON_1
, true);
573 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "MBOX dw1:\n");
575 BT_MBOX_PRINT(1, BR_MAX_TX_POWER
, false);
576 BT_MBOX_PRINT(1, IP_SR
, false);
577 BT_MBOX_PRINT(1, LE_MSTR
, false);
578 BT_MBOX_PRINT(1, AGGR_TRFC_LD
, false);
579 BT_MBOX_PRINT(1, MSG_TYPE
, false);
580 BT_MBOX_PRINT(1, SSN
, true);
582 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "MBOX dw2:\n");
584 BT_MBOX_PRINT(2, SNIFF_ACT
, false);
585 BT_MBOX_PRINT(2, PAG
, false);
586 BT_MBOX_PRINT(2, INQUIRY
, false);
587 BT_MBOX_PRINT(2, CONN
, false);
588 BT_MBOX_PRINT(2, SNIFF_INTERVAL
, false);
589 BT_MBOX_PRINT(2, DISC
, false);
590 BT_MBOX_PRINT(2, SCO_TX_ACT
, false);
591 BT_MBOX_PRINT(2, SCO_RX_ACT
, false);
592 BT_MBOX_PRINT(2, ESCO_RE_TX
, false);
593 BT_MBOX_PRINT(2, SCO_DURATION
, true);
595 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "MBOX dw3:\n");
597 BT_MBOX_PRINT(3, SCO_STATE
, false);
598 BT_MBOX_PRINT(3, SNIFF_STATE
, false);
599 BT_MBOX_PRINT(3, A2DP_STATE
, false);
600 BT_MBOX_PRINT(3, A2DP_SRC
, false);
601 BT_MBOX_PRINT(3, ACL_STATE
, false);
602 BT_MBOX_PRINT(3, MSTR_STATE
, false);
603 BT_MBOX_PRINT(3, OBX_STATE
, false);
604 BT_MBOX_PRINT(3, OPEN_CON_2
, false);
605 BT_MBOX_PRINT(3, TRAFFIC_LOAD
, false);
606 BT_MBOX_PRINT(3, CHL_SEQN_LSB
, false);
607 BT_MBOX_PRINT(3, INBAND_P
, false);
608 BT_MBOX_PRINT(3, MSG_TYPE_2
, false);
609 BT_MBOX_PRINT(3, SSN_2
, false);
610 BT_MBOX_PRINT(3, UPDATE_REQUEST
, true);
615 static ssize_t
iwl_dbgfs_bt_notif_read(struct file
*file
, char __user
*user_buf
,
616 size_t count
, loff_t
*ppos
)
618 struct iwl_mvm
*mvm
= file
->private_data
;
619 struct iwl_bt_coex_profile_notif
*notif
= &mvm
->last_bt_notif
;
621 int ret
, pos
= 0, bufsz
= sizeof(char) * 1024;
623 buf
= kmalloc(bufsz
, GFP_KERNEL
);
627 mutex_lock(&mvm
->mutex
);
629 pos
+= iwl_mvm_coex_dump_mbox(notif
, buf
, pos
, bufsz
);
631 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "bt_ci_compliance = %d\n",
632 notif
->bt_ci_compliance
);
633 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "primary_ch_lut = %d\n",
634 le32_to_cpu(notif
->primary_ch_lut
));
635 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "secondary_ch_lut = %d\n",
636 le32_to_cpu(notif
->secondary_ch_lut
));
637 pos
+= scnprintf(buf
+ pos
,
638 bufsz
- pos
, "bt_activity_grading = %d\n",
639 le32_to_cpu(notif
->bt_activity_grading
));
640 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "bt_rrc = %d\n",
641 notif
->rrc_status
& 0xF);
642 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "bt_ttc = %d\n",
643 notif
->ttc_status
& 0xF);
645 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "sync_sco = %d\n",
646 IWL_MVM_BT_COEX_SYNC2SCO
);
647 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "mplut = %d\n",
648 IWL_MVM_BT_COEX_MPLUT
);
650 mutex_unlock(&mvm
->mutex
);
652 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
659 static ssize_t
iwl_dbgfs_bt_cmd_read(struct file
*file
, char __user
*user_buf
,
660 size_t count
, loff_t
*ppos
)
662 struct iwl_mvm
*mvm
= file
->private_data
;
663 struct iwl_bt_coex_ci_cmd
*cmd
= &mvm
->last_bt_ci_cmd
;
665 int bufsz
= sizeof(buf
);
668 mutex_lock(&mvm
->mutex
);
670 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Channel inhibition CMD\n");
671 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
672 "\tPrimary Channel Bitmap 0x%016llx\n",
673 le64_to_cpu(cmd
->bt_primary_ci
));
674 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
675 "\tSecondary Channel Bitmap 0x%016llx\n",
676 le64_to_cpu(cmd
->bt_secondary_ci
));
678 mutex_unlock(&mvm
->mutex
);
680 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
684 iwl_dbgfs_bt_tx_prio_write(struct iwl_mvm
*mvm
, char *buf
,
685 size_t count
, loff_t
*ppos
)
689 if (sscanf(buf
, "%u", &bt_tx_prio
) != 1)
694 mvm
->bt_tx_prio
= bt_tx_prio
;
700 iwl_dbgfs_bt_force_ant_write(struct iwl_mvm
*mvm
, char *buf
,
701 size_t count
, loff_t
*ppos
)
703 static const char * const modes_str
[BT_FORCE_ANT_MAX
] = {
704 [BT_FORCE_ANT_DIS
] = "dis",
705 [BT_FORCE_ANT_AUTO
] = "auto",
706 [BT_FORCE_ANT_BT
] = "bt",
707 [BT_FORCE_ANT_WIFI
] = "wifi",
709 int ret
, bt_force_ant_mode
;
711 ret
= match_string(modes_str
, ARRAY_SIZE(modes_str
), buf
);
715 bt_force_ant_mode
= ret
;
717 mutex_lock(&mvm
->mutex
);
718 if (mvm
->bt_force_ant_mode
== bt_force_ant_mode
)
721 mvm
->bt_force_ant_mode
= bt_force_ant_mode
;
722 IWL_DEBUG_COEX(mvm
, "Force mode: %s\n",
723 modes_str
[mvm
->bt_force_ant_mode
]);
725 if (iwl_mvm_firmware_running(mvm
))
726 ret
= iwl_mvm_send_bt_init_conf(mvm
);
731 mutex_unlock(&mvm
->mutex
);
735 static ssize_t
iwl_dbgfs_fw_ver_read(struct file
*file
, char __user
*user_buf
,
736 size_t count
, loff_t
*ppos
)
738 struct iwl_mvm
*mvm
= file
->private_data
;
739 char *buff
, *pos
, *endpos
;
740 static const size_t bufsz
= 1024;
743 buff
= kmalloc(bufsz
, GFP_KERNEL
);
748 endpos
= pos
+ bufsz
;
750 pos
+= scnprintf(pos
, endpos
- pos
, "FW prefix: %s\n",
751 mvm
->trans
->cfg
->fw_name_pre
);
752 pos
+= scnprintf(pos
, endpos
- pos
, "FW: %s\n",
753 mvm
->fwrt
.fw
->human_readable
);
754 pos
+= scnprintf(pos
, endpos
- pos
, "Device: %s\n",
755 mvm
->fwrt
.trans
->name
);
756 pos
+= scnprintf(pos
, endpos
- pos
, "Bus: %s\n",
757 mvm
->fwrt
.dev
->bus
->name
);
759 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buff
, pos
- buff
);
765 #define PRINT_STATS_LE32(_struct, _memb) \
766 pos += scnprintf(buf + pos, bufsz - pos, \
768 le32_to_cpu(_struct->_memb))
770 static ssize_t
iwl_dbgfs_fw_rx_stats_read(struct file
*file
,
771 char __user
*user_buf
, size_t count
,
774 struct iwl_mvm
*mvm
= file
->private_data
;
775 static const char *fmt_table
= "\t%-30s %10u\n";
776 static const char *fmt_header
= "%-32s\n";
782 if (iwl_mvm_has_new_rx_stats_api(mvm
))
783 bufsz
= ((sizeof(struct mvm_statistics_rx
) /
784 sizeof(__le32
)) * 43) + (4 * 33) + 1;
786 /* 43 = size of each data line; 33 = size of each header */
787 bufsz
= ((sizeof(struct mvm_statistics_rx_v3
) /
788 sizeof(__le32
)) * 43) + (4 * 33) + 1;
790 buf
= kzalloc(bufsz
, GFP_KERNEL
);
794 mutex_lock(&mvm
->mutex
);
796 if (iwl_mvm_firmware_running(mvm
))
797 iwl_mvm_request_statistics(mvm
, false);
799 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, fmt_header
,
800 "Statistics_Rx - OFDM");
801 if (!iwl_mvm_has_new_rx_stats_api(mvm
)) {
802 struct mvm_statistics_rx_phy_v2
*ofdm
= &mvm
->rx_stats_v3
.ofdm
;
804 PRINT_STATS_LE32(ofdm
, ina_cnt
);
805 PRINT_STATS_LE32(ofdm
, fina_cnt
);
806 PRINT_STATS_LE32(ofdm
, plcp_err
);
807 PRINT_STATS_LE32(ofdm
, crc32_err
);
808 PRINT_STATS_LE32(ofdm
, overrun_err
);
809 PRINT_STATS_LE32(ofdm
, early_overrun_err
);
810 PRINT_STATS_LE32(ofdm
, crc32_good
);
811 PRINT_STATS_LE32(ofdm
, false_alarm_cnt
);
812 PRINT_STATS_LE32(ofdm
, fina_sync_err_cnt
);
813 PRINT_STATS_LE32(ofdm
, sfd_timeout
);
814 PRINT_STATS_LE32(ofdm
, fina_timeout
);
815 PRINT_STATS_LE32(ofdm
, unresponded_rts
);
816 PRINT_STATS_LE32(ofdm
, rxe_frame_lmt_overrun
);
817 PRINT_STATS_LE32(ofdm
, sent_ack_cnt
);
818 PRINT_STATS_LE32(ofdm
, sent_cts_cnt
);
819 PRINT_STATS_LE32(ofdm
, sent_ba_rsp_cnt
);
820 PRINT_STATS_LE32(ofdm
, dsp_self_kill
);
821 PRINT_STATS_LE32(ofdm
, mh_format_err
);
822 PRINT_STATS_LE32(ofdm
, re_acq_main_rssi_sum
);
823 PRINT_STATS_LE32(ofdm
, reserved
);
825 struct mvm_statistics_rx_phy
*ofdm
= &mvm
->rx_stats
.ofdm
;
827 PRINT_STATS_LE32(ofdm
, unresponded_rts
);
828 PRINT_STATS_LE32(ofdm
, rxe_frame_lmt_overrun
);
829 PRINT_STATS_LE32(ofdm
, sent_ba_rsp_cnt
);
830 PRINT_STATS_LE32(ofdm
, dsp_self_kill
);
831 PRINT_STATS_LE32(ofdm
, reserved
);
834 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, fmt_header
,
835 "Statistics_Rx - CCK");
836 if (!iwl_mvm_has_new_rx_stats_api(mvm
)) {
837 struct mvm_statistics_rx_phy_v2
*cck
= &mvm
->rx_stats_v3
.cck
;
839 PRINT_STATS_LE32(cck
, ina_cnt
);
840 PRINT_STATS_LE32(cck
, fina_cnt
);
841 PRINT_STATS_LE32(cck
, plcp_err
);
842 PRINT_STATS_LE32(cck
, crc32_err
);
843 PRINT_STATS_LE32(cck
, overrun_err
);
844 PRINT_STATS_LE32(cck
, early_overrun_err
);
845 PRINT_STATS_LE32(cck
, crc32_good
);
846 PRINT_STATS_LE32(cck
, false_alarm_cnt
);
847 PRINT_STATS_LE32(cck
, fina_sync_err_cnt
);
848 PRINT_STATS_LE32(cck
, sfd_timeout
);
849 PRINT_STATS_LE32(cck
, fina_timeout
);
850 PRINT_STATS_LE32(cck
, unresponded_rts
);
851 PRINT_STATS_LE32(cck
, rxe_frame_lmt_overrun
);
852 PRINT_STATS_LE32(cck
, sent_ack_cnt
);
853 PRINT_STATS_LE32(cck
, sent_cts_cnt
);
854 PRINT_STATS_LE32(cck
, sent_ba_rsp_cnt
);
855 PRINT_STATS_LE32(cck
, dsp_self_kill
);
856 PRINT_STATS_LE32(cck
, mh_format_err
);
857 PRINT_STATS_LE32(cck
, re_acq_main_rssi_sum
);
858 PRINT_STATS_LE32(cck
, reserved
);
860 struct mvm_statistics_rx_phy
*cck
= &mvm
->rx_stats
.cck
;
862 PRINT_STATS_LE32(cck
, unresponded_rts
);
863 PRINT_STATS_LE32(cck
, rxe_frame_lmt_overrun
);
864 PRINT_STATS_LE32(cck
, sent_ba_rsp_cnt
);
865 PRINT_STATS_LE32(cck
, dsp_self_kill
);
866 PRINT_STATS_LE32(cck
, reserved
);
869 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, fmt_header
,
870 "Statistics_Rx - GENERAL");
871 if (!iwl_mvm_has_new_rx_stats_api(mvm
)) {
872 struct mvm_statistics_rx_non_phy_v3
*general
=
873 &mvm
->rx_stats_v3
.general
;
875 PRINT_STATS_LE32(general
, bogus_cts
);
876 PRINT_STATS_LE32(general
, bogus_ack
);
877 PRINT_STATS_LE32(general
, non_bssid_frames
);
878 PRINT_STATS_LE32(general
, filtered_frames
);
879 PRINT_STATS_LE32(general
, non_channel_beacons
);
880 PRINT_STATS_LE32(general
, channel_beacons
);
881 PRINT_STATS_LE32(general
, num_missed_bcon
);
882 PRINT_STATS_LE32(general
, adc_rx_saturation_time
);
883 PRINT_STATS_LE32(general
, ina_detection_search_time
);
884 PRINT_STATS_LE32(general
, beacon_silence_rssi_a
);
885 PRINT_STATS_LE32(general
, beacon_silence_rssi_b
);
886 PRINT_STATS_LE32(general
, beacon_silence_rssi_c
);
887 PRINT_STATS_LE32(general
, interference_data_flag
);
888 PRINT_STATS_LE32(general
, channel_load
);
889 PRINT_STATS_LE32(general
, dsp_false_alarms
);
890 PRINT_STATS_LE32(general
, beacon_rssi_a
);
891 PRINT_STATS_LE32(general
, beacon_rssi_b
);
892 PRINT_STATS_LE32(general
, beacon_rssi_c
);
893 PRINT_STATS_LE32(general
, beacon_energy_a
);
894 PRINT_STATS_LE32(general
, beacon_energy_b
);
895 PRINT_STATS_LE32(general
, beacon_energy_c
);
896 PRINT_STATS_LE32(general
, num_bt_kills
);
897 PRINT_STATS_LE32(general
, mac_id
);
898 PRINT_STATS_LE32(general
, directed_data_mpdu
);
900 struct mvm_statistics_rx_non_phy
*general
=
901 &mvm
->rx_stats
.general
;
903 PRINT_STATS_LE32(general
, bogus_cts
);
904 PRINT_STATS_LE32(general
, bogus_ack
);
905 PRINT_STATS_LE32(general
, non_channel_beacons
);
906 PRINT_STATS_LE32(general
, channel_beacons
);
907 PRINT_STATS_LE32(general
, num_missed_bcon
);
908 PRINT_STATS_LE32(general
, adc_rx_saturation_time
);
909 PRINT_STATS_LE32(general
, ina_detection_search_time
);
910 PRINT_STATS_LE32(general
, beacon_silence_rssi_a
);
911 PRINT_STATS_LE32(general
, beacon_silence_rssi_b
);
912 PRINT_STATS_LE32(general
, beacon_silence_rssi_c
);
913 PRINT_STATS_LE32(general
, interference_data_flag
);
914 PRINT_STATS_LE32(general
, channel_load
);
915 PRINT_STATS_LE32(general
, beacon_rssi_a
);
916 PRINT_STATS_LE32(general
, beacon_rssi_b
);
917 PRINT_STATS_LE32(general
, beacon_rssi_c
);
918 PRINT_STATS_LE32(general
, beacon_energy_a
);
919 PRINT_STATS_LE32(general
, beacon_energy_b
);
920 PRINT_STATS_LE32(general
, beacon_energy_c
);
921 PRINT_STATS_LE32(general
, num_bt_kills
);
922 PRINT_STATS_LE32(general
, mac_id
);
925 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, fmt_header
,
926 "Statistics_Rx - HT");
927 if (!iwl_mvm_has_new_rx_stats_api(mvm
)) {
928 struct mvm_statistics_rx_ht_phy_v1
*ht
=
929 &mvm
->rx_stats_v3
.ofdm_ht
;
931 PRINT_STATS_LE32(ht
, plcp_err
);
932 PRINT_STATS_LE32(ht
, overrun_err
);
933 PRINT_STATS_LE32(ht
, early_overrun_err
);
934 PRINT_STATS_LE32(ht
, crc32_good
);
935 PRINT_STATS_LE32(ht
, crc32_err
);
936 PRINT_STATS_LE32(ht
, mh_format_err
);
937 PRINT_STATS_LE32(ht
, agg_crc32_good
);
938 PRINT_STATS_LE32(ht
, agg_mpdu_cnt
);
939 PRINT_STATS_LE32(ht
, agg_cnt
);
940 PRINT_STATS_LE32(ht
, unsupport_mcs
);
942 struct mvm_statistics_rx_ht_phy
*ht
=
943 &mvm
->rx_stats
.ofdm_ht
;
945 PRINT_STATS_LE32(ht
, mh_format_err
);
946 PRINT_STATS_LE32(ht
, agg_mpdu_cnt
);
947 PRINT_STATS_LE32(ht
, agg_cnt
);
948 PRINT_STATS_LE32(ht
, unsupport_mcs
);
951 mutex_unlock(&mvm
->mutex
);
953 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
958 #undef PRINT_STAT_LE32
960 static ssize_t
iwl_dbgfs_frame_stats_read(struct iwl_mvm
*mvm
,
961 char __user
*user_buf
, size_t count
,
963 struct iwl_mvm_frame_stats
*stats
)
965 char *buff
, *pos
, *endpos
;
968 static const size_t bufsz
= 1024;
970 buff
= kmalloc(bufsz
, GFP_KERNEL
);
974 spin_lock_bh(&mvm
->drv_stats_lock
);
977 endpos
= pos
+ bufsz
;
979 pos
+= scnprintf(pos
, endpos
- pos
,
980 "Legacy/HT/VHT\t:\t%d/%d/%d\n",
981 stats
->legacy_frames
,
984 pos
+= scnprintf(pos
, endpos
- pos
, "20/40/80\t:\t%d/%d/%d\n",
987 stats
->bw_80_frames
);
988 pos
+= scnprintf(pos
, endpos
- pos
, "NGI/SGI\t\t:\t%d/%d\n",
991 pos
+= scnprintf(pos
, endpos
- pos
, "SISO/MIMO2\t:\t%d/%d\n",
993 stats
->mimo2_frames
);
994 pos
+= scnprintf(pos
, endpos
- pos
, "FAIL/SCSS\t:\t%d/%d\n",
996 stats
->success_frames
);
997 pos
+= scnprintf(pos
, endpos
- pos
, "MPDUs agg\t:\t%d\n",
999 pos
+= scnprintf(pos
, endpos
- pos
, "A-MPDUs\t\t:\t%d\n",
1000 stats
->ampdu_count
);
1001 pos
+= scnprintf(pos
, endpos
- pos
, "Avg MPDUs/A-MPDU:\t%d\n",
1002 stats
->ampdu_count
> 0 ?
1003 (stats
->agg_frames
/ stats
->ampdu_count
) : 0);
1005 pos
+= scnprintf(pos
, endpos
- pos
, "Last Rates\n");
1007 idx
= stats
->last_frame_idx
- 1;
1008 for (i
= 0; i
< ARRAY_SIZE(stats
->last_rates
); i
++) {
1009 idx
= (idx
+ 1) % ARRAY_SIZE(stats
->last_rates
);
1010 if (stats
->last_rates
[idx
] == 0)
1012 pos
+= scnprintf(pos
, endpos
- pos
, "Rate[%d]: ",
1013 (int)(ARRAY_SIZE(stats
->last_rates
) - i
));
1014 pos
+= rs_pretty_print_rate(pos
, endpos
- pos
,
1015 stats
->last_rates
[idx
]);
1017 spin_unlock_bh(&mvm
->drv_stats_lock
);
1019 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buff
, pos
- buff
);
1025 static ssize_t
iwl_dbgfs_drv_rx_stats_read(struct file
*file
,
1026 char __user
*user_buf
, size_t count
,
1029 struct iwl_mvm
*mvm
= file
->private_data
;
1031 return iwl_dbgfs_frame_stats_read(mvm
, user_buf
, count
, ppos
,
1032 &mvm
->drv_rx_stats
);
1035 static ssize_t
iwl_dbgfs_fw_restart_write(struct iwl_mvm
*mvm
, char *buf
,
1036 size_t count
, loff_t
*ppos
)
1038 int __maybe_unused ret
;
1040 if (!iwl_mvm_firmware_running(mvm
))
1043 mutex_lock(&mvm
->mutex
);
1045 /* allow one more restart that we're provoking here */
1046 if (mvm
->fw_restart
>= 0)
1049 /* take the return value to make compiler happy - it will fail anyway */
1050 ret
= iwl_mvm_send_cmd_pdu(mvm
, REPLY_ERROR
, 0, 0, NULL
);
1052 mutex_unlock(&mvm
->mutex
);
1057 static ssize_t
iwl_dbgfs_fw_nmi_write(struct iwl_mvm
*mvm
, char *buf
,
1058 size_t count
, loff_t
*ppos
)
1060 if (!iwl_mvm_firmware_running(mvm
))
1063 iwl_force_nmi(mvm
->trans
);
1069 iwl_dbgfs_scan_ant_rxchain_read(struct file
*file
,
1070 char __user
*user_buf
,
1071 size_t count
, loff_t
*ppos
)
1073 struct iwl_mvm
*mvm
= file
->private_data
;
1076 const size_t bufsz
= sizeof(buf
);
1078 /* print which antennas were set for the scan command by the user */
1079 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Antennas for scan: ");
1080 if (mvm
->scan_rx_ant
& ANT_A
)
1081 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "A");
1082 if (mvm
->scan_rx_ant
& ANT_B
)
1083 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "B");
1084 if (mvm
->scan_rx_ant
& ANT_C
)
1085 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "C");
1086 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, " (%hhx)\n", mvm
->scan_rx_ant
);
1088 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1092 iwl_dbgfs_scan_ant_rxchain_write(struct iwl_mvm
*mvm
, char *buf
,
1093 size_t count
, loff_t
*ppos
)
1097 if (!iwl_mvm_firmware_running(mvm
))
1100 if (sscanf(buf
, "%hhx", &scan_rx_ant
) != 1)
1102 if (scan_rx_ant
> ANT_ABC
)
1104 if (scan_rx_ant
& ~(iwl_mvm_get_valid_rx_ant(mvm
)))
1107 if (mvm
->scan_rx_ant
!= scan_rx_ant
) {
1108 mvm
->scan_rx_ant
= scan_rx_ant
;
1109 if (fw_has_capa(&mvm
->fw
->ucode_capa
,
1110 IWL_UCODE_TLV_CAPA_UMAC_SCAN
))
1111 iwl_mvm_config_scan(mvm
);
1117 static ssize_t
iwl_dbgfs_indirection_tbl_write(struct iwl_mvm
*mvm
,
1118 char *buf
, size_t count
,
1121 struct iwl_rss_config_cmd cmd
= {
1122 .flags
= cpu_to_le32(IWL_RSS_ENABLE
),
1123 .hash_mask
= IWL_RSS_HASH_TYPE_IPV4_TCP
|
1124 IWL_RSS_HASH_TYPE_IPV4_UDP
|
1125 IWL_RSS_HASH_TYPE_IPV4_PAYLOAD
|
1126 IWL_RSS_HASH_TYPE_IPV6_TCP
|
1127 IWL_RSS_HASH_TYPE_IPV6_UDP
|
1128 IWL_RSS_HASH_TYPE_IPV6_PAYLOAD
,
1130 int ret
, i
, num_repeats
, nbytes
= count
/ 2;
1132 ret
= hex2bin(cmd
.indirection_table
, buf
, nbytes
);
1137 * The input is the redirection table, partial or full.
1138 * Repeat the pattern if needed.
1139 * For example, input of 01020F will be repeated 42 times,
1140 * indirecting RSS hash results to queues 1, 2, 15 (skipping
1143 num_repeats
= ARRAY_SIZE(cmd
.indirection_table
) / nbytes
;
1144 for (i
= 1; i
< num_repeats
; i
++)
1145 memcpy(&cmd
.indirection_table
[i
* nbytes
],
1146 cmd
.indirection_table
, nbytes
);
1147 /* handle cut in the middle pattern for the last places */
1148 memcpy(&cmd
.indirection_table
[i
* nbytes
], cmd
.indirection_table
,
1149 ARRAY_SIZE(cmd
.indirection_table
) % nbytes
);
1151 netdev_rss_key_fill(cmd
.secret_key
, sizeof(cmd
.secret_key
));
1153 mutex_lock(&mvm
->mutex
);
1154 if (iwl_mvm_firmware_running(mvm
))
1155 ret
= iwl_mvm_send_cmd_pdu(mvm
, RSS_CONFIG_CMD
, 0,
1159 mutex_unlock(&mvm
->mutex
);
1161 return ret
?: count
;
1164 static ssize_t
iwl_dbgfs_inject_packet_write(struct iwl_mvm
*mvm
,
1165 char *buf
, size_t count
,
1168 struct iwl_rx_cmd_buffer rxb
= {
1169 ._rx_page_order
= 0,
1170 .truesize
= 0, /* not used */
1173 struct iwl_rx_packet
*pkt
;
1174 struct iwl_rx_mpdu_desc
*desc
;
1175 int bin_len
= count
/ 2;
1177 size_t mpdu_cmd_hdr_size
= (mvm
->trans
->trans_cfg
->device_family
>=
1178 IWL_DEVICE_FAMILY_AX210
) ?
1179 sizeof(struct iwl_rx_mpdu_desc
) :
1180 IWL_RX_DESC_SIZE_V1
;
1182 if (!iwl_mvm_firmware_running(mvm
))
1185 /* supporting only 9000 descriptor */
1186 if (!mvm
->trans
->trans_cfg
->mq_rx_supported
)
1189 rxb
._page
= alloc_pages(GFP_ATOMIC
, 0);
1192 pkt
= rxb_addr(&rxb
);
1194 ret
= hex2bin(page_address(rxb
._page
), buf
, bin_len
);
1198 /* avoid invalid memory access */
1199 if (bin_len
< sizeof(*pkt
) + mpdu_cmd_hdr_size
)
1202 /* check this is RX packet */
1203 if (WIDE_ID(pkt
->hdr
.group_id
, pkt
->hdr
.cmd
) !=
1204 WIDE_ID(LEGACY_GROUP
, REPLY_RX_MPDU_CMD
))
1207 /* check the length in metadata matches actual received length */
1208 desc
= (void *)pkt
->data
;
1209 if (le16_to_cpu(desc
->mpdu_len
) !=
1210 (bin_len
- mpdu_cmd_hdr_size
- sizeof(*pkt
)))
1214 iwl_mvm_rx_mpdu_mq(mvm
, NULL
, &rxb
, 0);
1221 return ret
?: count
;
1224 static int _iwl_dbgfs_inject_beacon_ie(struct iwl_mvm
*mvm
, char *bin
, int len
)
1226 struct ieee80211_vif
*vif
;
1227 struct iwl_mvm_vif
*mvmvif
;
1228 struct sk_buff
*beacon
;
1229 struct ieee80211_tx_info
*info
;
1230 struct iwl_mac_beacon_cmd beacon_cmd
= {};
1237 /* Element len should be represented by u8 */
1241 if (!iwl_mvm_firmware_running(mvm
))
1244 if (!iwl_mvm_has_new_tx_api(mvm
) &&
1245 !fw_has_api(&mvm
->fw
->ucode_capa
,
1246 IWL_UCODE_TLV_API_NEW_BEACON_TEMPLATE
))
1251 for (i
= 0; i
< NUM_MAC_INDEX_DRIVER
; i
++) {
1252 vif
= iwl_mvm_rcu_dereference_vif_id(mvm
, i
, true);
1256 if (vif
->type
== NL80211_IFTYPE_AP
)
1260 if (i
== NUM_MAC_INDEX_DRIVER
|| !vif
)
1263 mvm
->hw
->extra_beacon_tailroom
= len
;
1265 beacon
= ieee80211_beacon_get_template(mvm
->hw
, vif
, NULL
);
1269 if (len
&& hex2bin(skb_put_zero(beacon
, len
), bin
, len
)) {
1270 dev_kfree_skb(beacon
);
1274 mvm
->beacon_inject_active
= true;
1276 mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
1277 info
= IEEE80211_SKB_CB(beacon
);
1278 rate
= iwl_mvm_mac_ctxt_get_lowest_rate(info
, vif
);
1279 flags
= iwl_mvm_mac80211_idx_to_hwrate(rate
);
1281 if (rate
== IWL_FIRST_CCK_RATE
)
1282 flags
|= IWL_MAC_BEACON_CCK
;
1284 beacon_cmd
.flags
= cpu_to_le16(flags
);
1285 beacon_cmd
.byte_cnt
= cpu_to_le16((u16
)beacon
->len
);
1286 beacon_cmd
.template_id
= cpu_to_le32((u32
)mvmvif
->id
);
1288 iwl_mvm_mac_ctxt_set_tim(mvm
, &beacon_cmd
.tim_idx
,
1289 &beacon_cmd
.tim_size
,
1290 beacon
->data
, beacon
->len
);
1292 mutex_lock(&mvm
->mutex
);
1293 iwl_mvm_mac_ctxt_send_beacon_cmd(mvm
, beacon
, &beacon_cmd
,
1294 sizeof(beacon_cmd
));
1295 mutex_unlock(&mvm
->mutex
);
1297 dev_kfree_skb(beacon
);
1307 static ssize_t
iwl_dbgfs_inject_beacon_ie_write(struct iwl_mvm
*mvm
,
1308 char *buf
, size_t count
,
1311 int ret
= _iwl_dbgfs_inject_beacon_ie(mvm
, buf
, count
);
1313 mvm
->hw
->extra_beacon_tailroom
= 0;
1314 return ret
?: count
;
1317 static ssize_t
iwl_dbgfs_inject_beacon_ie_restore_write(struct iwl_mvm
*mvm
,
1322 int ret
= _iwl_dbgfs_inject_beacon_ie(mvm
, NULL
, 0);
1324 mvm
->hw
->extra_beacon_tailroom
= 0;
1325 mvm
->beacon_inject_active
= false;
1326 return ret
?: count
;
1329 static ssize_t
iwl_dbgfs_fw_dbg_conf_read(struct file
*file
,
1330 char __user
*user_buf
,
1331 size_t count
, loff_t
*ppos
)
1333 struct iwl_mvm
*mvm
= file
->private_data
;
1336 const size_t bufsz
= sizeof(buf
);
1339 mutex_lock(&mvm
->mutex
);
1340 conf
= mvm
->fwrt
.dump
.conf
;
1341 mutex_unlock(&mvm
->mutex
);
1343 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "%d\n", conf
);
1345 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1348 static ssize_t
iwl_dbgfs_fw_dbg_conf_write(struct iwl_mvm
*mvm
,
1349 char *buf
, size_t count
,
1352 unsigned int conf_id
;
1355 if (!iwl_mvm_firmware_running(mvm
))
1358 ret
= kstrtouint(buf
, 0, &conf_id
);
1362 if (WARN_ON(conf_id
>= FW_DBG_CONF_MAX
))
1365 mutex_lock(&mvm
->mutex
);
1366 ret
= iwl_fw_start_dbg_conf(&mvm
->fwrt
, conf_id
);
1367 mutex_unlock(&mvm
->mutex
);
1369 return ret
?: count
;
1372 static ssize_t
iwl_dbgfs_fw_dbg_collect_write(struct iwl_mvm
*mvm
,
1373 char *buf
, size_t count
,
1379 iwl_dbg_tlv_time_point(&mvm
->fwrt
, IWL_FW_INI_TIME_POINT_USER_TRIGGER
,
1382 iwl_fw_dbg_collect(&mvm
->fwrt
, FW_DBG_TRIGGER_USER
, buf
,
1388 #define ADD_TEXT(...) pos += scnprintf(buf + pos, bufsz - pos, __VA_ARGS__)
1389 #ifdef CONFIG_IWLWIFI_BCAST_FILTERING
1390 static ssize_t
iwl_dbgfs_bcast_filters_read(struct file
*file
,
1391 char __user
*user_buf
,
1392 size_t count
, loff_t
*ppos
)
1394 struct iwl_mvm
*mvm
= file
->private_data
;
1395 struct iwl_bcast_filter_cmd cmd
;
1396 const struct iwl_fw_bcast_filter
*filter
;
1402 buf
= kzalloc(bufsz
, GFP_KERNEL
);
1406 mutex_lock(&mvm
->mutex
);
1407 if (!iwl_mvm_bcast_filter_build_cmd(mvm
, &cmd
)) {
1409 mutex_unlock(&mvm
->mutex
);
1412 mutex_unlock(&mvm
->mutex
);
1414 for (i
= 0; cmd
.filters
[i
].attrs
[0].mask
; i
++) {
1415 filter
= &cmd
.filters
[i
];
1417 ADD_TEXT("Filter [%d]:\n", i
);
1418 ADD_TEXT("\tDiscard=%d\n", filter
->discard
);
1419 ADD_TEXT("\tFrame Type: %s\n",
1420 filter
->frame_type
? "IPv4" : "Generic");
1422 for (j
= 0; j
< ARRAY_SIZE(filter
->attrs
); j
++) {
1423 const struct iwl_fw_bcast_filter_attr
*attr
;
1425 attr
= &filter
->attrs
[j
];
1429 ADD_TEXT("\tAttr [%d]: offset=%d (from %s), mask=0x%x, value=0x%x reserved=0x%x\n",
1431 attr
->offset_type
? "IP End" :
1433 be32_to_cpu(attr
->mask
),
1434 be32_to_cpu(attr
->val
),
1435 le16_to_cpu(attr
->reserved1
));
1439 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1444 static ssize_t
iwl_dbgfs_bcast_filters_write(struct iwl_mvm
*mvm
, char *buf
,
1445 size_t count
, loff_t
*ppos
)
1448 struct iwl_fw_bcast_filter filter
= {};
1449 struct iwl_bcast_filter_cmd cmd
;
1450 u32 filter_id
, attr_id
, mask
, value
;
1453 if (sscanf(buf
, "%d %hhi %hhi %n", &filter_id
, &filter
.discard
,
1454 &filter
.frame_type
, &pos
) != 3)
1457 if (filter_id
>= ARRAY_SIZE(mvm
->dbgfs_bcast_filtering
.cmd
.filters
) ||
1458 filter
.frame_type
> BCAST_FILTER_FRAME_TYPE_IPV4
)
1461 for (attr_id
= 0; attr_id
< ARRAY_SIZE(filter
.attrs
);
1463 struct iwl_fw_bcast_filter_attr
*attr
=
1464 &filter
.attrs
[attr_id
];
1469 if (sscanf(&buf
[pos
], "%hhi %hhi %i %i %n",
1470 &attr
->offset
, &attr
->offset_type
,
1471 &mask
, &value
, &next_pos
) != 4)
1474 attr
->mask
= cpu_to_be32(mask
);
1475 attr
->val
= cpu_to_be32(value
);
1482 mutex_lock(&mvm
->mutex
);
1483 memcpy(&mvm
->dbgfs_bcast_filtering
.cmd
.filters
[filter_id
],
1484 &filter
, sizeof(filter
));
1486 /* send updated bcast filtering configuration */
1487 if (iwl_mvm_firmware_running(mvm
) &&
1488 mvm
->dbgfs_bcast_filtering
.override
&&
1489 iwl_mvm_bcast_filter_build_cmd(mvm
, &cmd
))
1490 err
= iwl_mvm_send_cmd_pdu(mvm
, BCAST_FILTER_CMD
, 0,
1492 mutex_unlock(&mvm
->mutex
);
1494 return err
?: count
;
1497 static ssize_t
iwl_dbgfs_bcast_filters_macs_read(struct file
*file
,
1498 char __user
*user_buf
,
1499 size_t count
, loff_t
*ppos
)
1501 struct iwl_mvm
*mvm
= file
->private_data
;
1502 struct iwl_bcast_filter_cmd cmd
;
1508 buf
= kzalloc(bufsz
, GFP_KERNEL
);
1512 mutex_lock(&mvm
->mutex
);
1513 if (!iwl_mvm_bcast_filter_build_cmd(mvm
, &cmd
)) {
1515 mutex_unlock(&mvm
->mutex
);
1518 mutex_unlock(&mvm
->mutex
);
1520 for (i
= 0; i
< ARRAY_SIZE(cmd
.macs
); i
++) {
1521 const struct iwl_fw_bcast_mac
*mac
= &cmd
.macs
[i
];
1523 ADD_TEXT("Mac [%d]: discard=%d attached_filters=0x%x\n",
1524 i
, mac
->default_discard
, mac
->attached_filters
);
1527 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1532 static ssize_t
iwl_dbgfs_bcast_filters_macs_write(struct iwl_mvm
*mvm
,
1533 char *buf
, size_t count
,
1536 struct iwl_bcast_filter_cmd cmd
;
1537 struct iwl_fw_bcast_mac mac
= {};
1538 u32 mac_id
, attached_filters
;
1541 if (!mvm
->bcast_filters
)
1544 if (sscanf(buf
, "%d %hhi %i", &mac_id
, &mac
.default_discard
,
1545 &attached_filters
) != 3)
1548 if (mac_id
>= ARRAY_SIZE(cmd
.macs
) ||
1549 mac
.default_discard
> 1 ||
1550 attached_filters
>= BIT(ARRAY_SIZE(cmd
.filters
)))
1553 mac
.attached_filters
= cpu_to_le16(attached_filters
);
1555 mutex_lock(&mvm
->mutex
);
1556 memcpy(&mvm
->dbgfs_bcast_filtering
.cmd
.macs
[mac_id
],
1559 /* send updated bcast filtering configuration */
1560 if (iwl_mvm_firmware_running(mvm
) &&
1561 mvm
->dbgfs_bcast_filtering
.override
&&
1562 iwl_mvm_bcast_filter_build_cmd(mvm
, &cmd
))
1563 err
= iwl_mvm_send_cmd_pdu(mvm
, BCAST_FILTER_CMD
, 0,
1565 mutex_unlock(&mvm
->mutex
);
1567 return err
?: count
;
1571 #define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \
1572 _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm)
1573 #define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
1574 _MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm)
1575 #define MVM_DEBUGFS_ADD_FILE_ALIAS(alias, name, parent, mode) do { \
1576 debugfs_create_file(alias, mode, parent, mvm, \
1577 &iwl_dbgfs_##name##_ops); \
1579 #define MVM_DEBUGFS_ADD_FILE(name, parent, mode) \
1580 MVM_DEBUGFS_ADD_FILE_ALIAS(#name, name, parent, mode)
1582 #define MVM_DEBUGFS_WRITE_STA_FILE_OPS(name, bufsz) \
1583 _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct ieee80211_sta)
1584 #define MVM_DEBUGFS_READ_WRITE_STA_FILE_OPS(name, bufsz) \
1585 _MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct ieee80211_sta)
1587 #define MVM_DEBUGFS_ADD_STA_FILE_ALIAS(alias, name, parent, mode) do { \
1588 debugfs_create_file(alias, mode, parent, sta, \
1589 &iwl_dbgfs_##name##_ops); \
1591 #define MVM_DEBUGFS_ADD_STA_FILE(name, parent, mode) \
1592 MVM_DEBUGFS_ADD_STA_FILE_ALIAS(#name, name, parent, mode)
1595 iwl_dbgfs_prph_reg_read(struct file
*file
,
1596 char __user
*user_buf
,
1597 size_t count
, loff_t
*ppos
)
1599 struct iwl_mvm
*mvm
= file
->private_data
;
1602 const size_t bufsz
= sizeof(buf
);
1604 if (!mvm
->dbgfs_prph_reg_addr
)
1607 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Reg 0x%x: (0x%x)\n",
1608 mvm
->dbgfs_prph_reg_addr
,
1609 iwl_read_prph(mvm
->trans
, mvm
->dbgfs_prph_reg_addr
));
1611 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1615 iwl_dbgfs_prph_reg_write(struct iwl_mvm
*mvm
, char *buf
,
1616 size_t count
, loff_t
*ppos
)
1621 args
= sscanf(buf
, "%i %i", &mvm
->dbgfs_prph_reg_addr
, &value
);
1622 /* if we only want to set the reg address - nothing more to do */
1626 /* otherwise, make sure we have both address and value */
1630 iwl_write_prph(mvm
->trans
, mvm
->dbgfs_prph_reg_addr
, value
);
1637 iwl_dbgfs_send_echo_cmd_write(struct iwl_mvm
*mvm
, char *buf
,
1638 size_t count
, loff_t
*ppos
)
1642 if (!iwl_mvm_firmware_running(mvm
))
1645 mutex_lock(&mvm
->mutex
);
1646 ret
= iwl_mvm_send_cmd_pdu(mvm
, ECHO_CMD
, 0, 0, NULL
);
1647 mutex_unlock(&mvm
->mutex
);
1649 return ret
?: count
;
1652 struct iwl_mvm_sniffer_apply
{
1653 struct iwl_mvm
*mvm
;
1658 static bool iwl_mvm_sniffer_apply(struct iwl_notif_wait_data
*notif_data
,
1659 struct iwl_rx_packet
*pkt
, void *data
)
1661 struct iwl_mvm_sniffer_apply
*apply
= data
;
1663 apply
->mvm
->cur_aid
= cpu_to_le16(apply
->aid
);
1664 memcpy(apply
->mvm
->cur_bssid
, apply
->bssid
,
1665 sizeof(apply
->mvm
->cur_bssid
));
1671 iwl_dbgfs_he_sniffer_params_write(struct iwl_mvm
*mvm
, char *buf
,
1672 size_t count
, loff_t
*ppos
)
1674 struct iwl_notification_wait wait
;
1675 struct iwl_he_monitor_cmd he_mon_cmd
= {};
1676 struct iwl_mvm_sniffer_apply apply
= {
1680 iwl_cmd_id(HE_AIR_SNIFFER_CONFIG_CMD
, DATA_PATH_GROUP
, 0),
1685 if (!iwl_mvm_firmware_running(mvm
))
1688 ret
= sscanf(buf
, "%x %2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx", &aid
,
1689 &he_mon_cmd
.bssid
[0], &he_mon_cmd
.bssid
[1],
1690 &he_mon_cmd
.bssid
[2], &he_mon_cmd
.bssid
[3],
1691 &he_mon_cmd
.bssid
[4], &he_mon_cmd
.bssid
[5]);
1695 he_mon_cmd
.aid
= cpu_to_le16(aid
);
1698 apply
.bssid
= (void *)he_mon_cmd
.bssid
;
1700 mutex_lock(&mvm
->mutex
);
1703 * Use the notification waiter to get our function triggered
1704 * in sequence with other RX. This ensures that frames we get
1705 * on the RX queue _before_ the new configuration is applied
1706 * still have mvm->cur_aid pointing to the old AID, and that
1707 * frames on the RX queue _after_ the firmware processed the
1708 * new configuration (and sent the response, synchronously)
1709 * get mvm->cur_aid correctly set to the new AID.
1711 iwl_init_notification_wait(&mvm
->notif_wait
, &wait
,
1712 wait_cmds
, ARRAY_SIZE(wait_cmds
),
1713 iwl_mvm_sniffer_apply
, &apply
);
1715 ret
= iwl_mvm_send_cmd_pdu(mvm
, iwl_cmd_id(HE_AIR_SNIFFER_CONFIG_CMD
,
1716 DATA_PATH_GROUP
, 0), 0,
1717 sizeof(he_mon_cmd
), &he_mon_cmd
);
1719 /* no need to really wait, we already did anyway */
1720 iwl_remove_notification(&mvm
->notif_wait
, &wait
);
1722 mutex_unlock(&mvm
->mutex
);
1724 return ret
?: count
;
1728 iwl_dbgfs_he_sniffer_params_read(struct file
*file
, char __user
*user_buf
,
1729 size_t count
, loff_t
*ppos
)
1731 struct iwl_mvm
*mvm
= file
->private_data
;
1735 len
= scnprintf(buf
, sizeof(buf
),
1736 "%d %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n",
1737 le16_to_cpu(mvm
->cur_aid
), mvm
->cur_bssid
[0],
1738 mvm
->cur_bssid
[1], mvm
->cur_bssid
[2], mvm
->cur_bssid
[3],
1739 mvm
->cur_bssid
[4], mvm
->cur_bssid
[5]);
1741 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
1745 iwl_dbgfs_uapsd_noagg_bssids_read(struct file
*file
, char __user
*user_buf
,
1746 size_t count
, loff_t
*ppos
)
1748 struct iwl_mvm
*mvm
= file
->private_data
;
1749 u8 buf
[IWL_MVM_UAPSD_NOAGG_BSSIDS_NUM
* ETH_ALEN
* 3 + 1];
1750 unsigned int pos
= 0;
1751 size_t bufsz
= sizeof(buf
);
1754 mutex_lock(&mvm
->mutex
);
1756 for (i
= 0; i
< IWL_MVM_UAPSD_NOAGG_LIST_LEN
; i
++)
1757 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "%pM\n",
1758 mvm
->uapsd_noagg_bssids
[i
].addr
);
1760 mutex_unlock(&mvm
->mutex
);
1762 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1766 iwl_dbgfs_ltr_config_write(struct iwl_mvm
*mvm
,
1767 char *buf
, size_t count
, loff_t
*ppos
)
1770 struct iwl_ltr_config_cmd ltr_config
= {0};
1772 if (!iwl_mvm_firmware_running(mvm
))
1775 if (sscanf(buf
, "%x,%x,%x,%x,%x,%x,%x",
1777 <r_config
.static_long
,
1778 <r_config
.static_short
,
1779 <r_config
.ltr_cfg_values
[0],
1780 <r_config
.ltr_cfg_values
[1],
1781 <r_config
.ltr_cfg_values
[2],
1782 <r_config
.ltr_cfg_values
[3]) != 7) {
1786 mutex_lock(&mvm
->mutex
);
1787 ret
= iwl_mvm_send_cmd_pdu(mvm
, LTR_CONFIG
, 0, sizeof(ltr_config
),
1789 mutex_unlock(&mvm
->mutex
);
1792 IWL_ERR(mvm
, "failed to send ltr configuration cmd\n");
1794 return ret
?: count
;
1797 MVM_DEBUGFS_READ_WRITE_FILE_OPS(prph_reg
, 64);
1799 /* Device wide debugfs entries */
1800 MVM_DEBUGFS_READ_FILE_OPS(ctdp_budget
);
1801 MVM_DEBUGFS_WRITE_FILE_OPS(stop_ctdp
, 8);
1802 MVM_DEBUGFS_WRITE_FILE_OPS(force_ctkill
, 8);
1803 MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush
, 16);
1804 MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain
, 8);
1805 MVM_DEBUGFS_WRITE_FILE_OPS(send_echo_cmd
, 8);
1806 MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram
, 64);
1807 MVM_DEBUGFS_READ_WRITE_FILE_OPS(set_nic_temperature
, 64);
1808 MVM_DEBUGFS_READ_FILE_OPS(nic_temp
);
1809 MVM_DEBUGFS_READ_FILE_OPS(stations
);
1810 MVM_DEBUGFS_READ_FILE_OPS(rs_data
);
1811 MVM_DEBUGFS_READ_FILE_OPS(bt_notif
);
1812 MVM_DEBUGFS_READ_FILE_OPS(bt_cmd
);
1813 MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off
, 64);
1814 MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats
);
1815 MVM_DEBUGFS_READ_FILE_OPS(drv_rx_stats
);
1816 MVM_DEBUGFS_READ_FILE_OPS(fw_ver
);
1817 MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart
, 10);
1818 MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi
, 10);
1819 MVM_DEBUGFS_WRITE_FILE_OPS(bt_tx_prio
, 10);
1820 MVM_DEBUGFS_WRITE_FILE_OPS(bt_force_ant
, 10);
1821 MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain
, 8);
1822 MVM_DEBUGFS_READ_WRITE_FILE_OPS(fw_dbg_conf
, 8);
1823 MVM_DEBUGFS_WRITE_FILE_OPS(fw_dbg_collect
, 64);
1824 MVM_DEBUGFS_WRITE_FILE_OPS(indirection_tbl
,
1825 (IWL_RSS_INDIRECTION_TABLE_SIZE
* 2));
1826 MVM_DEBUGFS_WRITE_FILE_OPS(inject_packet
, 512);
1827 MVM_DEBUGFS_WRITE_FILE_OPS(inject_beacon_ie
, 512);
1828 MVM_DEBUGFS_WRITE_FILE_OPS(inject_beacon_ie_restore
, 512);
1830 MVM_DEBUGFS_READ_FILE_OPS(uapsd_noagg_bssids
);
1832 #ifdef CONFIG_IWLWIFI_BCAST_FILTERING
1833 MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters
, 256);
1834 MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters_macs
, 256);
1838 MVM_DEBUGFS_READ_FILE_OPS(sar_geo_profile
);
1841 MVM_DEBUGFS_READ_WRITE_STA_FILE_OPS(amsdu_len
, 16);
1843 MVM_DEBUGFS_READ_WRITE_FILE_OPS(he_sniffer_params
, 32);
1845 MVM_DEBUGFS_WRITE_FILE_OPS(ltr_config
, 512);
1847 static ssize_t
iwl_dbgfs_mem_read(struct file
*file
, char __user
*user_buf
,
1848 size_t count
, loff_t
*ppos
)
1850 struct iwl_mvm
*mvm
= file
->private_data
;
1851 struct iwl_dbg_mem_access_cmd cmd
= {};
1852 struct iwl_dbg_mem_access_rsp
*rsp
;
1853 struct iwl_host_cmd hcmd
= {
1854 .flags
= CMD_WANT_SKB
| CMD_SEND_IN_RFKILL
,
1856 .len
= { sizeof(cmd
) },
1861 if (!iwl_mvm_firmware_running(mvm
))
1864 hcmd
.id
= iwl_cmd_id(*ppos
>> 24 ? UMAC_RD_WR
: LMAC_RD_WR
,
1866 cmd
.op
= cpu_to_le32(DEBUG_MEM_OP_READ
);
1868 /* Take care of alignment of both the position and the length */
1869 delta
= *ppos
& 0x3;
1870 cmd
.addr
= cpu_to_le32(*ppos
- delta
);
1871 cmd
.len
= cpu_to_le32(min(ALIGN(count
+ delta
, 4) / 4,
1872 (size_t)DEBUG_MEM_MAX_SIZE_DWORDS
));
1874 mutex_lock(&mvm
->mutex
);
1875 ret
= iwl_mvm_send_cmd(mvm
, &hcmd
);
1876 mutex_unlock(&mvm
->mutex
);
1881 rsp
= (void *)hcmd
.resp_pkt
->data
;
1882 if (le32_to_cpu(rsp
->status
) != DEBUG_MEM_STATUS_SUCCESS
) {
1887 len
= min((size_t)le32_to_cpu(rsp
->len
) << 2,
1888 iwl_rx_packet_payload_len(hcmd
.resp_pkt
) - sizeof(*rsp
));
1889 len
= min(len
- delta
, count
);
1895 ret
= len
- copy_to_user(user_buf
, (void *)rsp
->data
+ delta
, len
);
1899 iwl_free_resp(&hcmd
);
1903 static ssize_t
iwl_dbgfs_mem_write(struct file
*file
,
1904 const char __user
*user_buf
, size_t count
,
1907 struct iwl_mvm
*mvm
= file
->private_data
;
1908 struct iwl_dbg_mem_access_cmd
*cmd
;
1909 struct iwl_dbg_mem_access_rsp
*rsp
;
1910 struct iwl_host_cmd hcmd
= {};
1916 if (!iwl_mvm_firmware_running(mvm
))
1919 hcmd
.id
= iwl_cmd_id(*ppos
>> 24 ? UMAC_RD_WR
: LMAC_RD_WR
,
1922 if (*ppos
& 0x3 || count
< 4) {
1923 op
= DEBUG_MEM_OP_WRITE_BYTES
;
1924 len
= min(count
, (size_t)(4 - (*ppos
& 0x3)));
1927 op
= DEBUG_MEM_OP_WRITE
;
1928 len
= min(count
>> 2, (size_t)DEBUG_MEM_MAX_SIZE_DWORDS
);
1929 data_size
= len
<< 2;
1932 cmd_size
= sizeof(*cmd
) + ALIGN(data_size
, 4);
1933 cmd
= kzalloc(cmd_size
, GFP_KERNEL
);
1937 cmd
->op
= cpu_to_le32(op
);
1938 cmd
->len
= cpu_to_le32(len
);
1939 cmd
->addr
= cpu_to_le32(*ppos
);
1940 if (copy_from_user((void *)cmd
->data
, user_buf
, data_size
)) {
1945 hcmd
.flags
= CMD_WANT_SKB
| CMD_SEND_IN_RFKILL
,
1946 hcmd
.data
[0] = (void *)cmd
;
1947 hcmd
.len
[0] = cmd_size
;
1949 mutex_lock(&mvm
->mutex
);
1950 ret
= iwl_mvm_send_cmd(mvm
, &hcmd
);
1951 mutex_unlock(&mvm
->mutex
);
1958 rsp
= (void *)hcmd
.resp_pkt
->data
;
1959 if (rsp
->status
!= DEBUG_MEM_STATUS_SUCCESS
) {
1968 iwl_free_resp(&hcmd
);
1972 static const struct file_operations iwl_dbgfs_mem_ops
= {
1973 .read
= iwl_dbgfs_mem_read
,
1974 .write
= iwl_dbgfs_mem_write
,
1975 .open
= simple_open
,
1976 .llseek
= default_llseek
,
1979 void iwl_mvm_sta_add_debugfs(struct ieee80211_hw
*hw
,
1980 struct ieee80211_vif
*vif
,
1981 struct ieee80211_sta
*sta
,
1984 struct iwl_mvm
*mvm
= IWL_MAC80211_GET_MVM(hw
);
1986 if (iwl_mvm_has_tlc_offload(mvm
)) {
1987 MVM_DEBUGFS_ADD_STA_FILE(rs_data
, dir
, 0400);
1989 MVM_DEBUGFS_ADD_STA_FILE(amsdu_len
, dir
, 0600);
1992 void iwl_mvm_dbgfs_register(struct iwl_mvm
*mvm
, struct dentry
*dbgfs_dir
)
1994 struct dentry
*bcast_dir __maybe_unused
;
1997 spin_lock_init(&mvm
->drv_stats_lock
);
1999 mvm
->debugfs_dir
= dbgfs_dir
;
2001 MVM_DEBUGFS_ADD_FILE(tx_flush
, mvm
->debugfs_dir
, 0200);
2002 MVM_DEBUGFS_ADD_FILE(sta_drain
, mvm
->debugfs_dir
, 0200);
2003 MVM_DEBUGFS_ADD_FILE(sram
, mvm
->debugfs_dir
, 0600);
2004 MVM_DEBUGFS_ADD_FILE(set_nic_temperature
, mvm
->debugfs_dir
, 0600);
2005 MVM_DEBUGFS_ADD_FILE(nic_temp
, dbgfs_dir
, 0400);
2006 MVM_DEBUGFS_ADD_FILE(ctdp_budget
, dbgfs_dir
, 0400);
2007 MVM_DEBUGFS_ADD_FILE(stop_ctdp
, dbgfs_dir
, 0200);
2008 MVM_DEBUGFS_ADD_FILE(force_ctkill
, dbgfs_dir
, 0200);
2009 MVM_DEBUGFS_ADD_FILE(stations
, dbgfs_dir
, 0400);
2010 MVM_DEBUGFS_ADD_FILE(bt_notif
, dbgfs_dir
, 0400);
2011 MVM_DEBUGFS_ADD_FILE(bt_cmd
, dbgfs_dir
, 0400);
2012 MVM_DEBUGFS_ADD_FILE(disable_power_off
, mvm
->debugfs_dir
, 0600);
2013 MVM_DEBUGFS_ADD_FILE(fw_ver
, mvm
->debugfs_dir
, 0400);
2014 MVM_DEBUGFS_ADD_FILE(fw_rx_stats
, mvm
->debugfs_dir
, 0400);
2015 MVM_DEBUGFS_ADD_FILE(drv_rx_stats
, mvm
->debugfs_dir
, 0400);
2016 MVM_DEBUGFS_ADD_FILE(fw_restart
, mvm
->debugfs_dir
, 0200);
2017 MVM_DEBUGFS_ADD_FILE(fw_nmi
, mvm
->debugfs_dir
, 0200);
2018 MVM_DEBUGFS_ADD_FILE(bt_tx_prio
, mvm
->debugfs_dir
, 0200);
2019 MVM_DEBUGFS_ADD_FILE(bt_force_ant
, mvm
->debugfs_dir
, 0200);
2020 MVM_DEBUGFS_ADD_FILE(scan_ant_rxchain
, mvm
->debugfs_dir
, 0600);
2021 MVM_DEBUGFS_ADD_FILE(prph_reg
, mvm
->debugfs_dir
, 0600);
2022 MVM_DEBUGFS_ADD_FILE(fw_dbg_conf
, mvm
->debugfs_dir
, 0600);
2023 MVM_DEBUGFS_ADD_FILE(fw_dbg_collect
, mvm
->debugfs_dir
, 0200);
2024 MVM_DEBUGFS_ADD_FILE(send_echo_cmd
, mvm
->debugfs_dir
, 0200);
2025 MVM_DEBUGFS_ADD_FILE(indirection_tbl
, mvm
->debugfs_dir
, 0200);
2026 MVM_DEBUGFS_ADD_FILE(inject_packet
, mvm
->debugfs_dir
, 0200);
2027 MVM_DEBUGFS_ADD_FILE(inject_beacon_ie
, mvm
->debugfs_dir
, 0200);
2028 MVM_DEBUGFS_ADD_FILE(inject_beacon_ie_restore
, mvm
->debugfs_dir
, 0200);
2030 MVM_DEBUGFS_ADD_FILE(sar_geo_profile
, dbgfs_dir
, 0400);
2032 MVM_DEBUGFS_ADD_FILE(he_sniffer_params
, mvm
->debugfs_dir
, 0600);
2034 if (fw_has_capa(&mvm
->fw
->ucode_capa
, IWL_UCODE_TLV_CAPA_SET_LTR_GEN2
))
2035 MVM_DEBUGFS_ADD_FILE(ltr_config
, mvm
->debugfs_dir
, 0200);
2037 debugfs_create_bool("enable_scan_iteration_notif", 0600,
2038 mvm
->debugfs_dir
, &mvm
->scan_iter_notif_enabled
);
2039 debugfs_create_bool("drop_bcn_ap_mode", 0600, mvm
->debugfs_dir
,
2040 &mvm
->drop_bcn_ap_mode
);
2042 MVM_DEBUGFS_ADD_FILE(uapsd_noagg_bssids
, mvm
->debugfs_dir
, S_IRUSR
);
2044 #ifdef CONFIG_IWLWIFI_BCAST_FILTERING
2045 if (mvm
->fw
->ucode_capa
.flags
& IWL_UCODE_TLV_FLAGS_BCAST_FILTERING
) {
2046 bcast_dir
= debugfs_create_dir("bcast_filtering",
2049 debugfs_create_bool("override", 0600, bcast_dir
,
2050 &mvm
->dbgfs_bcast_filtering
.override
);
2052 MVM_DEBUGFS_ADD_FILE_ALIAS("filters", bcast_filters
,
2054 MVM_DEBUGFS_ADD_FILE_ALIAS("macs", bcast_filters_macs
,
2059 #ifdef CONFIG_PM_SLEEP
2060 MVM_DEBUGFS_ADD_FILE(d3_test
, mvm
->debugfs_dir
, 0400);
2061 debugfs_create_bool("d3_wake_sysassert", 0600, mvm
->debugfs_dir
,
2062 &mvm
->d3_wake_sysassert
);
2063 debugfs_create_u32("last_netdetect_scans", 0400, mvm
->debugfs_dir
,
2064 &mvm
->last_netdetect_scans
);
2067 debugfs_create_u8("ps_disabled", 0400, mvm
->debugfs_dir
,
2069 debugfs_create_blob("nvm_hw", 0400, mvm
->debugfs_dir
,
2071 debugfs_create_blob("nvm_sw", 0400, mvm
->debugfs_dir
,
2073 debugfs_create_blob("nvm_calib", 0400, mvm
->debugfs_dir
,
2074 &mvm
->nvm_calib_blob
);
2075 debugfs_create_blob("nvm_prod", 0400, mvm
->debugfs_dir
,
2076 &mvm
->nvm_prod_blob
);
2077 debugfs_create_blob("nvm_phy_sku", 0400, mvm
->debugfs_dir
,
2078 &mvm
->nvm_phy_sku_blob
);
2079 debugfs_create_blob("nvm_reg", S_IRUSR
,
2080 mvm
->debugfs_dir
, &mvm
->nvm_reg_blob
);
2082 debugfs_create_file("mem", 0600, dbgfs_dir
, mvm
, &iwl_dbgfs_mem_ops
);
2085 * Create a symlink with mac80211. It will be removed when mac80211
2086 * exists (before the opmode exists which removes the target.)
2088 snprintf(buf
, 100, "../../%pd2", dbgfs_dir
->d_parent
);
2089 debugfs_create_symlink("iwlwifi", mvm
->hw
->wiphy
->debugfsdir
, buf
);