2 * Copyright (c) 2005-2011 Atheros Communications Inc.
3 * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 #include <linux/module.h>
19 #include <linux/debugfs.h>
20 #include <linux/version.h>
21 #include <linux/vermagic.h>
22 #include <linux/vmalloc.h>
28 #define ATH10K_DEBUG_HTT_STATS_INTERVAL 1000
30 #define ATH10K_FW_CRASH_DUMP_VERSION 1
33 * enum ath10k_fw_crash_dump_type - types of data in the dump file
34 * @ATH10K_FW_CRASH_DUMP_REGDUMP: Register crash dump in binary format
36 enum ath10k_fw_crash_dump_type
{
37 ATH10K_FW_CRASH_DUMP_REGISTERS
= 0,
39 ATH10K_FW_CRASH_DUMP_MAX
,
42 struct ath10k_tlv_dump_data
{
43 /* see ath10k_fw_crash_dump_type above */
49 /* pad to 32-bit boundaries as needed */
53 struct ath10k_dump_file_data
{
54 /* dump file information */
56 /* "ATH10K-FW-DUMP" */
61 /* file dump version */
64 /* some info we can get from ath10k struct that might help */
70 /* 0 for now, in place for later hardware */
73 __le32 target_version
;
74 __le32 fw_version_major
;
75 __le32 fw_version_minor
;
76 __le32 fw_version_release
;
77 __le32 fw_version_build
;
78 __le32 phy_capability
;
79 __le32 hw_min_tx_power
;
80 __le32 hw_max_tx_power
;
85 /* firmware version string */
86 char fw_ver
[ETHTOOL_FWVERS_LEN
];
88 /* Kernel related information */
90 /* time-of-day stamp */
93 /* time-of-day stamp, nano-seconds */
96 /* LINUX_VERSION_CODE */
97 __le32 kernel_ver_code
;
102 /* room for growth w/out changing binary format */
105 /* struct ath10k_tlv_dump_data + more */
109 int ath10k_info(struct ath10k
*ar
, const char *fmt
, ...)
111 struct va_format vaf
= {
119 ret
= dev_info(ar
->dev
, "%pV", &vaf
);
120 trace_ath10k_log_info(ar
, &vaf
);
125 EXPORT_SYMBOL(ath10k_info
);
127 void ath10k_print_driver_info(struct ath10k
*ar
)
129 ath10k_info(ar
, "%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d\n",
133 ar
->hw
->wiphy
->fw_version
,
135 ar
->htt
.target_version_major
,
136 ar
->htt
.target_version_minor
);
137 ath10k_info(ar
, "debug %d debugfs %d tracing %d dfs %d testmode %d\n",
138 config_enabled(CONFIG_ATH10K_DEBUG
),
139 config_enabled(CONFIG_ATH10K_DEBUGFS
),
140 config_enabled(CONFIG_ATH10K_TRACING
),
141 config_enabled(CONFIG_ATH10K_DFS_CERTIFIED
),
142 config_enabled(CONFIG_NL80211_TESTMODE
));
144 EXPORT_SYMBOL(ath10k_print_driver_info
);
146 int ath10k_err(struct ath10k
*ar
, const char *fmt
, ...)
148 struct va_format vaf
= {
156 ret
= dev_err(ar
->dev
, "%pV", &vaf
);
157 trace_ath10k_log_err(ar
, &vaf
);
162 EXPORT_SYMBOL(ath10k_err
);
164 int ath10k_warn(struct ath10k
*ar
, const char *fmt
, ...)
166 struct va_format vaf
= {
173 dev_warn_ratelimited(ar
->dev
, "%pV", &vaf
);
174 trace_ath10k_log_warn(ar
, &vaf
);
180 EXPORT_SYMBOL(ath10k_warn
);
182 #ifdef CONFIG_ATH10K_DEBUGFS
184 void ath10k_debug_read_service_map(struct ath10k
*ar
,
188 memcpy(ar
->debug
.wmi_service_bitmap
, service_map
, map_size
);
191 static ssize_t
ath10k_read_wmi_services(struct file
*file
,
192 char __user
*user_buf
,
193 size_t count
, loff_t
*ppos
)
195 struct ath10k
*ar
= file
->private_data
;
197 unsigned int len
= 0, buf_len
= 4096;
203 buf
= kzalloc(buf_len
, GFP_KERNEL
);
207 mutex_lock(&ar
->conf_mutex
);
212 for (i
= 0; i
< WMI_SERVICE_MAX
; i
++) {
213 enabled
= test_bit(i
, ar
->debug
.wmi_service_bitmap
);
214 name
= wmi_service_name(i
);
218 len
+= scnprintf(buf
+ len
, buf_len
- len
,
219 "%-40s %s (bit %d)\n",
220 "unknown", "enabled", i
);
225 len
+= scnprintf(buf
+ len
, buf_len
- len
,
227 name
, enabled
? "enabled" : "-");
230 ret_cnt
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
232 mutex_unlock(&ar
->conf_mutex
);
238 static const struct file_operations fops_wmi_services
= {
239 .read
= ath10k_read_wmi_services
,
241 .owner
= THIS_MODULE
,
242 .llseek
= default_llseek
,
245 void ath10k_debug_read_target_stats(struct ath10k
*ar
,
246 struct wmi_stats_event
*ev
)
249 struct ath10k_target_stats
*stats
;
250 int num_pdev_stats
, num_vdev_stats
, num_peer_stats
;
251 struct wmi_pdev_stats_10x
*ps
;
254 spin_lock_bh(&ar
->data_lock
);
256 stats
= &ar
->debug
.target_stats
;
258 num_pdev_stats
= __le32_to_cpu(ev
->num_pdev_stats
); /* 0 or 1 */
259 num_vdev_stats
= __le32_to_cpu(ev
->num_vdev_stats
); /* 0 or max vdevs */
260 num_peer_stats
= __le32_to_cpu(ev
->num_peer_stats
); /* 0 or max peers */
262 if (num_pdev_stats
) {
263 ps
= (struct wmi_pdev_stats_10x
*)tmp
;
265 stats
->ch_noise_floor
= __le32_to_cpu(ps
->chan_nf
);
266 stats
->tx_frame_count
= __le32_to_cpu(ps
->tx_frame_count
);
267 stats
->rx_frame_count
= __le32_to_cpu(ps
->rx_frame_count
);
268 stats
->rx_clear_count
= __le32_to_cpu(ps
->rx_clear_count
);
269 stats
->cycle_count
= __le32_to_cpu(ps
->cycle_count
);
270 stats
->phy_err_count
= __le32_to_cpu(ps
->phy_err_count
);
271 stats
->chan_tx_power
= __le32_to_cpu(ps
->chan_tx_pwr
);
273 stats
->comp_queued
= __le32_to_cpu(ps
->wal
.tx
.comp_queued
);
274 stats
->comp_delivered
=
275 __le32_to_cpu(ps
->wal
.tx
.comp_delivered
);
276 stats
->msdu_enqued
= __le32_to_cpu(ps
->wal
.tx
.msdu_enqued
);
277 stats
->mpdu_enqued
= __le32_to_cpu(ps
->wal
.tx
.mpdu_enqued
);
278 stats
->wmm_drop
= __le32_to_cpu(ps
->wal
.tx
.wmm_drop
);
279 stats
->local_enqued
= __le32_to_cpu(ps
->wal
.tx
.local_enqued
);
280 stats
->local_freed
= __le32_to_cpu(ps
->wal
.tx
.local_freed
);
281 stats
->hw_queued
= __le32_to_cpu(ps
->wal
.tx
.hw_queued
);
282 stats
->hw_reaped
= __le32_to_cpu(ps
->wal
.tx
.hw_reaped
);
283 stats
->underrun
= __le32_to_cpu(ps
->wal
.tx
.underrun
);
284 stats
->tx_abort
= __le32_to_cpu(ps
->wal
.tx
.tx_abort
);
285 stats
->mpdus_requed
= __le32_to_cpu(ps
->wal
.tx
.mpdus_requed
);
286 stats
->tx_ko
= __le32_to_cpu(ps
->wal
.tx
.tx_ko
);
287 stats
->data_rc
= __le32_to_cpu(ps
->wal
.tx
.data_rc
);
288 stats
->self_triggers
= __le32_to_cpu(ps
->wal
.tx
.self_triggers
);
289 stats
->sw_retry_failure
=
290 __le32_to_cpu(ps
->wal
.tx
.sw_retry_failure
);
291 stats
->illgl_rate_phy_err
=
292 __le32_to_cpu(ps
->wal
.tx
.illgl_rate_phy_err
);
293 stats
->pdev_cont_xretry
=
294 __le32_to_cpu(ps
->wal
.tx
.pdev_cont_xretry
);
295 stats
->pdev_tx_timeout
=
296 __le32_to_cpu(ps
->wal
.tx
.pdev_tx_timeout
);
297 stats
->pdev_resets
= __le32_to_cpu(ps
->wal
.tx
.pdev_resets
);
298 stats
->phy_underrun
= __le32_to_cpu(ps
->wal
.tx
.phy_underrun
);
299 stats
->txop_ovf
= __le32_to_cpu(ps
->wal
.tx
.txop_ovf
);
301 stats
->mid_ppdu_route_change
=
302 __le32_to_cpu(ps
->wal
.rx
.mid_ppdu_route_change
);
303 stats
->status_rcvd
= __le32_to_cpu(ps
->wal
.rx
.status_rcvd
);
304 stats
->r0_frags
= __le32_to_cpu(ps
->wal
.rx
.r0_frags
);
305 stats
->r1_frags
= __le32_to_cpu(ps
->wal
.rx
.r1_frags
);
306 stats
->r2_frags
= __le32_to_cpu(ps
->wal
.rx
.r2_frags
);
307 stats
->r3_frags
= __le32_to_cpu(ps
->wal
.rx
.r3_frags
);
308 stats
->htt_msdus
= __le32_to_cpu(ps
->wal
.rx
.htt_msdus
);
309 stats
->htt_mpdus
= __le32_to_cpu(ps
->wal
.rx
.htt_mpdus
);
310 stats
->loc_msdus
= __le32_to_cpu(ps
->wal
.rx
.loc_msdus
);
311 stats
->loc_mpdus
= __le32_to_cpu(ps
->wal
.rx
.loc_mpdus
);
312 stats
->oversize_amsdu
=
313 __le32_to_cpu(ps
->wal
.rx
.oversize_amsdu
);
314 stats
->phy_errs
= __le32_to_cpu(ps
->wal
.rx
.phy_errs
);
315 stats
->phy_err_drop
= __le32_to_cpu(ps
->wal
.rx
.phy_err_drop
);
316 stats
->mpdu_errs
= __le32_to_cpu(ps
->wal
.rx
.mpdu_errs
);
318 if (test_bit(ATH10K_FW_FEATURE_WMI_10X
,
320 stats
->ack_rx_bad
= __le32_to_cpu(ps
->ack_rx_bad
);
321 stats
->rts_bad
= __le32_to_cpu(ps
->rts_bad
);
322 stats
->rts_good
= __le32_to_cpu(ps
->rts_good
);
323 stats
->fcs_bad
= __le32_to_cpu(ps
->fcs_bad
);
324 stats
->no_beacons
= __le32_to_cpu(ps
->no_beacons
);
325 stats
->mib_int_count
= __le32_to_cpu(ps
->mib_int_count
);
326 tmp
+= sizeof(struct wmi_pdev_stats_10x
);
328 tmp
+= sizeof(struct wmi_pdev_stats_old
);
333 /* Currently firmware does not support VDEV stats */
334 if (num_vdev_stats
) {
335 struct wmi_vdev_stats
*vdev_stats
;
337 for (i
= 0; i
< num_vdev_stats
; i
++) {
338 vdev_stats
= (struct wmi_vdev_stats
*)tmp
;
339 tmp
+= sizeof(struct wmi_vdev_stats
);
343 if (num_peer_stats
) {
344 struct wmi_peer_stats_10x
*peer_stats
;
345 struct ath10k_peer_stat
*s
;
347 stats
->peers
= num_peer_stats
;
349 for (i
= 0; i
< num_peer_stats
; i
++) {
350 peer_stats
= (struct wmi_peer_stats_10x
*)tmp
;
351 s
= &stats
->peer_stat
[i
];
353 memcpy(s
->peer_macaddr
, &peer_stats
->peer_macaddr
.addr
,
355 s
->peer_rssi
= __le32_to_cpu(peer_stats
->peer_rssi
);
357 __le32_to_cpu(peer_stats
->peer_tx_rate
);
358 if (test_bit(ATH10K_FW_FEATURE_WMI_10X
,
361 __le32_to_cpu(peer_stats
->peer_rx_rate
);
362 tmp
+= sizeof(struct wmi_peer_stats_10x
);
365 tmp
+= sizeof(struct wmi_peer_stats_old
);
370 spin_unlock_bh(&ar
->data_lock
);
371 complete(&ar
->debug
.event_stats_compl
);
374 static ssize_t
ath10k_read_fw_stats(struct file
*file
, char __user
*user_buf
,
375 size_t count
, loff_t
*ppos
)
377 struct ath10k
*ar
= file
->private_data
;
378 struct ath10k_target_stats
*fw_stats
;
380 unsigned int len
= 0, buf_len
= 8000;
386 fw_stats
= &ar
->debug
.target_stats
;
388 mutex_lock(&ar
->conf_mutex
);
390 if (ar
->state
!= ATH10K_STATE_ON
)
393 buf
= kzalloc(buf_len
, GFP_KERNEL
);
397 ret
= ath10k_wmi_request_stats(ar
, WMI_REQUEST_PEER_STAT
);
399 ath10k_warn(ar
, "could not request stats (%d)\n", ret
);
403 left
= wait_for_completion_timeout(&ar
->debug
.event_stats_compl
, 1*HZ
);
407 spin_lock_bh(&ar
->data_lock
);
408 len
+= scnprintf(buf
+ len
, buf_len
- len
, "\n");
409 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s\n",
410 "ath10k PDEV stats");
411 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s\n\n",
412 "=================");
414 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
415 "Channel noise floor", fw_stats
->ch_noise_floor
);
416 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
417 "Channel TX power", fw_stats
->chan_tx_power
);
418 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
419 "TX frame count", fw_stats
->tx_frame_count
);
420 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
421 "RX frame count", fw_stats
->rx_frame_count
);
422 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
423 "RX clear count", fw_stats
->rx_clear_count
);
424 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
425 "Cycle count", fw_stats
->cycle_count
);
426 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
427 "PHY error count", fw_stats
->phy_err_count
);
428 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
429 "RTS bad count", fw_stats
->rts_bad
);
430 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
431 "RTS good count", fw_stats
->rts_good
);
432 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
433 "FCS bad count", fw_stats
->fcs_bad
);
434 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
435 "No beacon count", fw_stats
->no_beacons
);
436 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10u\n",
437 "MIB int count", fw_stats
->mib_int_count
);
439 len
+= scnprintf(buf
+ len
, buf_len
- len
, "\n");
440 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s\n",
441 "ath10k PDEV TX stats");
442 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s\n\n",
443 "=================");
445 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
446 "HTT cookies queued", fw_stats
->comp_queued
);
447 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
448 "HTT cookies disp.", fw_stats
->comp_delivered
);
449 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
450 "MSDU queued", fw_stats
->msdu_enqued
);
451 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
452 "MPDU queued", fw_stats
->mpdu_enqued
);
453 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
454 "MSDUs dropped", fw_stats
->wmm_drop
);
455 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
456 "Local enqued", fw_stats
->local_enqued
);
457 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
458 "Local freed", fw_stats
->local_freed
);
459 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
460 "HW queued", fw_stats
->hw_queued
);
461 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
462 "PPDUs reaped", fw_stats
->hw_reaped
);
463 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
464 "Num underruns", fw_stats
->underrun
);
465 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
466 "PPDUs cleaned", fw_stats
->tx_abort
);
467 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
468 "MPDUs requed", fw_stats
->mpdus_requed
);
469 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
470 "Excessive retries", fw_stats
->tx_ko
);
471 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
472 "HW rate", fw_stats
->data_rc
);
473 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
474 "Sched self tiggers", fw_stats
->self_triggers
);
475 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
476 "Dropped due to SW retries",
477 fw_stats
->sw_retry_failure
);
478 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
479 "Illegal rate phy errors",
480 fw_stats
->illgl_rate_phy_err
);
481 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
482 "Pdev continous xretry", fw_stats
->pdev_cont_xretry
);
483 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
484 "TX timeout", fw_stats
->pdev_tx_timeout
);
485 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
486 "PDEV resets", fw_stats
->pdev_resets
);
487 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
488 "PHY underrun", fw_stats
->phy_underrun
);
489 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
490 "MPDU is more than txop limit", fw_stats
->txop_ovf
);
492 len
+= scnprintf(buf
+ len
, buf_len
- len
, "\n");
493 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s\n",
494 "ath10k PDEV RX stats");
495 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s\n\n",
496 "=================");
498 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
499 "Mid PPDU route change",
500 fw_stats
->mid_ppdu_route_change
);
501 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
502 "Tot. number of statuses", fw_stats
->status_rcvd
);
503 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
504 "Extra frags on rings 0", fw_stats
->r0_frags
);
505 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
506 "Extra frags on rings 1", fw_stats
->r1_frags
);
507 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
508 "Extra frags on rings 2", fw_stats
->r2_frags
);
509 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
510 "Extra frags on rings 3", fw_stats
->r3_frags
);
511 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
512 "MSDUs delivered to HTT", fw_stats
->htt_msdus
);
513 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
514 "MPDUs delivered to HTT", fw_stats
->htt_mpdus
);
515 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
516 "MSDUs delivered to stack", fw_stats
->loc_msdus
);
517 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
518 "MPDUs delivered to stack", fw_stats
->loc_mpdus
);
519 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
520 "Oversized AMSUs", fw_stats
->oversize_amsdu
);
521 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
522 "PHY errors", fw_stats
->phy_errs
);
523 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
524 "PHY errors drops", fw_stats
->phy_err_drop
);
525 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %10d\n",
526 "MPDU errors (FCS, MIC, ENC)", fw_stats
->mpdu_errs
);
528 len
+= scnprintf(buf
+ len
, buf_len
- len
, "\n");
529 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s (%d)\n",
530 "ath10k PEER stats", fw_stats
->peers
);
531 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s\n\n",
532 "=================");
534 for (i
= 0; i
< fw_stats
->peers
; i
++) {
535 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %pM\n",
537 fw_stats
->peer_stat
[i
].peer_macaddr
);
538 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %u\n",
539 "Peer RSSI", fw_stats
->peer_stat
[i
].peer_rssi
);
540 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %u\n",
542 fw_stats
->peer_stat
[i
].peer_tx_rate
);
543 len
+= scnprintf(buf
+ len
, buf_len
- len
, "%30s %u\n",
545 fw_stats
->peer_stat
[i
].peer_rx_rate
);
546 len
+= scnprintf(buf
+ len
, buf_len
- len
, "\n");
548 spin_unlock_bh(&ar
->data_lock
);
553 ret_cnt
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
556 mutex_unlock(&ar
->conf_mutex
);
561 static const struct file_operations fops_fw_stats
= {
562 .read
= ath10k_read_fw_stats
,
564 .owner
= THIS_MODULE
,
565 .llseek
= default_llseek
,
568 /* This is a clean assert crash in firmware. */
569 static int ath10k_debug_fw_assert(struct ath10k
*ar
)
571 struct wmi_vdev_install_key_cmd
*cmd
;
574 skb
= ath10k_wmi_alloc_skb(ar
, sizeof(*cmd
) + 16);
578 cmd
= (struct wmi_vdev_install_key_cmd
*)skb
->data
;
579 memset(cmd
, 0, sizeof(*cmd
));
581 /* big enough number so that firmware asserts */
582 cmd
->vdev_id
= __cpu_to_le32(0x7ffe);
584 return ath10k_wmi_cmd_send(ar
, skb
,
585 ar
->wmi
.cmd
->vdev_install_key_cmdid
);
588 static ssize_t
ath10k_read_simulate_fw_crash(struct file
*file
,
589 char __user
*user_buf
,
590 size_t count
, loff_t
*ppos
)
593 "To simulate firmware crash write one of the keywords to this file:\n"
594 "`soft` - this will send WMI_FORCE_FW_HANG_ASSERT to firmware if FW supports that command.\n"
595 "`hard` - this will send to firmware command with illegal parameters causing firmware crash.\n"
596 "`assert` - this will send special illegal parameter to firmware to cause assert failure and crash.\n";
598 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, strlen(buf
));
601 /* Simulate firmware crash:
602 * 'soft': Call wmi command causing firmware hang. This firmware hang is
603 * recoverable by warm firmware reset.
604 * 'hard': Force firmware crash by setting any vdev parameter for not allowed
605 * vdev id. This is hard firmware crash because it is recoverable only by cold
608 static ssize_t
ath10k_write_simulate_fw_crash(struct file
*file
,
609 const char __user
*user_buf
,
610 size_t count
, loff_t
*ppos
)
612 struct ath10k
*ar
= file
->private_data
;
616 mutex_lock(&ar
->conf_mutex
);
618 simple_write_to_buffer(buf
, sizeof(buf
) - 1, ppos
, user_buf
, count
);
620 /* make sure that buf is null terminated */
621 buf
[sizeof(buf
) - 1] = 0;
623 if (ar
->state
!= ATH10K_STATE_ON
&&
624 ar
->state
!= ATH10K_STATE_RESTARTED
) {
629 /* drop the possible '\n' from the end */
630 if (buf
[count
- 1] == '\n') {
635 if (!strcmp(buf
, "soft")) {
636 ath10k_info(ar
, "simulating soft firmware crash\n");
637 ret
= ath10k_wmi_force_fw_hang(ar
, WMI_FORCE_FW_HANG_ASSERT
, 0);
638 } else if (!strcmp(buf
, "hard")) {
639 ath10k_info(ar
, "simulating hard firmware crash\n");
640 /* 0x7fff is vdev id, and it is always out of range for all
641 * firmware variants in order to force a firmware crash.
643 ret
= ath10k_wmi_vdev_set_param(ar
, 0x7fff,
644 ar
->wmi
.vdev_param
->rts_threshold
,
646 } else if (!strcmp(buf
, "assert")) {
647 ath10k_info(ar
, "simulating firmware assert crash\n");
648 ret
= ath10k_debug_fw_assert(ar
);
655 ath10k_warn(ar
, "failed to simulate firmware crash: %d\n", ret
);
662 mutex_unlock(&ar
->conf_mutex
);
666 static const struct file_operations fops_simulate_fw_crash
= {
667 .read
= ath10k_read_simulate_fw_crash
,
668 .write
= ath10k_write_simulate_fw_crash
,
670 .owner
= THIS_MODULE
,
671 .llseek
= default_llseek
,
674 static ssize_t
ath10k_read_chip_id(struct file
*file
, char __user
*user_buf
,
675 size_t count
, loff_t
*ppos
)
677 struct ath10k
*ar
= file
->private_data
;
681 len
= scnprintf(buf
, sizeof(buf
), "0x%08x\n", ar
->chip_id
);
683 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
686 static const struct file_operations fops_chip_id
= {
687 .read
= ath10k_read_chip_id
,
689 .owner
= THIS_MODULE
,
690 .llseek
= default_llseek
,
693 struct ath10k_fw_crash_data
*
694 ath10k_debug_get_new_fw_crash_data(struct ath10k
*ar
)
696 struct ath10k_fw_crash_data
*crash_data
= ar
->debug
.fw_crash_data
;
698 lockdep_assert_held(&ar
->data_lock
);
700 crash_data
->crashed_since_read
= true;
701 uuid_le_gen(&crash_data
->uuid
);
702 getnstimeofday(&crash_data
->timestamp
);
706 EXPORT_SYMBOL(ath10k_debug_get_new_fw_crash_data
);
708 static struct ath10k_dump_file_data
*ath10k_build_dump_file(struct ath10k
*ar
)
710 struct ath10k_fw_crash_data
*crash_data
= ar
->debug
.fw_crash_data
;
711 struct ath10k_dump_file_data
*dump_data
;
712 struct ath10k_tlv_dump_data
*dump_tlv
;
713 int hdr_len
= sizeof(*dump_data
);
714 unsigned int len
, sofar
= 0;
718 len
+= sizeof(*dump_tlv
) + sizeof(crash_data
->registers
);
722 /* This is going to get big when we start dumping FW RAM and such,
723 * so go ahead and use vmalloc.
729 spin_lock_bh(&ar
->data_lock
);
731 if (!crash_data
->crashed_since_read
) {
732 spin_unlock_bh(&ar
->data_lock
);
737 dump_data
= (struct ath10k_dump_file_data
*)(buf
);
738 strlcpy(dump_data
->df_magic
, "ATH10K-FW-DUMP",
739 sizeof(dump_data
->df_magic
));
740 dump_data
->len
= cpu_to_le32(len
);
742 dump_data
->version
= cpu_to_le32(ATH10K_FW_CRASH_DUMP_VERSION
);
744 memcpy(dump_data
->uuid
, &crash_data
->uuid
, sizeof(dump_data
->uuid
));
745 dump_data
->chip_id
= cpu_to_le32(ar
->chip_id
);
746 dump_data
->bus_type
= cpu_to_le32(0);
747 dump_data
->target_version
= cpu_to_le32(ar
->target_version
);
748 dump_data
->fw_version_major
= cpu_to_le32(ar
->fw_version_major
);
749 dump_data
->fw_version_minor
= cpu_to_le32(ar
->fw_version_minor
);
750 dump_data
->fw_version_release
= cpu_to_le32(ar
->fw_version_release
);
751 dump_data
->fw_version_build
= cpu_to_le32(ar
->fw_version_build
);
752 dump_data
->phy_capability
= cpu_to_le32(ar
->phy_capability
);
753 dump_data
->hw_min_tx_power
= cpu_to_le32(ar
->hw_min_tx_power
);
754 dump_data
->hw_max_tx_power
= cpu_to_le32(ar
->hw_max_tx_power
);
755 dump_data
->ht_cap_info
= cpu_to_le32(ar
->ht_cap_info
);
756 dump_data
->vht_cap_info
= cpu_to_le32(ar
->vht_cap_info
);
757 dump_data
->num_rf_chains
= cpu_to_le32(ar
->num_rf_chains
);
759 strlcpy(dump_data
->fw_ver
, ar
->hw
->wiphy
->fw_version
,
760 sizeof(dump_data
->fw_ver
));
762 dump_data
->kernel_ver_code
= cpu_to_le32(LINUX_VERSION_CODE
);
763 strlcpy(dump_data
->kernel_ver
, VERMAGIC_STRING
,
764 sizeof(dump_data
->kernel_ver
));
766 dump_data
->tv_sec
= cpu_to_le64(crash_data
->timestamp
.tv_sec
);
767 dump_data
->tv_nsec
= cpu_to_le64(crash_data
->timestamp
.tv_nsec
);
769 /* Gather crash-dump */
770 dump_tlv
= (struct ath10k_tlv_dump_data
*)(buf
+ sofar
);
771 dump_tlv
->type
= cpu_to_le32(ATH10K_FW_CRASH_DUMP_REGISTERS
);
772 dump_tlv
->tlv_len
= cpu_to_le32(sizeof(crash_data
->registers
));
773 memcpy(dump_tlv
->tlv_data
, &crash_data
->registers
,
774 sizeof(crash_data
->registers
));
775 sofar
+= sizeof(*dump_tlv
) + sizeof(crash_data
->registers
);
777 ar
->debug
.fw_crash_data
->crashed_since_read
= false;
779 spin_unlock_bh(&ar
->data_lock
);
784 static int ath10k_fw_crash_dump_open(struct inode
*inode
, struct file
*file
)
786 struct ath10k
*ar
= inode
->i_private
;
787 struct ath10k_dump_file_data
*dump
;
789 dump
= ath10k_build_dump_file(ar
);
793 file
->private_data
= dump
;
798 static ssize_t
ath10k_fw_crash_dump_read(struct file
*file
,
799 char __user
*user_buf
,
800 size_t count
, loff_t
*ppos
)
802 struct ath10k_dump_file_data
*dump_file
= file
->private_data
;
804 return simple_read_from_buffer(user_buf
, count
, ppos
,
806 le32_to_cpu(dump_file
->len
));
809 static int ath10k_fw_crash_dump_release(struct inode
*inode
,
812 vfree(file
->private_data
);
817 static const struct file_operations fops_fw_crash_dump
= {
818 .open
= ath10k_fw_crash_dump_open
,
819 .read
= ath10k_fw_crash_dump_read
,
820 .release
= ath10k_fw_crash_dump_release
,
821 .owner
= THIS_MODULE
,
822 .llseek
= default_llseek
,
825 static int ath10k_debug_htt_stats_req(struct ath10k
*ar
)
830 lockdep_assert_held(&ar
->conf_mutex
);
832 if (ar
->debug
.htt_stats_mask
== 0)
833 /* htt stats are disabled */
836 if (ar
->state
!= ATH10K_STATE_ON
)
839 cookie
= get_jiffies_64();
841 ret
= ath10k_htt_h2t_stats_req(&ar
->htt
, ar
->debug
.htt_stats_mask
,
844 ath10k_warn(ar
, "failed to send htt stats request: %d\n", ret
);
848 queue_delayed_work(ar
->workqueue
, &ar
->debug
.htt_stats_dwork
,
849 msecs_to_jiffies(ATH10K_DEBUG_HTT_STATS_INTERVAL
));
854 static void ath10k_debug_htt_stats_dwork(struct work_struct
*work
)
856 struct ath10k
*ar
= container_of(work
, struct ath10k
,
857 debug
.htt_stats_dwork
.work
);
859 mutex_lock(&ar
->conf_mutex
);
861 ath10k_debug_htt_stats_req(ar
);
863 mutex_unlock(&ar
->conf_mutex
);
866 static ssize_t
ath10k_read_htt_stats_mask(struct file
*file
,
867 char __user
*user_buf
,
868 size_t count
, loff_t
*ppos
)
870 struct ath10k
*ar
= file
->private_data
;
874 len
= scnprintf(buf
, sizeof(buf
), "%lu\n", ar
->debug
.htt_stats_mask
);
876 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
879 static ssize_t
ath10k_write_htt_stats_mask(struct file
*file
,
880 const char __user
*user_buf
,
881 size_t count
, loff_t
*ppos
)
883 struct ath10k
*ar
= file
->private_data
;
887 ret
= kstrtoul_from_user(user_buf
, count
, 0, &mask
);
891 /* max 8 bit masks (for now) */
895 mutex_lock(&ar
->conf_mutex
);
897 ar
->debug
.htt_stats_mask
= mask
;
899 ret
= ath10k_debug_htt_stats_req(ar
);
906 mutex_unlock(&ar
->conf_mutex
);
911 static const struct file_operations fops_htt_stats_mask
= {
912 .read
= ath10k_read_htt_stats_mask
,
913 .write
= ath10k_write_htt_stats_mask
,
915 .owner
= THIS_MODULE
,
916 .llseek
= default_llseek
,
919 static ssize_t
ath10k_read_htt_max_amsdu_ampdu(struct file
*file
,
920 char __user
*user_buf
,
921 size_t count
, loff_t
*ppos
)
923 struct ath10k
*ar
= file
->private_data
;
925 u8 amsdu
= 3, ampdu
= 64;
928 mutex_lock(&ar
->conf_mutex
);
930 if (ar
->debug
.htt_max_amsdu
)
931 amsdu
= ar
->debug
.htt_max_amsdu
;
933 if (ar
->debug
.htt_max_ampdu
)
934 ampdu
= ar
->debug
.htt_max_ampdu
;
936 mutex_unlock(&ar
->conf_mutex
);
938 len
= scnprintf(buf
, sizeof(buf
), "%u %u\n", amsdu
, ampdu
);
940 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
943 static ssize_t
ath10k_write_htt_max_amsdu_ampdu(struct file
*file
,
944 const char __user
*user_buf
,
945 size_t count
, loff_t
*ppos
)
947 struct ath10k
*ar
= file
->private_data
;
950 unsigned int amsdu
, ampdu
;
952 simple_write_to_buffer(buf
, sizeof(buf
) - 1, ppos
, user_buf
, count
);
954 /* make sure that buf is null terminated */
955 buf
[sizeof(buf
) - 1] = 0;
957 res
= sscanf(buf
, "%u %u", &amsdu
, &du
);
962 mutex_lock(&ar
->conf_mutex
);
964 res
= ath10k_htt_h2t_aggr_cfg_msg(&ar
->htt
, ampdu
, amsdu
);
969 ar
->debug
.htt_max_amsdu
= amsdu
;
970 ar
->debug
.htt_max_ampdu
= ampdu
;
973 mutex_unlock(&ar
->conf_mutex
);
977 static const struct file_operations fops_htt_max_amsdu_ampdu
= {
978 .read
= ath10k_read_htt_max_amsdu_ampdu
,
979 .write
= ath10k_write_htt_max_amsdu_ampdu
,
981 .owner
= THIS_MODULE
,
982 .llseek
= default_llseek
,
985 static ssize_t
ath10k_read_fw_dbglog(struct file
*file
,
986 char __user
*user_buf
,
987 size_t count
, loff_t
*ppos
)
989 struct ath10k
*ar
= file
->private_data
;
993 len
= scnprintf(buf
, sizeof(buf
), "0x%08x\n",
994 ar
->debug
.fw_dbglog_mask
);
996 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
999 static ssize_t
ath10k_write_fw_dbglog(struct file
*file
,
1000 const char __user
*user_buf
,
1001 size_t count
, loff_t
*ppos
)
1003 struct ath10k
*ar
= file
->private_data
;
1007 ret
= kstrtoul_from_user(user_buf
, count
, 0, &mask
);
1011 mutex_lock(&ar
->conf_mutex
);
1013 ar
->debug
.fw_dbglog_mask
= mask
;
1015 if (ar
->state
== ATH10K_STATE_ON
) {
1016 ret
= ath10k_wmi_dbglog_cfg(ar
, ar
->debug
.fw_dbglog_mask
);
1018 ath10k_warn(ar
, "dbglog cfg failed from debugfs: %d\n",
1027 mutex_unlock(&ar
->conf_mutex
);
1032 static const struct file_operations fops_fw_dbglog
= {
1033 .read
= ath10k_read_fw_dbglog
,
1034 .write
= ath10k_write_fw_dbglog
,
1035 .open
= simple_open
,
1036 .owner
= THIS_MODULE
,
1037 .llseek
= default_llseek
,
1040 int ath10k_debug_start(struct ath10k
*ar
)
1044 lockdep_assert_held(&ar
->conf_mutex
);
1046 ret
= ath10k_debug_htt_stats_req(ar
);
1048 /* continue normally anyway, this isn't serious */
1049 ath10k_warn(ar
, "failed to start htt stats workqueue: %d\n",
1052 if (ar
->debug
.fw_dbglog_mask
) {
1053 ret
= ath10k_wmi_dbglog_cfg(ar
, ar
->debug
.fw_dbglog_mask
);
1056 ath10k_warn(ar
, "failed to enable dbglog during start: %d",
1063 void ath10k_debug_stop(struct ath10k
*ar
)
1065 lockdep_assert_held(&ar
->conf_mutex
);
1067 /* Must not use _sync to avoid deadlock, we do that in
1068 * ath10k_debug_destroy(). The check for htt_stats_mask is to avoid
1069 * warning from del_timer(). */
1070 if (ar
->debug
.htt_stats_mask
!= 0)
1071 cancel_delayed_work(&ar
->debug
.htt_stats_dwork
);
1073 ar
->debug
.htt_max_amsdu
= 0;
1074 ar
->debug
.htt_max_ampdu
= 0;
1077 static ssize_t
ath10k_write_simulate_radar(struct file
*file
,
1078 const char __user
*user_buf
,
1079 size_t count
, loff_t
*ppos
)
1081 struct ath10k
*ar
= file
->private_data
;
1083 ieee80211_radar_detected(ar
->hw
);
1088 static const struct file_operations fops_simulate_radar
= {
1089 .write
= ath10k_write_simulate_radar
,
1090 .open
= simple_open
,
1091 .owner
= THIS_MODULE
,
1092 .llseek
= default_llseek
,
1095 #define ATH10K_DFS_STAT(s, p) (\
1096 len += scnprintf(buf + len, size - len, "%-28s : %10u\n", s, \
1097 ar->debug.dfs_stats.p))
1099 #define ATH10K_DFS_POOL_STAT(s, p) (\
1100 len += scnprintf(buf + len, size - len, "%-28s : %10u\n", s, \
1101 ar->debug.dfs_pool_stats.p))
1103 static ssize_t
ath10k_read_dfs_stats(struct file
*file
, char __user
*user_buf
,
1104 size_t count
, loff_t
*ppos
)
1106 int retval
= 0, len
= 0;
1107 const int size
= 8000;
1108 struct ath10k
*ar
= file
->private_data
;
1111 buf
= kzalloc(size
, GFP_KERNEL
);
1115 if (!ar
->dfs_detector
) {
1116 len
+= scnprintf(buf
+ len
, size
- len
, "DFS not enabled\n");
1120 ar
->debug
.dfs_pool_stats
=
1121 ar
->dfs_detector
->get_stats(ar
->dfs_detector
);
1123 len
+= scnprintf(buf
+ len
, size
- len
, "Pulse detector statistics:\n");
1125 ATH10K_DFS_STAT("reported phy errors", phy_errors
);
1126 ATH10K_DFS_STAT("pulse events reported", pulses_total
);
1127 ATH10K_DFS_STAT("DFS pulses detected", pulses_detected
);
1128 ATH10K_DFS_STAT("DFS pulses discarded", pulses_discarded
);
1129 ATH10K_DFS_STAT("Radars detected", radar_detected
);
1131 len
+= scnprintf(buf
+ len
, size
- len
, "Global Pool statistics:\n");
1132 ATH10K_DFS_POOL_STAT("Pool references", pool_reference
);
1133 ATH10K_DFS_POOL_STAT("Pulses allocated", pulse_allocated
);
1134 ATH10K_DFS_POOL_STAT("Pulses alloc error", pulse_alloc_error
);
1135 ATH10K_DFS_POOL_STAT("Pulses in use", pulse_used
);
1136 ATH10K_DFS_POOL_STAT("Seqs. allocated", pseq_allocated
);
1137 ATH10K_DFS_POOL_STAT("Seqs. alloc error", pseq_alloc_error
);
1138 ATH10K_DFS_POOL_STAT("Seqs. in use", pseq_used
);
1144 retval
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
1150 static const struct file_operations fops_dfs_stats
= {
1151 .read
= ath10k_read_dfs_stats
,
1152 .open
= simple_open
,
1153 .owner
= THIS_MODULE
,
1154 .llseek
= default_llseek
,
1157 int ath10k_debug_create(struct ath10k
*ar
)
1159 ar
->debug
.fw_crash_data
= vzalloc(sizeof(*ar
->debug
.fw_crash_data
));
1160 if (!ar
->debug
.fw_crash_data
)
1166 void ath10k_debug_destroy(struct ath10k
*ar
)
1168 vfree(ar
->debug
.fw_crash_data
);
1169 ar
->debug
.fw_crash_data
= NULL
;
1172 int ath10k_debug_register(struct ath10k
*ar
)
1174 ar
->debug
.debugfs_phy
= debugfs_create_dir("ath10k",
1175 ar
->hw
->wiphy
->debugfsdir
);
1176 if (IS_ERR_OR_NULL(ar
->debug
.debugfs_phy
)) {
1177 if (IS_ERR(ar
->debug
.debugfs_phy
))
1178 return PTR_ERR(ar
->debug
.debugfs_phy
);
1183 INIT_DELAYED_WORK(&ar
->debug
.htt_stats_dwork
,
1184 ath10k_debug_htt_stats_dwork
);
1186 init_completion(&ar
->debug
.event_stats_compl
);
1188 debugfs_create_file("fw_stats", S_IRUSR
, ar
->debug
.debugfs_phy
, ar
,
1191 debugfs_create_file("wmi_services", S_IRUSR
, ar
->debug
.debugfs_phy
, ar
,
1192 &fops_wmi_services
);
1194 debugfs_create_file("simulate_fw_crash", S_IRUSR
, ar
->debug
.debugfs_phy
,
1195 ar
, &fops_simulate_fw_crash
);
1197 debugfs_create_file("fw_crash_dump", S_IRUSR
, ar
->debug
.debugfs_phy
,
1198 ar
, &fops_fw_crash_dump
);
1200 debugfs_create_file("chip_id", S_IRUSR
, ar
->debug
.debugfs_phy
,
1203 debugfs_create_file("htt_stats_mask", S_IRUSR
, ar
->debug
.debugfs_phy
,
1204 ar
, &fops_htt_stats_mask
);
1206 debugfs_create_file("htt_max_amsdu_ampdu", S_IRUSR
| S_IWUSR
,
1207 ar
->debug
.debugfs_phy
, ar
,
1208 &fops_htt_max_amsdu_ampdu
);
1210 debugfs_create_file("fw_dbglog", S_IRUSR
, ar
->debug
.debugfs_phy
,
1211 ar
, &fops_fw_dbglog
);
1213 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED
)) {
1214 debugfs_create_file("dfs_simulate_radar", S_IWUSR
,
1215 ar
->debug
.debugfs_phy
, ar
,
1216 &fops_simulate_radar
);
1218 debugfs_create_bool("dfs_block_radar_events", S_IWUSR
,
1219 ar
->debug
.debugfs_phy
,
1220 &ar
->dfs_block_radar_events
);
1222 debugfs_create_file("dfs_stats", S_IRUSR
,
1223 ar
->debug
.debugfs_phy
, ar
,
1230 void ath10k_debug_unregister(struct ath10k
*ar
)
1232 cancel_delayed_work_sync(&ar
->debug
.htt_stats_dwork
);
1235 #endif /* CONFIG_ATH10K_DEBUGFS */
1237 #ifdef CONFIG_ATH10K_DEBUG
1238 void ath10k_dbg(struct ath10k
*ar
, enum ath10k_debug_mask mask
,
1239 const char *fmt
, ...)
1241 struct va_format vaf
;
1244 va_start(args
, fmt
);
1249 if (ath10k_debug_mask
& mask
)
1250 dev_printk(KERN_DEBUG
, ar
->dev
, "%pV", &vaf
);
1252 trace_ath10k_log_dbg(ar
, mask
, &vaf
);
1256 EXPORT_SYMBOL(ath10k_dbg
);
1258 void ath10k_dbg_dump(struct ath10k
*ar
,
1259 enum ath10k_debug_mask mask
,
1260 const char *msg
, const char *prefix
,
1261 const void *buf
, size_t len
)
1263 if (ath10k_debug_mask
& mask
) {
1265 ath10k_dbg(ar
, mask
, "%s\n", msg
);
1267 print_hex_dump_bytes(prefix
, DUMP_PREFIX_OFFSET
, buf
, len
);
1270 /* tracing code doesn't like null strings :/ */
1271 trace_ath10k_log_dbg_dump(ar
, msg
? msg
: "", prefix
? prefix
: "",
1274 EXPORT_SYMBOL(ath10k_dbg_dump
);
1276 #endif /* CONFIG_ATH10K_DEBUG */