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
, 0xFF, 0) ? : count
;
152 mutex_unlock(&mvm
->mutex
);
156 IWL_DEBUG_TX_QUEUES(mvm
, "FLUSHING queues mask to flush = 0x%x\n",
159 mutex_lock(&mvm
->mutex
);
160 ret
= iwl_mvm_flush_tx_path(mvm
, flush_arg
, 0) ? : count
;
161 mutex_unlock(&mvm
->mutex
);
166 static ssize_t
iwl_dbgfs_sta_drain_write(struct iwl_mvm
*mvm
, char *buf
,
167 size_t count
, loff_t
*ppos
)
169 struct iwl_mvm_sta
*mvmsta
;
170 int sta_id
, drain
, ret
;
172 if (!iwl_mvm_firmware_running(mvm
) ||
173 mvm
->fwrt
.cur_fw_img
!= IWL_UCODE_REGULAR
)
176 if (sscanf(buf
, "%d %d", &sta_id
, &drain
) != 2)
178 if (sta_id
< 0 || sta_id
>= IWL_MVM_STATION_COUNT
)
180 if (drain
< 0 || drain
> 1)
183 mutex_lock(&mvm
->mutex
);
185 mvmsta
= iwl_mvm_sta_from_staid_protected(mvm
, sta_id
);
190 ret
= iwl_mvm_drain_sta(mvm
, mvmsta
, drain
) ? : count
;
192 mutex_unlock(&mvm
->mutex
);
197 static ssize_t
iwl_dbgfs_sram_read(struct file
*file
, char __user
*user_buf
,
198 size_t count
, loff_t
*ppos
)
200 struct iwl_mvm
*mvm
= file
->private_data
;
201 const struct fw_img
*img
;
202 unsigned int ofs
, len
;
206 if (!iwl_mvm_firmware_running(mvm
))
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
;
214 if (mvm
->dbgfs_sram_len
) {
215 ofs
= mvm
->dbgfs_sram_offset
;
216 len
= mvm
->dbgfs_sram_len
;
219 ptr
= kzalloc(len
, GFP_KERNEL
);
223 iwl_trans_read_mem_bytes(mvm
->trans
, ofs
, ptr
, len
);
225 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, ptr
, len
);
232 static ssize_t
iwl_dbgfs_sram_write(struct iwl_mvm
*mvm
, char *buf
,
233 size_t count
, loff_t
*ppos
)
235 const struct fw_img
*img
;
237 u32 img_offset
, img_len
;
239 if (!iwl_mvm_firmware_running(mvm
))
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
;
246 if (sscanf(buf
, "%x,%x", &offset
, &len
) == 2) {
247 if ((offset
& 0x3) || (len
& 0x3))
250 if (offset
+ len
> img_offset
+ img_len
)
253 mvm
->dbgfs_sram_offset
= offset
;
254 mvm
->dbgfs_sram_len
= len
;
256 mvm
->dbgfs_sram_offset
= 0;
257 mvm
->dbgfs_sram_len
= 0;
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
)
267 struct iwl_mvm
*mvm
= file
->private_data
;
271 if (!mvm
->temperature_test
)
272 pos
= scnprintf(buf
, sizeof(buf
), "disabled\n");
274 pos
= scnprintf(buf
, sizeof(buf
), "%d\n", mvm
->temperature
);
276 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
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
286 static ssize_t
iwl_dbgfs_set_nic_temperature_write(struct iwl_mvm
*mvm
,
287 char *buf
, size_t count
,
292 if (!iwl_mvm_firmware_running(mvm
) && !mvm
->temperature_test
)
295 if (kstrtoint(buf
, 10, &temperature
))
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
)
303 mutex_lock(&mvm
->mutex
);
304 if (temperature
== IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE
) {
305 if (!mvm
->temperature_test
)
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
313 mvm
->temperature
= 0;
315 mvm
->temperature_test
= true;
316 mvm
->temperature
= temperature
;
318 IWL_DEBUG_TEMP(mvm
, "%sabling debug set temperature (temp = %d)\n",
319 mvm
->temperature_test
? "En" : "Dis" ,
321 /* handle the temperature change */
322 iwl_mvm_tt_handler(mvm
);
325 mutex_unlock(&mvm
->mutex
);
330 static ssize_t
iwl_dbgfs_nic_temp_read(struct file
*file
,
331 char __user
*user_buf
,
332 size_t count
, loff_t
*ppos
)
334 struct iwl_mvm
*mvm
= file
->private_data
;
339 if (!iwl_mvm_firmware_running(mvm
))
342 mutex_lock(&mvm
->mutex
);
343 ret
= iwl_mvm_get_temp(mvm
, &temp
);
344 mutex_unlock(&mvm
->mutex
);
349 pos
= scnprintf(buf
, sizeof(buf
), "%d\n", temp
);
351 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
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
)
359 struct iwl_mvm
*mvm
= file
->private_data
;
362 int bufsz
= sizeof(buf
);
366 if (!iwl_mvm_firmware_running(mvm
))
369 mutex_lock(&mvm
->mutex
);
370 tbl_idx
= iwl_mvm_get_sar_geo_profile(mvm
);
372 mutex_unlock(&mvm
->mutex
);
377 pos
= scnprintf(buf
, bufsz
,
378 "SAR geographic profile disabled\n");
380 value
= &mvm
->geo_profiles
[tbl_idx
- 1].values
[0];
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]);
391 mutex_unlock(&mvm
->mutex
);
393 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
397 static ssize_t
iwl_dbgfs_stations_read(struct file
*file
, char __user
*user_buf
,
398 size_t count
, loff_t
*ppos
)
400 struct iwl_mvm
*mvm
= file
->private_data
;
401 struct ieee80211_sta
*sta
;
403 int i
, pos
= 0, bufsz
= sizeof(buf
);
405 mutex_lock(&mvm
->mutex
);
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
));
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",
417 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "%pM\n",
421 mutex_unlock(&mvm
->mutex
);
423 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
426 static ssize_t
iwl_dbgfs_rs_data_read(struct file
*file
, char __user
*user_buf
,
427 size_t count
, loff_t
*ppos
)
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;
438 buff
= kmalloc(bufsz
, GFP_KERNEL
);
442 mutex_lock(&mvm
->mutex
);
444 desc
+= scnprintf(buff
+ desc
, bufsz
- desc
, "sta_id %d\n",
445 lq_sta
->pers
.sta_id
);
446 desc
+= scnprintf(buff
+ desc
, bufsz
- desc
,
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
);
461 desc
+= rs_pretty_print_rate(buff
+ desc
, bufsz
- desc
,
462 lq_sta
->last_rate_n_flags
);
463 mutex_unlock(&mvm
->mutex
);
465 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buff
, desc
);
470 static ssize_t
iwl_dbgfs_disable_power_off_read(struct file
*file
,
471 char __user
*user_buf
,
472 size_t count
, loff_t
*ppos
)
474 struct iwl_mvm
*mvm
= file
->private_data
;
476 int bufsz
= sizeof(buf
);
479 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "disable_power_off_d0=%d\n",
480 mvm
->disable_power_off
);
481 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "disable_power_off_d3=%d\n",
482 mvm
->disable_power_off_d3
);
484 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
487 static ssize_t
iwl_dbgfs_disable_power_off_write(struct iwl_mvm
*mvm
, char *buf
,
488 size_t count
, loff_t
*ppos
)
492 if (!iwl_mvm_firmware_running(mvm
))
495 if (!strncmp("disable_power_off_d0=", buf
, 21)) {
496 if (sscanf(buf
+ 21, "%d", &val
) != 1)
498 mvm
->disable_power_off
= val
;
499 } else if (!strncmp("disable_power_off_d3=", buf
, 21)) {
500 if (sscanf(buf
+ 21, "%d", &val
) != 1)
502 mvm
->disable_power_off_d3
= val
;
507 mutex_lock(&mvm
->mutex
);
508 ret
= iwl_mvm_power_update_device(mvm
);
509 mutex_unlock(&mvm
->mutex
);
515 int iwl_mvm_coex_dump_mbox(struct iwl_bt_coex_profile_notif
*notif
, char *buf
,
518 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "MBOX dw0:\n");
520 BT_MBOX_PRINT(0, LE_SLAVE_LAT
, false);
521 BT_MBOX_PRINT(0, LE_PROF1
, false);
522 BT_MBOX_PRINT(0, LE_PROF2
, false);
523 BT_MBOX_PRINT(0, LE_PROF_OTHER
, false);
524 BT_MBOX_PRINT(0, CHL_SEQ_N
, false);
525 BT_MBOX_PRINT(0, INBAND_S
, false);
526 BT_MBOX_PRINT(0, LE_MIN_RSSI
, false);
527 BT_MBOX_PRINT(0, LE_SCAN
, false);
528 BT_MBOX_PRINT(0, LE_ADV
, false);
529 BT_MBOX_PRINT(0, LE_MAX_TX_POWER
, false);
530 BT_MBOX_PRINT(0, OPEN_CON_1
, true);
532 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "MBOX dw1:\n");
534 BT_MBOX_PRINT(1, BR_MAX_TX_POWER
, false);
535 BT_MBOX_PRINT(1, IP_SR
, false);
536 BT_MBOX_PRINT(1, LE_MSTR
, false);
537 BT_MBOX_PRINT(1, AGGR_TRFC_LD
, false);
538 BT_MBOX_PRINT(1, MSG_TYPE
, false);
539 BT_MBOX_PRINT(1, SSN
, true);
541 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "MBOX dw2:\n");
543 BT_MBOX_PRINT(2, SNIFF_ACT
, false);
544 BT_MBOX_PRINT(2, PAG
, false);
545 BT_MBOX_PRINT(2, INQUIRY
, false);
546 BT_MBOX_PRINT(2, CONN
, false);
547 BT_MBOX_PRINT(2, SNIFF_INTERVAL
, false);
548 BT_MBOX_PRINT(2, DISC
, false);
549 BT_MBOX_PRINT(2, SCO_TX_ACT
, false);
550 BT_MBOX_PRINT(2, SCO_RX_ACT
, false);
551 BT_MBOX_PRINT(2, ESCO_RE_TX
, false);
552 BT_MBOX_PRINT(2, SCO_DURATION
, true);
554 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "MBOX dw3:\n");
556 BT_MBOX_PRINT(3, SCO_STATE
, false);
557 BT_MBOX_PRINT(3, SNIFF_STATE
, false);
558 BT_MBOX_PRINT(3, A2DP_STATE
, false);
559 BT_MBOX_PRINT(3, A2DP_SRC
, false);
560 BT_MBOX_PRINT(3, ACL_STATE
, false);
561 BT_MBOX_PRINT(3, MSTR_STATE
, false);
562 BT_MBOX_PRINT(3, OBX_STATE
, false);
563 BT_MBOX_PRINT(3, OPEN_CON_2
, false);
564 BT_MBOX_PRINT(3, TRAFFIC_LOAD
, false);
565 BT_MBOX_PRINT(3, CHL_SEQN_LSB
, false);
566 BT_MBOX_PRINT(3, INBAND_P
, false);
567 BT_MBOX_PRINT(3, MSG_TYPE_2
, false);
568 BT_MBOX_PRINT(3, SSN_2
, false);
569 BT_MBOX_PRINT(3, UPDATE_REQUEST
, true);
574 static ssize_t
iwl_dbgfs_bt_notif_read(struct file
*file
, char __user
*user_buf
,
575 size_t count
, loff_t
*ppos
)
577 struct iwl_mvm
*mvm
= file
->private_data
;
578 struct iwl_bt_coex_profile_notif
*notif
= &mvm
->last_bt_notif
;
580 int ret
, pos
= 0, bufsz
= sizeof(char) * 1024;
582 buf
= kmalloc(bufsz
, GFP_KERNEL
);
586 mutex_lock(&mvm
->mutex
);
588 pos
+= iwl_mvm_coex_dump_mbox(notif
, buf
, pos
, bufsz
);
590 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "bt_ci_compliance = %d\n",
591 notif
->bt_ci_compliance
);
592 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "primary_ch_lut = %d\n",
593 le32_to_cpu(notif
->primary_ch_lut
));
594 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "secondary_ch_lut = %d\n",
595 le32_to_cpu(notif
->secondary_ch_lut
));
596 pos
+= scnprintf(buf
+ pos
,
597 bufsz
- pos
, "bt_activity_grading = %d\n",
598 le32_to_cpu(notif
->bt_activity_grading
));
599 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "bt_rrc = %d\n",
600 notif
->rrc_status
& 0xF);
601 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "bt_ttc = %d\n",
602 notif
->ttc_status
& 0xF);
604 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "sync_sco = %d\n",
605 IWL_MVM_BT_COEX_SYNC2SCO
);
606 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "mplut = %d\n",
607 IWL_MVM_BT_COEX_MPLUT
);
609 mutex_unlock(&mvm
->mutex
);
611 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
618 static ssize_t
iwl_dbgfs_bt_cmd_read(struct file
*file
, char __user
*user_buf
,
619 size_t count
, loff_t
*ppos
)
621 struct iwl_mvm
*mvm
= file
->private_data
;
622 struct iwl_bt_coex_ci_cmd
*cmd
= &mvm
->last_bt_ci_cmd
;
624 int bufsz
= sizeof(buf
);
627 mutex_lock(&mvm
->mutex
);
629 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Channel inhibition CMD\n");
630 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
631 "\tPrimary Channel Bitmap 0x%016llx\n",
632 le64_to_cpu(cmd
->bt_primary_ci
));
633 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
634 "\tSecondary Channel Bitmap 0x%016llx\n",
635 le64_to_cpu(cmd
->bt_secondary_ci
));
637 mutex_unlock(&mvm
->mutex
);
639 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
643 iwl_dbgfs_bt_tx_prio_write(struct iwl_mvm
*mvm
, char *buf
,
644 size_t count
, loff_t
*ppos
)
648 if (sscanf(buf
, "%u", &bt_tx_prio
) != 1)
653 mvm
->bt_tx_prio
= bt_tx_prio
;
659 iwl_dbgfs_bt_force_ant_write(struct iwl_mvm
*mvm
, char *buf
,
660 size_t count
, loff_t
*ppos
)
662 static const char * const modes_str
[BT_FORCE_ANT_MAX
] = {
663 [BT_FORCE_ANT_DIS
] = "dis",
664 [BT_FORCE_ANT_AUTO
] = "auto",
665 [BT_FORCE_ANT_BT
] = "bt",
666 [BT_FORCE_ANT_WIFI
] = "wifi",
668 int ret
, bt_force_ant_mode
;
670 ret
= match_string(modes_str
, ARRAY_SIZE(modes_str
), buf
);
674 bt_force_ant_mode
= ret
;
676 mutex_lock(&mvm
->mutex
);
677 if (mvm
->bt_force_ant_mode
== bt_force_ant_mode
)
680 mvm
->bt_force_ant_mode
= bt_force_ant_mode
;
681 IWL_DEBUG_COEX(mvm
, "Force mode: %s\n",
682 modes_str
[mvm
->bt_force_ant_mode
]);
684 if (iwl_mvm_firmware_running(mvm
))
685 ret
= iwl_mvm_send_bt_init_conf(mvm
);
690 mutex_unlock(&mvm
->mutex
);
694 static ssize_t
iwl_dbgfs_fw_ver_read(struct file
*file
, char __user
*user_buf
,
695 size_t count
, loff_t
*ppos
)
697 struct iwl_mvm
*mvm
= file
->private_data
;
698 char *buff
, *pos
, *endpos
;
699 static const size_t bufsz
= 1024;
702 buff
= kmalloc(bufsz
, GFP_KERNEL
);
707 endpos
= pos
+ bufsz
;
709 pos
+= scnprintf(pos
, endpos
- pos
, "FW prefix: %s\n",
710 mvm
->trans
->cfg
->fw_name_pre
);
711 pos
+= scnprintf(pos
, endpos
- pos
, "FW: %s\n",
712 mvm
->fwrt
.fw
->human_readable
);
713 pos
+= scnprintf(pos
, endpos
- pos
, "Device: %s\n",
714 mvm
->fwrt
.trans
->cfg
->name
);
715 pos
+= scnprintf(pos
, endpos
- pos
, "Bus: %s\n",
716 mvm
->fwrt
.dev
->bus
->name
);
718 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buff
, pos
- buff
);
724 #define PRINT_STATS_LE32(_struct, _memb) \
725 pos += scnprintf(buf + pos, bufsz - pos, \
727 le32_to_cpu(_struct->_memb))
729 static ssize_t
iwl_dbgfs_fw_rx_stats_read(struct file
*file
,
730 char __user
*user_buf
, size_t count
,
733 struct iwl_mvm
*mvm
= file
->private_data
;
734 static const char *fmt_table
= "\t%-30s %10u\n";
735 static const char *fmt_header
= "%-32s\n";
741 if (iwl_mvm_has_new_rx_stats_api(mvm
))
742 bufsz
= ((sizeof(struct mvm_statistics_rx
) /
743 sizeof(__le32
)) * 43) + (4 * 33) + 1;
745 /* 43 = size of each data line; 33 = size of each header */
746 bufsz
= ((sizeof(struct mvm_statistics_rx_v3
) /
747 sizeof(__le32
)) * 43) + (4 * 33) + 1;
749 buf
= kzalloc(bufsz
, GFP_KERNEL
);
753 mutex_lock(&mvm
->mutex
);
755 if (iwl_mvm_firmware_running(mvm
))
756 iwl_mvm_request_statistics(mvm
, false);
758 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, fmt_header
,
759 "Statistics_Rx - OFDM");
760 if (!iwl_mvm_has_new_rx_stats_api(mvm
)) {
761 struct mvm_statistics_rx_phy_v2
*ofdm
= &mvm
->rx_stats_v3
.ofdm
;
763 PRINT_STATS_LE32(ofdm
, ina_cnt
);
764 PRINT_STATS_LE32(ofdm
, fina_cnt
);
765 PRINT_STATS_LE32(ofdm
, plcp_err
);
766 PRINT_STATS_LE32(ofdm
, crc32_err
);
767 PRINT_STATS_LE32(ofdm
, overrun_err
);
768 PRINT_STATS_LE32(ofdm
, early_overrun_err
);
769 PRINT_STATS_LE32(ofdm
, crc32_good
);
770 PRINT_STATS_LE32(ofdm
, false_alarm_cnt
);
771 PRINT_STATS_LE32(ofdm
, fina_sync_err_cnt
);
772 PRINT_STATS_LE32(ofdm
, sfd_timeout
);
773 PRINT_STATS_LE32(ofdm
, fina_timeout
);
774 PRINT_STATS_LE32(ofdm
, unresponded_rts
);
775 PRINT_STATS_LE32(ofdm
, rxe_frame_lmt_overrun
);
776 PRINT_STATS_LE32(ofdm
, sent_ack_cnt
);
777 PRINT_STATS_LE32(ofdm
, sent_cts_cnt
);
778 PRINT_STATS_LE32(ofdm
, sent_ba_rsp_cnt
);
779 PRINT_STATS_LE32(ofdm
, dsp_self_kill
);
780 PRINT_STATS_LE32(ofdm
, mh_format_err
);
781 PRINT_STATS_LE32(ofdm
, re_acq_main_rssi_sum
);
782 PRINT_STATS_LE32(ofdm
, reserved
);
784 struct mvm_statistics_rx_phy
*ofdm
= &mvm
->rx_stats
.ofdm
;
786 PRINT_STATS_LE32(ofdm
, unresponded_rts
);
787 PRINT_STATS_LE32(ofdm
, rxe_frame_lmt_overrun
);
788 PRINT_STATS_LE32(ofdm
, sent_ba_rsp_cnt
);
789 PRINT_STATS_LE32(ofdm
, dsp_self_kill
);
790 PRINT_STATS_LE32(ofdm
, reserved
);
793 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, fmt_header
,
794 "Statistics_Rx - CCK");
795 if (!iwl_mvm_has_new_rx_stats_api(mvm
)) {
796 struct mvm_statistics_rx_phy_v2
*cck
= &mvm
->rx_stats_v3
.cck
;
798 PRINT_STATS_LE32(cck
, ina_cnt
);
799 PRINT_STATS_LE32(cck
, fina_cnt
);
800 PRINT_STATS_LE32(cck
, plcp_err
);
801 PRINT_STATS_LE32(cck
, crc32_err
);
802 PRINT_STATS_LE32(cck
, overrun_err
);
803 PRINT_STATS_LE32(cck
, early_overrun_err
);
804 PRINT_STATS_LE32(cck
, crc32_good
);
805 PRINT_STATS_LE32(cck
, false_alarm_cnt
);
806 PRINT_STATS_LE32(cck
, fina_sync_err_cnt
);
807 PRINT_STATS_LE32(cck
, sfd_timeout
);
808 PRINT_STATS_LE32(cck
, fina_timeout
);
809 PRINT_STATS_LE32(cck
, unresponded_rts
);
810 PRINT_STATS_LE32(cck
, rxe_frame_lmt_overrun
);
811 PRINT_STATS_LE32(cck
, sent_ack_cnt
);
812 PRINT_STATS_LE32(cck
, sent_cts_cnt
);
813 PRINT_STATS_LE32(cck
, sent_ba_rsp_cnt
);
814 PRINT_STATS_LE32(cck
, dsp_self_kill
);
815 PRINT_STATS_LE32(cck
, mh_format_err
);
816 PRINT_STATS_LE32(cck
, re_acq_main_rssi_sum
);
817 PRINT_STATS_LE32(cck
, reserved
);
819 struct mvm_statistics_rx_phy
*cck
= &mvm
->rx_stats
.cck
;
821 PRINT_STATS_LE32(cck
, unresponded_rts
);
822 PRINT_STATS_LE32(cck
, rxe_frame_lmt_overrun
);
823 PRINT_STATS_LE32(cck
, sent_ba_rsp_cnt
);
824 PRINT_STATS_LE32(cck
, dsp_self_kill
);
825 PRINT_STATS_LE32(cck
, reserved
);
828 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, fmt_header
,
829 "Statistics_Rx - GENERAL");
830 if (!iwl_mvm_has_new_rx_stats_api(mvm
)) {
831 struct mvm_statistics_rx_non_phy_v3
*general
=
832 &mvm
->rx_stats_v3
.general
;
834 PRINT_STATS_LE32(general
, bogus_cts
);
835 PRINT_STATS_LE32(general
, bogus_ack
);
836 PRINT_STATS_LE32(general
, non_bssid_frames
);
837 PRINT_STATS_LE32(general
, filtered_frames
);
838 PRINT_STATS_LE32(general
, non_channel_beacons
);
839 PRINT_STATS_LE32(general
, channel_beacons
);
840 PRINT_STATS_LE32(general
, num_missed_bcon
);
841 PRINT_STATS_LE32(general
, adc_rx_saturation_time
);
842 PRINT_STATS_LE32(general
, ina_detection_search_time
);
843 PRINT_STATS_LE32(general
, beacon_silence_rssi_a
);
844 PRINT_STATS_LE32(general
, beacon_silence_rssi_b
);
845 PRINT_STATS_LE32(general
, beacon_silence_rssi_c
);
846 PRINT_STATS_LE32(general
, interference_data_flag
);
847 PRINT_STATS_LE32(general
, channel_load
);
848 PRINT_STATS_LE32(general
, dsp_false_alarms
);
849 PRINT_STATS_LE32(general
, beacon_rssi_a
);
850 PRINT_STATS_LE32(general
, beacon_rssi_b
);
851 PRINT_STATS_LE32(general
, beacon_rssi_c
);
852 PRINT_STATS_LE32(general
, beacon_energy_a
);
853 PRINT_STATS_LE32(general
, beacon_energy_b
);
854 PRINT_STATS_LE32(general
, beacon_energy_c
);
855 PRINT_STATS_LE32(general
, num_bt_kills
);
856 PRINT_STATS_LE32(general
, mac_id
);
857 PRINT_STATS_LE32(general
, directed_data_mpdu
);
859 struct mvm_statistics_rx_non_phy
*general
=
860 &mvm
->rx_stats
.general
;
862 PRINT_STATS_LE32(general
, bogus_cts
);
863 PRINT_STATS_LE32(general
, bogus_ack
);
864 PRINT_STATS_LE32(general
, non_channel_beacons
);
865 PRINT_STATS_LE32(general
, channel_beacons
);
866 PRINT_STATS_LE32(general
, num_missed_bcon
);
867 PRINT_STATS_LE32(general
, adc_rx_saturation_time
);
868 PRINT_STATS_LE32(general
, ina_detection_search_time
);
869 PRINT_STATS_LE32(general
, beacon_silence_rssi_a
);
870 PRINT_STATS_LE32(general
, beacon_silence_rssi_b
);
871 PRINT_STATS_LE32(general
, beacon_silence_rssi_c
);
872 PRINT_STATS_LE32(general
, interference_data_flag
);
873 PRINT_STATS_LE32(general
, channel_load
);
874 PRINT_STATS_LE32(general
, beacon_rssi_a
);
875 PRINT_STATS_LE32(general
, beacon_rssi_b
);
876 PRINT_STATS_LE32(general
, beacon_rssi_c
);
877 PRINT_STATS_LE32(general
, beacon_energy_a
);
878 PRINT_STATS_LE32(general
, beacon_energy_b
);
879 PRINT_STATS_LE32(general
, beacon_energy_c
);
880 PRINT_STATS_LE32(general
, num_bt_kills
);
881 PRINT_STATS_LE32(general
, mac_id
);
884 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, fmt_header
,
885 "Statistics_Rx - HT");
886 if (!iwl_mvm_has_new_rx_stats_api(mvm
)) {
887 struct mvm_statistics_rx_ht_phy_v1
*ht
=
888 &mvm
->rx_stats_v3
.ofdm_ht
;
890 PRINT_STATS_LE32(ht
, plcp_err
);
891 PRINT_STATS_LE32(ht
, overrun_err
);
892 PRINT_STATS_LE32(ht
, early_overrun_err
);
893 PRINT_STATS_LE32(ht
, crc32_good
);
894 PRINT_STATS_LE32(ht
, crc32_err
);
895 PRINT_STATS_LE32(ht
, mh_format_err
);
896 PRINT_STATS_LE32(ht
, agg_crc32_good
);
897 PRINT_STATS_LE32(ht
, agg_mpdu_cnt
);
898 PRINT_STATS_LE32(ht
, agg_cnt
);
899 PRINT_STATS_LE32(ht
, unsupport_mcs
);
901 struct mvm_statistics_rx_ht_phy
*ht
=
902 &mvm
->rx_stats
.ofdm_ht
;
904 PRINT_STATS_LE32(ht
, mh_format_err
);
905 PRINT_STATS_LE32(ht
, agg_mpdu_cnt
);
906 PRINT_STATS_LE32(ht
, agg_cnt
);
907 PRINT_STATS_LE32(ht
, unsupport_mcs
);
910 mutex_unlock(&mvm
->mutex
);
912 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
917 #undef PRINT_STAT_LE32
919 static ssize_t
iwl_dbgfs_frame_stats_read(struct iwl_mvm
*mvm
,
920 char __user
*user_buf
, size_t count
,
922 struct iwl_mvm_frame_stats
*stats
)
924 char *buff
, *pos
, *endpos
;
927 static const size_t bufsz
= 1024;
929 buff
= kmalloc(bufsz
, GFP_KERNEL
);
933 spin_lock_bh(&mvm
->drv_stats_lock
);
936 endpos
= pos
+ bufsz
;
938 pos
+= scnprintf(pos
, endpos
- pos
,
939 "Legacy/HT/VHT\t:\t%d/%d/%d\n",
940 stats
->legacy_frames
,
943 pos
+= scnprintf(pos
, endpos
- pos
, "20/40/80\t:\t%d/%d/%d\n",
946 stats
->bw_80_frames
);
947 pos
+= scnprintf(pos
, endpos
- pos
, "NGI/SGI\t\t:\t%d/%d\n",
950 pos
+= scnprintf(pos
, endpos
- pos
, "SISO/MIMO2\t:\t%d/%d\n",
952 stats
->mimo2_frames
);
953 pos
+= scnprintf(pos
, endpos
- pos
, "FAIL/SCSS\t:\t%d/%d\n",
955 stats
->success_frames
);
956 pos
+= scnprintf(pos
, endpos
- pos
, "MPDUs agg\t:\t%d\n",
958 pos
+= scnprintf(pos
, endpos
- pos
, "A-MPDUs\t\t:\t%d\n",
960 pos
+= scnprintf(pos
, endpos
- pos
, "Avg MPDUs/A-MPDU:\t%d\n",
961 stats
->ampdu_count
> 0 ?
962 (stats
->agg_frames
/ stats
->ampdu_count
) : 0);
964 pos
+= scnprintf(pos
, endpos
- pos
, "Last Rates\n");
966 idx
= stats
->last_frame_idx
- 1;
967 for (i
= 0; i
< ARRAY_SIZE(stats
->last_rates
); i
++) {
968 idx
= (idx
+ 1) % ARRAY_SIZE(stats
->last_rates
);
969 if (stats
->last_rates
[idx
] == 0)
971 pos
+= scnprintf(pos
, endpos
- pos
, "Rate[%d]: ",
972 (int)(ARRAY_SIZE(stats
->last_rates
) - i
));
973 pos
+= rs_pretty_print_rate(pos
, endpos
- pos
,
974 stats
->last_rates
[idx
]);
976 spin_unlock_bh(&mvm
->drv_stats_lock
);
978 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buff
, pos
- buff
);
984 static ssize_t
iwl_dbgfs_drv_rx_stats_read(struct file
*file
,
985 char __user
*user_buf
, size_t count
,
988 struct iwl_mvm
*mvm
= file
->private_data
;
990 return iwl_dbgfs_frame_stats_read(mvm
, user_buf
, count
, ppos
,
994 static ssize_t
iwl_dbgfs_fw_restart_write(struct iwl_mvm
*mvm
, char *buf
,
995 size_t count
, loff_t
*ppos
)
997 int __maybe_unused ret
;
999 if (!iwl_mvm_firmware_running(mvm
))
1002 mutex_lock(&mvm
->mutex
);
1004 /* allow one more restart that we're provoking here */
1005 if (mvm
->fw_restart
>= 0)
1008 /* take the return value to make compiler happy - it will fail anyway */
1009 ret
= iwl_mvm_send_cmd_pdu(mvm
, REPLY_ERROR
, 0, 0, NULL
);
1011 mutex_unlock(&mvm
->mutex
);
1016 static ssize_t
iwl_dbgfs_fw_nmi_write(struct iwl_mvm
*mvm
, char *buf
,
1017 size_t count
, loff_t
*ppos
)
1021 if (!iwl_mvm_firmware_running(mvm
))
1024 ret
= iwl_mvm_ref_sync(mvm
, IWL_MVM_REF_NMI
);
1028 iwl_force_nmi(mvm
->trans
);
1030 iwl_mvm_unref(mvm
, IWL_MVM_REF_NMI
);
1036 iwl_dbgfs_scan_ant_rxchain_read(struct file
*file
,
1037 char __user
*user_buf
,
1038 size_t count
, loff_t
*ppos
)
1040 struct iwl_mvm
*mvm
= file
->private_data
;
1043 const size_t bufsz
= sizeof(buf
);
1045 /* print which antennas were set for the scan command by the user */
1046 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Antennas for scan: ");
1047 if (mvm
->scan_rx_ant
& ANT_A
)
1048 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "A");
1049 if (mvm
->scan_rx_ant
& ANT_B
)
1050 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "B");
1051 if (mvm
->scan_rx_ant
& ANT_C
)
1052 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "C");
1053 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, " (%hhx)\n", mvm
->scan_rx_ant
);
1055 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1059 iwl_dbgfs_scan_ant_rxchain_write(struct iwl_mvm
*mvm
, char *buf
,
1060 size_t count
, loff_t
*ppos
)
1064 if (!iwl_mvm_firmware_running(mvm
))
1067 if (sscanf(buf
, "%hhx", &scan_rx_ant
) != 1)
1069 if (scan_rx_ant
> ANT_ABC
)
1071 if (scan_rx_ant
& ~(iwl_mvm_get_valid_rx_ant(mvm
)))
1074 if (mvm
->scan_rx_ant
!= scan_rx_ant
) {
1075 mvm
->scan_rx_ant
= scan_rx_ant
;
1076 if (fw_has_capa(&mvm
->fw
->ucode_capa
,
1077 IWL_UCODE_TLV_CAPA_UMAC_SCAN
))
1078 iwl_mvm_config_scan(mvm
);
1084 static ssize_t
iwl_dbgfs_indirection_tbl_write(struct iwl_mvm
*mvm
,
1085 char *buf
, size_t count
,
1088 struct iwl_rss_config_cmd cmd
= {
1089 .flags
= cpu_to_le32(IWL_RSS_ENABLE
),
1090 .hash_mask
= IWL_RSS_HASH_TYPE_IPV4_TCP
|
1091 IWL_RSS_HASH_TYPE_IPV4_UDP
|
1092 IWL_RSS_HASH_TYPE_IPV4_PAYLOAD
|
1093 IWL_RSS_HASH_TYPE_IPV6_TCP
|
1094 IWL_RSS_HASH_TYPE_IPV6_UDP
|
1095 IWL_RSS_HASH_TYPE_IPV6_PAYLOAD
,
1097 int ret
, i
, num_repeats
, nbytes
= count
/ 2;
1099 ret
= hex2bin(cmd
.indirection_table
, buf
, nbytes
);
1104 * The input is the redirection table, partial or full.
1105 * Repeat the pattern if needed.
1106 * For example, input of 01020F will be repeated 42 times,
1107 * indirecting RSS hash results to queues 1, 2, 15 (skipping
1110 num_repeats
= ARRAY_SIZE(cmd
.indirection_table
) / nbytes
;
1111 for (i
= 1; i
< num_repeats
; i
++)
1112 memcpy(&cmd
.indirection_table
[i
* nbytes
],
1113 cmd
.indirection_table
, nbytes
);
1114 /* handle cut in the middle pattern for the last places */
1115 memcpy(&cmd
.indirection_table
[i
* nbytes
], cmd
.indirection_table
,
1116 ARRAY_SIZE(cmd
.indirection_table
) % nbytes
);
1118 netdev_rss_key_fill(cmd
.secret_key
, sizeof(cmd
.secret_key
));
1120 mutex_lock(&mvm
->mutex
);
1121 if (iwl_mvm_firmware_running(mvm
))
1122 ret
= iwl_mvm_send_cmd_pdu(mvm
, RSS_CONFIG_CMD
, 0,
1126 mutex_unlock(&mvm
->mutex
);
1128 return ret
?: count
;
1131 static ssize_t
iwl_dbgfs_inject_packet_write(struct iwl_mvm
*mvm
,
1132 char *buf
, size_t count
,
1135 struct iwl_rx_cmd_buffer rxb
= {
1136 ._rx_page_order
= 0,
1137 .truesize
= 0, /* not used */
1140 struct iwl_rx_packet
*pkt
;
1141 struct iwl_rx_mpdu_desc
*desc
;
1142 int bin_len
= count
/ 2;
1144 size_t mpdu_cmd_hdr_size
=
1145 (mvm
->trans
->cfg
->device_family
>= IWL_DEVICE_FAMILY_22560
) ?
1146 sizeof(struct iwl_rx_mpdu_desc
) :
1147 IWL_RX_DESC_SIZE_V1
;
1149 if (!iwl_mvm_firmware_running(mvm
))
1152 /* supporting only 9000 descriptor */
1153 if (!mvm
->trans
->cfg
->mq_rx_supported
)
1156 rxb
._page
= alloc_pages(GFP_ATOMIC
, 0);
1159 pkt
= rxb_addr(&rxb
);
1161 ret
= hex2bin(page_address(rxb
._page
), buf
, bin_len
);
1165 /* avoid invalid memory access */
1166 if (bin_len
< sizeof(*pkt
) + mpdu_cmd_hdr_size
)
1169 /* check this is RX packet */
1170 if (WIDE_ID(pkt
->hdr
.group_id
, pkt
->hdr
.cmd
) !=
1171 WIDE_ID(LEGACY_GROUP
, REPLY_RX_MPDU_CMD
))
1174 /* check the length in metadata matches actual received length */
1175 desc
= (void *)pkt
->data
;
1176 if (le16_to_cpu(desc
->mpdu_len
) !=
1177 (bin_len
- mpdu_cmd_hdr_size
- sizeof(*pkt
)))
1181 iwl_mvm_rx_mpdu_mq(mvm
, NULL
, &rxb
, 0);
1188 return ret
?: count
;
1191 static int _iwl_dbgfs_inject_beacon_ie(struct iwl_mvm
*mvm
, char *bin
, int len
)
1193 struct ieee80211_vif
*vif
;
1194 struct iwl_mvm_vif
*mvmvif
;
1195 struct sk_buff
*beacon
;
1196 struct ieee80211_tx_info
*info
;
1197 struct iwl_mac_beacon_cmd beacon_cmd
= {};
1204 /* Element len should be represented by u8 */
1208 if (!iwl_mvm_firmware_running(mvm
))
1211 if (!iwl_mvm_has_new_tx_api(mvm
) &&
1212 !fw_has_api(&mvm
->fw
->ucode_capa
,
1213 IWL_UCODE_TLV_API_NEW_BEACON_TEMPLATE
))
1218 for (i
= 0; i
< NUM_MAC_INDEX_DRIVER
; i
++) {
1219 vif
= iwl_mvm_rcu_dereference_vif_id(mvm
, i
, true);
1223 if (vif
->type
== NL80211_IFTYPE_AP
)
1227 if (i
== NUM_MAC_INDEX_DRIVER
|| !vif
)
1230 mvm
->hw
->extra_beacon_tailroom
= len
;
1232 beacon
= ieee80211_beacon_get_template(mvm
->hw
, vif
, NULL
);
1236 if (len
&& hex2bin(skb_put_zero(beacon
, len
), bin
, len
)) {
1237 dev_kfree_skb(beacon
);
1241 mvm
->beacon_inject_active
= true;
1243 mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
1244 info
= IEEE80211_SKB_CB(beacon
);
1245 rate
= iwl_mvm_mac_ctxt_get_lowest_rate(info
, vif
);
1246 flags
= iwl_mvm_mac80211_idx_to_hwrate(rate
);
1248 if (rate
== IWL_FIRST_CCK_RATE
)
1249 flags
|= IWL_MAC_BEACON_CCK
;
1251 beacon_cmd
.flags
= cpu_to_le16(flags
);
1252 beacon_cmd
.byte_cnt
= cpu_to_le16((u16
)beacon
->len
);
1253 beacon_cmd
.template_id
= cpu_to_le32((u32
)mvmvif
->id
);
1255 iwl_mvm_mac_ctxt_set_tim(mvm
, &beacon_cmd
.tim_idx
,
1256 &beacon_cmd
.tim_size
,
1257 beacon
->data
, beacon
->len
);
1259 mutex_lock(&mvm
->mutex
);
1260 iwl_mvm_mac_ctxt_send_beacon_cmd(mvm
, beacon
, &beacon_cmd
,
1261 sizeof(beacon_cmd
));
1262 mutex_unlock(&mvm
->mutex
);
1264 dev_kfree_skb(beacon
);
1274 static ssize_t
iwl_dbgfs_inject_beacon_ie_write(struct iwl_mvm
*mvm
,
1275 char *buf
, size_t count
,
1278 int ret
= _iwl_dbgfs_inject_beacon_ie(mvm
, buf
, count
);
1280 mvm
->hw
->extra_beacon_tailroom
= 0;
1281 return ret
?: count
;
1284 static ssize_t
iwl_dbgfs_inject_beacon_ie_restore_write(struct iwl_mvm
*mvm
,
1289 int ret
= _iwl_dbgfs_inject_beacon_ie(mvm
, NULL
, 0);
1291 mvm
->hw
->extra_beacon_tailroom
= 0;
1292 mvm
->beacon_inject_active
= false;
1293 return ret
?: count
;
1296 static ssize_t
iwl_dbgfs_fw_dbg_conf_read(struct file
*file
,
1297 char __user
*user_buf
,
1298 size_t count
, loff_t
*ppos
)
1300 struct iwl_mvm
*mvm
= file
->private_data
;
1303 const size_t bufsz
= sizeof(buf
);
1306 mutex_lock(&mvm
->mutex
);
1307 conf
= mvm
->fwrt
.dump
.conf
;
1308 mutex_unlock(&mvm
->mutex
);
1310 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "%d\n", conf
);
1312 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1315 static ssize_t
iwl_dbgfs_fw_dbg_conf_write(struct iwl_mvm
*mvm
,
1316 char *buf
, size_t count
,
1319 unsigned int conf_id
;
1322 if (!iwl_mvm_firmware_running(mvm
))
1325 ret
= kstrtouint(buf
, 0, &conf_id
);
1329 if (WARN_ON(conf_id
>= FW_DBG_CONF_MAX
))
1332 mutex_lock(&mvm
->mutex
);
1333 ret
= iwl_fw_start_dbg_conf(&mvm
->fwrt
, conf_id
);
1334 mutex_unlock(&mvm
->mutex
);
1336 return ret
?: count
;
1339 static ssize_t
iwl_dbgfs_fw_dbg_collect_write(struct iwl_mvm
*mvm
,
1340 char *buf
, size_t count
,
1345 ret
= iwl_mvm_ref_sync(mvm
, IWL_MVM_REF_PRPH_WRITE
);
1351 iwl_fw_dbg_collect(&mvm
->fwrt
, FW_DBG_TRIGGER_USER
, buf
,
1354 iwl_mvm_unref(mvm
, IWL_MVM_REF_PRPH_WRITE
);
1359 static ssize_t
iwl_dbgfs_max_amsdu_len_write(struct iwl_mvm
*mvm
,
1360 char *buf
, size_t count
,
1363 unsigned int max_amsdu_len
;
1366 ret
= kstrtouint(buf
, 0, &max_amsdu_len
);
1370 if (max_amsdu_len
> IEEE80211_MAX_MPDU_LEN_VHT_11454
)
1372 mvm
->max_amsdu_len
= max_amsdu_len
;
1377 #define ADD_TEXT(...) pos += scnprintf(buf + pos, bufsz - pos, __VA_ARGS__)
1378 #ifdef CONFIG_IWLWIFI_BCAST_FILTERING
1379 static ssize_t
iwl_dbgfs_bcast_filters_read(struct file
*file
,
1380 char __user
*user_buf
,
1381 size_t count
, loff_t
*ppos
)
1383 struct iwl_mvm
*mvm
= file
->private_data
;
1384 struct iwl_bcast_filter_cmd cmd
;
1385 const struct iwl_fw_bcast_filter
*filter
;
1391 buf
= kzalloc(bufsz
, GFP_KERNEL
);
1395 mutex_lock(&mvm
->mutex
);
1396 if (!iwl_mvm_bcast_filter_build_cmd(mvm
, &cmd
)) {
1398 mutex_unlock(&mvm
->mutex
);
1401 mutex_unlock(&mvm
->mutex
);
1403 for (i
= 0; cmd
.filters
[i
].attrs
[0].mask
; i
++) {
1404 filter
= &cmd
.filters
[i
];
1406 ADD_TEXT("Filter [%d]:\n", i
);
1407 ADD_TEXT("\tDiscard=%d\n", filter
->discard
);
1408 ADD_TEXT("\tFrame Type: %s\n",
1409 filter
->frame_type
? "IPv4" : "Generic");
1411 for (j
= 0; j
< ARRAY_SIZE(filter
->attrs
); j
++) {
1412 const struct iwl_fw_bcast_filter_attr
*attr
;
1414 attr
= &filter
->attrs
[j
];
1418 ADD_TEXT("\tAttr [%d]: offset=%d (from %s), mask=0x%x, value=0x%x reserved=0x%x\n",
1420 attr
->offset_type
? "IP End" :
1422 be32_to_cpu(attr
->mask
),
1423 be32_to_cpu(attr
->val
),
1424 le16_to_cpu(attr
->reserved1
));
1428 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1433 static ssize_t
iwl_dbgfs_bcast_filters_write(struct iwl_mvm
*mvm
, char *buf
,
1434 size_t count
, loff_t
*ppos
)
1437 struct iwl_fw_bcast_filter filter
= {};
1438 struct iwl_bcast_filter_cmd cmd
;
1439 u32 filter_id
, attr_id
, mask
, value
;
1442 if (sscanf(buf
, "%d %hhi %hhi %n", &filter_id
, &filter
.discard
,
1443 &filter
.frame_type
, &pos
) != 3)
1446 if (filter_id
>= ARRAY_SIZE(mvm
->dbgfs_bcast_filtering
.cmd
.filters
) ||
1447 filter
.frame_type
> BCAST_FILTER_FRAME_TYPE_IPV4
)
1450 for (attr_id
= 0; attr_id
< ARRAY_SIZE(filter
.attrs
);
1452 struct iwl_fw_bcast_filter_attr
*attr
=
1453 &filter
.attrs
[attr_id
];
1458 if (sscanf(&buf
[pos
], "%hhi %hhi %i %i %n",
1459 &attr
->offset
, &attr
->offset_type
,
1460 &mask
, &value
, &next_pos
) != 4)
1463 attr
->mask
= cpu_to_be32(mask
);
1464 attr
->val
= cpu_to_be32(value
);
1471 mutex_lock(&mvm
->mutex
);
1472 memcpy(&mvm
->dbgfs_bcast_filtering
.cmd
.filters
[filter_id
],
1473 &filter
, sizeof(filter
));
1475 /* send updated bcast filtering configuration */
1476 if (iwl_mvm_firmware_running(mvm
) &&
1477 mvm
->dbgfs_bcast_filtering
.override
&&
1478 iwl_mvm_bcast_filter_build_cmd(mvm
, &cmd
))
1479 err
= iwl_mvm_send_cmd_pdu(mvm
, BCAST_FILTER_CMD
, 0,
1481 mutex_unlock(&mvm
->mutex
);
1483 return err
?: count
;
1486 static ssize_t
iwl_dbgfs_bcast_filters_macs_read(struct file
*file
,
1487 char __user
*user_buf
,
1488 size_t count
, loff_t
*ppos
)
1490 struct iwl_mvm
*mvm
= file
->private_data
;
1491 struct iwl_bcast_filter_cmd cmd
;
1497 buf
= kzalloc(bufsz
, GFP_KERNEL
);
1501 mutex_lock(&mvm
->mutex
);
1502 if (!iwl_mvm_bcast_filter_build_cmd(mvm
, &cmd
)) {
1504 mutex_unlock(&mvm
->mutex
);
1507 mutex_unlock(&mvm
->mutex
);
1509 for (i
= 0; i
< ARRAY_SIZE(cmd
.macs
); i
++) {
1510 const struct iwl_fw_bcast_mac
*mac
= &cmd
.macs
[i
];
1512 ADD_TEXT("Mac [%d]: discard=%d attached_filters=0x%x\n",
1513 i
, mac
->default_discard
, mac
->attached_filters
);
1516 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1521 static ssize_t
iwl_dbgfs_bcast_filters_macs_write(struct iwl_mvm
*mvm
,
1522 char *buf
, size_t count
,
1525 struct iwl_bcast_filter_cmd cmd
;
1526 struct iwl_fw_bcast_mac mac
= {};
1527 u32 mac_id
, attached_filters
;
1530 if (!mvm
->bcast_filters
)
1533 if (sscanf(buf
, "%d %hhi %i", &mac_id
, &mac
.default_discard
,
1534 &attached_filters
) != 3)
1537 if (mac_id
>= ARRAY_SIZE(cmd
.macs
) ||
1538 mac
.default_discard
> 1 ||
1539 attached_filters
>= BIT(ARRAY_SIZE(cmd
.filters
)))
1542 mac
.attached_filters
= cpu_to_le16(attached_filters
);
1544 mutex_lock(&mvm
->mutex
);
1545 memcpy(&mvm
->dbgfs_bcast_filtering
.cmd
.macs
[mac_id
],
1548 /* send updated bcast filtering configuration */
1549 if (iwl_mvm_firmware_running(mvm
) &&
1550 mvm
->dbgfs_bcast_filtering
.override
&&
1551 iwl_mvm_bcast_filter_build_cmd(mvm
, &cmd
))
1552 err
= iwl_mvm_send_cmd_pdu(mvm
, BCAST_FILTER_CMD
, 0,
1554 mutex_unlock(&mvm
->mutex
);
1556 return err
?: count
;
1560 #ifdef CONFIG_PM_SLEEP
1561 static ssize_t
iwl_dbgfs_d3_sram_write(struct iwl_mvm
*mvm
, char *buf
,
1562 size_t count
, loff_t
*ppos
)
1566 if (sscanf(buf
, "%d", &store
) != 1)
1569 mvm
->store_d3_resume_sram
= store
;
1574 static ssize_t
iwl_dbgfs_d3_sram_read(struct file
*file
, char __user
*user_buf
,
1575 size_t count
, loff_t
*ppos
)
1577 struct iwl_mvm
*mvm
= file
->private_data
;
1578 const struct fw_img
*img
;
1579 int ofs
, len
, pos
= 0;
1582 u8
*ptr
= mvm
->d3_resume_sram
;
1584 img
= &mvm
->fw
->img
[IWL_UCODE_WOWLAN
];
1585 len
= img
->sec
[IWL_UCODE_SECTION_DATA
].len
;
1587 bufsz
= len
* 4 + 256;
1588 buf
= kzalloc(bufsz
, GFP_KERNEL
);
1592 pos
+= scnprintf(buf
, bufsz
, "D3 SRAM capture: %sabled\n",
1593 mvm
->store_d3_resume_sram
? "en" : "dis");
1596 for (ofs
= 0; ofs
< len
; ofs
+= 16) {
1597 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1598 "0x%.4x %16ph\n", ofs
, ptr
+ ofs
);
1601 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1602 "(no data captured)\n");
1605 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1613 #define PRINT_MVM_REF(ref) do { \
1614 if (mvm->refs[ref]) \
1615 pos += scnprintf(buf + pos, bufsz - pos, \
1616 "\t(0x%lx): %d %s\n", \
1617 BIT(ref), mvm->refs[ref], #ref); \
1620 static ssize_t
iwl_dbgfs_d0i3_refs_read(struct file
*file
,
1621 char __user
*user_buf
,
1622 size_t count
, loff_t
*ppos
)
1624 struct iwl_mvm
*mvm
= file
->private_data
;
1627 const size_t bufsz
= sizeof(buf
);
1630 for (i
= 0; i
< IWL_MVM_REF_COUNT
; i
++)
1634 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "taken mvm refs: 0x%x\n",
1637 PRINT_MVM_REF(IWL_MVM_REF_UCODE_DOWN
);
1638 PRINT_MVM_REF(IWL_MVM_REF_SCAN
);
1639 PRINT_MVM_REF(IWL_MVM_REF_ROC
);
1640 PRINT_MVM_REF(IWL_MVM_REF_ROC_AUX
);
1641 PRINT_MVM_REF(IWL_MVM_REF_P2P_CLIENT
);
1642 PRINT_MVM_REF(IWL_MVM_REF_AP_IBSS
);
1643 PRINT_MVM_REF(IWL_MVM_REF_USER
);
1644 PRINT_MVM_REF(IWL_MVM_REF_TX
);
1645 PRINT_MVM_REF(IWL_MVM_REF_TX_AGG
);
1646 PRINT_MVM_REF(IWL_MVM_REF_ADD_IF
);
1647 PRINT_MVM_REF(IWL_MVM_REF_START_AP
);
1648 PRINT_MVM_REF(IWL_MVM_REF_BSS_CHANGED
);
1649 PRINT_MVM_REF(IWL_MVM_REF_PREPARE_TX
);
1650 PRINT_MVM_REF(IWL_MVM_REF_PROTECT_TDLS
);
1651 PRINT_MVM_REF(IWL_MVM_REF_CHECK_CTKILL
);
1652 PRINT_MVM_REF(IWL_MVM_REF_PRPH_READ
);
1653 PRINT_MVM_REF(IWL_MVM_REF_PRPH_WRITE
);
1654 PRINT_MVM_REF(IWL_MVM_REF_NMI
);
1655 PRINT_MVM_REF(IWL_MVM_REF_TM_CMD
);
1656 PRINT_MVM_REF(IWL_MVM_REF_EXIT_WORK
);
1657 PRINT_MVM_REF(IWL_MVM_REF_PROTECT_CSA
);
1658 PRINT_MVM_REF(IWL_MVM_REF_FW_DBG_COLLECT
);
1659 PRINT_MVM_REF(IWL_MVM_REF_INIT_UCODE
);
1660 PRINT_MVM_REF(IWL_MVM_REF_SENDING_CMD
);
1661 PRINT_MVM_REF(IWL_MVM_REF_RX
);
1663 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1666 static ssize_t
iwl_dbgfs_d0i3_refs_write(struct iwl_mvm
*mvm
, char *buf
,
1667 size_t count
, loff_t
*ppos
)
1669 unsigned long value
;
1673 ret
= kstrtoul(buf
, 10, &value
);
1677 mutex_lock(&mvm
->mutex
);
1679 taken
= mvm
->refs
[IWL_MVM_REF_USER
];
1680 if (value
== 1 && !taken
)
1681 iwl_mvm_ref(mvm
, IWL_MVM_REF_USER
);
1682 else if (value
== 0 && taken
)
1683 iwl_mvm_unref(mvm
, IWL_MVM_REF_USER
);
1687 mutex_unlock(&mvm
->mutex
);
1694 #define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \
1695 _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm)
1696 #define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
1697 _MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm)
1698 #define MVM_DEBUGFS_ADD_FILE_ALIAS(alias, name, parent, mode) do { \
1699 debugfs_create_file(alias, mode, parent, mvm, \
1700 &iwl_dbgfs_##name##_ops); \
1702 #define MVM_DEBUGFS_ADD_FILE(name, parent, mode) \
1703 MVM_DEBUGFS_ADD_FILE_ALIAS(#name, name, parent, mode)
1705 #define MVM_DEBUGFS_WRITE_STA_FILE_OPS(name, bufsz) \
1706 _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct ieee80211_sta)
1707 #define MVM_DEBUGFS_READ_WRITE_STA_FILE_OPS(name, bufsz) \
1708 _MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct ieee80211_sta)
1710 #define MVM_DEBUGFS_ADD_STA_FILE_ALIAS(alias, name, parent, mode) do { \
1711 debugfs_create_file(alias, mode, parent, sta, \
1712 &iwl_dbgfs_##name##_ops); \
1714 #define MVM_DEBUGFS_ADD_STA_FILE(name, parent, mode) \
1715 MVM_DEBUGFS_ADD_STA_FILE_ALIAS(#name, name, parent, mode)
1718 iwl_dbgfs_prph_reg_read(struct file
*file
,
1719 char __user
*user_buf
,
1720 size_t count
, loff_t
*ppos
)
1722 struct iwl_mvm
*mvm
= file
->private_data
;
1725 const size_t bufsz
= sizeof(buf
);
1728 if (!mvm
->dbgfs_prph_reg_addr
)
1731 ret
= iwl_mvm_ref_sync(mvm
, IWL_MVM_REF_PRPH_READ
);
1735 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Reg 0x%x: (0x%x)\n",
1736 mvm
->dbgfs_prph_reg_addr
,
1737 iwl_read_prph(mvm
->trans
, mvm
->dbgfs_prph_reg_addr
));
1739 iwl_mvm_unref(mvm
, IWL_MVM_REF_PRPH_READ
);
1741 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1745 iwl_dbgfs_prph_reg_write(struct iwl_mvm
*mvm
, char *buf
,
1746 size_t count
, loff_t
*ppos
)
1752 args
= sscanf(buf
, "%i %i", &mvm
->dbgfs_prph_reg_addr
, &value
);
1753 /* if we only want to set the reg address - nothing more to do */
1757 /* otherwise, make sure we have both address and value */
1761 ret
= iwl_mvm_ref_sync(mvm
, IWL_MVM_REF_PRPH_WRITE
);
1765 iwl_write_prph(mvm
->trans
, mvm
->dbgfs_prph_reg_addr
, value
);
1767 iwl_mvm_unref(mvm
, IWL_MVM_REF_PRPH_WRITE
);
1773 iwl_dbgfs_send_echo_cmd_write(struct iwl_mvm
*mvm
, char *buf
,
1774 size_t count
, loff_t
*ppos
)
1778 if (!iwl_mvm_firmware_running(mvm
))
1781 mutex_lock(&mvm
->mutex
);
1782 ret
= iwl_mvm_send_cmd_pdu(mvm
, ECHO_CMD
, 0, 0, NULL
);
1783 mutex_unlock(&mvm
->mutex
);
1785 return ret
?: count
;
1788 struct iwl_mvm_sniffer_apply
{
1789 struct iwl_mvm
*mvm
;
1794 static bool iwl_mvm_sniffer_apply(struct iwl_notif_wait_data
*notif_data
,
1795 struct iwl_rx_packet
*pkt
, void *data
)
1797 struct iwl_mvm_sniffer_apply
*apply
= data
;
1799 apply
->mvm
->cur_aid
= cpu_to_le16(apply
->aid
);
1800 memcpy(apply
->mvm
->cur_bssid
, apply
->bssid
,
1801 sizeof(apply
->mvm
->cur_bssid
));
1807 iwl_dbgfs_he_sniffer_params_write(struct iwl_mvm
*mvm
, char *buf
,
1808 size_t count
, loff_t
*ppos
)
1810 struct iwl_notification_wait wait
;
1811 struct iwl_he_monitor_cmd he_mon_cmd
= {};
1812 struct iwl_mvm_sniffer_apply apply
= {
1816 iwl_cmd_id(HE_AIR_SNIFFER_CONFIG_CMD
, DATA_PATH_GROUP
, 0),
1821 if (!iwl_mvm_firmware_running(mvm
))
1824 ret
= sscanf(buf
, "%x %2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx", &aid
,
1825 &he_mon_cmd
.bssid
[0], &he_mon_cmd
.bssid
[1],
1826 &he_mon_cmd
.bssid
[2], &he_mon_cmd
.bssid
[3],
1827 &he_mon_cmd
.bssid
[4], &he_mon_cmd
.bssid
[5]);
1831 he_mon_cmd
.aid
= cpu_to_le16(aid
);
1834 apply
.bssid
= (void *)he_mon_cmd
.bssid
;
1836 mutex_lock(&mvm
->mutex
);
1839 * Use the notification waiter to get our function triggered
1840 * in sequence with other RX. This ensures that frames we get
1841 * on the RX queue _before_ the new configuration is applied
1842 * still have mvm->cur_aid pointing to the old AID, and that
1843 * frames on the RX queue _after_ the firmware processed the
1844 * new configuration (and sent the response, synchronously)
1845 * get mvm->cur_aid correctly set to the new AID.
1847 iwl_init_notification_wait(&mvm
->notif_wait
, &wait
,
1848 wait_cmds
, ARRAY_SIZE(wait_cmds
),
1849 iwl_mvm_sniffer_apply
, &apply
);
1851 ret
= iwl_mvm_send_cmd_pdu(mvm
, iwl_cmd_id(HE_AIR_SNIFFER_CONFIG_CMD
,
1852 DATA_PATH_GROUP
, 0), 0,
1853 sizeof(he_mon_cmd
), &he_mon_cmd
);
1855 /* no need to really wait, we already did anyway */
1856 iwl_remove_notification(&mvm
->notif_wait
, &wait
);
1858 mutex_unlock(&mvm
->mutex
);
1860 return ret
?: count
;
1864 iwl_dbgfs_he_sniffer_params_read(struct file
*file
, char __user
*user_buf
,
1865 size_t count
, loff_t
*ppos
)
1867 struct iwl_mvm
*mvm
= file
->private_data
;
1871 len
= scnprintf(buf
, sizeof(buf
),
1872 "%d %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n",
1873 le16_to_cpu(mvm
->cur_aid
), mvm
->cur_bssid
[0],
1874 mvm
->cur_bssid
[1], mvm
->cur_bssid
[2], mvm
->cur_bssid
[3],
1875 mvm
->cur_bssid
[4], mvm
->cur_bssid
[5]);
1877 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
1881 iwl_dbgfs_uapsd_noagg_bssids_read(struct file
*file
, char __user
*user_buf
,
1882 size_t count
, loff_t
*ppos
)
1884 struct iwl_mvm
*mvm
= file
->private_data
;
1885 u8 buf
[IWL_MVM_UAPSD_NOAGG_BSSIDS_NUM
* ETH_ALEN
* 3 + 1];
1886 unsigned int pos
= 0;
1887 size_t bufsz
= sizeof(buf
);
1890 mutex_lock(&mvm
->mutex
);
1892 for (i
= 0; i
< IWL_MVM_UAPSD_NOAGG_LIST_LEN
; i
++)
1893 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "%pM\n",
1894 mvm
->uapsd_noagg_bssids
[i
].addr
);
1896 mutex_unlock(&mvm
->mutex
);
1898 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1901 MVM_DEBUGFS_READ_WRITE_FILE_OPS(prph_reg
, 64);
1903 /* Device wide debugfs entries */
1904 MVM_DEBUGFS_READ_FILE_OPS(ctdp_budget
);
1905 MVM_DEBUGFS_WRITE_FILE_OPS(stop_ctdp
, 8);
1906 MVM_DEBUGFS_WRITE_FILE_OPS(force_ctkill
, 8);
1907 MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush
, 16);
1908 MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain
, 8);
1909 MVM_DEBUGFS_WRITE_FILE_OPS(send_echo_cmd
, 8);
1910 MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram
, 64);
1911 MVM_DEBUGFS_READ_WRITE_FILE_OPS(set_nic_temperature
, 64);
1912 MVM_DEBUGFS_READ_FILE_OPS(nic_temp
);
1913 MVM_DEBUGFS_READ_FILE_OPS(stations
);
1914 MVM_DEBUGFS_READ_FILE_OPS(rs_data
);
1915 MVM_DEBUGFS_READ_FILE_OPS(bt_notif
);
1916 MVM_DEBUGFS_READ_FILE_OPS(bt_cmd
);
1917 MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off
, 64);
1918 MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats
);
1919 MVM_DEBUGFS_READ_FILE_OPS(drv_rx_stats
);
1920 MVM_DEBUGFS_READ_FILE_OPS(fw_ver
);
1921 MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart
, 10);
1922 MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi
, 10);
1923 MVM_DEBUGFS_WRITE_FILE_OPS(bt_tx_prio
, 10);
1924 MVM_DEBUGFS_WRITE_FILE_OPS(bt_force_ant
, 10);
1925 MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain
, 8);
1926 MVM_DEBUGFS_READ_WRITE_FILE_OPS(d0i3_refs
, 8);
1927 MVM_DEBUGFS_READ_WRITE_FILE_OPS(fw_dbg_conf
, 8);
1928 MVM_DEBUGFS_WRITE_FILE_OPS(fw_dbg_collect
, 64);
1929 MVM_DEBUGFS_WRITE_FILE_OPS(max_amsdu_len
, 8);
1930 MVM_DEBUGFS_WRITE_FILE_OPS(indirection_tbl
,
1931 (IWL_RSS_INDIRECTION_TABLE_SIZE
* 2));
1932 MVM_DEBUGFS_WRITE_FILE_OPS(inject_packet
, 512);
1933 MVM_DEBUGFS_WRITE_FILE_OPS(inject_beacon_ie
, 512);
1934 MVM_DEBUGFS_WRITE_FILE_OPS(inject_beacon_ie_restore
, 512);
1936 MVM_DEBUGFS_READ_FILE_OPS(uapsd_noagg_bssids
);
1938 #ifdef CONFIG_IWLWIFI_BCAST_FILTERING
1939 MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters
, 256);
1940 MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters_macs
, 256);
1943 #ifdef CONFIG_PM_SLEEP
1944 MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram
, 8);
1947 MVM_DEBUGFS_READ_FILE_OPS(sar_geo_profile
);
1950 MVM_DEBUGFS_READ_WRITE_FILE_OPS(he_sniffer_params
, 32);
1952 static ssize_t
iwl_dbgfs_mem_read(struct file
*file
, char __user
*user_buf
,
1953 size_t count
, loff_t
*ppos
)
1955 struct iwl_mvm
*mvm
= file
->private_data
;
1956 struct iwl_dbg_mem_access_cmd cmd
= {};
1957 struct iwl_dbg_mem_access_rsp
*rsp
;
1958 struct iwl_host_cmd hcmd
= {
1959 .flags
= CMD_WANT_SKB
| CMD_SEND_IN_RFKILL
,
1961 .len
= { sizeof(cmd
) },
1966 if (!iwl_mvm_firmware_running(mvm
))
1969 hcmd
.id
= iwl_cmd_id(*ppos
>> 24 ? UMAC_RD_WR
: LMAC_RD_WR
,
1971 cmd
.op
= cpu_to_le32(DEBUG_MEM_OP_READ
);
1973 /* Take care of alignment of both the position and the length */
1974 delta
= *ppos
& 0x3;
1975 cmd
.addr
= cpu_to_le32(*ppos
- delta
);
1976 cmd
.len
= cpu_to_le32(min(ALIGN(count
+ delta
, 4) / 4,
1977 (size_t)DEBUG_MEM_MAX_SIZE_DWORDS
));
1979 mutex_lock(&mvm
->mutex
);
1980 ret
= iwl_mvm_send_cmd(mvm
, &hcmd
);
1981 mutex_unlock(&mvm
->mutex
);
1986 rsp
= (void *)hcmd
.resp_pkt
->data
;
1987 if (le32_to_cpu(rsp
->status
) != DEBUG_MEM_STATUS_SUCCESS
) {
1992 len
= min((size_t)le32_to_cpu(rsp
->len
) << 2,
1993 iwl_rx_packet_payload_len(hcmd
.resp_pkt
) - sizeof(*rsp
));
1994 len
= min(len
- delta
, count
);
2000 ret
= len
- copy_to_user(user_buf
, (void *)rsp
->data
+ delta
, len
);
2004 iwl_free_resp(&hcmd
);
2008 static ssize_t
iwl_dbgfs_mem_write(struct file
*file
,
2009 const char __user
*user_buf
, size_t count
,
2012 struct iwl_mvm
*mvm
= file
->private_data
;
2013 struct iwl_dbg_mem_access_cmd
*cmd
;
2014 struct iwl_dbg_mem_access_rsp
*rsp
;
2015 struct iwl_host_cmd hcmd
= {};
2021 if (!iwl_mvm_firmware_running(mvm
))
2024 hcmd
.id
= iwl_cmd_id(*ppos
>> 24 ? UMAC_RD_WR
: LMAC_RD_WR
,
2027 if (*ppos
& 0x3 || count
< 4) {
2028 op
= DEBUG_MEM_OP_WRITE_BYTES
;
2029 len
= min(count
, (size_t)(4 - (*ppos
& 0x3)));
2032 op
= DEBUG_MEM_OP_WRITE
;
2033 len
= min(count
>> 2, (size_t)DEBUG_MEM_MAX_SIZE_DWORDS
);
2034 data_size
= len
<< 2;
2037 cmd_size
= sizeof(*cmd
) + ALIGN(data_size
, 4);
2038 cmd
= kzalloc(cmd_size
, GFP_KERNEL
);
2042 cmd
->op
= cpu_to_le32(op
);
2043 cmd
->len
= cpu_to_le32(len
);
2044 cmd
->addr
= cpu_to_le32(*ppos
);
2045 if (copy_from_user((void *)cmd
->data
, user_buf
, data_size
)) {
2050 hcmd
.flags
= CMD_WANT_SKB
| CMD_SEND_IN_RFKILL
,
2051 hcmd
.data
[0] = (void *)cmd
;
2052 hcmd
.len
[0] = cmd_size
;
2054 mutex_lock(&mvm
->mutex
);
2055 ret
= iwl_mvm_send_cmd(mvm
, &hcmd
);
2056 mutex_unlock(&mvm
->mutex
);
2063 rsp
= (void *)hcmd
.resp_pkt
->data
;
2064 if (rsp
->status
!= DEBUG_MEM_STATUS_SUCCESS
) {
2073 iwl_free_resp(&hcmd
);
2077 static const struct file_operations iwl_dbgfs_mem_ops
= {
2078 .read
= iwl_dbgfs_mem_read
,
2079 .write
= iwl_dbgfs_mem_write
,
2080 .open
= simple_open
,
2081 .llseek
= default_llseek
,
2084 void iwl_mvm_sta_add_debugfs(struct ieee80211_hw
*hw
,
2085 struct ieee80211_vif
*vif
,
2086 struct ieee80211_sta
*sta
,
2089 struct iwl_mvm
*mvm
= IWL_MAC80211_GET_MVM(hw
);
2091 if (iwl_mvm_has_tlc_offload(mvm
))
2092 MVM_DEBUGFS_ADD_STA_FILE(rs_data
, dir
, 0400);
2095 void iwl_mvm_dbgfs_register(struct iwl_mvm
*mvm
, struct dentry
*dbgfs_dir
)
2097 struct dentry
*bcast_dir __maybe_unused
;
2100 spin_lock_init(&mvm
->drv_stats_lock
);
2102 mvm
->debugfs_dir
= dbgfs_dir
;
2104 MVM_DEBUGFS_ADD_FILE(tx_flush
, mvm
->debugfs_dir
, 0200);
2105 MVM_DEBUGFS_ADD_FILE(sta_drain
, mvm
->debugfs_dir
, 0200);
2106 MVM_DEBUGFS_ADD_FILE(sram
, mvm
->debugfs_dir
, 0600);
2107 MVM_DEBUGFS_ADD_FILE(set_nic_temperature
, mvm
->debugfs_dir
, 0600);
2108 MVM_DEBUGFS_ADD_FILE(nic_temp
, dbgfs_dir
, 0400);
2109 MVM_DEBUGFS_ADD_FILE(ctdp_budget
, dbgfs_dir
, 0400);
2110 MVM_DEBUGFS_ADD_FILE(stop_ctdp
, dbgfs_dir
, 0200);
2111 MVM_DEBUGFS_ADD_FILE(force_ctkill
, dbgfs_dir
, 0200);
2112 MVM_DEBUGFS_ADD_FILE(stations
, dbgfs_dir
, 0400);
2113 MVM_DEBUGFS_ADD_FILE(bt_notif
, dbgfs_dir
, 0400);
2114 MVM_DEBUGFS_ADD_FILE(bt_cmd
, dbgfs_dir
, 0400);
2115 MVM_DEBUGFS_ADD_FILE(disable_power_off
, mvm
->debugfs_dir
, 0600);
2116 MVM_DEBUGFS_ADD_FILE(fw_ver
, mvm
->debugfs_dir
, 0400);
2117 MVM_DEBUGFS_ADD_FILE(fw_rx_stats
, mvm
->debugfs_dir
, 0400);
2118 MVM_DEBUGFS_ADD_FILE(drv_rx_stats
, mvm
->debugfs_dir
, 0400);
2119 MVM_DEBUGFS_ADD_FILE(fw_restart
, mvm
->debugfs_dir
, 0200);
2120 MVM_DEBUGFS_ADD_FILE(fw_nmi
, mvm
->debugfs_dir
, 0200);
2121 MVM_DEBUGFS_ADD_FILE(bt_tx_prio
, mvm
->debugfs_dir
, 0200);
2122 MVM_DEBUGFS_ADD_FILE(bt_force_ant
, mvm
->debugfs_dir
, 0200);
2123 MVM_DEBUGFS_ADD_FILE(scan_ant_rxchain
, mvm
->debugfs_dir
, 0600);
2124 MVM_DEBUGFS_ADD_FILE(prph_reg
, mvm
->debugfs_dir
, 0600);
2125 MVM_DEBUGFS_ADD_FILE(d0i3_refs
, mvm
->debugfs_dir
, 0600);
2126 MVM_DEBUGFS_ADD_FILE(fw_dbg_conf
, mvm
->debugfs_dir
, 0600);
2127 MVM_DEBUGFS_ADD_FILE(fw_dbg_collect
, mvm
->debugfs_dir
, 0200);
2128 MVM_DEBUGFS_ADD_FILE(max_amsdu_len
, mvm
->debugfs_dir
, 0200);
2129 MVM_DEBUGFS_ADD_FILE(send_echo_cmd
, mvm
->debugfs_dir
, 0200);
2130 MVM_DEBUGFS_ADD_FILE(indirection_tbl
, mvm
->debugfs_dir
, 0200);
2131 MVM_DEBUGFS_ADD_FILE(inject_packet
, mvm
->debugfs_dir
, 0200);
2132 MVM_DEBUGFS_ADD_FILE(inject_beacon_ie
, mvm
->debugfs_dir
, 0200);
2133 MVM_DEBUGFS_ADD_FILE(inject_beacon_ie_restore
, mvm
->debugfs_dir
, 0200);
2135 MVM_DEBUGFS_ADD_FILE(sar_geo_profile
, dbgfs_dir
, 0400);
2137 MVM_DEBUGFS_ADD_FILE(he_sniffer_params
, mvm
->debugfs_dir
, 0600);
2139 debugfs_create_bool("enable_scan_iteration_notif", 0600,
2140 mvm
->debugfs_dir
, &mvm
->scan_iter_notif_enabled
);
2141 debugfs_create_bool("drop_bcn_ap_mode", 0600, mvm
->debugfs_dir
,
2142 &mvm
->drop_bcn_ap_mode
);
2144 MVM_DEBUGFS_ADD_FILE(uapsd_noagg_bssids
, mvm
->debugfs_dir
, S_IRUSR
);
2146 #ifdef CONFIG_IWLWIFI_BCAST_FILTERING
2147 if (mvm
->fw
->ucode_capa
.flags
& IWL_UCODE_TLV_FLAGS_BCAST_FILTERING
) {
2148 bcast_dir
= debugfs_create_dir("bcast_filtering",
2151 debugfs_create_bool("override", 0600, bcast_dir
,
2152 &mvm
->dbgfs_bcast_filtering
.override
);
2154 MVM_DEBUGFS_ADD_FILE_ALIAS("filters", bcast_filters
,
2156 MVM_DEBUGFS_ADD_FILE_ALIAS("macs", bcast_filters_macs
,
2161 #ifdef CONFIG_PM_SLEEP
2162 MVM_DEBUGFS_ADD_FILE(d3_sram
, mvm
->debugfs_dir
, 0600);
2163 MVM_DEBUGFS_ADD_FILE(d3_test
, mvm
->debugfs_dir
, 0400);
2164 debugfs_create_bool("d3_wake_sysassert", 0600, mvm
->debugfs_dir
,
2165 &mvm
->d3_wake_sysassert
);
2166 debugfs_create_u32("last_netdetect_scans", 0400, mvm
->debugfs_dir
,
2167 &mvm
->last_netdetect_scans
);
2170 debugfs_create_u8("ps_disabled", 0400, mvm
->debugfs_dir
,
2172 debugfs_create_blob("nvm_hw", 0400, mvm
->debugfs_dir
,
2174 debugfs_create_blob("nvm_sw", 0400, mvm
->debugfs_dir
,
2176 debugfs_create_blob("nvm_calib", 0400, mvm
->debugfs_dir
,
2177 &mvm
->nvm_calib_blob
);
2178 debugfs_create_blob("nvm_prod", 0400, mvm
->debugfs_dir
,
2179 &mvm
->nvm_prod_blob
);
2180 debugfs_create_blob("nvm_phy_sku", 0400, mvm
->debugfs_dir
,
2181 &mvm
->nvm_phy_sku_blob
);
2182 debugfs_create_blob("nvm_reg", S_IRUSR
,
2183 mvm
->debugfs_dir
, &mvm
->nvm_reg_blob
);
2185 debugfs_create_file("mem", 0600, dbgfs_dir
, mvm
, &iwl_dbgfs_mem_ops
);
2188 * Create a symlink with mac80211. It will be removed when mac80211
2189 * exists (before the opmode exists which removes the target.)
2191 snprintf(buf
, 100, "../../%pd2", dbgfs_dir
->d_parent
);
2192 debugfs_create_symlink("iwlwifi", mvm
->hw
->wiphy
->debugfsdir
, buf
);