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.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
24 * The full GNU General Public License is included in this distribution
25 * in the file called COPYING.
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved.
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62 *****************************************************************************/
69 static ssize_t
iwl_dbgfs_tx_flush_write(struct iwl_mvm
*mvm
, char *buf
,
70 size_t count
, loff_t
*ppos
)
75 if (!mvm
->ucode_loaded
|| mvm
->cur_ucode
!= IWL_UCODE_REGULAR
)
78 if (sscanf(buf
, "%x", &scd_q_msk
) != 1)
81 IWL_ERR(mvm
, "FLUSHING queues: scd_q_msk = 0x%x\n", scd_q_msk
);
83 mutex_lock(&mvm
->mutex
);
84 ret
= iwl_mvm_flush_tx_path(mvm
, scd_q_msk
, true) ? : count
;
85 mutex_unlock(&mvm
->mutex
);
90 static ssize_t
iwl_dbgfs_sta_drain_write(struct iwl_mvm
*mvm
, char *buf
,
91 size_t count
, loff_t
*ppos
)
93 struct ieee80211_sta
*sta
;
94 int sta_id
, drain
, ret
;
96 if (!mvm
->ucode_loaded
|| mvm
->cur_ucode
!= IWL_UCODE_REGULAR
)
99 if (sscanf(buf
, "%d %d", &sta_id
, &drain
) != 2)
101 if (sta_id
< 0 || sta_id
>= IWL_MVM_STATION_COUNT
)
103 if (drain
< 0 || drain
> 1)
106 mutex_lock(&mvm
->mutex
);
108 sta
= rcu_dereference_protected(mvm
->fw_id_to_mac_id
[sta_id
],
109 lockdep_is_held(&mvm
->mutex
));
110 if (IS_ERR_OR_NULL(sta
))
113 ret
= iwl_mvm_drain_sta(mvm
, (void *)sta
->drv_priv
, drain
) ? :
116 mutex_unlock(&mvm
->mutex
);
121 static ssize_t
iwl_dbgfs_sram_read(struct file
*file
, char __user
*user_buf
,
122 size_t count
, loff_t
*ppos
)
124 struct iwl_mvm
*mvm
= file
->private_data
;
125 const struct fw_img
*img
;
126 unsigned int ofs
, len
;
130 if (!mvm
->ucode_loaded
)
133 /* default is to dump the entire data segment */
134 img
= &mvm
->fw
->img
[mvm
->cur_ucode
];
135 ofs
= img
->sec
[IWL_UCODE_SECTION_DATA
].offset
;
136 len
= img
->sec
[IWL_UCODE_SECTION_DATA
].len
;
138 if (mvm
->dbgfs_sram_len
) {
139 ofs
= mvm
->dbgfs_sram_offset
;
140 len
= mvm
->dbgfs_sram_len
;
143 ptr
= kzalloc(len
, GFP_KERNEL
);
147 iwl_trans_read_mem_bytes(mvm
->trans
, ofs
, ptr
, len
);
149 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, ptr
, len
);
156 static ssize_t
iwl_dbgfs_sram_write(struct iwl_mvm
*mvm
, char *buf
,
157 size_t count
, loff_t
*ppos
)
159 const struct fw_img
*img
;
161 u32 img_offset
, img_len
;
163 if (!mvm
->ucode_loaded
)
166 img
= &mvm
->fw
->img
[mvm
->cur_ucode
];
167 img_offset
= img
->sec
[IWL_UCODE_SECTION_DATA
].offset
;
168 img_len
= img
->sec
[IWL_UCODE_SECTION_DATA
].len
;
170 if (sscanf(buf
, "%x,%x", &offset
, &len
) == 2) {
171 if ((offset
& 0x3) || (len
& 0x3))
174 if (offset
+ len
> img_offset
+ img_len
)
177 mvm
->dbgfs_sram_offset
= offset
;
178 mvm
->dbgfs_sram_len
= len
;
180 mvm
->dbgfs_sram_offset
= 0;
181 mvm
->dbgfs_sram_len
= 0;
187 static ssize_t
iwl_dbgfs_stations_read(struct file
*file
, char __user
*user_buf
,
188 size_t count
, loff_t
*ppos
)
190 struct iwl_mvm
*mvm
= file
->private_data
;
191 struct ieee80211_sta
*sta
;
193 int i
, pos
= 0, bufsz
= sizeof(buf
);
195 mutex_lock(&mvm
->mutex
);
197 for (i
= 0; i
< IWL_MVM_STATION_COUNT
; i
++) {
198 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "%.2d: ", i
);
199 sta
= rcu_dereference_protected(mvm
->fw_id_to_mac_id
[i
],
200 lockdep_is_held(&mvm
->mutex
));
202 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "N/A\n");
203 else if (IS_ERR(sta
))
204 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "%ld\n",
207 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "%pM\n",
211 mutex_unlock(&mvm
->mutex
);
213 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
216 static ssize_t
iwl_dbgfs_disable_power_off_read(struct file
*file
,
217 char __user
*user_buf
,
218 size_t count
, loff_t
*ppos
)
220 struct iwl_mvm
*mvm
= file
->private_data
;
222 int bufsz
= sizeof(buf
);
225 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "disable_power_off_d0=%d\n",
226 mvm
->disable_power_off
);
227 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "disable_power_off_d3=%d\n",
228 mvm
->disable_power_off_d3
);
230 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
233 static ssize_t
iwl_dbgfs_disable_power_off_write(struct iwl_mvm
*mvm
, char *buf
,
234 size_t count
, loff_t
*ppos
)
238 if (!mvm
->ucode_loaded
)
241 if (!strncmp("disable_power_off_d0=", buf
, 21)) {
242 if (sscanf(buf
+ 21, "%d", &val
) != 1)
244 mvm
->disable_power_off
= val
;
245 } else if (!strncmp("disable_power_off_d3=", buf
, 21)) {
246 if (sscanf(buf
+ 21, "%d", &val
) != 1)
248 mvm
->disable_power_off_d3
= val
;
253 mutex_lock(&mvm
->mutex
);
254 ret
= iwl_mvm_power_update_device_mode(mvm
);
255 mutex_unlock(&mvm
->mutex
);
260 #define BT_MBOX_MSG(_notif, _num, _field) \
261 ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\
262 >> BT_MBOX##_num##_##_field##_POS)
265 #define BT_MBOX_PRINT(_num, _field, _end) \
266 pos += scnprintf(buf + pos, bufsz - pos, \
269 BT_MBOX_MSG(notif, _num, _field), \
272 static ssize_t
iwl_dbgfs_bt_notif_read(struct file
*file
, char __user
*user_buf
,
273 size_t count
, loff_t
*ppos
)
275 struct iwl_mvm
*mvm
= file
->private_data
;
276 struct iwl_bt_coex_profile_notif
*notif
= &mvm
->last_bt_notif
;
278 int ret
, pos
= 0, bufsz
= sizeof(char) * 1024;
280 buf
= kmalloc(bufsz
, GFP_KERNEL
);
284 mutex_lock(&mvm
->mutex
);
286 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "MBOX dw0:\n");
288 BT_MBOX_PRINT(0, LE_SLAVE_LAT
, false);
289 BT_MBOX_PRINT(0, LE_PROF1
, false);
290 BT_MBOX_PRINT(0, LE_PROF2
, false);
291 BT_MBOX_PRINT(0, LE_PROF_OTHER
, false);
292 BT_MBOX_PRINT(0, CHL_SEQ_N
, false);
293 BT_MBOX_PRINT(0, INBAND_S
, false);
294 BT_MBOX_PRINT(0, LE_MIN_RSSI
, false);
295 BT_MBOX_PRINT(0, LE_SCAN
, false);
296 BT_MBOX_PRINT(0, LE_ADV
, false);
297 BT_MBOX_PRINT(0, LE_MAX_TX_POWER
, false);
298 BT_MBOX_PRINT(0, OPEN_CON_1
, true);
300 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "MBOX dw1:\n");
302 BT_MBOX_PRINT(1, BR_MAX_TX_POWER
, false);
303 BT_MBOX_PRINT(1, IP_SR
, false);
304 BT_MBOX_PRINT(1, LE_MSTR
, false);
305 BT_MBOX_PRINT(1, AGGR_TRFC_LD
, false);
306 BT_MBOX_PRINT(1, MSG_TYPE
, false);
307 BT_MBOX_PRINT(1, SSN
, true);
309 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "MBOX dw2:\n");
311 BT_MBOX_PRINT(2, SNIFF_ACT
, false);
312 BT_MBOX_PRINT(2, PAG
, false);
313 BT_MBOX_PRINT(2, INQUIRY
, false);
314 BT_MBOX_PRINT(2, CONN
, false);
315 BT_MBOX_PRINT(2, SNIFF_INTERVAL
, false);
316 BT_MBOX_PRINT(2, DISC
, false);
317 BT_MBOX_PRINT(2, SCO_TX_ACT
, false);
318 BT_MBOX_PRINT(2, SCO_RX_ACT
, false);
319 BT_MBOX_PRINT(2, ESCO_RE_TX
, false);
320 BT_MBOX_PRINT(2, SCO_DURATION
, true);
322 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "MBOX dw3:\n");
324 BT_MBOX_PRINT(3, SCO_STATE
, false);
325 BT_MBOX_PRINT(3, SNIFF_STATE
, false);
326 BT_MBOX_PRINT(3, A2DP_STATE
, false);
327 BT_MBOX_PRINT(3, ACL_STATE
, false);
328 BT_MBOX_PRINT(3, MSTR_STATE
, false);
329 BT_MBOX_PRINT(3, OBX_STATE
, false);
330 BT_MBOX_PRINT(3, OPEN_CON_2
, false);
331 BT_MBOX_PRINT(3, TRAFFIC_LOAD
, false);
332 BT_MBOX_PRINT(3, CHL_SEQN_LSB
, false);
333 BT_MBOX_PRINT(3, INBAND_P
, false);
334 BT_MBOX_PRINT(3, MSG_TYPE_2
, false);
335 BT_MBOX_PRINT(3, SSN_2
, false);
336 BT_MBOX_PRINT(3, UPDATE_REQUEST
, true);
338 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "bt_status = %d\n",
340 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "bt_open_conn = %d\n",
341 notif
->bt_open_conn
);
342 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "bt_traffic_load = %d\n",
343 notif
->bt_traffic_load
);
344 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "bt_agg_traffic_load = %d\n",
345 notif
->bt_agg_traffic_load
);
346 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "bt_ci_compliance = %d\n",
347 notif
->bt_ci_compliance
);
348 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "primary_ch_lut = %d\n",
349 le32_to_cpu(notif
->primary_ch_lut
));
350 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "secondary_ch_lut = %d\n",
351 le32_to_cpu(notif
->secondary_ch_lut
));
352 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "bt_activity_grading = %d\n",
353 le32_to_cpu(notif
->bt_activity_grading
));
355 mutex_unlock(&mvm
->mutex
);
357 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
364 static ssize_t
iwl_dbgfs_bt_cmd_read(struct file
*file
, char __user
*user_buf
,
365 size_t count
, loff_t
*ppos
)
367 struct iwl_mvm
*mvm
= file
->private_data
;
368 struct iwl_bt_coex_ci_cmd
*cmd
= &mvm
->last_bt_ci_cmd
;
370 int bufsz
= sizeof(buf
);
373 mutex_lock(&mvm
->mutex
);
375 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "Channel inhibition CMD\n");
376 pos
+= scnprintf(buf
+pos
, bufsz
-pos
,
377 "\tPrimary Channel Bitmap 0x%016llx Fat: %d\n",
378 le64_to_cpu(cmd
->bt_primary_ci
),
379 !!cmd
->co_run_bw_primary
);
380 pos
+= scnprintf(buf
+pos
, bufsz
-pos
,
381 "\tSecondary Channel Bitmap 0x%016llx Fat: %d\n",
382 le64_to_cpu(cmd
->bt_secondary_ci
),
383 !!cmd
->co_run_bw_secondary
);
385 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "BT Configuration CMD\n");
386 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "\tACK Kill Mask 0x%08x\n",
387 iwl_bt_ack_kill_msk
[mvm
->bt_kill_msk
]);
388 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "\tCTS Kill Mask 0x%08x\n",
389 iwl_bt_cts_kill_msk
[mvm
->bt_kill_msk
]);
391 mutex_unlock(&mvm
->mutex
);
393 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
396 #define PRINT_STATS_LE32(_str, _val) \
397 pos += scnprintf(buf + pos, bufsz - pos, \
401 static ssize_t
iwl_dbgfs_fw_rx_stats_read(struct file
*file
,
402 char __user
*user_buf
, size_t count
,
405 struct iwl_mvm
*mvm
= file
->private_data
;
406 static const char *fmt_table
= "\t%-30s %10u\n";
407 static const char *fmt_header
= "%-32s\n";
411 /* 43 is the size of each data line, 33 is the size of each header */
413 ((sizeof(struct mvm_statistics_rx
) / sizeof(__le32
)) * 43) +
416 struct mvm_statistics_rx_phy
*ofdm
;
417 struct mvm_statistics_rx_phy
*cck
;
418 struct mvm_statistics_rx_non_phy
*general
;
419 struct mvm_statistics_rx_ht_phy
*ht
;
421 buf
= kzalloc(bufsz
, GFP_KERNEL
);
425 mutex_lock(&mvm
->mutex
);
427 ofdm
= &mvm
->rx_stats
.ofdm
;
428 cck
= &mvm
->rx_stats
.cck
;
429 general
= &mvm
->rx_stats
.general
;
430 ht
= &mvm
->rx_stats
.ofdm_ht
;
432 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, fmt_header
,
433 "Statistics_Rx - OFDM");
434 PRINT_STATS_LE32("ina_cnt", ofdm
->ina_cnt
);
435 PRINT_STATS_LE32("fina_cnt", ofdm
->fina_cnt
);
436 PRINT_STATS_LE32("plcp_err", ofdm
->plcp_err
);
437 PRINT_STATS_LE32("crc32_err", ofdm
->crc32_err
);
438 PRINT_STATS_LE32("overrun_err", ofdm
->overrun_err
);
439 PRINT_STATS_LE32("early_overrun_err", ofdm
->early_overrun_err
);
440 PRINT_STATS_LE32("crc32_good", ofdm
->crc32_good
);
441 PRINT_STATS_LE32("false_alarm_cnt", ofdm
->false_alarm_cnt
);
442 PRINT_STATS_LE32("fina_sync_err_cnt", ofdm
->fina_sync_err_cnt
);
443 PRINT_STATS_LE32("sfd_timeout", ofdm
->sfd_timeout
);
444 PRINT_STATS_LE32("fina_timeout", ofdm
->fina_timeout
);
445 PRINT_STATS_LE32("unresponded_rts", ofdm
->unresponded_rts
);
446 PRINT_STATS_LE32("rxe_frame_lmt_overrun",
447 ofdm
->rxe_frame_limit_overrun
);
448 PRINT_STATS_LE32("sent_ack_cnt", ofdm
->sent_ack_cnt
);
449 PRINT_STATS_LE32("sent_cts_cnt", ofdm
->sent_cts_cnt
);
450 PRINT_STATS_LE32("sent_ba_rsp_cnt", ofdm
->sent_ba_rsp_cnt
);
451 PRINT_STATS_LE32("dsp_self_kill", ofdm
->dsp_self_kill
);
452 PRINT_STATS_LE32("mh_format_err", ofdm
->mh_format_err
);
453 PRINT_STATS_LE32("re_acq_main_rssi_sum", ofdm
->re_acq_main_rssi_sum
);
454 PRINT_STATS_LE32("reserved", ofdm
->reserved
);
456 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, fmt_header
,
457 "Statistics_Rx - CCK");
458 PRINT_STATS_LE32("ina_cnt", cck
->ina_cnt
);
459 PRINT_STATS_LE32("fina_cnt", cck
->fina_cnt
);
460 PRINT_STATS_LE32("plcp_err", cck
->plcp_err
);
461 PRINT_STATS_LE32("crc32_err", cck
->crc32_err
);
462 PRINT_STATS_LE32("overrun_err", cck
->overrun_err
);
463 PRINT_STATS_LE32("early_overrun_err", cck
->early_overrun_err
);
464 PRINT_STATS_LE32("crc32_good", cck
->crc32_good
);
465 PRINT_STATS_LE32("false_alarm_cnt", cck
->false_alarm_cnt
);
466 PRINT_STATS_LE32("fina_sync_err_cnt", cck
->fina_sync_err_cnt
);
467 PRINT_STATS_LE32("sfd_timeout", cck
->sfd_timeout
);
468 PRINT_STATS_LE32("fina_timeout", cck
->fina_timeout
);
469 PRINT_STATS_LE32("unresponded_rts", cck
->unresponded_rts
);
470 PRINT_STATS_LE32("rxe_frame_lmt_overrun",
471 cck
->rxe_frame_limit_overrun
);
472 PRINT_STATS_LE32("sent_ack_cnt", cck
->sent_ack_cnt
);
473 PRINT_STATS_LE32("sent_cts_cnt", cck
->sent_cts_cnt
);
474 PRINT_STATS_LE32("sent_ba_rsp_cnt", cck
->sent_ba_rsp_cnt
);
475 PRINT_STATS_LE32("dsp_self_kill", cck
->dsp_self_kill
);
476 PRINT_STATS_LE32("mh_format_err", cck
->mh_format_err
);
477 PRINT_STATS_LE32("re_acq_main_rssi_sum", cck
->re_acq_main_rssi_sum
);
478 PRINT_STATS_LE32("reserved", cck
->reserved
);
480 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, fmt_header
,
481 "Statistics_Rx - GENERAL");
482 PRINT_STATS_LE32("bogus_cts", general
->bogus_cts
);
483 PRINT_STATS_LE32("bogus_ack", general
->bogus_ack
);
484 PRINT_STATS_LE32("non_bssid_frames", general
->non_bssid_frames
);
485 PRINT_STATS_LE32("filtered_frames", general
->filtered_frames
);
486 PRINT_STATS_LE32("non_channel_beacons", general
->non_channel_beacons
);
487 PRINT_STATS_LE32("channel_beacons", general
->channel_beacons
);
488 PRINT_STATS_LE32("num_missed_bcon", general
->num_missed_bcon
);
489 PRINT_STATS_LE32("adc_rx_saturation_time",
490 general
->adc_rx_saturation_time
);
491 PRINT_STATS_LE32("ina_detection_search_time",
492 general
->ina_detection_search_time
);
493 PRINT_STATS_LE32("beacon_silence_rssi_a",
494 general
->beacon_silence_rssi_a
);
495 PRINT_STATS_LE32("beacon_silence_rssi_b",
496 general
->beacon_silence_rssi_b
);
497 PRINT_STATS_LE32("beacon_silence_rssi_c",
498 general
->beacon_silence_rssi_c
);
499 PRINT_STATS_LE32("interference_data_flag",
500 general
->interference_data_flag
);
501 PRINT_STATS_LE32("channel_load", general
->channel_load
);
502 PRINT_STATS_LE32("dsp_false_alarms", general
->dsp_false_alarms
);
503 PRINT_STATS_LE32("beacon_rssi_a", general
->beacon_rssi_a
);
504 PRINT_STATS_LE32("beacon_rssi_b", general
->beacon_rssi_b
);
505 PRINT_STATS_LE32("beacon_rssi_c", general
->beacon_rssi_c
);
506 PRINT_STATS_LE32("beacon_energy_a", general
->beacon_energy_a
);
507 PRINT_STATS_LE32("beacon_energy_b", general
->beacon_energy_b
);
508 PRINT_STATS_LE32("beacon_energy_c", general
->beacon_energy_c
);
509 PRINT_STATS_LE32("num_bt_kills", general
->num_bt_kills
);
510 PRINT_STATS_LE32("mac_id", general
->mac_id
);
511 PRINT_STATS_LE32("directed_data_mpdu", general
->directed_data_mpdu
);
513 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, fmt_header
,
514 "Statistics_Rx - HT");
515 PRINT_STATS_LE32("plcp_err", ht
->plcp_err
);
516 PRINT_STATS_LE32("overrun_err", ht
->overrun_err
);
517 PRINT_STATS_LE32("early_overrun_err", ht
->early_overrun_err
);
518 PRINT_STATS_LE32("crc32_good", ht
->crc32_good
);
519 PRINT_STATS_LE32("crc32_err", ht
->crc32_err
);
520 PRINT_STATS_LE32("mh_format_err", ht
->mh_format_err
);
521 PRINT_STATS_LE32("agg_crc32_good", ht
->agg_crc32_good
);
522 PRINT_STATS_LE32("agg_mpdu_cnt", ht
->agg_mpdu_cnt
);
523 PRINT_STATS_LE32("agg_cnt", ht
->agg_cnt
);
524 PRINT_STATS_LE32("unsupport_mcs", ht
->unsupport_mcs
);
526 mutex_unlock(&mvm
->mutex
);
528 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
533 #undef PRINT_STAT_LE32
535 static ssize_t
iwl_dbgfs_fw_restart_write(struct iwl_mvm
*mvm
, char *buf
,
536 size_t count
, loff_t
*ppos
)
540 mutex_lock(&mvm
->mutex
);
542 /* allow one more restart that we're provoking here */
543 if (mvm
->restart_fw
>= 0)
546 /* take the return value to make compiler happy - it will fail anyway */
547 ret
= iwl_mvm_send_cmd_pdu(mvm
, REPLY_ERROR
, CMD_SYNC
, 0, NULL
);
549 mutex_unlock(&mvm
->mutex
);
554 static ssize_t
iwl_dbgfs_fw_nmi_write(struct iwl_mvm
*mvm
, char *buf
,
555 size_t count
, loff_t
*ppos
)
557 iwl_write_prph(mvm
->trans
, DEVICE_SET_NMI_REG
, 1);
563 iwl_dbgfs_scan_ant_rxchain_read(struct file
*file
,
564 char __user
*user_buf
,
565 size_t count
, loff_t
*ppos
)
567 struct iwl_mvm
*mvm
= file
->private_data
;
570 const size_t bufsz
= sizeof(buf
);
572 /* print which antennas were set for the scan command by the user */
573 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Antennas for scan: ");
574 if (mvm
->scan_rx_ant
& ANT_A
)
575 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "A");
576 if (mvm
->scan_rx_ant
& ANT_B
)
577 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "B");
578 if (mvm
->scan_rx_ant
& ANT_C
)
579 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "C");
580 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, " (%hhx)\n", mvm
->scan_rx_ant
);
582 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
586 iwl_dbgfs_scan_ant_rxchain_write(struct iwl_mvm
*mvm
, char *buf
,
587 size_t count
, loff_t
*ppos
)
591 if (sscanf(buf
, "%hhx", &scan_rx_ant
) != 1)
593 if (scan_rx_ant
> ANT_ABC
)
595 if (scan_rx_ant
& ~iwl_fw_valid_rx_ant(mvm
->fw
))
598 mvm
->scan_rx_ant
= scan_rx_ant
;
603 #ifdef CONFIG_PM_SLEEP
604 static ssize_t
iwl_dbgfs_d3_sram_write(struct iwl_mvm
*mvm
, char *buf
,
605 size_t count
, loff_t
*ppos
)
609 if (sscanf(buf
, "%d", &store
) != 1)
612 mvm
->store_d3_resume_sram
= store
;
617 static ssize_t
iwl_dbgfs_d3_sram_read(struct file
*file
, char __user
*user_buf
,
618 size_t count
, loff_t
*ppos
)
620 struct iwl_mvm
*mvm
= file
->private_data
;
621 const struct fw_img
*img
;
622 int ofs
, len
, pos
= 0;
625 u8
*ptr
= mvm
->d3_resume_sram
;
627 img
= &mvm
->fw
->img
[IWL_UCODE_WOWLAN
];
628 len
= img
->sec
[IWL_UCODE_SECTION_DATA
].len
;
630 bufsz
= len
* 4 + 256;
631 buf
= kzalloc(bufsz
, GFP_KERNEL
);
635 pos
+= scnprintf(buf
, bufsz
, "D3 SRAM capture: %sabled\n",
636 mvm
->store_d3_resume_sram
? "en" : "dis");
639 for (ofs
= 0; ofs
< len
; ofs
+= 16) {
640 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
642 hex_dump_to_buffer(ptr
+ ofs
, 16, 16, 1, buf
+ pos
,
644 pos
+= strlen(buf
+ pos
);
649 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
650 "(no data captured)\n");
653 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
661 #define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \
662 _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm)
663 #define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
664 _MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm)
665 #define MVM_DEBUGFS_ADD_FILE(name, parent, mode) do { \
666 if (!debugfs_create_file(#name, mode, parent, mvm, \
667 &iwl_dbgfs_##name##_ops)) \
671 /* Device wide debugfs entries */
672 MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush
, 16);
673 MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain
, 8);
674 MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram
, 64);
675 MVM_DEBUGFS_READ_FILE_OPS(stations
);
676 MVM_DEBUGFS_READ_FILE_OPS(bt_notif
);
677 MVM_DEBUGFS_READ_FILE_OPS(bt_cmd
);
678 MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off
, 64);
679 MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats
);
680 MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart
, 10);
681 MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi
, 10);
682 MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain
, 8);
684 #ifdef CONFIG_PM_SLEEP
685 MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram
, 8);
688 int iwl_mvm_dbgfs_register(struct iwl_mvm
*mvm
, struct dentry
*dbgfs_dir
)
692 mvm
->debugfs_dir
= dbgfs_dir
;
694 MVM_DEBUGFS_ADD_FILE(tx_flush
, mvm
->debugfs_dir
, S_IWUSR
);
695 MVM_DEBUGFS_ADD_FILE(sta_drain
, mvm
->debugfs_dir
, S_IWUSR
);
696 MVM_DEBUGFS_ADD_FILE(sram
, mvm
->debugfs_dir
, S_IWUSR
| S_IRUSR
);
697 MVM_DEBUGFS_ADD_FILE(stations
, dbgfs_dir
, S_IRUSR
);
698 MVM_DEBUGFS_ADD_FILE(bt_notif
, dbgfs_dir
, S_IRUSR
);
699 MVM_DEBUGFS_ADD_FILE(bt_cmd
, dbgfs_dir
, S_IRUSR
);
700 if (mvm
->fw
->ucode_capa
.flags
& IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD
)
701 MVM_DEBUGFS_ADD_FILE(disable_power_off
, mvm
->debugfs_dir
,
703 MVM_DEBUGFS_ADD_FILE(fw_rx_stats
, mvm
->debugfs_dir
, S_IRUSR
);
704 MVM_DEBUGFS_ADD_FILE(fw_restart
, mvm
->debugfs_dir
, S_IWUSR
);
705 MVM_DEBUGFS_ADD_FILE(fw_nmi
, mvm
->debugfs_dir
, S_IWUSR
);
706 MVM_DEBUGFS_ADD_FILE(scan_ant_rxchain
, mvm
->debugfs_dir
,
708 #ifdef CONFIG_PM_SLEEP
709 MVM_DEBUGFS_ADD_FILE(d3_sram
, mvm
->debugfs_dir
, S_IRUSR
| S_IWUSR
);
710 MVM_DEBUGFS_ADD_FILE(d3_test
, mvm
->debugfs_dir
, S_IRUSR
);
711 if (!debugfs_create_bool("d3_wake_sysassert", S_IRUSR
| S_IWUSR
,
712 mvm
->debugfs_dir
, &mvm
->d3_wake_sysassert
))
716 if (!debugfs_create_blob("nvm_hw", S_IRUSR
,
717 mvm
->debugfs_dir
, &mvm
->nvm_hw_blob
))
719 if (!debugfs_create_blob("nvm_sw", S_IRUSR
,
720 mvm
->debugfs_dir
, &mvm
->nvm_sw_blob
))
722 if (!debugfs_create_blob("nvm_calib", S_IRUSR
,
723 mvm
->debugfs_dir
, &mvm
->nvm_calib_blob
))
725 if (!debugfs_create_blob("nvm_prod", S_IRUSR
,
726 mvm
->debugfs_dir
, &mvm
->nvm_prod_blob
))
730 * Create a symlink with mac80211. It will be removed when mac80211
731 * exists (before the opmode exists which removes the target.)
733 snprintf(buf
, 100, "../../%s/%s",
734 dbgfs_dir
->d_parent
->d_parent
->d_name
.name
,
735 dbgfs_dir
->d_parent
->d_name
.name
);
736 if (!debugfs_create_symlink("iwlwifi", mvm
->hw
->wiphy
->debugfsdir
, buf
))
741 IWL_ERR(mvm
, "Can't create the mvm debugfs directory\n");