1 /* 2 * Copyright (c) 2005-2011 Atheros Communications Inc. 3 * Copyright (c) 2011-2013 Qualcomm Atheros, Inc. 4 * 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. 8 * 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. 16 */ 17 18 #include <linux/module.h> 19 #include <linux/debugfs.h> 20 #include <linux/vmalloc.h> 21 #include <linux/utsname.h> 22 23 #include "core.h" 24 #include "debug.h" 25 #include "hif.h" 26 27 /* ms */ 28 #define ATH10K_DEBUG_HTT_STATS_INTERVAL 1000 29 30 #define ATH10K_FW_CRASH_DUMP_VERSION 1 31 32 /** 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 35 */ 36 enum ath10k_fw_crash_dump_type { 37 ATH10K_FW_CRASH_DUMP_REGISTERS = 0, 38 39 ATH10K_FW_CRASH_DUMP_MAX, 40 }; 41 42 struct ath10k_tlv_dump_data { 43 /* see ath10k_fw_crash_dump_type above */ 44 __le32 type; 45 46 /* in bytes */ 47 __le32 tlv_len; 48 49 /* pad to 32-bit boundaries as needed */ 50 u8 tlv_data[]; 51 } __packed; 52 53 struct ath10k_dump_file_data { 54 /* dump file information */ 55 56 /* "ATH10K-FW-DUMP" */ 57 char df_magic[16]; 58 59 __le32 len; 60 61 /* file dump version */ 62 __le32 version; 63 64 /* some info we can get from ath10k struct that might help */ 65 66 u8 uuid[16]; 67 68 __le32 chip_id; 69 70 /* 0 for now, in place for later hardware */ 71 __le32 bus_type; 72 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; 81 __le32 ht_cap_info; 82 __le32 vht_cap_info; 83 __le32 num_rf_chains; 84 85 /* firmware version string */ 86 char fw_ver[ETHTOOL_FWVERS_LEN]; 87 88 /* Kernel related information */ 89 90 /* time-of-day stamp */ 91 __le64 tv_sec; 92 93 /* time-of-day stamp, nano-seconds */ 94 __le64 tv_nsec; 95 96 /* LINUX_VERSION_CODE */ 97 __le32 kernel_ver_code; 98 99 /* VERMAGIC_STRING */ 100 char kernel_ver[64]; 101 102 /* room for growth w/out changing binary format */ 103 u8 unused[128]; 104 105 /* struct ath10k_tlv_dump_data + more */ 106 u8 data[0]; 107 } __packed; 108 109 void ath10k_info(struct ath10k *ar, const char *fmt, ...) 110 { 111 struct va_format vaf = { 112 .fmt = fmt, 113 }; 114 va_list args; 115 116 va_start(args, fmt); 117 vaf.va = &args; 118 dev_info(ar->dev, "%pV", &vaf); 119 trace_ath10k_log_info(ar, &vaf); 120 va_end(args); 121 } 122 EXPORT_SYMBOL(ath10k_info); 123 124 void ath10k_print_driver_info(struct ath10k *ar) 125 { 126 ath10k_info(ar, "%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d wmi %d.%d.%d.%d cal %s max_sta %d\n", 127 ar->hw_params.name, 128 ar->target_version, 129 ar->chip_id, 130 ar->hw->wiphy->fw_version, 131 ar->fw_api, 132 ar->htt.target_version_major, 133 ar->htt.target_version_minor, 134 ar->fw_version_major, 135 ar->fw_version_minor, 136 ar->fw_version_release, 137 ar->fw_version_build, 138 ath10k_cal_mode_str(ar->cal_mode), 139 ar->max_num_stations); 140 ath10k_info(ar, "debug %d debugfs %d tracing %d dfs %d testmode %d\n", 141 config_enabled(CONFIG_ATH10K_DEBUG), 142 config_enabled(CONFIG_ATH10K_DEBUGFS), 143 config_enabled(CONFIG_ATH10K_TRACING), 144 config_enabled(CONFIG_ATH10K_DFS_CERTIFIED), 145 config_enabled(CONFIG_NL80211_TESTMODE)); 146 } 147 EXPORT_SYMBOL(ath10k_print_driver_info); 148 149 void ath10k_err(struct ath10k *ar, const char *fmt, ...) 150 { 151 struct va_format vaf = { 152 .fmt = fmt, 153 }; 154 va_list args; 155 156 va_start(args, fmt); 157 vaf.va = &args; 158 dev_err(ar->dev, "%pV", &vaf); 159 trace_ath10k_log_err(ar, &vaf); 160 va_end(args); 161 } 162 EXPORT_SYMBOL(ath10k_err); 163 164 void ath10k_warn(struct ath10k *ar, const char *fmt, ...) 165 { 166 struct va_format vaf = { 167 .fmt = fmt, 168 }; 169 va_list args; 170 171 va_start(args, fmt); 172 vaf.va = &args; 173 dev_warn_ratelimited(ar->dev, "%pV", &vaf); 174 trace_ath10k_log_warn(ar, &vaf); 175 176 va_end(args); 177 } 178 EXPORT_SYMBOL(ath10k_warn); 179 180 #ifdef CONFIG_ATH10K_DEBUGFS 181 182 static ssize_t ath10k_read_wmi_services(struct file *file, 183 char __user *user_buf, 184 size_t count, loff_t *ppos) 185 { 186 struct ath10k *ar = file->private_data; 187 char *buf; 188 unsigned int len = 0, buf_len = 4096; 189 const char *name; 190 ssize_t ret_cnt; 191 bool enabled; 192 int i; 193 194 buf = kzalloc(buf_len, GFP_KERNEL); 195 if (!buf) 196 return -ENOMEM; 197 198 mutex_lock(&ar->conf_mutex); 199 200 if (len > buf_len) 201 len = buf_len; 202 203 spin_lock_bh(&ar->data_lock); 204 for (i = 0; i < WMI_SERVICE_MAX; i++) { 205 enabled = test_bit(i, ar->wmi.svc_map); 206 name = wmi_service_name(i); 207 208 if (!name) { 209 if (enabled) 210 len += scnprintf(buf + len, buf_len - len, 211 "%-40s %s (bit %d)\n", 212 "unknown", "enabled", i); 213 214 continue; 215 } 216 217 len += scnprintf(buf + len, buf_len - len, 218 "%-40s %s\n", 219 name, enabled ? "enabled" : "-"); 220 } 221 spin_unlock_bh(&ar->data_lock); 222 223 ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); 224 225 mutex_unlock(&ar->conf_mutex); 226 227 kfree(buf); 228 return ret_cnt; 229 } 230 231 static const struct file_operations fops_wmi_services = { 232 .read = ath10k_read_wmi_services, 233 .open = simple_open, 234 .owner = THIS_MODULE, 235 .llseek = default_llseek, 236 }; 237 238 static void ath10k_debug_fw_stats_pdevs_free(struct list_head *head) 239 { 240 struct ath10k_fw_stats_pdev *i, *tmp; 241 242 list_for_each_entry_safe(i, tmp, head, list) { 243 list_del(&i->list); 244 kfree(i); 245 } 246 } 247 248 static void ath10k_debug_fw_stats_peers_free(struct list_head *head) 249 { 250 struct ath10k_fw_stats_peer *i, *tmp; 251 252 list_for_each_entry_safe(i, tmp, head, list) { 253 list_del(&i->list); 254 kfree(i); 255 } 256 } 257 258 static void ath10k_debug_fw_stats_reset(struct ath10k *ar) 259 { 260 spin_lock_bh(&ar->data_lock); 261 ar->debug.fw_stats_done = false; 262 ath10k_debug_fw_stats_pdevs_free(&ar->debug.fw_stats.pdevs); 263 ath10k_debug_fw_stats_peers_free(&ar->debug.fw_stats.peers); 264 spin_unlock_bh(&ar->data_lock); 265 } 266 267 static size_t ath10k_debug_fw_stats_num_peers(struct list_head *head) 268 { 269 struct ath10k_fw_stats_peer *i; 270 size_t num = 0; 271 272 list_for_each_entry(i, head, list) 273 ++num; 274 275 return num; 276 } 277 278 void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb) 279 { 280 struct ath10k_fw_stats stats = {}; 281 bool is_start, is_started, is_end; 282 size_t num_peers; 283 int ret; 284 285 INIT_LIST_HEAD(&stats.pdevs); 286 INIT_LIST_HEAD(&stats.peers); 287 288 spin_lock_bh(&ar->data_lock); 289 ret = ath10k_wmi_pull_fw_stats(ar, skb, &stats); 290 if (ret) { 291 ath10k_warn(ar, "failed to pull fw stats: %d\n", ret); 292 goto unlock; 293 } 294 295 /* Stat data may exceed htc-wmi buffer limit. In such case firmware 296 * splits the stats data and delivers it in a ping-pong fashion of 297 * request cmd-update event. 298 * 299 * However there is no explicit end-of-data. Instead start-of-data is 300 * used as an implicit one. This works as follows: 301 * a) discard stat update events until one with pdev stats is 302 * delivered - this skips session started at end of (b) 303 * b) consume stat update events until another one with pdev stats is 304 * delivered which is treated as end-of-data and is itself discarded 305 */ 306 307 if (ar->debug.fw_stats_done) { 308 ath10k_warn(ar, "received unsolicited stats update event\n"); 309 goto free; 310 } 311 312 num_peers = ath10k_debug_fw_stats_num_peers(&ar->debug.fw_stats.peers); 313 is_start = (list_empty(&ar->debug.fw_stats.pdevs) && 314 !list_empty(&stats.pdevs)); 315 is_end = (!list_empty(&ar->debug.fw_stats.pdevs) && 316 !list_empty(&stats.pdevs)); 317 318 if (is_start) 319 list_splice_tail_init(&stats.pdevs, &ar->debug.fw_stats.pdevs); 320 321 if (is_end) 322 ar->debug.fw_stats_done = true; 323 324 is_started = !list_empty(&ar->debug.fw_stats.pdevs); 325 326 if (is_started && !is_end) { 327 if (num_peers >= ATH10K_MAX_NUM_PEER_IDS) { 328 /* Although this is unlikely impose a sane limit to 329 * prevent firmware from DoS-ing the host. 330 */ 331 ath10k_warn(ar, "dropping fw peer stats\n"); 332 goto free; 333 } 334 335 list_splice_tail_init(&stats.peers, &ar->debug.fw_stats.peers); 336 } 337 338 complete(&ar->debug.fw_stats_complete); 339 340 free: 341 /* In some cases lists have been spliced and cleared. Free up 342 * resources if that is not the case. 343 */ 344 ath10k_debug_fw_stats_pdevs_free(&stats.pdevs); 345 ath10k_debug_fw_stats_peers_free(&stats.peers); 346 347 unlock: 348 spin_unlock_bh(&ar->data_lock); 349 } 350 351 static int ath10k_debug_fw_stats_request(struct ath10k *ar) 352 { 353 unsigned long timeout; 354 int ret; 355 356 lockdep_assert_held(&ar->conf_mutex); 357 358 timeout = jiffies + msecs_to_jiffies(1*HZ); 359 360 ath10k_debug_fw_stats_reset(ar); 361 362 for (;;) { 363 if (time_after(jiffies, timeout)) 364 return -ETIMEDOUT; 365 366 reinit_completion(&ar->debug.fw_stats_complete); 367 368 ret = ath10k_wmi_request_stats(ar, WMI_REQUEST_PEER_STAT); 369 if (ret) { 370 ath10k_warn(ar, "could not request stats (%d)\n", ret); 371 return ret; 372 } 373 374 ret = wait_for_completion_timeout(&ar->debug.fw_stats_complete, 375 1*HZ); 376 if (ret <= 0) 377 return -ETIMEDOUT; 378 379 spin_lock_bh(&ar->data_lock); 380 if (ar->debug.fw_stats_done) { 381 spin_unlock_bh(&ar->data_lock); 382 break; 383 } 384 spin_unlock_bh(&ar->data_lock); 385 } 386 387 return 0; 388 } 389 390 /* FIXME: How to calculate the buffer size sanely? */ 391 #define ATH10K_FW_STATS_BUF_SIZE (1024*1024) 392 393 static void ath10k_fw_stats_fill(struct ath10k *ar, 394 struct ath10k_fw_stats *fw_stats, 395 char *buf) 396 { 397 unsigned int len = 0; 398 unsigned int buf_len = ATH10K_FW_STATS_BUF_SIZE; 399 const struct ath10k_fw_stats_pdev *pdev; 400 const struct ath10k_fw_stats_peer *peer; 401 size_t num_peers; 402 403 spin_lock_bh(&ar->data_lock); 404 405 pdev = list_first_entry_or_null(&fw_stats->pdevs, 406 struct ath10k_fw_stats_pdev, list); 407 if (!pdev) { 408 ath10k_warn(ar, "failed to get pdev stats\n"); 409 goto unlock; 410 } 411 412 num_peers = ath10k_debug_fw_stats_num_peers(&fw_stats->peers); 413 414 len += scnprintf(buf + len, buf_len - len, "\n"); 415 len += scnprintf(buf + len, buf_len - len, "%30s\n", 416 "ath10k PDEV stats"); 417 len += scnprintf(buf + len, buf_len - len, "%30s\n\n", 418 "================="); 419 420 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 421 "Channel noise floor", pdev->ch_noise_floor); 422 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 423 "Channel TX power", pdev->chan_tx_power); 424 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 425 "TX frame count", pdev->tx_frame_count); 426 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 427 "RX frame count", pdev->rx_frame_count); 428 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 429 "RX clear count", pdev->rx_clear_count); 430 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 431 "Cycle count", pdev->cycle_count); 432 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 433 "PHY error count", pdev->phy_err_count); 434 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 435 "RTS bad count", pdev->rts_bad); 436 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 437 "RTS good count", pdev->rts_good); 438 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 439 "FCS bad count", pdev->fcs_bad); 440 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 441 "No beacon count", pdev->no_beacons); 442 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 443 "MIB int count", pdev->mib_int_count); 444 445 len += scnprintf(buf + len, buf_len - len, "\n"); 446 len += scnprintf(buf + len, buf_len - len, "%30s\n", 447 "ath10k PDEV TX stats"); 448 len += scnprintf(buf + len, buf_len - len, "%30s\n\n", 449 "================="); 450 451 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 452 "HTT cookies queued", pdev->comp_queued); 453 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 454 "HTT cookies disp.", pdev->comp_delivered); 455 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 456 "MSDU queued", pdev->msdu_enqued); 457 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 458 "MPDU queued", pdev->mpdu_enqued); 459 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 460 "MSDUs dropped", pdev->wmm_drop); 461 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 462 "Local enqued", pdev->local_enqued); 463 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 464 "Local freed", pdev->local_freed); 465 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 466 "HW queued", pdev->hw_queued); 467 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 468 "PPDUs reaped", pdev->hw_reaped); 469 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 470 "Num underruns", pdev->underrun); 471 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 472 "PPDUs cleaned", pdev->tx_abort); 473 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 474 "MPDUs requed", pdev->mpdus_requed); 475 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 476 "Excessive retries", pdev->tx_ko); 477 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 478 "HW rate", pdev->data_rc); 479 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 480 "Sched self tiggers", pdev->self_triggers); 481 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 482 "Dropped due to SW retries", 483 pdev->sw_retry_failure); 484 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 485 "Illegal rate phy errors", 486 pdev->illgl_rate_phy_err); 487 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 488 "Pdev continous xretry", pdev->pdev_cont_xretry); 489 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 490 "TX timeout", pdev->pdev_tx_timeout); 491 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 492 "PDEV resets", pdev->pdev_resets); 493 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 494 "PHY underrun", pdev->phy_underrun); 495 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 496 "MPDU is more than txop limit", pdev->txop_ovf); 497 498 len += scnprintf(buf + len, buf_len - len, "\n"); 499 len += scnprintf(buf + len, buf_len - len, "%30s\n", 500 "ath10k PDEV RX stats"); 501 len += scnprintf(buf + len, buf_len - len, "%30s\n\n", 502 "================="); 503 504 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 505 "Mid PPDU route change", 506 pdev->mid_ppdu_route_change); 507 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 508 "Tot. number of statuses", pdev->status_rcvd); 509 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 510 "Extra frags on rings 0", pdev->r0_frags); 511 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 512 "Extra frags on rings 1", pdev->r1_frags); 513 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 514 "Extra frags on rings 2", pdev->r2_frags); 515 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 516 "Extra frags on rings 3", pdev->r3_frags); 517 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 518 "MSDUs delivered to HTT", pdev->htt_msdus); 519 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 520 "MPDUs delivered to HTT", pdev->htt_mpdus); 521 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 522 "MSDUs delivered to stack", pdev->loc_msdus); 523 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 524 "MPDUs delivered to stack", pdev->loc_mpdus); 525 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 526 "Oversized AMSUs", pdev->oversize_amsdu); 527 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 528 "PHY errors", pdev->phy_errs); 529 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 530 "PHY errors drops", pdev->phy_err_drop); 531 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 532 "MPDU errors (FCS, MIC, ENC)", pdev->mpdu_errs); 533 534 len += scnprintf(buf + len, buf_len - len, "\n"); 535 len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n", 536 "ath10k PEER stats", num_peers); 537 len += scnprintf(buf + len, buf_len - len, "%30s\n\n", 538 "================="); 539 540 list_for_each_entry(peer, &fw_stats->peers, list) { 541 len += scnprintf(buf + len, buf_len - len, "%30s %pM\n", 542 "Peer MAC address", peer->peer_macaddr); 543 len += scnprintf(buf + len, buf_len - len, "%30s %u\n", 544 "Peer RSSI", peer->peer_rssi); 545 len += scnprintf(buf + len, buf_len - len, "%30s %u\n", 546 "Peer TX rate", peer->peer_tx_rate); 547 len += scnprintf(buf + len, buf_len - len, "%30s %u\n", 548 "Peer RX rate", peer->peer_rx_rate); 549 len += scnprintf(buf + len, buf_len - len, "\n"); 550 } 551 552 unlock: 553 spin_unlock_bh(&ar->data_lock); 554 555 if (len >= buf_len) 556 buf[len - 1] = 0; 557 else 558 buf[len] = 0; 559 } 560 561 static int ath10k_fw_stats_open(struct inode *inode, struct file *file) 562 { 563 struct ath10k *ar = inode->i_private; 564 void *buf = NULL; 565 int ret; 566 567 mutex_lock(&ar->conf_mutex); 568 569 if (ar->state != ATH10K_STATE_ON) { 570 ret = -ENETDOWN; 571 goto err_unlock; 572 } 573 574 buf = vmalloc(ATH10K_FW_STATS_BUF_SIZE); 575 if (!buf) { 576 ret = -ENOMEM; 577 goto err_unlock; 578 } 579 580 ret = ath10k_debug_fw_stats_request(ar); 581 if (ret) { 582 ath10k_warn(ar, "failed to request fw stats: %d\n", ret); 583 goto err_free; 584 } 585 586 ath10k_fw_stats_fill(ar, &ar->debug.fw_stats, buf); 587 file->private_data = buf; 588 589 mutex_unlock(&ar->conf_mutex); 590 return 0; 591 592 err_free: 593 vfree(buf); 594 595 err_unlock: 596 mutex_unlock(&ar->conf_mutex); 597 return ret; 598 } 599 600 static int ath10k_fw_stats_release(struct inode *inode, struct file *file) 601 { 602 vfree(file->private_data); 603 604 return 0; 605 } 606 607 static ssize_t ath10k_fw_stats_read(struct file *file, char __user *user_buf, 608 size_t count, loff_t *ppos) 609 { 610 const char *buf = file->private_data; 611 unsigned int len = strlen(buf); 612 613 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 614 } 615 616 static const struct file_operations fops_fw_stats = { 617 .open = ath10k_fw_stats_open, 618 .release = ath10k_fw_stats_release, 619 .read = ath10k_fw_stats_read, 620 .owner = THIS_MODULE, 621 .llseek = default_llseek, 622 }; 623 624 static ssize_t ath10k_debug_fw_reset_stats_read(struct file *file, 625 char __user *user_buf, 626 size_t count, loff_t *ppos) 627 { 628 struct ath10k *ar = file->private_data; 629 int ret, len, buf_len; 630 char *buf; 631 632 buf_len = 500; 633 buf = kmalloc(buf_len, GFP_KERNEL); 634 if (!buf) 635 return -ENOMEM; 636 637 spin_lock_bh(&ar->data_lock); 638 639 len = 0; 640 len += scnprintf(buf + len, buf_len - len, 641 "fw_crash_counter\t\t%d\n", ar->stats.fw_crash_counter); 642 len += scnprintf(buf + len, buf_len - len, 643 "fw_warm_reset_counter\t\t%d\n", 644 ar->stats.fw_warm_reset_counter); 645 len += scnprintf(buf + len, buf_len - len, 646 "fw_cold_reset_counter\t\t%d\n", 647 ar->stats.fw_cold_reset_counter); 648 649 spin_unlock_bh(&ar->data_lock); 650 651 ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); 652 653 kfree(buf); 654 655 return ret; 656 } 657 658 static const struct file_operations fops_fw_reset_stats = { 659 .open = simple_open, 660 .read = ath10k_debug_fw_reset_stats_read, 661 .owner = THIS_MODULE, 662 .llseek = default_llseek, 663 }; 664 665 /* This is a clean assert crash in firmware. */ 666 static int ath10k_debug_fw_assert(struct ath10k *ar) 667 { 668 struct wmi_vdev_install_key_cmd *cmd; 669 struct sk_buff *skb; 670 671 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd) + 16); 672 if (!skb) 673 return -ENOMEM; 674 675 cmd = (struct wmi_vdev_install_key_cmd *)skb->data; 676 memset(cmd, 0, sizeof(*cmd)); 677 678 /* big enough number so that firmware asserts */ 679 cmd->vdev_id = __cpu_to_le32(0x7ffe); 680 681 return ath10k_wmi_cmd_send(ar, skb, 682 ar->wmi.cmd->vdev_install_key_cmdid); 683 } 684 685 static ssize_t ath10k_read_simulate_fw_crash(struct file *file, 686 char __user *user_buf, 687 size_t count, loff_t *ppos) 688 { 689 const char buf[] = 690 "To simulate firmware crash write one of the keywords to this file:\n" 691 "`soft` - this will send WMI_FORCE_FW_HANG_ASSERT to firmware if FW supports that command.\n" 692 "`hard` - this will send to firmware command with illegal parameters causing firmware crash.\n" 693 "`assert` - this will send special illegal parameter to firmware to cause assert failure and crash.\n" 694 "`hw-restart` - this will simply queue hw restart without fw/hw actually crashing.\n"; 695 696 return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf)); 697 } 698 699 /* Simulate firmware crash: 700 * 'soft': Call wmi command causing firmware hang. This firmware hang is 701 * recoverable by warm firmware reset. 702 * 'hard': Force firmware crash by setting any vdev parameter for not allowed 703 * vdev id. This is hard firmware crash because it is recoverable only by cold 704 * firmware reset. 705 */ 706 static ssize_t ath10k_write_simulate_fw_crash(struct file *file, 707 const char __user *user_buf, 708 size_t count, loff_t *ppos) 709 { 710 struct ath10k *ar = file->private_data; 711 char buf[32]; 712 int ret; 713 714 mutex_lock(&ar->conf_mutex); 715 716 simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); 717 718 /* make sure that buf is null terminated */ 719 buf[sizeof(buf) - 1] = 0; 720 721 if (ar->state != ATH10K_STATE_ON && 722 ar->state != ATH10K_STATE_RESTARTED) { 723 ret = -ENETDOWN; 724 goto exit; 725 } 726 727 /* drop the possible '\n' from the end */ 728 if (buf[count - 1] == '\n') { 729 buf[count - 1] = 0; 730 count--; 731 } 732 733 if (!strcmp(buf, "soft")) { 734 ath10k_info(ar, "simulating soft firmware crash\n"); 735 ret = ath10k_wmi_force_fw_hang(ar, WMI_FORCE_FW_HANG_ASSERT, 0); 736 } else if (!strcmp(buf, "hard")) { 737 ath10k_info(ar, "simulating hard firmware crash\n"); 738 /* 0x7fff is vdev id, and it is always out of range for all 739 * firmware variants in order to force a firmware crash. 740 */ 741 ret = ath10k_wmi_vdev_set_param(ar, 0x7fff, 742 ar->wmi.vdev_param->rts_threshold, 743 0); 744 } else if (!strcmp(buf, "assert")) { 745 ath10k_info(ar, "simulating firmware assert crash\n"); 746 ret = ath10k_debug_fw_assert(ar); 747 } else if (!strcmp(buf, "hw-restart")) { 748 ath10k_info(ar, "user requested hw restart\n"); 749 queue_work(ar->workqueue, &ar->restart_work); 750 ret = 0; 751 } else { 752 ret = -EINVAL; 753 goto exit; 754 } 755 756 if (ret) { 757 ath10k_warn(ar, "failed to simulate firmware crash: %d\n", ret); 758 goto exit; 759 } 760 761 ret = count; 762 763 exit: 764 mutex_unlock(&ar->conf_mutex); 765 return ret; 766 } 767 768 static const struct file_operations fops_simulate_fw_crash = { 769 .read = ath10k_read_simulate_fw_crash, 770 .write = ath10k_write_simulate_fw_crash, 771 .open = simple_open, 772 .owner = THIS_MODULE, 773 .llseek = default_llseek, 774 }; 775 776 static ssize_t ath10k_read_chip_id(struct file *file, char __user *user_buf, 777 size_t count, loff_t *ppos) 778 { 779 struct ath10k *ar = file->private_data; 780 unsigned int len; 781 char buf[50]; 782 783 len = scnprintf(buf, sizeof(buf), "0x%08x\n", ar->chip_id); 784 785 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 786 } 787 788 static const struct file_operations fops_chip_id = { 789 .read = ath10k_read_chip_id, 790 .open = simple_open, 791 .owner = THIS_MODULE, 792 .llseek = default_llseek, 793 }; 794 795 struct ath10k_fw_crash_data * 796 ath10k_debug_get_new_fw_crash_data(struct ath10k *ar) 797 { 798 struct ath10k_fw_crash_data *crash_data = ar->debug.fw_crash_data; 799 800 lockdep_assert_held(&ar->data_lock); 801 802 crash_data->crashed_since_read = true; 803 uuid_le_gen(&crash_data->uuid); 804 getnstimeofday(&crash_data->timestamp); 805 806 return crash_data; 807 } 808 EXPORT_SYMBOL(ath10k_debug_get_new_fw_crash_data); 809 810 static struct ath10k_dump_file_data *ath10k_build_dump_file(struct ath10k *ar) 811 { 812 struct ath10k_fw_crash_data *crash_data = ar->debug.fw_crash_data; 813 struct ath10k_dump_file_data *dump_data; 814 struct ath10k_tlv_dump_data *dump_tlv; 815 int hdr_len = sizeof(*dump_data); 816 unsigned int len, sofar = 0; 817 unsigned char *buf; 818 819 len = hdr_len; 820 len += sizeof(*dump_tlv) + sizeof(crash_data->registers); 821 822 sofar += hdr_len; 823 824 /* This is going to get big when we start dumping FW RAM and such, 825 * so go ahead and use vmalloc. 826 */ 827 buf = vzalloc(len); 828 if (!buf) 829 return NULL; 830 831 spin_lock_bh(&ar->data_lock); 832 833 if (!crash_data->crashed_since_read) { 834 spin_unlock_bh(&ar->data_lock); 835 vfree(buf); 836 return NULL; 837 } 838 839 dump_data = (struct ath10k_dump_file_data *)(buf); 840 strlcpy(dump_data->df_magic, "ATH10K-FW-DUMP", 841 sizeof(dump_data->df_magic)); 842 dump_data->len = cpu_to_le32(len); 843 844 dump_data->version = cpu_to_le32(ATH10K_FW_CRASH_DUMP_VERSION); 845 846 memcpy(dump_data->uuid, &crash_data->uuid, sizeof(dump_data->uuid)); 847 dump_data->chip_id = cpu_to_le32(ar->chip_id); 848 dump_data->bus_type = cpu_to_le32(0); 849 dump_data->target_version = cpu_to_le32(ar->target_version); 850 dump_data->fw_version_major = cpu_to_le32(ar->fw_version_major); 851 dump_data->fw_version_minor = cpu_to_le32(ar->fw_version_minor); 852 dump_data->fw_version_release = cpu_to_le32(ar->fw_version_release); 853 dump_data->fw_version_build = cpu_to_le32(ar->fw_version_build); 854 dump_data->phy_capability = cpu_to_le32(ar->phy_capability); 855 dump_data->hw_min_tx_power = cpu_to_le32(ar->hw_min_tx_power); 856 dump_data->hw_max_tx_power = cpu_to_le32(ar->hw_max_tx_power); 857 dump_data->ht_cap_info = cpu_to_le32(ar->ht_cap_info); 858 dump_data->vht_cap_info = cpu_to_le32(ar->vht_cap_info); 859 dump_data->num_rf_chains = cpu_to_le32(ar->num_rf_chains); 860 861 strlcpy(dump_data->fw_ver, ar->hw->wiphy->fw_version, 862 sizeof(dump_data->fw_ver)); 863 864 dump_data->kernel_ver_code = 0; 865 strlcpy(dump_data->kernel_ver, init_utsname()->release, 866 sizeof(dump_data->kernel_ver)); 867 868 dump_data->tv_sec = cpu_to_le64(crash_data->timestamp.tv_sec); 869 dump_data->tv_nsec = cpu_to_le64(crash_data->timestamp.tv_nsec); 870 871 /* Gather crash-dump */ 872 dump_tlv = (struct ath10k_tlv_dump_data *)(buf + sofar); 873 dump_tlv->type = cpu_to_le32(ATH10K_FW_CRASH_DUMP_REGISTERS); 874 dump_tlv->tlv_len = cpu_to_le32(sizeof(crash_data->registers)); 875 memcpy(dump_tlv->tlv_data, &crash_data->registers, 876 sizeof(crash_data->registers)); 877 sofar += sizeof(*dump_tlv) + sizeof(crash_data->registers); 878 879 ar->debug.fw_crash_data->crashed_since_read = false; 880 881 spin_unlock_bh(&ar->data_lock); 882 883 return dump_data; 884 } 885 886 static int ath10k_fw_crash_dump_open(struct inode *inode, struct file *file) 887 { 888 struct ath10k *ar = inode->i_private; 889 struct ath10k_dump_file_data *dump; 890 891 dump = ath10k_build_dump_file(ar); 892 if (!dump) 893 return -ENODATA; 894 895 file->private_data = dump; 896 897 return 0; 898 } 899 900 static ssize_t ath10k_fw_crash_dump_read(struct file *file, 901 char __user *user_buf, 902 size_t count, loff_t *ppos) 903 { 904 struct ath10k_dump_file_data *dump_file = file->private_data; 905 906 return simple_read_from_buffer(user_buf, count, ppos, 907 dump_file, 908 le32_to_cpu(dump_file->len)); 909 } 910 911 static int ath10k_fw_crash_dump_release(struct inode *inode, 912 struct file *file) 913 { 914 vfree(file->private_data); 915 916 return 0; 917 } 918 919 static const struct file_operations fops_fw_crash_dump = { 920 .open = ath10k_fw_crash_dump_open, 921 .read = ath10k_fw_crash_dump_read, 922 .release = ath10k_fw_crash_dump_release, 923 .owner = THIS_MODULE, 924 .llseek = default_llseek, 925 }; 926 927 static ssize_t ath10k_reg_addr_read(struct file *file, 928 char __user *user_buf, 929 size_t count, loff_t *ppos) 930 { 931 struct ath10k *ar = file->private_data; 932 u8 buf[32]; 933 unsigned int len = 0; 934 u32 reg_addr; 935 936 mutex_lock(&ar->conf_mutex); 937 reg_addr = ar->debug.reg_addr; 938 mutex_unlock(&ar->conf_mutex); 939 940 len += scnprintf(buf + len, sizeof(buf) - len, "0x%x\n", reg_addr); 941 942 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 943 } 944 945 static ssize_t ath10k_reg_addr_write(struct file *file, 946 const char __user *user_buf, 947 size_t count, loff_t *ppos) 948 { 949 struct ath10k *ar = file->private_data; 950 u32 reg_addr; 951 int ret; 952 953 ret = kstrtou32_from_user(user_buf, count, 0, ®_addr); 954 if (ret) 955 return ret; 956 957 if (!IS_ALIGNED(reg_addr, 4)) 958 return -EFAULT; 959 960 mutex_lock(&ar->conf_mutex); 961 ar->debug.reg_addr = reg_addr; 962 mutex_unlock(&ar->conf_mutex); 963 964 return count; 965 } 966 967 static const struct file_operations fops_reg_addr = { 968 .read = ath10k_reg_addr_read, 969 .write = ath10k_reg_addr_write, 970 .open = simple_open, 971 .owner = THIS_MODULE, 972 .llseek = default_llseek, 973 }; 974 975 static ssize_t ath10k_reg_value_read(struct file *file, 976 char __user *user_buf, 977 size_t count, loff_t *ppos) 978 { 979 struct ath10k *ar = file->private_data; 980 u8 buf[48]; 981 unsigned int len; 982 u32 reg_addr, reg_val; 983 int ret; 984 985 mutex_lock(&ar->conf_mutex); 986 987 if (ar->state != ATH10K_STATE_ON && 988 ar->state != ATH10K_STATE_UTF) { 989 ret = -ENETDOWN; 990 goto exit; 991 } 992 993 reg_addr = ar->debug.reg_addr; 994 995 reg_val = ath10k_hif_read32(ar, reg_addr); 996 len = scnprintf(buf, sizeof(buf), "0x%08x:0x%08x\n", reg_addr, reg_val); 997 998 ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); 999 1000 exit: 1001 mutex_unlock(&ar->conf_mutex); 1002 1003 return ret; 1004 } 1005 1006 static ssize_t ath10k_reg_value_write(struct file *file, 1007 const char __user *user_buf, 1008 size_t count, loff_t *ppos) 1009 { 1010 struct ath10k *ar = file->private_data; 1011 u32 reg_addr, reg_val; 1012 int ret; 1013 1014 mutex_lock(&ar->conf_mutex); 1015 1016 if (ar->state != ATH10K_STATE_ON && 1017 ar->state != ATH10K_STATE_UTF) { 1018 ret = -ENETDOWN; 1019 goto exit; 1020 } 1021 1022 reg_addr = ar->debug.reg_addr; 1023 1024 ret = kstrtou32_from_user(user_buf, count, 0, ®_val); 1025 if (ret) 1026 goto exit; 1027 1028 ath10k_hif_write32(ar, reg_addr, reg_val); 1029 1030 ret = count; 1031 1032 exit: 1033 mutex_unlock(&ar->conf_mutex); 1034 1035 return ret; 1036 } 1037 1038 static const struct file_operations fops_reg_value = { 1039 .read = ath10k_reg_value_read, 1040 .write = ath10k_reg_value_write, 1041 .open = simple_open, 1042 .owner = THIS_MODULE, 1043 .llseek = default_llseek, 1044 }; 1045 1046 static ssize_t ath10k_mem_value_read(struct file *file, 1047 char __user *user_buf, 1048 size_t count, loff_t *ppos) 1049 { 1050 struct ath10k *ar = file->private_data; 1051 u8 *buf; 1052 int ret; 1053 1054 if (*ppos < 0) 1055 return -EINVAL; 1056 1057 if (!count) 1058 return 0; 1059 1060 mutex_lock(&ar->conf_mutex); 1061 1062 buf = vmalloc(count); 1063 if (!buf) { 1064 ret = -ENOMEM; 1065 goto exit; 1066 } 1067 1068 if (ar->state != ATH10K_STATE_ON && 1069 ar->state != ATH10K_STATE_UTF) { 1070 ret = -ENETDOWN; 1071 goto exit; 1072 } 1073 1074 ret = ath10k_hif_diag_read(ar, *ppos, buf, count); 1075 if (ret) { 1076 ath10k_warn(ar, "failed to read address 0x%08x via diagnose window fnrom debugfs: %d\n", 1077 (u32)(*ppos), ret); 1078 goto exit; 1079 } 1080 1081 ret = copy_to_user(user_buf, buf, count); 1082 if (ret) { 1083 ret = -EFAULT; 1084 goto exit; 1085 } 1086 1087 count -= ret; 1088 *ppos += count; 1089 ret = count; 1090 1091 exit: 1092 vfree(buf); 1093 mutex_unlock(&ar->conf_mutex); 1094 1095 return ret; 1096 } 1097 1098 static ssize_t ath10k_mem_value_write(struct file *file, 1099 const char __user *user_buf, 1100 size_t count, loff_t *ppos) 1101 { 1102 struct ath10k *ar = file->private_data; 1103 u8 *buf; 1104 int ret; 1105 1106 if (*ppos < 0) 1107 return -EINVAL; 1108 1109 if (!count) 1110 return 0; 1111 1112 mutex_lock(&ar->conf_mutex); 1113 1114 buf = vmalloc(count); 1115 if (!buf) { 1116 ret = -ENOMEM; 1117 goto exit; 1118 } 1119 1120 if (ar->state != ATH10K_STATE_ON && 1121 ar->state != ATH10K_STATE_UTF) { 1122 ret = -ENETDOWN; 1123 goto exit; 1124 } 1125 1126 ret = copy_from_user(buf, user_buf, count); 1127 if (ret) { 1128 ret = -EFAULT; 1129 goto exit; 1130 } 1131 1132 ret = ath10k_hif_diag_write(ar, *ppos, buf, count); 1133 if (ret) { 1134 ath10k_warn(ar, "failed to write address 0x%08x via diagnose window from debugfs: %d\n", 1135 (u32)(*ppos), ret); 1136 goto exit; 1137 } 1138 1139 *ppos += count; 1140 ret = count; 1141 1142 exit: 1143 vfree(buf); 1144 mutex_unlock(&ar->conf_mutex); 1145 1146 return ret; 1147 } 1148 1149 static const struct file_operations fops_mem_value = { 1150 .read = ath10k_mem_value_read, 1151 .write = ath10k_mem_value_write, 1152 .open = simple_open, 1153 .owner = THIS_MODULE, 1154 .llseek = default_llseek, 1155 }; 1156 1157 static int ath10k_debug_htt_stats_req(struct ath10k *ar) 1158 { 1159 u64 cookie; 1160 int ret; 1161 1162 lockdep_assert_held(&ar->conf_mutex); 1163 1164 if (ar->debug.htt_stats_mask == 0) 1165 /* htt stats are disabled */ 1166 return 0; 1167 1168 if (ar->state != ATH10K_STATE_ON) 1169 return 0; 1170 1171 cookie = get_jiffies_64(); 1172 1173 ret = ath10k_htt_h2t_stats_req(&ar->htt, ar->debug.htt_stats_mask, 1174 cookie); 1175 if (ret) { 1176 ath10k_warn(ar, "failed to send htt stats request: %d\n", ret); 1177 return ret; 1178 } 1179 1180 queue_delayed_work(ar->workqueue, &ar->debug.htt_stats_dwork, 1181 msecs_to_jiffies(ATH10K_DEBUG_HTT_STATS_INTERVAL)); 1182 1183 return 0; 1184 } 1185 1186 static void ath10k_debug_htt_stats_dwork(struct work_struct *work) 1187 { 1188 struct ath10k *ar = container_of(work, struct ath10k, 1189 debug.htt_stats_dwork.work); 1190 1191 mutex_lock(&ar->conf_mutex); 1192 1193 ath10k_debug_htt_stats_req(ar); 1194 1195 mutex_unlock(&ar->conf_mutex); 1196 } 1197 1198 static ssize_t ath10k_read_htt_stats_mask(struct file *file, 1199 char __user *user_buf, 1200 size_t count, loff_t *ppos) 1201 { 1202 struct ath10k *ar = file->private_data; 1203 char buf[32]; 1204 unsigned int len; 1205 1206 len = scnprintf(buf, sizeof(buf), "%lu\n", ar->debug.htt_stats_mask); 1207 1208 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 1209 } 1210 1211 static ssize_t ath10k_write_htt_stats_mask(struct file *file, 1212 const char __user *user_buf, 1213 size_t count, loff_t *ppos) 1214 { 1215 struct ath10k *ar = file->private_data; 1216 unsigned long mask; 1217 int ret; 1218 1219 ret = kstrtoul_from_user(user_buf, count, 0, &mask); 1220 if (ret) 1221 return ret; 1222 1223 /* max 8 bit masks (for now) */ 1224 if (mask > 0xff) 1225 return -E2BIG; 1226 1227 mutex_lock(&ar->conf_mutex); 1228 1229 ar->debug.htt_stats_mask = mask; 1230 1231 ret = ath10k_debug_htt_stats_req(ar); 1232 if (ret) 1233 goto out; 1234 1235 ret = count; 1236 1237 out: 1238 mutex_unlock(&ar->conf_mutex); 1239 1240 return ret; 1241 } 1242 1243 static const struct file_operations fops_htt_stats_mask = { 1244 .read = ath10k_read_htt_stats_mask, 1245 .write = ath10k_write_htt_stats_mask, 1246 .open = simple_open, 1247 .owner = THIS_MODULE, 1248 .llseek = default_llseek, 1249 }; 1250 1251 static ssize_t ath10k_read_htt_max_amsdu_ampdu(struct file *file, 1252 char __user *user_buf, 1253 size_t count, loff_t *ppos) 1254 { 1255 struct ath10k *ar = file->private_data; 1256 char buf[64]; 1257 u8 amsdu = 3, ampdu = 64; 1258 unsigned int len; 1259 1260 mutex_lock(&ar->conf_mutex); 1261 1262 if (ar->debug.htt_max_amsdu) 1263 amsdu = ar->debug.htt_max_amsdu; 1264 1265 if (ar->debug.htt_max_ampdu) 1266 ampdu = ar->debug.htt_max_ampdu; 1267 1268 mutex_unlock(&ar->conf_mutex); 1269 1270 len = scnprintf(buf, sizeof(buf), "%u %u\n", amsdu, ampdu); 1271 1272 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 1273 } 1274 1275 static ssize_t ath10k_write_htt_max_amsdu_ampdu(struct file *file, 1276 const char __user *user_buf, 1277 size_t count, loff_t *ppos) 1278 { 1279 struct ath10k *ar = file->private_data; 1280 int res; 1281 char buf[64]; 1282 unsigned int amsdu, ampdu; 1283 1284 simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); 1285 1286 /* make sure that buf is null terminated */ 1287 buf[sizeof(buf) - 1] = 0; 1288 1289 res = sscanf(buf, "%u %u", &amsdu, &du); 1290 1291 if (res != 2) 1292 return -EINVAL; 1293 1294 mutex_lock(&ar->conf_mutex); 1295 1296 res = ath10k_htt_h2t_aggr_cfg_msg(&ar->htt, ampdu, amsdu); 1297 if (res) 1298 goto out; 1299 1300 res = count; 1301 ar->debug.htt_max_amsdu = amsdu; 1302 ar->debug.htt_max_ampdu = ampdu; 1303 1304 out: 1305 mutex_unlock(&ar->conf_mutex); 1306 return res; 1307 } 1308 1309 static const struct file_operations fops_htt_max_amsdu_ampdu = { 1310 .read = ath10k_read_htt_max_amsdu_ampdu, 1311 .write = ath10k_write_htt_max_amsdu_ampdu, 1312 .open = simple_open, 1313 .owner = THIS_MODULE, 1314 .llseek = default_llseek, 1315 }; 1316 1317 static ssize_t ath10k_read_fw_dbglog(struct file *file, 1318 char __user *user_buf, 1319 size_t count, loff_t *ppos) 1320 { 1321 struct ath10k *ar = file->private_data; 1322 unsigned int len; 1323 char buf[32]; 1324 1325 len = scnprintf(buf, sizeof(buf), "0x%08x\n", 1326 ar->debug.fw_dbglog_mask); 1327 1328 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 1329 } 1330 1331 static ssize_t ath10k_write_fw_dbglog(struct file *file, 1332 const char __user *user_buf, 1333 size_t count, loff_t *ppos) 1334 { 1335 struct ath10k *ar = file->private_data; 1336 unsigned long mask; 1337 int ret; 1338 1339 ret = kstrtoul_from_user(user_buf, count, 0, &mask); 1340 if (ret) 1341 return ret; 1342 1343 mutex_lock(&ar->conf_mutex); 1344 1345 ar->debug.fw_dbglog_mask = mask; 1346 1347 if (ar->state == ATH10K_STATE_ON) { 1348 ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask); 1349 if (ret) { 1350 ath10k_warn(ar, "dbglog cfg failed from debugfs: %d\n", 1351 ret); 1352 goto exit; 1353 } 1354 } 1355 1356 ret = count; 1357 1358 exit: 1359 mutex_unlock(&ar->conf_mutex); 1360 1361 return ret; 1362 } 1363 1364 /* TODO: Would be nice to always support ethtool stats, would need to 1365 * move the stats storage out of ath10k_debug, or always have ath10k_debug 1366 * struct available.. 1367 */ 1368 1369 /* This generally cooresponds to the debugfs fw_stats file */ 1370 static const char ath10k_gstrings_stats[][ETH_GSTRING_LEN] = { 1371 "tx_pkts_nic", 1372 "tx_bytes_nic", 1373 "rx_pkts_nic", 1374 "rx_bytes_nic", 1375 "d_noise_floor", 1376 "d_cycle_count", 1377 "d_phy_error", 1378 "d_rts_bad", 1379 "d_rts_good", 1380 "d_tx_power", /* in .5 dbM I think */ 1381 "d_rx_crc_err", /* fcs_bad */ 1382 "d_no_beacon", 1383 "d_tx_mpdus_queued", 1384 "d_tx_msdu_queued", 1385 "d_tx_msdu_dropped", 1386 "d_local_enqued", 1387 "d_local_freed", 1388 "d_tx_ppdu_hw_queued", 1389 "d_tx_ppdu_reaped", 1390 "d_tx_fifo_underrun", 1391 "d_tx_ppdu_abort", 1392 "d_tx_mpdu_requed", 1393 "d_tx_excessive_retries", 1394 "d_tx_hw_rate", 1395 "d_tx_dropped_sw_retries", 1396 "d_tx_illegal_rate", 1397 "d_tx_continuous_xretries", 1398 "d_tx_timeout", 1399 "d_tx_mpdu_txop_limit", 1400 "d_pdev_resets", 1401 "d_rx_mid_ppdu_route_change", 1402 "d_rx_status", 1403 "d_rx_extra_frags_ring0", 1404 "d_rx_extra_frags_ring1", 1405 "d_rx_extra_frags_ring2", 1406 "d_rx_extra_frags_ring3", 1407 "d_rx_msdu_htt", 1408 "d_rx_mpdu_htt", 1409 "d_rx_msdu_stack", 1410 "d_rx_mpdu_stack", 1411 "d_rx_phy_err", 1412 "d_rx_phy_err_drops", 1413 "d_rx_mpdu_errors", /* FCS, MIC, ENC */ 1414 "d_fw_crash_count", 1415 "d_fw_warm_reset_count", 1416 "d_fw_cold_reset_count", 1417 }; 1418 1419 #define ATH10K_SSTATS_LEN ARRAY_SIZE(ath10k_gstrings_stats) 1420 1421 void ath10k_debug_get_et_strings(struct ieee80211_hw *hw, 1422 struct ieee80211_vif *vif, 1423 u32 sset, u8 *data) 1424 { 1425 if (sset == ETH_SS_STATS) 1426 memcpy(data, *ath10k_gstrings_stats, 1427 sizeof(ath10k_gstrings_stats)); 1428 } 1429 1430 int ath10k_debug_get_et_sset_count(struct ieee80211_hw *hw, 1431 struct ieee80211_vif *vif, int sset) 1432 { 1433 if (sset == ETH_SS_STATS) 1434 return ATH10K_SSTATS_LEN; 1435 1436 return 0; 1437 } 1438 1439 void ath10k_debug_get_et_stats(struct ieee80211_hw *hw, 1440 struct ieee80211_vif *vif, 1441 struct ethtool_stats *stats, u64 *data) 1442 { 1443 struct ath10k *ar = hw->priv; 1444 static const struct ath10k_fw_stats_pdev zero_stats = {}; 1445 const struct ath10k_fw_stats_pdev *pdev_stats; 1446 int i = 0, ret; 1447 1448 mutex_lock(&ar->conf_mutex); 1449 1450 if (ar->state == ATH10K_STATE_ON) { 1451 ret = ath10k_debug_fw_stats_request(ar); 1452 if (ret) { 1453 /* just print a warning and try to use older results */ 1454 ath10k_warn(ar, 1455 "failed to get fw stats for ethtool: %d\n", 1456 ret); 1457 } 1458 } 1459 1460 pdev_stats = list_first_entry_or_null(&ar->debug.fw_stats.pdevs, 1461 struct ath10k_fw_stats_pdev, 1462 list); 1463 if (!pdev_stats) { 1464 /* no results available so just return zeroes */ 1465 pdev_stats = &zero_stats; 1466 } 1467 1468 spin_lock_bh(&ar->data_lock); 1469 1470 data[i++] = pdev_stats->hw_reaped; /* ppdu reaped */ 1471 data[i++] = 0; /* tx bytes */ 1472 data[i++] = pdev_stats->htt_mpdus; 1473 data[i++] = 0; /* rx bytes */ 1474 data[i++] = pdev_stats->ch_noise_floor; 1475 data[i++] = pdev_stats->cycle_count; 1476 data[i++] = pdev_stats->phy_err_count; 1477 data[i++] = pdev_stats->rts_bad; 1478 data[i++] = pdev_stats->rts_good; 1479 data[i++] = pdev_stats->chan_tx_power; 1480 data[i++] = pdev_stats->fcs_bad; 1481 data[i++] = pdev_stats->no_beacons; 1482 data[i++] = pdev_stats->mpdu_enqued; 1483 data[i++] = pdev_stats->msdu_enqued; 1484 data[i++] = pdev_stats->wmm_drop; 1485 data[i++] = pdev_stats->local_enqued; 1486 data[i++] = pdev_stats->local_freed; 1487 data[i++] = pdev_stats->hw_queued; 1488 data[i++] = pdev_stats->hw_reaped; 1489 data[i++] = pdev_stats->underrun; 1490 data[i++] = pdev_stats->tx_abort; 1491 data[i++] = pdev_stats->mpdus_requed; 1492 data[i++] = pdev_stats->tx_ko; 1493 data[i++] = pdev_stats->data_rc; 1494 data[i++] = pdev_stats->sw_retry_failure; 1495 data[i++] = pdev_stats->illgl_rate_phy_err; 1496 data[i++] = pdev_stats->pdev_cont_xretry; 1497 data[i++] = pdev_stats->pdev_tx_timeout; 1498 data[i++] = pdev_stats->txop_ovf; 1499 data[i++] = pdev_stats->pdev_resets; 1500 data[i++] = pdev_stats->mid_ppdu_route_change; 1501 data[i++] = pdev_stats->status_rcvd; 1502 data[i++] = pdev_stats->r0_frags; 1503 data[i++] = pdev_stats->r1_frags; 1504 data[i++] = pdev_stats->r2_frags; 1505 data[i++] = pdev_stats->r3_frags; 1506 data[i++] = pdev_stats->htt_msdus; 1507 data[i++] = pdev_stats->htt_mpdus; 1508 data[i++] = pdev_stats->loc_msdus; 1509 data[i++] = pdev_stats->loc_mpdus; 1510 data[i++] = pdev_stats->phy_errs; 1511 data[i++] = pdev_stats->phy_err_drop; 1512 data[i++] = pdev_stats->mpdu_errs; 1513 data[i++] = ar->stats.fw_crash_counter; 1514 data[i++] = ar->stats.fw_warm_reset_counter; 1515 data[i++] = ar->stats.fw_cold_reset_counter; 1516 1517 spin_unlock_bh(&ar->data_lock); 1518 1519 mutex_unlock(&ar->conf_mutex); 1520 1521 WARN_ON(i != ATH10K_SSTATS_LEN); 1522 } 1523 1524 static const struct file_operations fops_fw_dbglog = { 1525 .read = ath10k_read_fw_dbglog, 1526 .write = ath10k_write_fw_dbglog, 1527 .open = simple_open, 1528 .owner = THIS_MODULE, 1529 .llseek = default_llseek, 1530 }; 1531 1532 static int ath10k_debug_cal_data_open(struct inode *inode, struct file *file) 1533 { 1534 struct ath10k *ar = inode->i_private; 1535 void *buf; 1536 u32 hi_addr; 1537 __le32 addr; 1538 int ret; 1539 1540 mutex_lock(&ar->conf_mutex); 1541 1542 if (ar->state != ATH10K_STATE_ON && 1543 ar->state != ATH10K_STATE_UTF) { 1544 ret = -ENETDOWN; 1545 goto err; 1546 } 1547 1548 buf = vmalloc(QCA988X_CAL_DATA_LEN); 1549 if (!buf) { 1550 ret = -ENOMEM; 1551 goto err; 1552 } 1553 1554 hi_addr = host_interest_item_address(HI_ITEM(hi_board_data)); 1555 1556 ret = ath10k_hif_diag_read(ar, hi_addr, &addr, sizeof(addr)); 1557 if (ret) { 1558 ath10k_warn(ar, "failed to read hi_board_data address: %d\n", ret); 1559 goto err_vfree; 1560 } 1561 1562 ret = ath10k_hif_diag_read(ar, le32_to_cpu(addr), buf, 1563 QCA988X_CAL_DATA_LEN); 1564 if (ret) { 1565 ath10k_warn(ar, "failed to read calibration data: %d\n", ret); 1566 goto err_vfree; 1567 } 1568 1569 file->private_data = buf; 1570 1571 mutex_unlock(&ar->conf_mutex); 1572 1573 return 0; 1574 1575 err_vfree: 1576 vfree(buf); 1577 1578 err: 1579 mutex_unlock(&ar->conf_mutex); 1580 1581 return ret; 1582 } 1583 1584 static ssize_t ath10k_debug_cal_data_read(struct file *file, 1585 char __user *user_buf, 1586 size_t count, loff_t *ppos) 1587 { 1588 void *buf = file->private_data; 1589 1590 return simple_read_from_buffer(user_buf, count, ppos, 1591 buf, QCA988X_CAL_DATA_LEN); 1592 } 1593 1594 static int ath10k_debug_cal_data_release(struct inode *inode, 1595 struct file *file) 1596 { 1597 vfree(file->private_data); 1598 1599 return 0; 1600 } 1601 1602 static const struct file_operations fops_cal_data = { 1603 .open = ath10k_debug_cal_data_open, 1604 .read = ath10k_debug_cal_data_read, 1605 .release = ath10k_debug_cal_data_release, 1606 .owner = THIS_MODULE, 1607 .llseek = default_llseek, 1608 }; 1609 1610 int ath10k_debug_start(struct ath10k *ar) 1611 { 1612 int ret; 1613 1614 lockdep_assert_held(&ar->conf_mutex); 1615 1616 ret = ath10k_debug_htt_stats_req(ar); 1617 if (ret) 1618 /* continue normally anyway, this isn't serious */ 1619 ath10k_warn(ar, "failed to start htt stats workqueue: %d\n", 1620 ret); 1621 1622 if (ar->debug.fw_dbglog_mask) { 1623 ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask); 1624 if (ret) 1625 /* not serious */ 1626 ath10k_warn(ar, "failed to enable dbglog during start: %d", 1627 ret); 1628 } 1629 1630 if (ar->debug.pktlog_filter) { 1631 ret = ath10k_wmi_pdev_pktlog_enable(ar, 1632 ar->debug.pktlog_filter); 1633 if (ret) 1634 /* not serious */ 1635 ath10k_warn(ar, 1636 "failed to enable pktlog filter %x: %d\n", 1637 ar->debug.pktlog_filter, ret); 1638 } else { 1639 ret = ath10k_wmi_pdev_pktlog_disable(ar); 1640 if (ret) 1641 /* not serious */ 1642 ath10k_warn(ar, "failed to disable pktlog: %d\n", ret); 1643 } 1644 1645 return ret; 1646 } 1647 1648 void ath10k_debug_stop(struct ath10k *ar) 1649 { 1650 lockdep_assert_held(&ar->conf_mutex); 1651 1652 /* Must not use _sync to avoid deadlock, we do that in 1653 * ath10k_debug_destroy(). The check for htt_stats_mask is to avoid 1654 * warning from del_timer(). */ 1655 if (ar->debug.htt_stats_mask != 0) 1656 cancel_delayed_work(&ar->debug.htt_stats_dwork); 1657 1658 ar->debug.htt_max_amsdu = 0; 1659 ar->debug.htt_max_ampdu = 0; 1660 1661 ath10k_wmi_pdev_pktlog_disable(ar); 1662 } 1663 1664 static ssize_t ath10k_write_simulate_radar(struct file *file, 1665 const char __user *user_buf, 1666 size_t count, loff_t *ppos) 1667 { 1668 struct ath10k *ar = file->private_data; 1669 1670 ieee80211_radar_detected(ar->hw); 1671 1672 return count; 1673 } 1674 1675 static const struct file_operations fops_simulate_radar = { 1676 .write = ath10k_write_simulate_radar, 1677 .open = simple_open, 1678 .owner = THIS_MODULE, 1679 .llseek = default_llseek, 1680 }; 1681 1682 #define ATH10K_DFS_STAT(s, p) (\ 1683 len += scnprintf(buf + len, size - len, "%-28s : %10u\n", s, \ 1684 ar->debug.dfs_stats.p)) 1685 1686 #define ATH10K_DFS_POOL_STAT(s, p) (\ 1687 len += scnprintf(buf + len, size - len, "%-28s : %10u\n", s, \ 1688 ar->debug.dfs_pool_stats.p)) 1689 1690 static ssize_t ath10k_read_dfs_stats(struct file *file, char __user *user_buf, 1691 size_t count, loff_t *ppos) 1692 { 1693 int retval = 0, len = 0; 1694 const int size = 8000; 1695 struct ath10k *ar = file->private_data; 1696 char *buf; 1697 1698 buf = kzalloc(size, GFP_KERNEL); 1699 if (buf == NULL) 1700 return -ENOMEM; 1701 1702 if (!ar->dfs_detector) { 1703 len += scnprintf(buf + len, size - len, "DFS not enabled\n"); 1704 goto exit; 1705 } 1706 1707 ar->debug.dfs_pool_stats = 1708 ar->dfs_detector->get_stats(ar->dfs_detector); 1709 1710 len += scnprintf(buf + len, size - len, "Pulse detector statistics:\n"); 1711 1712 ATH10K_DFS_STAT("reported phy errors", phy_errors); 1713 ATH10K_DFS_STAT("pulse events reported", pulses_total); 1714 ATH10K_DFS_STAT("DFS pulses detected", pulses_detected); 1715 ATH10K_DFS_STAT("DFS pulses discarded", pulses_discarded); 1716 ATH10K_DFS_STAT("Radars detected", radar_detected); 1717 1718 len += scnprintf(buf + len, size - len, "Global Pool statistics:\n"); 1719 ATH10K_DFS_POOL_STAT("Pool references", pool_reference); 1720 ATH10K_DFS_POOL_STAT("Pulses allocated", pulse_allocated); 1721 ATH10K_DFS_POOL_STAT("Pulses alloc error", pulse_alloc_error); 1722 ATH10K_DFS_POOL_STAT("Pulses in use", pulse_used); 1723 ATH10K_DFS_POOL_STAT("Seqs. allocated", pseq_allocated); 1724 ATH10K_DFS_POOL_STAT("Seqs. alloc error", pseq_alloc_error); 1725 ATH10K_DFS_POOL_STAT("Seqs. in use", pseq_used); 1726 1727 exit: 1728 if (len > size) 1729 len = size; 1730 1731 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 1732 kfree(buf); 1733 1734 return retval; 1735 } 1736 1737 static const struct file_operations fops_dfs_stats = { 1738 .read = ath10k_read_dfs_stats, 1739 .open = simple_open, 1740 .owner = THIS_MODULE, 1741 .llseek = default_llseek, 1742 }; 1743 1744 static ssize_t ath10k_write_pktlog_filter(struct file *file, 1745 const char __user *ubuf, 1746 size_t count, loff_t *ppos) 1747 { 1748 struct ath10k *ar = file->private_data; 1749 u32 filter; 1750 int ret; 1751 1752 if (kstrtouint_from_user(ubuf, count, 0, &filter)) 1753 return -EINVAL; 1754 1755 mutex_lock(&ar->conf_mutex); 1756 1757 if (ar->state != ATH10K_STATE_ON) { 1758 ar->debug.pktlog_filter = filter; 1759 ret = count; 1760 goto out; 1761 } 1762 1763 if (filter && (filter != ar->debug.pktlog_filter)) { 1764 ret = ath10k_wmi_pdev_pktlog_enable(ar, filter); 1765 if (ret) { 1766 ath10k_warn(ar, "failed to enable pktlog filter %x: %d\n", 1767 ar->debug.pktlog_filter, ret); 1768 goto out; 1769 } 1770 } else { 1771 ret = ath10k_wmi_pdev_pktlog_disable(ar); 1772 if (ret) { 1773 ath10k_warn(ar, "failed to disable pktlog: %d\n", ret); 1774 goto out; 1775 } 1776 } 1777 1778 ar->debug.pktlog_filter = filter; 1779 ret = count; 1780 1781 out: 1782 mutex_unlock(&ar->conf_mutex); 1783 return ret; 1784 } 1785 1786 static ssize_t ath10k_read_pktlog_filter(struct file *file, char __user *ubuf, 1787 size_t count, loff_t *ppos) 1788 { 1789 char buf[32]; 1790 struct ath10k *ar = file->private_data; 1791 int len = 0; 1792 1793 mutex_lock(&ar->conf_mutex); 1794 len = scnprintf(buf, sizeof(buf) - len, "%08x\n", 1795 ar->debug.pktlog_filter); 1796 mutex_unlock(&ar->conf_mutex); 1797 1798 return simple_read_from_buffer(ubuf, count, ppos, buf, len); 1799 } 1800 1801 static const struct file_operations fops_pktlog_filter = { 1802 .read = ath10k_read_pktlog_filter, 1803 .write = ath10k_write_pktlog_filter, 1804 .open = simple_open 1805 }; 1806 1807 int ath10k_debug_create(struct ath10k *ar) 1808 { 1809 ar->debug.fw_crash_data = vzalloc(sizeof(*ar->debug.fw_crash_data)); 1810 if (!ar->debug.fw_crash_data) 1811 return -ENOMEM; 1812 1813 INIT_LIST_HEAD(&ar->debug.fw_stats.pdevs); 1814 INIT_LIST_HEAD(&ar->debug.fw_stats.peers); 1815 1816 return 0; 1817 } 1818 1819 void ath10k_debug_destroy(struct ath10k *ar) 1820 { 1821 vfree(ar->debug.fw_crash_data); 1822 ar->debug.fw_crash_data = NULL; 1823 1824 ath10k_debug_fw_stats_reset(ar); 1825 } 1826 1827 int ath10k_debug_register(struct ath10k *ar) 1828 { 1829 ar->debug.debugfs_phy = debugfs_create_dir("ath10k", 1830 ar->hw->wiphy->debugfsdir); 1831 if (IS_ERR_OR_NULL(ar->debug.debugfs_phy)) { 1832 if (IS_ERR(ar->debug.debugfs_phy)) 1833 return PTR_ERR(ar->debug.debugfs_phy); 1834 1835 return -ENOMEM; 1836 } 1837 1838 INIT_DELAYED_WORK(&ar->debug.htt_stats_dwork, 1839 ath10k_debug_htt_stats_dwork); 1840 1841 init_completion(&ar->debug.fw_stats_complete); 1842 1843 debugfs_create_file("fw_stats", S_IRUSR, ar->debug.debugfs_phy, ar, 1844 &fops_fw_stats); 1845 1846 debugfs_create_file("fw_reset_stats", S_IRUSR, ar->debug.debugfs_phy, 1847 ar, &fops_fw_reset_stats); 1848 1849 debugfs_create_file("wmi_services", S_IRUSR, ar->debug.debugfs_phy, ar, 1850 &fops_wmi_services); 1851 1852 debugfs_create_file("simulate_fw_crash", S_IRUSR, ar->debug.debugfs_phy, 1853 ar, &fops_simulate_fw_crash); 1854 1855 debugfs_create_file("fw_crash_dump", S_IRUSR, ar->debug.debugfs_phy, 1856 ar, &fops_fw_crash_dump); 1857 1858 debugfs_create_file("reg_addr", S_IRUSR | S_IWUSR, 1859 ar->debug.debugfs_phy, ar, &fops_reg_addr); 1860 1861 debugfs_create_file("reg_value", S_IRUSR | S_IWUSR, 1862 ar->debug.debugfs_phy, ar, &fops_reg_value); 1863 1864 debugfs_create_file("mem_value", S_IRUSR | S_IWUSR, 1865 ar->debug.debugfs_phy, ar, &fops_mem_value); 1866 1867 debugfs_create_file("chip_id", S_IRUSR, ar->debug.debugfs_phy, 1868 ar, &fops_chip_id); 1869 1870 debugfs_create_file("htt_stats_mask", S_IRUSR, ar->debug.debugfs_phy, 1871 ar, &fops_htt_stats_mask); 1872 1873 debugfs_create_file("htt_max_amsdu_ampdu", S_IRUSR | S_IWUSR, 1874 ar->debug.debugfs_phy, ar, 1875 &fops_htt_max_amsdu_ampdu); 1876 1877 debugfs_create_file("fw_dbglog", S_IRUSR, ar->debug.debugfs_phy, 1878 ar, &fops_fw_dbglog); 1879 1880 debugfs_create_file("cal_data", S_IRUSR, ar->debug.debugfs_phy, 1881 ar, &fops_cal_data); 1882 1883 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED)) { 1884 debugfs_create_file("dfs_simulate_radar", S_IWUSR, 1885 ar->debug.debugfs_phy, ar, 1886 &fops_simulate_radar); 1887 1888 debugfs_create_bool("dfs_block_radar_events", S_IWUSR, 1889 ar->debug.debugfs_phy, 1890 &ar->dfs_block_radar_events); 1891 1892 debugfs_create_file("dfs_stats", S_IRUSR, 1893 ar->debug.debugfs_phy, ar, 1894 &fops_dfs_stats); 1895 } 1896 1897 debugfs_create_file("pktlog_filter", S_IRUGO | S_IWUSR, 1898 ar->debug.debugfs_phy, ar, &fops_pktlog_filter); 1899 1900 return 0; 1901 } 1902 1903 void ath10k_debug_unregister(struct ath10k *ar) 1904 { 1905 cancel_delayed_work_sync(&ar->debug.htt_stats_dwork); 1906 } 1907 1908 #endif /* CONFIG_ATH10K_DEBUGFS */ 1909 1910 #ifdef CONFIG_ATH10K_DEBUG 1911 void ath10k_dbg(struct ath10k *ar, enum ath10k_debug_mask mask, 1912 const char *fmt, ...) 1913 { 1914 struct va_format vaf; 1915 va_list args; 1916 1917 va_start(args, fmt); 1918 1919 vaf.fmt = fmt; 1920 vaf.va = &args; 1921 1922 if (ath10k_debug_mask & mask) 1923 dev_printk(KERN_DEBUG, ar->dev, "%pV", &vaf); 1924 1925 trace_ath10k_log_dbg(ar, mask, &vaf); 1926 1927 va_end(args); 1928 } 1929 EXPORT_SYMBOL(ath10k_dbg); 1930 1931 void ath10k_dbg_dump(struct ath10k *ar, 1932 enum ath10k_debug_mask mask, 1933 const char *msg, const char *prefix, 1934 const void *buf, size_t len) 1935 { 1936 char linebuf[256]; 1937 unsigned int linebuflen; 1938 const void *ptr; 1939 1940 if (ath10k_debug_mask & mask) { 1941 if (msg) 1942 ath10k_dbg(ar, mask, "%s\n", msg); 1943 1944 for (ptr = buf; (ptr - buf) < len; ptr += 16) { 1945 linebuflen = 0; 1946 linebuflen += scnprintf(linebuf + linebuflen, 1947 sizeof(linebuf) - linebuflen, 1948 "%s%08x: ", 1949 (prefix ? prefix : ""), 1950 (unsigned int)(ptr - buf)); 1951 hex_dump_to_buffer(ptr, len - (ptr - buf), 16, 1, 1952 linebuf + linebuflen, 1953 sizeof(linebuf) - linebuflen, true); 1954 dev_printk(KERN_DEBUG, ar->dev, "%s\n", linebuf); 1955 } 1956 } 1957 1958 /* tracing code doesn't like null strings :/ */ 1959 trace_ath10k_log_dbg_dump(ar, msg ? msg : "", prefix ? prefix : "", 1960 buf, len); 1961 } 1962 EXPORT_SYMBOL(ath10k_dbg_dump); 1963 1964 #endif /* CONFIG_ATH10K_DEBUG */ 1965