1 // SPDX-License-Identifier: ISC 2 /* 3 * Copyright (c) 2005-2011 Atheros Communications Inc. 4 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. 5 * Copyright (c) 2018, The Linux Foundation. All rights reserved. 6 * Copyright (c) 2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved. 7 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 8 */ 9 10 #include <linux/module.h> 11 #include <linux/debugfs.h> 12 #include <linux/export.h> 13 #include <linux/vmalloc.h> 14 #include <linux/crc32.h> 15 #include <linux/firmware.h> 16 #include <linux/kstrtox.h> 17 18 #if defined(__FreeBSD__) 19 #ifdef CONFIG_ATH10K_DEBUG 20 #include <sys/sbuf.h> 21 #endif 22 #endif 23 24 #include "core.h" 25 #include "debug.h" 26 #include "hif.h" 27 #include "wmi-ops.h" 28 29 /* ms */ 30 #define ATH10K_DEBUG_HTT_STATS_INTERVAL 1000 31 32 #define ATH10K_DEBUG_CAL_DATA_LEN 12064 33 34 void ath10k_info(struct ath10k *ar, const char *fmt, ...) 35 { 36 struct va_format vaf = { 37 .fmt = fmt, 38 }; 39 va_list args; 40 41 va_start(args, fmt); 42 vaf.va = &args; 43 #if defined(__linux__) 44 dev_info(ar->dev, "%pV", &vaf); 45 #elif defined(__FreeBSD__) 46 { 47 char *str; 48 vasprintf(&str, M_KMALLOC, fmt, args); 49 dev_printk(KERN_DEBUG, ar->dev, "%s", str); 50 free(str, M_KMALLOC); 51 } 52 #endif 53 trace_ath10k_log_info(ar, &vaf); 54 va_end(args); 55 } 56 EXPORT_SYMBOL(ath10k_info); 57 58 void ath10k_debug_print_hwfw_info(struct ath10k *ar) 59 { 60 const struct firmware *firmware; 61 char fw_features[128] = {}; 62 u32 crc = 0; 63 64 ath10k_core_get_fw_features_str(ar, fw_features, sizeof(fw_features)); 65 66 #if defined(__linux__) 67 ath10k_info(ar, "%s target 0x%08x chip_id 0x%08x sub %04x:%04x", 68 #elif defined(__FreeBSD__) 69 ath10k_info(ar, "%s target 0x%08x chip_id 0x%08x sub %04x:%04x\n", 70 #endif 71 ar->hw_params.name, 72 ar->target_version, 73 ar->bus_param.chip_id, 74 ar->id.subsystem_vendor, ar->id.subsystem_device); 75 76 ath10k_info(ar, "kconfig debug %d debugfs %d tracing %d dfs %d testmode %d\n", 77 IS_ENABLED(CONFIG_ATH10K_DEBUG), 78 IS_ENABLED(CONFIG_ATH10K_DEBUGFS), 79 IS_ENABLED(CONFIG_ATH10K_TRACING), 80 IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED), 81 IS_ENABLED(CONFIG_NL80211_TESTMODE)); 82 83 firmware = ar->normal_mode_fw.fw_file.firmware; 84 if (firmware) 85 crc = crc32_le(0, firmware->data, firmware->size); 86 87 ath10k_info(ar, "firmware ver %s api %d features %s crc32 %08x\n", 88 ar->hw->wiphy->fw_version, 89 ar->fw_api, 90 fw_features, 91 crc); 92 } 93 94 void ath10k_debug_print_board_info(struct ath10k *ar) 95 { 96 char boardinfo[100]; 97 const struct firmware *board; 98 u32 crc; 99 100 if (ar->id.bmi_ids_valid) 101 scnprintf(boardinfo, sizeof(boardinfo), "%d:%d", 102 ar->id.bmi_chip_id, ar->id.bmi_board_id); 103 else 104 scnprintf(boardinfo, sizeof(boardinfo), "N/A"); 105 106 board = ar->normal_mode_fw.board; 107 if (!IS_ERR_OR_NULL(board)) 108 crc = crc32_le(0, board->data, board->size); 109 else 110 crc = 0; 111 112 #if defined(__linux__) 113 ath10k_info(ar, "board_file api %d bmi_id %s crc32 %08x", 114 #elif defined(__FreeBSD__) 115 ath10k_info(ar, "board_file api %d bmi_id %s crc32 %08x\n", 116 #endif 117 ar->bd_api, 118 boardinfo, 119 crc); 120 } 121 122 void ath10k_debug_print_boot_info(struct ath10k *ar) 123 { 124 ath10k_info(ar, "htt-ver %d.%d wmi-op %d htt-op %d cal %s max-sta %d raw %d hwcrypto %d\n", 125 ar->htt.target_version_major, 126 ar->htt.target_version_minor, 127 ar->normal_mode_fw.fw_file.wmi_op_version, 128 ar->normal_mode_fw.fw_file.htt_op_version, 129 ath10k_cal_mode_str(ar->cal_mode), 130 ar->max_num_stations, 131 test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags), 132 !test_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags)); 133 } 134 135 void ath10k_print_driver_info(struct ath10k *ar) 136 { 137 ath10k_debug_print_hwfw_info(ar); 138 ath10k_debug_print_board_info(ar); 139 ath10k_debug_print_boot_info(ar); 140 } 141 EXPORT_SYMBOL(ath10k_print_driver_info); 142 143 void ath10k_err(struct ath10k *ar, const char *fmt, ...) 144 { 145 struct va_format vaf = { 146 .fmt = fmt, 147 }; 148 va_list args; 149 150 va_start(args, fmt); 151 vaf.va = &args; 152 #if defined(__linux__) 153 dev_err(ar->dev, "%pV", &vaf); 154 #elif defined(__FreeBSD__) 155 { 156 char *str; 157 vasprintf(&str, M_KMALLOC, fmt, args); 158 dev_err(ar->dev, "%s", str); 159 free(str, M_KMALLOC); 160 } 161 #endif 162 trace_ath10k_log_err(ar, &vaf); 163 va_end(args); 164 } 165 EXPORT_SYMBOL(ath10k_err); 166 167 void ath10k_warn(struct ath10k *ar, const char *fmt, ...) 168 { 169 struct va_format vaf = { 170 .fmt = fmt, 171 }; 172 va_list args; 173 174 va_start(args, fmt); 175 vaf.va = &args; 176 #if defined(__linux__) 177 dev_warn_ratelimited(ar->dev, "%pV", &vaf); 178 #elif defined(__FreeBSD__) 179 { 180 char *str; 181 vasprintf(&str, M_KMALLOC, fmt, args); 182 dev_warn_ratelimited(ar->dev, "%s", str); 183 free(str, M_KMALLOC); 184 } 185 #endif 186 trace_ath10k_log_warn(ar, &vaf); 187 188 va_end(args); 189 } 190 EXPORT_SYMBOL(ath10k_warn); 191 192 #ifdef CONFIG_ATH10K_DEBUGFS 193 194 static ssize_t ath10k_read_wmi_services(struct file *file, 195 char __user *user_buf, 196 size_t count, loff_t *ppos) 197 { 198 struct ath10k *ar = file->private_data; 199 char *buf; 200 size_t len = 0, buf_len = 8192; 201 const char *name; 202 ssize_t ret_cnt; 203 bool enabled; 204 int i; 205 206 buf = kzalloc(buf_len, GFP_KERNEL); 207 if (!buf) 208 return -ENOMEM; 209 210 mutex_lock(&ar->conf_mutex); 211 212 spin_lock_bh(&ar->data_lock); 213 for (i = 0; i < WMI_SERVICE_MAX; i++) { 214 enabled = test_bit(i, ar->wmi.svc_map); 215 name = wmi_service_name(i); 216 217 if (!name) { 218 if (enabled) 219 len += scnprintf(buf + len, buf_len - len, 220 "%-40s %s (bit %d)\n", 221 "unknown", "enabled", i); 222 223 continue; 224 } 225 226 len += scnprintf(buf + len, buf_len - len, 227 "%-40s %s\n", 228 name, enabled ? "enabled" : "-"); 229 } 230 spin_unlock_bh(&ar->data_lock); 231 232 ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); 233 234 mutex_unlock(&ar->conf_mutex); 235 236 kfree(buf); 237 return ret_cnt; 238 } 239 240 static const struct file_operations fops_wmi_services = { 241 .read = ath10k_read_wmi_services, 242 .open = simple_open, 243 .owner = THIS_MODULE, 244 .llseek = default_llseek, 245 }; 246 247 static void ath10k_fw_stats_pdevs_free(struct list_head *head) 248 { 249 struct ath10k_fw_stats_pdev *i, *tmp; 250 251 list_for_each_entry_safe(i, tmp, head, list) { 252 list_del(&i->list); 253 kfree(i); 254 } 255 } 256 257 static void ath10k_fw_stats_vdevs_free(struct list_head *head) 258 { 259 struct ath10k_fw_stats_vdev *i, *tmp; 260 261 list_for_each_entry_safe(i, tmp, head, list) { 262 list_del(&i->list); 263 kfree(i); 264 } 265 } 266 267 static void ath10k_fw_stats_peers_free(struct list_head *head) 268 { 269 struct ath10k_fw_stats_peer *i, *tmp; 270 271 list_for_each_entry_safe(i, tmp, head, list) { 272 list_del(&i->list); 273 kfree(i); 274 } 275 } 276 277 static void ath10k_fw_extd_stats_peers_free(struct list_head *head) 278 { 279 struct ath10k_fw_extd_stats_peer *i, *tmp; 280 281 list_for_each_entry_safe(i, tmp, head, list) { 282 list_del(&i->list); 283 kfree(i); 284 } 285 } 286 287 static void ath10k_debug_fw_stats_reset(struct ath10k *ar) 288 { 289 spin_lock_bh(&ar->data_lock); 290 ar->debug.fw_stats_done = false; 291 ar->debug.fw_stats.extended = false; 292 ath10k_fw_stats_pdevs_free(&ar->debug.fw_stats.pdevs); 293 ath10k_fw_stats_vdevs_free(&ar->debug.fw_stats.vdevs); 294 ath10k_fw_stats_peers_free(&ar->debug.fw_stats.peers); 295 ath10k_fw_extd_stats_peers_free(&ar->debug.fw_stats.peers_extd); 296 spin_unlock_bh(&ar->data_lock); 297 } 298 299 void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb) 300 { 301 struct ath10k_fw_stats stats = {}; 302 bool is_start, is_started, is_end; 303 size_t num_peers; 304 size_t num_vdevs; 305 int ret; 306 307 INIT_LIST_HEAD(&stats.pdevs); 308 INIT_LIST_HEAD(&stats.vdevs); 309 INIT_LIST_HEAD(&stats.peers); 310 INIT_LIST_HEAD(&stats.peers_extd); 311 312 spin_lock_bh(&ar->data_lock); 313 ret = ath10k_wmi_pull_fw_stats(ar, skb, &stats); 314 if (ret) { 315 ath10k_warn(ar, "failed to pull fw stats: %d\n", ret); 316 goto free; 317 } 318 319 /* Stat data may exceed htc-wmi buffer limit. In such case firmware 320 * splits the stats data and delivers it in a ping-pong fashion of 321 * request cmd-update event. 322 * 323 * However there is no explicit end-of-data. Instead start-of-data is 324 * used as an implicit one. This works as follows: 325 * a) discard stat update events until one with pdev stats is 326 * delivered - this skips session started at end of (b) 327 * b) consume stat update events until another one with pdev stats is 328 * delivered which is treated as end-of-data and is itself discarded 329 */ 330 if (ath10k_peer_stats_enabled(ar)) 331 ath10k_sta_update_rx_duration(ar, &stats); 332 333 if (ar->debug.fw_stats_done) { 334 if (!ath10k_peer_stats_enabled(ar)) 335 ath10k_warn(ar, "received unsolicited stats update event\n"); 336 337 goto free; 338 } 339 340 num_peers = list_count_nodes(&ar->debug.fw_stats.peers); 341 num_vdevs = list_count_nodes(&ar->debug.fw_stats.vdevs); 342 is_start = (list_empty(&ar->debug.fw_stats.pdevs) && 343 !list_empty(&stats.pdevs)); 344 is_end = (!list_empty(&ar->debug.fw_stats.pdevs) && 345 !list_empty(&stats.pdevs)); 346 347 if (is_start) 348 list_splice_tail_init(&stats.pdevs, &ar->debug.fw_stats.pdevs); 349 350 if (is_end) 351 ar->debug.fw_stats_done = true; 352 353 if (stats.extended) 354 ar->debug.fw_stats.extended = true; 355 356 is_started = !list_empty(&ar->debug.fw_stats.pdevs); 357 358 if (is_started && !is_end) { 359 if (num_peers >= ATH10K_MAX_NUM_PEER_IDS) { 360 /* Although this is unlikely impose a sane limit to 361 * prevent firmware from DoS-ing the host. 362 */ 363 ath10k_fw_stats_peers_free(&ar->debug.fw_stats.peers); 364 ath10k_fw_extd_stats_peers_free(&ar->debug.fw_stats.peers_extd); 365 ath10k_warn(ar, "dropping fw peer stats\n"); 366 goto free; 367 } 368 369 if (num_vdevs >= BITS_PER_LONG) { 370 ath10k_fw_stats_vdevs_free(&ar->debug.fw_stats.vdevs); 371 ath10k_warn(ar, "dropping fw vdev stats\n"); 372 goto free; 373 } 374 375 if (!list_empty(&stats.peers)) 376 list_splice_tail_init(&stats.peers_extd, 377 &ar->debug.fw_stats.peers_extd); 378 379 list_splice_tail_init(&stats.peers, &ar->debug.fw_stats.peers); 380 list_splice_tail_init(&stats.vdevs, &ar->debug.fw_stats.vdevs); 381 } 382 383 complete(&ar->debug.fw_stats_complete); 384 385 free: 386 /* In some cases lists have been spliced and cleared. Free up 387 * resources if that is not the case. 388 */ 389 ath10k_fw_stats_pdevs_free(&stats.pdevs); 390 ath10k_fw_stats_vdevs_free(&stats.vdevs); 391 ath10k_fw_stats_peers_free(&stats.peers); 392 ath10k_fw_extd_stats_peers_free(&stats.peers_extd); 393 394 spin_unlock_bh(&ar->data_lock); 395 } 396 397 int ath10k_debug_fw_stats_request(struct ath10k *ar) 398 { 399 unsigned long timeout, time_left; 400 int ret; 401 402 lockdep_assert_held(&ar->conf_mutex); 403 404 timeout = jiffies + msecs_to_jiffies(1 * HZ); 405 406 ath10k_debug_fw_stats_reset(ar); 407 408 for (;;) { 409 if (time_after(jiffies, timeout)) 410 return -ETIMEDOUT; 411 412 reinit_completion(&ar->debug.fw_stats_complete); 413 414 ret = ath10k_wmi_request_stats(ar, ar->fw_stats_req_mask); 415 if (ret) { 416 ath10k_warn(ar, "could not request stats (%d)\n", ret); 417 return ret; 418 } 419 420 time_left = 421 wait_for_completion_timeout(&ar->debug.fw_stats_complete, 422 1 * HZ); 423 if (!time_left) 424 return -ETIMEDOUT; 425 426 spin_lock_bh(&ar->data_lock); 427 if (ar->debug.fw_stats_done) { 428 spin_unlock_bh(&ar->data_lock); 429 break; 430 } 431 spin_unlock_bh(&ar->data_lock); 432 } 433 434 return 0; 435 } 436 437 static int ath10k_fw_stats_open(struct inode *inode, struct file *file) 438 { 439 struct ath10k *ar = inode->i_private; 440 void *buf = NULL; 441 int ret; 442 443 mutex_lock(&ar->conf_mutex); 444 445 if (ar->state != ATH10K_STATE_ON) { 446 ret = -ENETDOWN; 447 goto err_unlock; 448 } 449 450 buf = vmalloc(ATH10K_FW_STATS_BUF_SIZE); 451 if (!buf) { 452 ret = -ENOMEM; 453 goto err_unlock; 454 } 455 456 ret = ath10k_debug_fw_stats_request(ar); 457 if (ret) { 458 ath10k_warn(ar, "failed to request fw stats: %d\n", ret); 459 goto err_free; 460 } 461 462 ret = ath10k_wmi_fw_stats_fill(ar, &ar->debug.fw_stats, buf); 463 if (ret) { 464 ath10k_warn(ar, "failed to fill fw stats: %d\n", ret); 465 goto err_free; 466 } 467 468 file->private_data = buf; 469 470 mutex_unlock(&ar->conf_mutex); 471 return 0; 472 473 err_free: 474 vfree(buf); 475 476 err_unlock: 477 mutex_unlock(&ar->conf_mutex); 478 return ret; 479 } 480 481 static int ath10k_fw_stats_release(struct inode *inode, struct file *file) 482 { 483 vfree(file->private_data); 484 485 return 0; 486 } 487 488 static ssize_t ath10k_fw_stats_read(struct file *file, char __user *user_buf, 489 size_t count, loff_t *ppos) 490 { 491 const char *buf = file->private_data; 492 size_t len = strlen(buf); 493 494 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 495 } 496 497 static const struct file_operations fops_fw_stats = { 498 .open = ath10k_fw_stats_open, 499 .release = ath10k_fw_stats_release, 500 .read = ath10k_fw_stats_read, 501 .owner = THIS_MODULE, 502 .llseek = default_llseek, 503 }; 504 505 static ssize_t ath10k_debug_fw_reset_stats_read(struct file *file, 506 char __user *user_buf, 507 size_t count, loff_t *ppos) 508 { 509 struct ath10k *ar = file->private_data; 510 int ret; 511 size_t len = 0, buf_len = 500; 512 char *buf; 513 514 buf = kmalloc(buf_len, GFP_KERNEL); 515 if (!buf) 516 return -ENOMEM; 517 518 spin_lock_bh(&ar->data_lock); 519 520 len += scnprintf(buf + len, buf_len - len, 521 "fw_crash_counter\t\t%d\n", ar->stats.fw_crash_counter); 522 len += scnprintf(buf + len, buf_len - len, 523 "fw_warm_reset_counter\t\t%d\n", 524 ar->stats.fw_warm_reset_counter); 525 len += scnprintf(buf + len, buf_len - len, 526 "fw_cold_reset_counter\t\t%d\n", 527 ar->stats.fw_cold_reset_counter); 528 529 spin_unlock_bh(&ar->data_lock); 530 531 ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); 532 533 kfree(buf); 534 535 return ret; 536 } 537 538 static const struct file_operations fops_fw_reset_stats = { 539 .open = simple_open, 540 .read = ath10k_debug_fw_reset_stats_read, 541 .owner = THIS_MODULE, 542 .llseek = default_llseek, 543 }; 544 545 /* This is a clean assert crash in firmware. */ 546 static int ath10k_debug_fw_assert(struct ath10k *ar) 547 { 548 struct wmi_vdev_install_key_cmd *cmd; 549 struct sk_buff *skb; 550 551 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd) + 16); 552 if (!skb) 553 return -ENOMEM; 554 555 cmd = (struct wmi_vdev_install_key_cmd *)skb->data; 556 memset(cmd, 0, sizeof(*cmd)); 557 558 /* big enough number so that firmware asserts */ 559 cmd->vdev_id = __cpu_to_le32(0x7ffe); 560 561 return ath10k_wmi_cmd_send(ar, skb, 562 ar->wmi.cmd->vdev_install_key_cmdid); 563 } 564 565 static ssize_t ath10k_read_simulate_fw_crash(struct file *file, 566 char __user *user_buf, 567 size_t count, loff_t *ppos) 568 { 569 const char buf[] = 570 "To simulate firmware crash write one of the keywords to this file:\n" 571 "`soft` - this will send WMI_FORCE_FW_HANG_ASSERT to firmware if FW supports that command.\n" 572 "`hard` - this will send to firmware command with illegal parameters causing firmware crash.\n" 573 "`assert` - this will send special illegal parameter to firmware to cause assert failure and crash.\n" 574 "`hw-restart` - this will simply queue hw restart without fw/hw actually crashing.\n"; 575 576 return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf)); 577 } 578 579 /* Simulate firmware crash: 580 * 'soft': Call wmi command causing firmware hang. This firmware hang is 581 * recoverable by warm firmware reset. 582 * 'hard': Force firmware crash by setting any vdev parameter for not allowed 583 * vdev id. This is hard firmware crash because it is recoverable only by cold 584 * firmware reset. 585 */ 586 static ssize_t ath10k_write_simulate_fw_crash(struct file *file, 587 const char __user *user_buf, 588 size_t count, loff_t *ppos) 589 { 590 struct ath10k *ar = file->private_data; 591 char buf[32] = {}; 592 ssize_t rc; 593 int ret; 594 595 /* filter partial writes and invalid commands */ 596 if (*ppos != 0 || count >= sizeof(buf) || count == 0) 597 return -EINVAL; 598 599 rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); 600 if (rc < 0) 601 return rc; 602 603 /* drop the possible '\n' from the end */ 604 if (buf[*ppos - 1] == '\n') 605 buf[*ppos - 1] = '\0'; 606 607 mutex_lock(&ar->conf_mutex); 608 609 if (ar->state != ATH10K_STATE_ON && 610 ar->state != ATH10K_STATE_RESTARTED) { 611 ret = -ENETDOWN; 612 goto exit; 613 } 614 615 if (!strcmp(buf, "soft")) { 616 ath10k_info(ar, "simulating soft firmware crash\n"); 617 ret = ath10k_wmi_force_fw_hang(ar, WMI_FORCE_FW_HANG_ASSERT, 0); 618 } else if (!strcmp(buf, "hard")) { 619 ath10k_info(ar, "simulating hard firmware crash\n"); 620 /* 0x7fff is vdev id, and it is always out of range for all 621 * firmware variants in order to force a firmware crash. 622 */ 623 ret = ath10k_wmi_vdev_set_param(ar, 0x7fff, 624 ar->wmi.vdev_param->rts_threshold, 625 0); 626 } else if (!strcmp(buf, "assert")) { 627 ath10k_info(ar, "simulating firmware assert crash\n"); 628 ret = ath10k_debug_fw_assert(ar); 629 } else if (!strcmp(buf, "hw-restart")) { 630 ath10k_info(ar, "user requested hw restart\n"); 631 ath10k_core_start_recovery(ar); 632 ret = 0; 633 } else { 634 ret = -EINVAL; 635 goto exit; 636 } 637 638 if (ret) { 639 ath10k_warn(ar, "failed to simulate firmware crash: %d\n", ret); 640 goto exit; 641 } 642 643 ret = count; 644 645 exit: 646 mutex_unlock(&ar->conf_mutex); 647 return ret; 648 } 649 650 static const struct file_operations fops_simulate_fw_crash = { 651 .read = ath10k_read_simulate_fw_crash, 652 .write = ath10k_write_simulate_fw_crash, 653 .open = simple_open, 654 .owner = THIS_MODULE, 655 .llseek = default_llseek, 656 }; 657 658 static ssize_t ath10k_read_chip_id(struct file *file, char __user *user_buf, 659 size_t count, loff_t *ppos) 660 { 661 struct ath10k *ar = file->private_data; 662 size_t len; 663 char buf[50]; 664 665 len = scnprintf(buf, sizeof(buf), "0x%08x\n", ar->bus_param.chip_id); 666 667 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 668 } 669 670 static const struct file_operations fops_chip_id = { 671 .read = ath10k_read_chip_id, 672 .open = simple_open, 673 .owner = THIS_MODULE, 674 .llseek = default_llseek, 675 }; 676 677 static ssize_t ath10k_reg_addr_read(struct file *file, 678 char __user *user_buf, 679 size_t count, loff_t *ppos) 680 { 681 struct ath10k *ar = file->private_data; 682 u8 buf[32]; 683 size_t len = 0; 684 u32 reg_addr; 685 686 mutex_lock(&ar->conf_mutex); 687 reg_addr = ar->debug.reg_addr; 688 mutex_unlock(&ar->conf_mutex); 689 690 len += scnprintf(buf + len, sizeof(buf) - len, "0x%x\n", reg_addr); 691 692 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 693 } 694 695 static ssize_t ath10k_reg_addr_write(struct file *file, 696 const char __user *user_buf, 697 size_t count, loff_t *ppos) 698 { 699 struct ath10k *ar = file->private_data; 700 u32 reg_addr; 701 int ret; 702 703 ret = kstrtou32_from_user(user_buf, count, 0, ®_addr); 704 if (ret) 705 return ret; 706 707 if (!IS_ALIGNED(reg_addr, 4)) 708 return -EFAULT; 709 710 mutex_lock(&ar->conf_mutex); 711 ar->debug.reg_addr = reg_addr; 712 mutex_unlock(&ar->conf_mutex); 713 714 return count; 715 } 716 717 static const struct file_operations fops_reg_addr = { 718 .read = ath10k_reg_addr_read, 719 .write = ath10k_reg_addr_write, 720 .open = simple_open, 721 .owner = THIS_MODULE, 722 .llseek = default_llseek, 723 }; 724 725 static ssize_t ath10k_reg_value_read(struct file *file, 726 char __user *user_buf, 727 size_t count, loff_t *ppos) 728 { 729 struct ath10k *ar = file->private_data; 730 u8 buf[48]; 731 size_t len; 732 u32 reg_addr, reg_val; 733 int ret; 734 735 mutex_lock(&ar->conf_mutex); 736 737 if (ar->state != ATH10K_STATE_ON && 738 ar->state != ATH10K_STATE_UTF) { 739 ret = -ENETDOWN; 740 goto exit; 741 } 742 743 reg_addr = ar->debug.reg_addr; 744 745 reg_val = ath10k_hif_read32(ar, reg_addr); 746 len = scnprintf(buf, sizeof(buf), "0x%08x:0x%08x\n", reg_addr, reg_val); 747 748 ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); 749 750 exit: 751 mutex_unlock(&ar->conf_mutex); 752 753 return ret; 754 } 755 756 static ssize_t ath10k_reg_value_write(struct file *file, 757 const char __user *user_buf, 758 size_t count, loff_t *ppos) 759 { 760 struct ath10k *ar = file->private_data; 761 u32 reg_addr, reg_val; 762 int ret; 763 764 mutex_lock(&ar->conf_mutex); 765 766 if (ar->state != ATH10K_STATE_ON && 767 ar->state != ATH10K_STATE_UTF) { 768 ret = -ENETDOWN; 769 goto exit; 770 } 771 772 reg_addr = ar->debug.reg_addr; 773 774 ret = kstrtou32_from_user(user_buf, count, 0, ®_val); 775 if (ret) 776 goto exit; 777 778 ath10k_hif_write32(ar, reg_addr, reg_val); 779 780 ret = count; 781 782 exit: 783 mutex_unlock(&ar->conf_mutex); 784 785 return ret; 786 } 787 788 static const struct file_operations fops_reg_value = { 789 .read = ath10k_reg_value_read, 790 .write = ath10k_reg_value_write, 791 .open = simple_open, 792 .owner = THIS_MODULE, 793 .llseek = default_llseek, 794 }; 795 796 static ssize_t ath10k_mem_value_read(struct file *file, 797 char __user *user_buf, 798 size_t count, loff_t *ppos) 799 { 800 struct ath10k *ar = file->private_data; 801 u8 *buf; 802 int ret; 803 804 if (*ppos < 0) 805 return -EINVAL; 806 807 if (!count) 808 return 0; 809 810 mutex_lock(&ar->conf_mutex); 811 812 buf = vmalloc(count); 813 if (!buf) { 814 ret = -ENOMEM; 815 goto exit; 816 } 817 818 if (ar->state != ATH10K_STATE_ON && 819 ar->state != ATH10K_STATE_UTF) { 820 ret = -ENETDOWN; 821 goto exit; 822 } 823 824 ret = ath10k_hif_diag_read(ar, *ppos, buf, count); 825 if (ret) { 826 ath10k_warn(ar, "failed to read address 0x%08x via diagnose window from debugfs: %d\n", 827 (u32)(*ppos), ret); 828 goto exit; 829 } 830 831 ret = copy_to_user(user_buf, buf, count); 832 if (ret) { 833 ret = -EFAULT; 834 goto exit; 835 } 836 837 count -= ret; 838 *ppos += count; 839 ret = count; 840 841 exit: 842 vfree(buf); 843 mutex_unlock(&ar->conf_mutex); 844 845 return ret; 846 } 847 848 static ssize_t ath10k_mem_value_write(struct file *file, 849 const char __user *user_buf, 850 size_t count, loff_t *ppos) 851 { 852 struct ath10k *ar = file->private_data; 853 u8 *buf; 854 int ret; 855 856 if (*ppos < 0) 857 return -EINVAL; 858 859 if (!count) 860 return 0; 861 862 mutex_lock(&ar->conf_mutex); 863 864 buf = vmalloc(count); 865 if (!buf) { 866 ret = -ENOMEM; 867 goto exit; 868 } 869 870 if (ar->state != ATH10K_STATE_ON && 871 ar->state != ATH10K_STATE_UTF) { 872 ret = -ENETDOWN; 873 goto exit; 874 } 875 876 ret = copy_from_user(buf, user_buf, count); 877 if (ret) { 878 ret = -EFAULT; 879 goto exit; 880 } 881 882 ret = ath10k_hif_diag_write(ar, *ppos, buf, count); 883 if (ret) { 884 ath10k_warn(ar, "failed to write address 0x%08x via diagnose window from debugfs: %d\n", 885 (u32)(*ppos), ret); 886 goto exit; 887 } 888 889 *ppos += count; 890 ret = count; 891 892 exit: 893 vfree(buf); 894 mutex_unlock(&ar->conf_mutex); 895 896 return ret; 897 } 898 899 static const struct file_operations fops_mem_value = { 900 .read = ath10k_mem_value_read, 901 .write = ath10k_mem_value_write, 902 .open = simple_open, 903 .owner = THIS_MODULE, 904 .llseek = default_llseek, 905 }; 906 907 static int ath10k_debug_htt_stats_req(struct ath10k *ar) 908 { 909 u64 cookie; 910 int ret; 911 912 lockdep_assert_held(&ar->conf_mutex); 913 914 if (ar->debug.htt_stats_mask == 0) 915 /* htt stats are disabled */ 916 return 0; 917 918 if (ar->state != ATH10K_STATE_ON) 919 return 0; 920 921 cookie = get_jiffies_64(); 922 923 ret = ath10k_htt_h2t_stats_req(&ar->htt, ar->debug.htt_stats_mask, 924 ar->debug.reset_htt_stats, cookie); 925 if (ret) { 926 ath10k_warn(ar, "failed to send htt stats request: %d\n", ret); 927 return ret; 928 } 929 930 queue_delayed_work(ar->workqueue, &ar->debug.htt_stats_dwork, 931 msecs_to_jiffies(ATH10K_DEBUG_HTT_STATS_INTERVAL)); 932 933 return 0; 934 } 935 936 static void ath10k_debug_htt_stats_dwork(struct work_struct *work) 937 { 938 struct ath10k *ar = container_of(work, struct ath10k, 939 debug.htt_stats_dwork.work); 940 941 mutex_lock(&ar->conf_mutex); 942 943 ath10k_debug_htt_stats_req(ar); 944 945 mutex_unlock(&ar->conf_mutex); 946 } 947 948 static ssize_t ath10k_read_htt_stats_mask(struct file *file, 949 char __user *user_buf, 950 size_t count, loff_t *ppos) 951 { 952 struct ath10k *ar = file->private_data; 953 char buf[32]; 954 size_t len; 955 956 len = scnprintf(buf, sizeof(buf), "%lu\n", ar->debug.htt_stats_mask); 957 958 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 959 } 960 961 static ssize_t ath10k_write_htt_stats_mask(struct file *file, 962 const char __user *user_buf, 963 size_t count, loff_t *ppos) 964 { 965 struct ath10k *ar = file->private_data; 966 unsigned long mask; 967 int ret; 968 969 ret = kstrtoul_from_user(user_buf, count, 0, &mask); 970 if (ret) 971 return ret; 972 973 /* max 17 bit masks (for now) */ 974 if (mask > HTT_STATS_BIT_MASK) 975 return -E2BIG; 976 977 mutex_lock(&ar->conf_mutex); 978 979 ar->debug.htt_stats_mask = mask; 980 981 ret = ath10k_debug_htt_stats_req(ar); 982 if (ret) 983 goto out; 984 985 ret = count; 986 987 out: 988 mutex_unlock(&ar->conf_mutex); 989 990 return ret; 991 } 992 993 static const struct file_operations fops_htt_stats_mask = { 994 .read = ath10k_read_htt_stats_mask, 995 .write = ath10k_write_htt_stats_mask, 996 .open = simple_open, 997 .owner = THIS_MODULE, 998 .llseek = default_llseek, 999 }; 1000 1001 static ssize_t ath10k_read_htt_max_amsdu_ampdu(struct file *file, 1002 char __user *user_buf, 1003 size_t count, loff_t *ppos) 1004 { 1005 struct ath10k *ar = file->private_data; 1006 char buf[64]; 1007 u8 amsdu, ampdu; 1008 size_t len; 1009 1010 mutex_lock(&ar->conf_mutex); 1011 1012 amsdu = ar->htt.max_num_amsdu; 1013 ampdu = ar->htt.max_num_ampdu; 1014 mutex_unlock(&ar->conf_mutex); 1015 1016 len = scnprintf(buf, sizeof(buf), "%u %u\n", amsdu, ampdu); 1017 1018 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 1019 } 1020 1021 static ssize_t ath10k_write_htt_max_amsdu_ampdu(struct file *file, 1022 const char __user *user_buf, 1023 size_t count, loff_t *ppos) 1024 { 1025 struct ath10k *ar = file->private_data; 1026 int res; 1027 char buf[64] = {}; 1028 unsigned int amsdu, ampdu; 1029 1030 res = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, 1031 user_buf, count); 1032 if (res <= 0) 1033 return res; 1034 1035 res = sscanf(buf, "%u %u", &amsdu, &du); 1036 1037 if (res != 2) 1038 return -EINVAL; 1039 1040 mutex_lock(&ar->conf_mutex); 1041 1042 res = ath10k_htt_h2t_aggr_cfg_msg(&ar->htt, ampdu, amsdu); 1043 if (res) 1044 goto out; 1045 1046 res = count; 1047 ar->htt.max_num_amsdu = amsdu; 1048 ar->htt.max_num_ampdu = ampdu; 1049 1050 out: 1051 mutex_unlock(&ar->conf_mutex); 1052 return res; 1053 } 1054 1055 static const struct file_operations fops_htt_max_amsdu_ampdu = { 1056 .read = ath10k_read_htt_max_amsdu_ampdu, 1057 .write = ath10k_write_htt_max_amsdu_ampdu, 1058 .open = simple_open, 1059 .owner = THIS_MODULE, 1060 .llseek = default_llseek, 1061 }; 1062 1063 static ssize_t ath10k_read_fw_dbglog(struct file *file, 1064 char __user *user_buf, 1065 size_t count, loff_t *ppos) 1066 { 1067 struct ath10k *ar = file->private_data; 1068 size_t len; 1069 char buf[96]; 1070 1071 len = scnprintf(buf, sizeof(buf), "0x%16llx %u\n", 1072 ar->debug.fw_dbglog_mask, ar->debug.fw_dbglog_level); 1073 1074 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 1075 } 1076 1077 static ssize_t ath10k_write_fw_dbglog(struct file *file, 1078 const char __user *user_buf, 1079 size_t count, loff_t *ppos) 1080 { 1081 struct ath10k *ar = file->private_data; 1082 int ret; 1083 char buf[96] = {}; 1084 unsigned int log_level; 1085 u64 mask; 1086 1087 ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, 1088 user_buf, count); 1089 if (ret <= 0) 1090 return ret; 1091 1092 ret = sscanf(buf, "%llx %u", &mask, &log_level); 1093 1094 if (!ret) 1095 return -EINVAL; 1096 1097 if (ret == 1) 1098 /* default if user did not specify */ 1099 log_level = ATH10K_DBGLOG_LEVEL_WARN; 1100 1101 mutex_lock(&ar->conf_mutex); 1102 1103 ar->debug.fw_dbglog_mask = mask; 1104 ar->debug.fw_dbglog_level = log_level; 1105 1106 if (ar->state == ATH10K_STATE_ON) { 1107 ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask, 1108 ar->debug.fw_dbglog_level); 1109 if (ret) { 1110 ath10k_warn(ar, "dbglog cfg failed from debugfs: %d\n", 1111 ret); 1112 goto exit; 1113 } 1114 } 1115 1116 ret = count; 1117 1118 exit: 1119 mutex_unlock(&ar->conf_mutex); 1120 1121 return ret; 1122 } 1123 1124 /* TODO: Would be nice to always support ethtool stats, would need to 1125 * move the stats storage out of ath10k_debug, or always have ath10k_debug 1126 * struct available.. 1127 */ 1128 1129 /* This generally corresponds to the debugfs fw_stats file */ 1130 static const char ath10k_gstrings_stats[][ETH_GSTRING_LEN] = { 1131 "tx_pkts_nic", 1132 "tx_bytes_nic", 1133 "rx_pkts_nic", 1134 "rx_bytes_nic", 1135 "d_noise_floor", 1136 "d_cycle_count", 1137 "d_phy_error", 1138 "d_rts_bad", 1139 "d_rts_good", 1140 "d_tx_power", /* in .5 dbM I think */ 1141 "d_rx_crc_err", /* fcs_bad */ 1142 "d_rx_crc_err_drop", /* frame with FCS error, dropped late in kernel */ 1143 "d_no_beacon", 1144 "d_tx_mpdus_queued", 1145 "d_tx_msdu_queued", 1146 "d_tx_msdu_dropped", 1147 "d_local_enqued", 1148 "d_local_freed", 1149 "d_tx_ppdu_hw_queued", 1150 "d_tx_ppdu_reaped", 1151 "d_tx_fifo_underrun", 1152 "d_tx_ppdu_abort", 1153 "d_tx_mpdu_requeued", 1154 "d_tx_excessive_retries", 1155 "d_tx_hw_rate", 1156 "d_tx_dropped_sw_retries", 1157 "d_tx_illegal_rate", 1158 "d_tx_continuous_xretries", 1159 "d_tx_timeout", 1160 "d_tx_mpdu_txop_limit", 1161 "d_pdev_resets", 1162 "d_rx_mid_ppdu_route_change", 1163 "d_rx_status", 1164 "d_rx_extra_frags_ring0", 1165 "d_rx_extra_frags_ring1", 1166 "d_rx_extra_frags_ring2", 1167 "d_rx_extra_frags_ring3", 1168 "d_rx_msdu_htt", 1169 "d_rx_mpdu_htt", 1170 "d_rx_msdu_stack", 1171 "d_rx_mpdu_stack", 1172 "d_rx_phy_err", 1173 "d_rx_phy_err_drops", 1174 "d_rx_mpdu_errors", /* FCS, MIC, ENC */ 1175 "d_fw_crash_count", 1176 "d_fw_warm_reset_count", 1177 "d_fw_cold_reset_count", 1178 }; 1179 1180 #define ATH10K_SSTATS_LEN ARRAY_SIZE(ath10k_gstrings_stats) 1181 1182 void ath10k_debug_get_et_strings(struct ieee80211_hw *hw, 1183 struct ieee80211_vif *vif, 1184 u32 sset, u8 *data) 1185 { 1186 if (sset == ETH_SS_STATS) 1187 memcpy(data, ath10k_gstrings_stats, 1188 sizeof(ath10k_gstrings_stats)); 1189 } 1190 1191 int ath10k_debug_get_et_sset_count(struct ieee80211_hw *hw, 1192 struct ieee80211_vif *vif, int sset) 1193 { 1194 if (sset == ETH_SS_STATS) 1195 return ATH10K_SSTATS_LEN; 1196 1197 return 0; 1198 } 1199 1200 void ath10k_debug_get_et_stats(struct ieee80211_hw *hw, 1201 struct ieee80211_vif *vif, 1202 struct ethtool_stats *stats, u64 *data) 1203 { 1204 struct ath10k *ar = hw->priv; 1205 static const struct ath10k_fw_stats_pdev zero_stats = {}; 1206 const struct ath10k_fw_stats_pdev *pdev_stats; 1207 int i = 0, ret; 1208 1209 mutex_lock(&ar->conf_mutex); 1210 1211 if (ar->state == ATH10K_STATE_ON) { 1212 ret = ath10k_debug_fw_stats_request(ar); 1213 if (ret) { 1214 /* just print a warning and try to use older results */ 1215 ath10k_warn(ar, 1216 "failed to get fw stats for ethtool: %d\n", 1217 ret); 1218 } 1219 } 1220 1221 pdev_stats = list_first_entry_or_null(&ar->debug.fw_stats.pdevs, 1222 struct ath10k_fw_stats_pdev, 1223 list); 1224 if (!pdev_stats) { 1225 /* no results available so just return zeroes */ 1226 pdev_stats = &zero_stats; 1227 } 1228 1229 spin_lock_bh(&ar->data_lock); 1230 1231 data[i++] = pdev_stats->hw_reaped; /* ppdu reaped */ 1232 data[i++] = 0; /* tx bytes */ 1233 data[i++] = pdev_stats->htt_mpdus; 1234 data[i++] = 0; /* rx bytes */ 1235 data[i++] = pdev_stats->ch_noise_floor; 1236 data[i++] = pdev_stats->cycle_count; 1237 data[i++] = pdev_stats->phy_err_count; 1238 data[i++] = pdev_stats->rts_bad; 1239 data[i++] = pdev_stats->rts_good; 1240 data[i++] = pdev_stats->chan_tx_power; 1241 data[i++] = pdev_stats->fcs_bad; 1242 data[i++] = ar->stats.rx_crc_err_drop; 1243 data[i++] = pdev_stats->no_beacons; 1244 data[i++] = pdev_stats->mpdu_enqued; 1245 data[i++] = pdev_stats->msdu_enqued; 1246 data[i++] = pdev_stats->wmm_drop; 1247 data[i++] = pdev_stats->local_enqued; 1248 data[i++] = pdev_stats->local_freed; 1249 data[i++] = pdev_stats->hw_queued; 1250 data[i++] = pdev_stats->hw_reaped; 1251 data[i++] = pdev_stats->underrun; 1252 data[i++] = pdev_stats->tx_abort; 1253 data[i++] = pdev_stats->mpdus_requeued; 1254 data[i++] = pdev_stats->tx_ko; 1255 data[i++] = pdev_stats->data_rc; 1256 data[i++] = pdev_stats->sw_retry_failure; 1257 data[i++] = pdev_stats->illgl_rate_phy_err; 1258 data[i++] = pdev_stats->pdev_cont_xretry; 1259 data[i++] = pdev_stats->pdev_tx_timeout; 1260 data[i++] = pdev_stats->txop_ovf; 1261 data[i++] = pdev_stats->pdev_resets; 1262 data[i++] = pdev_stats->mid_ppdu_route_change; 1263 data[i++] = pdev_stats->status_rcvd; 1264 data[i++] = pdev_stats->r0_frags; 1265 data[i++] = pdev_stats->r1_frags; 1266 data[i++] = pdev_stats->r2_frags; 1267 data[i++] = pdev_stats->r3_frags; 1268 data[i++] = pdev_stats->htt_msdus; 1269 data[i++] = pdev_stats->htt_mpdus; 1270 data[i++] = pdev_stats->loc_msdus; 1271 data[i++] = pdev_stats->loc_mpdus; 1272 data[i++] = pdev_stats->phy_errs; 1273 data[i++] = pdev_stats->phy_err_drop; 1274 data[i++] = pdev_stats->mpdu_errs; 1275 data[i++] = ar->stats.fw_crash_counter; 1276 data[i++] = ar->stats.fw_warm_reset_counter; 1277 data[i++] = ar->stats.fw_cold_reset_counter; 1278 1279 spin_unlock_bh(&ar->data_lock); 1280 1281 mutex_unlock(&ar->conf_mutex); 1282 1283 WARN_ON(i != ATH10K_SSTATS_LEN); 1284 } 1285 1286 static const struct file_operations fops_fw_dbglog = { 1287 .read = ath10k_read_fw_dbglog, 1288 .write = ath10k_write_fw_dbglog, 1289 .open = simple_open, 1290 .owner = THIS_MODULE, 1291 .llseek = default_llseek, 1292 }; 1293 1294 static int ath10k_debug_cal_data_fetch(struct ath10k *ar) 1295 { 1296 u32 hi_addr; 1297 __le32 addr; 1298 int ret; 1299 1300 lockdep_assert_held(&ar->conf_mutex); 1301 1302 if (WARN_ON(ar->hw_params.cal_data_len > ATH10K_DEBUG_CAL_DATA_LEN)) 1303 return -EINVAL; 1304 1305 if (ar->hw_params.cal_data_len == 0) 1306 return -EOPNOTSUPP; 1307 1308 hi_addr = host_interest_item_address(HI_ITEM(hi_board_data)); 1309 1310 ret = ath10k_hif_diag_read(ar, hi_addr, &addr, sizeof(addr)); 1311 if (ret) { 1312 ath10k_warn(ar, "failed to read hi_board_data address: %d\n", 1313 ret); 1314 return ret; 1315 } 1316 1317 ret = ath10k_hif_diag_read(ar, le32_to_cpu(addr), ar->debug.cal_data, 1318 ar->hw_params.cal_data_len); 1319 if (ret) { 1320 ath10k_warn(ar, "failed to read calibration data: %d\n", ret); 1321 return ret; 1322 } 1323 1324 return 0; 1325 } 1326 1327 static int ath10k_debug_cal_data_open(struct inode *inode, struct file *file) 1328 { 1329 struct ath10k *ar = inode->i_private; 1330 1331 mutex_lock(&ar->conf_mutex); 1332 1333 if (ar->state == ATH10K_STATE_ON || 1334 ar->state == ATH10K_STATE_UTF) { 1335 ath10k_debug_cal_data_fetch(ar); 1336 } 1337 1338 file->private_data = ar; 1339 mutex_unlock(&ar->conf_mutex); 1340 1341 return 0; 1342 } 1343 1344 static ssize_t ath10k_debug_cal_data_read(struct file *file, 1345 char __user *user_buf, 1346 size_t count, loff_t *ppos) 1347 { 1348 struct ath10k *ar = file->private_data; 1349 1350 mutex_lock(&ar->conf_mutex); 1351 1352 count = simple_read_from_buffer(user_buf, count, ppos, 1353 ar->debug.cal_data, 1354 ar->hw_params.cal_data_len); 1355 1356 mutex_unlock(&ar->conf_mutex); 1357 1358 return count; 1359 } 1360 1361 static ssize_t ath10k_write_ani_enable(struct file *file, 1362 const char __user *user_buf, 1363 size_t count, loff_t *ppos) 1364 { 1365 struct ath10k *ar = file->private_data; 1366 int ret; 1367 u8 enable; 1368 1369 if (kstrtou8_from_user(user_buf, count, 0, &enable)) 1370 return -EINVAL; 1371 1372 mutex_lock(&ar->conf_mutex); 1373 1374 if (ar->ani_enabled == enable) { 1375 ret = count; 1376 goto exit; 1377 } 1378 1379 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->ani_enable, 1380 enable); 1381 if (ret) { 1382 ath10k_warn(ar, "ani_enable failed from debugfs: %d\n", ret); 1383 goto exit; 1384 } 1385 ar->ani_enabled = enable; 1386 1387 ret = count; 1388 1389 exit: 1390 mutex_unlock(&ar->conf_mutex); 1391 1392 return ret; 1393 } 1394 1395 static ssize_t ath10k_read_ani_enable(struct file *file, char __user *user_buf, 1396 size_t count, loff_t *ppos) 1397 { 1398 struct ath10k *ar = file->private_data; 1399 size_t len; 1400 char buf[32]; 1401 1402 len = scnprintf(buf, sizeof(buf), "%d\n", ar->ani_enabled); 1403 1404 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 1405 } 1406 1407 static const struct file_operations fops_ani_enable = { 1408 .read = ath10k_read_ani_enable, 1409 .write = ath10k_write_ani_enable, 1410 .open = simple_open, 1411 .owner = THIS_MODULE, 1412 .llseek = default_llseek, 1413 }; 1414 1415 static const struct file_operations fops_cal_data = { 1416 .open = ath10k_debug_cal_data_open, 1417 .read = ath10k_debug_cal_data_read, 1418 .owner = THIS_MODULE, 1419 .llseek = default_llseek, 1420 }; 1421 1422 static ssize_t ath10k_read_nf_cal_period(struct file *file, 1423 char __user *user_buf, 1424 size_t count, loff_t *ppos) 1425 { 1426 struct ath10k *ar = file->private_data; 1427 size_t len; 1428 char buf[32]; 1429 1430 len = scnprintf(buf, sizeof(buf), "%d\n", ar->debug.nf_cal_period); 1431 1432 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 1433 } 1434 1435 static ssize_t ath10k_write_nf_cal_period(struct file *file, 1436 const char __user *user_buf, 1437 size_t count, loff_t *ppos) 1438 { 1439 struct ath10k *ar = file->private_data; 1440 unsigned long period; 1441 int ret; 1442 1443 ret = kstrtoul_from_user(user_buf, count, 0, &period); 1444 if (ret) 1445 return ret; 1446 1447 if (period > WMI_PDEV_PARAM_CAL_PERIOD_MAX) 1448 return -EINVAL; 1449 1450 /* there's no way to switch back to the firmware default */ 1451 if (period == 0) 1452 return -EINVAL; 1453 1454 mutex_lock(&ar->conf_mutex); 1455 1456 ar->debug.nf_cal_period = period; 1457 1458 if (ar->state != ATH10K_STATE_ON) { 1459 /* firmware is not running, nothing else to do */ 1460 ret = count; 1461 goto exit; 1462 } 1463 1464 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->cal_period, 1465 ar->debug.nf_cal_period); 1466 if (ret) { 1467 ath10k_warn(ar, "cal period cfg failed from debugfs: %d\n", 1468 ret); 1469 goto exit; 1470 } 1471 1472 ret = count; 1473 1474 exit: 1475 mutex_unlock(&ar->conf_mutex); 1476 1477 return ret; 1478 } 1479 1480 static const struct file_operations fops_nf_cal_period = { 1481 .read = ath10k_read_nf_cal_period, 1482 .write = ath10k_write_nf_cal_period, 1483 .open = simple_open, 1484 .owner = THIS_MODULE, 1485 .llseek = default_llseek, 1486 }; 1487 1488 #define ATH10K_TPC_CONFIG_BUF_SIZE (1024 * 1024) 1489 1490 static int ath10k_debug_tpc_stats_request(struct ath10k *ar) 1491 { 1492 int ret; 1493 unsigned long time_left; 1494 1495 lockdep_assert_held(&ar->conf_mutex); 1496 1497 reinit_completion(&ar->debug.tpc_complete); 1498 1499 ret = ath10k_wmi_pdev_get_tpc_config(ar, WMI_TPC_CONFIG_PARAM); 1500 if (ret) { 1501 ath10k_warn(ar, "failed to request tpc config: %d\n", ret); 1502 return ret; 1503 } 1504 1505 time_left = wait_for_completion_timeout(&ar->debug.tpc_complete, 1506 1 * HZ); 1507 if (time_left == 0) 1508 return -ETIMEDOUT; 1509 1510 return 0; 1511 } 1512 1513 void ath10k_debug_tpc_stats_process(struct ath10k *ar, 1514 struct ath10k_tpc_stats *tpc_stats) 1515 { 1516 spin_lock_bh(&ar->data_lock); 1517 1518 kfree(ar->debug.tpc_stats); 1519 ar->debug.tpc_stats = tpc_stats; 1520 complete(&ar->debug.tpc_complete); 1521 1522 spin_unlock_bh(&ar->data_lock); 1523 } 1524 1525 void 1526 ath10k_debug_tpc_stats_final_process(struct ath10k *ar, 1527 struct ath10k_tpc_stats_final *tpc_stats) 1528 { 1529 spin_lock_bh(&ar->data_lock); 1530 1531 kfree(ar->debug.tpc_stats_final); 1532 ar->debug.tpc_stats_final = tpc_stats; 1533 complete(&ar->debug.tpc_complete); 1534 1535 spin_unlock_bh(&ar->data_lock); 1536 } 1537 1538 static void ath10k_tpc_stats_print(struct ath10k_tpc_stats *tpc_stats, 1539 unsigned int j, char *buf, size_t *len) 1540 { 1541 int i; 1542 size_t buf_len; 1543 static const char table_str[][5] = { "CDD", 1544 "STBC", 1545 "TXBF" }; 1546 static const char pream_str[][6] = { "CCK", 1547 "OFDM", 1548 "HT20", 1549 "HT40", 1550 "VHT20", 1551 "VHT40", 1552 "VHT80", 1553 "HTCUP" }; 1554 1555 buf_len = ATH10K_TPC_CONFIG_BUF_SIZE; 1556 *len += scnprintf(buf + *len, buf_len - *len, 1557 "********************************\n"); 1558 *len += scnprintf(buf + *len, buf_len - *len, 1559 "******************* %s POWER TABLE ****************\n", 1560 table_str[j]); 1561 *len += scnprintf(buf + *len, buf_len - *len, 1562 "********************************\n"); 1563 *len += scnprintf(buf + *len, buf_len - *len, 1564 "No. Preamble Rate_code "); 1565 1566 for (i = 0; i < tpc_stats->num_tx_chain; i++) 1567 *len += scnprintf(buf + *len, buf_len - *len, 1568 "tpc_value%d ", i); 1569 1570 *len += scnprintf(buf + *len, buf_len - *len, "\n"); 1571 1572 for (i = 0; i < tpc_stats->rate_max; i++) { 1573 *len += scnprintf(buf + *len, buf_len - *len, 1574 "%8d %s 0x%2x %s\n", i, 1575 pream_str[tpc_stats->tpc_table[j].pream_idx[i]], 1576 tpc_stats->tpc_table[j].rate_code[i], 1577 tpc_stats->tpc_table[j].tpc_value[i]); 1578 } 1579 1580 *len += scnprintf(buf + *len, buf_len - *len, 1581 "***********************************\n"); 1582 } 1583 1584 static void ath10k_tpc_stats_fill(struct ath10k *ar, 1585 struct ath10k_tpc_stats *tpc_stats, 1586 char *buf) 1587 { 1588 int j; 1589 size_t len, buf_len; 1590 1591 len = 0; 1592 buf_len = ATH10K_TPC_CONFIG_BUF_SIZE; 1593 1594 spin_lock_bh(&ar->data_lock); 1595 1596 if (!tpc_stats) { 1597 ath10k_warn(ar, "failed to get tpc stats\n"); 1598 goto unlock; 1599 } 1600 1601 len += scnprintf(buf + len, buf_len - len, "\n"); 1602 len += scnprintf(buf + len, buf_len - len, 1603 "*************************************\n"); 1604 len += scnprintf(buf + len, buf_len - len, 1605 "TPC config for channel %4d mode %d\n", 1606 tpc_stats->chan_freq, 1607 tpc_stats->phy_mode); 1608 len += scnprintf(buf + len, buf_len - len, 1609 "*************************************\n"); 1610 len += scnprintf(buf + len, buf_len - len, 1611 "CTL = 0x%2x Reg. Domain = %2d\n", 1612 tpc_stats->ctl, 1613 tpc_stats->reg_domain); 1614 len += scnprintf(buf + len, buf_len - len, 1615 "Antenna Gain = %2d Reg. Max Antenna Gain = %2d\n", 1616 tpc_stats->twice_antenna_gain, 1617 tpc_stats->twice_antenna_reduction); 1618 len += scnprintf(buf + len, buf_len - len, 1619 "Power Limit = %2d Reg. Max Power = %2d\n", 1620 tpc_stats->power_limit, 1621 tpc_stats->twice_max_rd_power / 2); 1622 len += scnprintf(buf + len, buf_len - len, 1623 "Num tx chains = %2d Num supported rates = %2d\n", 1624 tpc_stats->num_tx_chain, 1625 tpc_stats->rate_max); 1626 1627 for (j = 0; j < WMI_TPC_FLAG; j++) { 1628 switch (j) { 1629 case WMI_TPC_TABLE_TYPE_CDD: 1630 if (tpc_stats->flag[j] == ATH10K_TPC_TABLE_TYPE_FLAG) { 1631 len += scnprintf(buf + len, buf_len - len, 1632 "CDD not supported\n"); 1633 break; 1634 } 1635 1636 ath10k_tpc_stats_print(tpc_stats, j, buf, &len); 1637 break; 1638 case WMI_TPC_TABLE_TYPE_STBC: 1639 if (tpc_stats->flag[j] == ATH10K_TPC_TABLE_TYPE_FLAG) { 1640 len += scnprintf(buf + len, buf_len - len, 1641 "STBC not supported\n"); 1642 break; 1643 } 1644 1645 ath10k_tpc_stats_print(tpc_stats, j, buf, &len); 1646 break; 1647 case WMI_TPC_TABLE_TYPE_TXBF: 1648 if (tpc_stats->flag[j] == ATH10K_TPC_TABLE_TYPE_FLAG) { 1649 len += scnprintf(buf + len, buf_len - len, 1650 "TXBF not supported\n***************************\n"); 1651 break; 1652 } 1653 1654 ath10k_tpc_stats_print(tpc_stats, j, buf, &len); 1655 break; 1656 default: 1657 len += scnprintf(buf + len, buf_len - len, 1658 "Invalid Type\n"); 1659 break; 1660 } 1661 } 1662 1663 unlock: 1664 spin_unlock_bh(&ar->data_lock); 1665 1666 if (len >= buf_len) 1667 buf[len - 1] = 0; 1668 else 1669 buf[len] = 0; 1670 } 1671 1672 static int ath10k_tpc_stats_open(struct inode *inode, struct file *file) 1673 { 1674 struct ath10k *ar = inode->i_private; 1675 void *buf = NULL; 1676 int ret; 1677 1678 mutex_lock(&ar->conf_mutex); 1679 1680 if (ar->state != ATH10K_STATE_ON) { 1681 ret = -ENETDOWN; 1682 goto err_unlock; 1683 } 1684 1685 buf = vmalloc(ATH10K_TPC_CONFIG_BUF_SIZE); 1686 if (!buf) { 1687 ret = -ENOMEM; 1688 goto err_unlock; 1689 } 1690 1691 ret = ath10k_debug_tpc_stats_request(ar); 1692 if (ret) { 1693 ath10k_warn(ar, "failed to request tpc config stats: %d\n", 1694 ret); 1695 goto err_free; 1696 } 1697 1698 ath10k_tpc_stats_fill(ar, ar->debug.tpc_stats, buf); 1699 file->private_data = buf; 1700 1701 mutex_unlock(&ar->conf_mutex); 1702 return 0; 1703 1704 err_free: 1705 vfree(buf); 1706 1707 err_unlock: 1708 mutex_unlock(&ar->conf_mutex); 1709 return ret; 1710 } 1711 1712 static int ath10k_tpc_stats_release(struct inode *inode, struct file *file) 1713 { 1714 vfree(file->private_data); 1715 1716 return 0; 1717 } 1718 1719 static ssize_t ath10k_tpc_stats_read(struct file *file, char __user *user_buf, 1720 size_t count, loff_t *ppos) 1721 { 1722 const char *buf = file->private_data; 1723 size_t len = strlen(buf); 1724 1725 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 1726 } 1727 1728 static const struct file_operations fops_tpc_stats = { 1729 .open = ath10k_tpc_stats_open, 1730 .release = ath10k_tpc_stats_release, 1731 .read = ath10k_tpc_stats_read, 1732 .owner = THIS_MODULE, 1733 .llseek = default_llseek, 1734 }; 1735 1736 int ath10k_debug_start(struct ath10k *ar) 1737 { 1738 int ret; 1739 1740 lockdep_assert_held(&ar->conf_mutex); 1741 1742 ret = ath10k_debug_htt_stats_req(ar); 1743 if (ret) 1744 /* continue normally anyway, this isn't serious */ 1745 ath10k_warn(ar, "failed to start htt stats workqueue: %d\n", 1746 ret); 1747 1748 if (ar->debug.fw_dbglog_mask) { 1749 ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask, 1750 ATH10K_DBGLOG_LEVEL_WARN); 1751 if (ret) 1752 /* not serious */ 1753 ath10k_warn(ar, "failed to enable dbglog during start: %d", 1754 ret); 1755 } 1756 1757 if (ar->pktlog_filter) { 1758 ret = ath10k_wmi_pdev_pktlog_enable(ar, 1759 ar->pktlog_filter); 1760 if (ret) 1761 /* not serious */ 1762 ath10k_warn(ar, 1763 "failed to enable pktlog filter %x: %d\n", 1764 ar->pktlog_filter, ret); 1765 } else { 1766 ret = ath10k_wmi_pdev_pktlog_disable(ar); 1767 if (ret) 1768 /* not serious */ 1769 ath10k_warn(ar, "failed to disable pktlog: %d\n", ret); 1770 } 1771 1772 if (ar->debug.nf_cal_period && 1773 !test_bit(ATH10K_FW_FEATURE_NON_BMI, 1774 ar->normal_mode_fw.fw_file.fw_features)) { 1775 ret = ath10k_wmi_pdev_set_param(ar, 1776 ar->wmi.pdev_param->cal_period, 1777 ar->debug.nf_cal_period); 1778 if (ret) 1779 /* not serious */ 1780 ath10k_warn(ar, "cal period cfg failed from debug start: %d\n", 1781 ret); 1782 } 1783 1784 return ret; 1785 } 1786 1787 void ath10k_debug_stop(struct ath10k *ar) 1788 { 1789 lockdep_assert_held(&ar->conf_mutex); 1790 1791 if (!test_bit(ATH10K_FW_FEATURE_NON_BMI, 1792 ar->normal_mode_fw.fw_file.fw_features)) 1793 ath10k_debug_cal_data_fetch(ar); 1794 1795 /* Must not use _sync to avoid deadlock, we do that in 1796 * ath10k_debug_destroy(). The check for htt_stats_mask is to avoid 1797 * warning from timer_delete(). 1798 */ 1799 if (ar->debug.htt_stats_mask != 0) 1800 cancel_delayed_work(&ar->debug.htt_stats_dwork); 1801 1802 ath10k_wmi_pdev_pktlog_disable(ar); 1803 } 1804 1805 static ssize_t ath10k_write_simulate_radar(struct file *file, 1806 const char __user *user_buf, 1807 size_t count, loff_t *ppos) 1808 { 1809 struct ath10k *ar = file->private_data; 1810 struct ath10k_vif *arvif; 1811 1812 /* Just check for the first vif alone, as all the vifs will be 1813 * sharing the same channel and if the channel is disabled, all the 1814 * vifs will share the same 'is_started' state. 1815 */ 1816 arvif = list_first_entry(&ar->arvifs, typeof(*arvif), list); 1817 if (!arvif->is_started) 1818 return -EINVAL; 1819 1820 ieee80211_radar_detected(ar->hw, NULL); 1821 1822 return count; 1823 } 1824 1825 static const struct file_operations fops_simulate_radar = { 1826 .write = ath10k_write_simulate_radar, 1827 .open = simple_open, 1828 .owner = THIS_MODULE, 1829 .llseek = default_llseek, 1830 }; 1831 1832 #define ATH10K_DFS_STAT(s, p) (\ 1833 len += scnprintf(buf + len, size - len, "%-28s : %10u\n", s, \ 1834 ar->debug.dfs_stats.p)) 1835 1836 #define ATH10K_DFS_POOL_STAT(s, p) (\ 1837 len += scnprintf(buf + len, size - len, "%-28s : %10u\n", s, \ 1838 ar->debug.dfs_pool_stats.p)) 1839 1840 static ssize_t ath10k_read_dfs_stats(struct file *file, char __user *user_buf, 1841 size_t count, loff_t *ppos) 1842 { 1843 int retval = 0, len = 0; 1844 const int size = 8000; 1845 struct ath10k *ar = file->private_data; 1846 char *buf; 1847 1848 buf = kzalloc(size, GFP_KERNEL); 1849 if (buf == NULL) 1850 return -ENOMEM; 1851 1852 if (!ar->dfs_detector) { 1853 len += scnprintf(buf + len, size - len, "DFS not enabled\n"); 1854 goto exit; 1855 } 1856 1857 ar->debug.dfs_pool_stats = 1858 ar->dfs_detector->get_stats(ar->dfs_detector); 1859 1860 len += scnprintf(buf + len, size - len, "Pulse detector statistics:\n"); 1861 1862 ATH10K_DFS_STAT("reported phy errors", phy_errors); 1863 ATH10K_DFS_STAT("pulse events reported", pulses_total); 1864 ATH10K_DFS_STAT("DFS pulses detected", pulses_detected); 1865 ATH10K_DFS_STAT("DFS pulses discarded", pulses_discarded); 1866 ATH10K_DFS_STAT("Radars detected", radar_detected); 1867 1868 len += scnprintf(buf + len, size - len, "Global Pool statistics:\n"); 1869 ATH10K_DFS_POOL_STAT("Pool references", pool_reference); 1870 ATH10K_DFS_POOL_STAT("Pulses allocated", pulse_allocated); 1871 ATH10K_DFS_POOL_STAT("Pulses alloc error", pulse_alloc_error); 1872 ATH10K_DFS_POOL_STAT("Pulses in use", pulse_used); 1873 ATH10K_DFS_POOL_STAT("Seqs. allocated", pseq_allocated); 1874 ATH10K_DFS_POOL_STAT("Seqs. alloc error", pseq_alloc_error); 1875 ATH10K_DFS_POOL_STAT("Seqs. in use", pseq_used); 1876 1877 exit: 1878 if (len > size) 1879 len = size; 1880 1881 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 1882 kfree(buf); 1883 1884 return retval; 1885 } 1886 1887 static const struct file_operations fops_dfs_stats = { 1888 .read = ath10k_read_dfs_stats, 1889 .open = simple_open, 1890 .owner = THIS_MODULE, 1891 .llseek = default_llseek, 1892 }; 1893 1894 static ssize_t ath10k_write_pktlog_filter(struct file *file, 1895 const char __user *ubuf, 1896 size_t count, loff_t *ppos) 1897 { 1898 struct ath10k *ar = file->private_data; 1899 u32 filter; 1900 int ret; 1901 1902 if (kstrtouint_from_user(ubuf, count, 0, &filter)) 1903 return -EINVAL; 1904 1905 mutex_lock(&ar->conf_mutex); 1906 1907 if (ar->state != ATH10K_STATE_ON) { 1908 ar->pktlog_filter = filter; 1909 ret = count; 1910 goto out; 1911 } 1912 1913 if (filter == ar->pktlog_filter) { 1914 ret = count; 1915 goto out; 1916 } 1917 1918 if (filter) { 1919 ret = ath10k_wmi_pdev_pktlog_enable(ar, filter); 1920 if (ret) { 1921 ath10k_warn(ar, "failed to enable pktlog filter %x: %d\n", 1922 ar->pktlog_filter, ret); 1923 goto out; 1924 } 1925 } else { 1926 ret = ath10k_wmi_pdev_pktlog_disable(ar); 1927 if (ret) { 1928 ath10k_warn(ar, "failed to disable pktlog: %d\n", ret); 1929 goto out; 1930 } 1931 } 1932 1933 ar->pktlog_filter = filter; 1934 ret = count; 1935 1936 out: 1937 mutex_unlock(&ar->conf_mutex); 1938 return ret; 1939 } 1940 1941 static ssize_t ath10k_read_pktlog_filter(struct file *file, char __user *ubuf, 1942 size_t count, loff_t *ppos) 1943 { 1944 char buf[32]; 1945 struct ath10k *ar = file->private_data; 1946 int len = 0; 1947 1948 mutex_lock(&ar->conf_mutex); 1949 len = scnprintf(buf, sizeof(buf) - len, "%08x\n", 1950 ar->pktlog_filter); 1951 mutex_unlock(&ar->conf_mutex); 1952 1953 return simple_read_from_buffer(ubuf, count, ppos, buf, len); 1954 } 1955 1956 static const struct file_operations fops_pktlog_filter = { 1957 .read = ath10k_read_pktlog_filter, 1958 .write = ath10k_write_pktlog_filter, 1959 .open = simple_open 1960 }; 1961 1962 static ssize_t ath10k_write_quiet_period(struct file *file, 1963 const char __user *ubuf, 1964 size_t count, loff_t *ppos) 1965 { 1966 struct ath10k *ar = file->private_data; 1967 u32 period; 1968 1969 if (kstrtouint_from_user(ubuf, count, 0, &period)) 1970 return -EINVAL; 1971 1972 if (period < ATH10K_QUIET_PERIOD_MIN) { 1973 ath10k_warn(ar, "Quiet period %u can not be lesser than 25ms\n", 1974 period); 1975 return -EINVAL; 1976 } 1977 mutex_lock(&ar->conf_mutex); 1978 ar->thermal.quiet_period = period; 1979 ath10k_thermal_set_throttling(ar); 1980 mutex_unlock(&ar->conf_mutex); 1981 1982 return count; 1983 } 1984 1985 static ssize_t ath10k_read_quiet_period(struct file *file, char __user *ubuf, 1986 size_t count, loff_t *ppos) 1987 { 1988 char buf[32]; 1989 struct ath10k *ar = file->private_data; 1990 int len = 0; 1991 1992 mutex_lock(&ar->conf_mutex); 1993 len = scnprintf(buf, sizeof(buf) - len, "%d\n", 1994 ar->thermal.quiet_period); 1995 mutex_unlock(&ar->conf_mutex); 1996 1997 return simple_read_from_buffer(ubuf, count, ppos, buf, len); 1998 } 1999 2000 static const struct file_operations fops_quiet_period = { 2001 .read = ath10k_read_quiet_period, 2002 .write = ath10k_write_quiet_period, 2003 .open = simple_open 2004 }; 2005 2006 static ssize_t ath10k_write_btcoex(struct file *file, 2007 const char __user *ubuf, 2008 size_t count, loff_t *ppos) 2009 { 2010 struct ath10k *ar = file->private_data; 2011 ssize_t ret; 2012 bool val; 2013 u32 pdev_param; 2014 2015 ret = kstrtobool_from_user(ubuf, count, &val); 2016 if (ret) 2017 return ret; 2018 2019 if (!ar->coex_support) 2020 return -EOPNOTSUPP; 2021 2022 mutex_lock(&ar->conf_mutex); 2023 2024 if (ar->state != ATH10K_STATE_ON && 2025 ar->state != ATH10K_STATE_RESTARTED) { 2026 ret = -ENETDOWN; 2027 goto exit; 2028 } 2029 2030 if (!(test_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags) ^ val)) { 2031 ret = count; 2032 goto exit; 2033 } 2034 2035 pdev_param = ar->wmi.pdev_param->enable_btcoex; 2036 if (test_bit(ATH10K_FW_FEATURE_BTCOEX_PARAM, 2037 ar->running_fw->fw_file.fw_features)) { 2038 ret = ath10k_wmi_pdev_set_param(ar, pdev_param, val); 2039 if (ret) { 2040 ath10k_warn(ar, "failed to enable btcoex: %zd\n", ret); 2041 ret = count; 2042 goto exit; 2043 } 2044 } else { 2045 ath10k_info(ar, "restarting firmware due to btcoex change"); 2046 ath10k_core_start_recovery(ar); 2047 } 2048 2049 if (val) 2050 set_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags); 2051 else 2052 clear_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags); 2053 2054 ret = count; 2055 2056 exit: 2057 mutex_unlock(&ar->conf_mutex); 2058 2059 return ret; 2060 } 2061 2062 static ssize_t ath10k_read_btcoex(struct file *file, char __user *ubuf, 2063 size_t count, loff_t *ppos) 2064 { 2065 char buf[32]; 2066 struct ath10k *ar = file->private_data; 2067 int len = 0; 2068 2069 mutex_lock(&ar->conf_mutex); 2070 len = scnprintf(buf, sizeof(buf) - len, "%d\n", 2071 test_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags)); 2072 mutex_unlock(&ar->conf_mutex); 2073 2074 return simple_read_from_buffer(ubuf, count, ppos, buf, len); 2075 } 2076 2077 static const struct file_operations fops_btcoex = { 2078 .read = ath10k_read_btcoex, 2079 .write = ath10k_write_btcoex, 2080 .open = simple_open 2081 }; 2082 2083 static ssize_t ath10k_write_enable_extd_tx_stats(struct file *file, 2084 const char __user *ubuf, 2085 size_t count, loff_t *ppos) 2086 { 2087 struct ath10k *ar = file->private_data; 2088 u32 filter; 2089 int ret; 2090 2091 if (kstrtouint_from_user(ubuf, count, 0, &filter)) 2092 return -EINVAL; 2093 2094 mutex_lock(&ar->conf_mutex); 2095 2096 if (ar->state != ATH10K_STATE_ON) { 2097 ar->debug.enable_extd_tx_stats = filter; 2098 ret = count; 2099 goto out; 2100 } 2101 2102 if (filter == ar->debug.enable_extd_tx_stats) { 2103 ret = count; 2104 goto out; 2105 } 2106 2107 ar->debug.enable_extd_tx_stats = filter; 2108 ret = count; 2109 2110 out: 2111 mutex_unlock(&ar->conf_mutex); 2112 return ret; 2113 } 2114 2115 static ssize_t ath10k_read_enable_extd_tx_stats(struct file *file, 2116 char __user *ubuf, 2117 size_t count, loff_t *ppos) 2118 2119 { 2120 char buf[32]; 2121 struct ath10k *ar = file->private_data; 2122 int len = 0; 2123 2124 mutex_lock(&ar->conf_mutex); 2125 len = scnprintf(buf, sizeof(buf) - len, "%08x\n", 2126 ar->debug.enable_extd_tx_stats); 2127 mutex_unlock(&ar->conf_mutex); 2128 2129 return simple_read_from_buffer(ubuf, count, ppos, buf, len); 2130 } 2131 2132 static const struct file_operations fops_enable_extd_tx_stats = { 2133 .read = ath10k_read_enable_extd_tx_stats, 2134 .write = ath10k_write_enable_extd_tx_stats, 2135 .open = simple_open 2136 }; 2137 2138 static ssize_t ath10k_write_peer_stats(struct file *file, 2139 const char __user *ubuf, 2140 size_t count, loff_t *ppos) 2141 { 2142 struct ath10k *ar = file->private_data; 2143 ssize_t ret; 2144 bool val; 2145 2146 ret = kstrtobool_from_user(ubuf, count, &val); 2147 if (ret) 2148 return ret; 2149 2150 mutex_lock(&ar->conf_mutex); 2151 2152 if (ar->state != ATH10K_STATE_ON && 2153 ar->state != ATH10K_STATE_RESTARTED) { 2154 ret = -ENETDOWN; 2155 goto exit; 2156 } 2157 2158 if (!(test_bit(ATH10K_FLAG_PEER_STATS, &ar->dev_flags) ^ val)) { 2159 ret = count; 2160 goto exit; 2161 } 2162 2163 if (val) 2164 set_bit(ATH10K_FLAG_PEER_STATS, &ar->dev_flags); 2165 else 2166 clear_bit(ATH10K_FLAG_PEER_STATS, &ar->dev_flags); 2167 2168 ath10k_info(ar, "restarting firmware due to Peer stats change"); 2169 2170 ath10k_core_start_recovery(ar); 2171 ret = count; 2172 2173 exit: 2174 mutex_unlock(&ar->conf_mutex); 2175 return ret; 2176 } 2177 2178 static ssize_t ath10k_read_peer_stats(struct file *file, char __user *ubuf, 2179 size_t count, loff_t *ppos) 2180 2181 { 2182 char buf[32]; 2183 struct ath10k *ar = file->private_data; 2184 int len = 0; 2185 2186 mutex_lock(&ar->conf_mutex); 2187 len = scnprintf(buf, sizeof(buf) - len, "%d\n", 2188 test_bit(ATH10K_FLAG_PEER_STATS, &ar->dev_flags)); 2189 mutex_unlock(&ar->conf_mutex); 2190 2191 return simple_read_from_buffer(ubuf, count, ppos, buf, len); 2192 } 2193 2194 static const struct file_operations fops_peer_stats = { 2195 .read = ath10k_read_peer_stats, 2196 .write = ath10k_write_peer_stats, 2197 .open = simple_open 2198 }; 2199 2200 static ssize_t ath10k_debug_fw_checksums_read(struct file *file, 2201 char __user *user_buf, 2202 size_t count, loff_t *ppos) 2203 { 2204 struct ath10k *ar = file->private_data; 2205 size_t len = 0, buf_len = 4096; 2206 ssize_t ret_cnt; 2207 char *buf; 2208 2209 buf = kzalloc(buf_len, GFP_KERNEL); 2210 if (!buf) 2211 return -ENOMEM; 2212 2213 mutex_lock(&ar->conf_mutex); 2214 2215 len += scnprintf(buf + len, buf_len - len, 2216 "firmware-N.bin\t\t%08x\n", 2217 crc32_le(0, ar->normal_mode_fw.fw_file.firmware->data, 2218 ar->normal_mode_fw.fw_file.firmware->size)); 2219 len += scnprintf(buf + len, buf_len - len, 2220 "athwlan\t\t\t%08x\n", 2221 crc32_le(0, ar->normal_mode_fw.fw_file.firmware_data, 2222 ar->normal_mode_fw.fw_file.firmware_len)); 2223 len += scnprintf(buf + len, buf_len - len, 2224 "otp\t\t\t%08x\n", 2225 crc32_le(0, ar->normal_mode_fw.fw_file.otp_data, 2226 ar->normal_mode_fw.fw_file.otp_len)); 2227 len += scnprintf(buf + len, buf_len - len, 2228 "codeswap\t\t%08x\n", 2229 crc32_le(0, ar->normal_mode_fw.fw_file.codeswap_data, 2230 ar->normal_mode_fw.fw_file.codeswap_len)); 2231 len += scnprintf(buf + len, buf_len - len, 2232 "board-N.bin\t\t%08x\n", 2233 crc32_le(0, ar->normal_mode_fw.board->data, 2234 ar->normal_mode_fw.board->size)); 2235 len += scnprintf(buf + len, buf_len - len, 2236 "board\t\t\t%08x\n", 2237 crc32_le(0, ar->normal_mode_fw.board_data, 2238 ar->normal_mode_fw.board_len)); 2239 2240 ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); 2241 2242 mutex_unlock(&ar->conf_mutex); 2243 2244 kfree(buf); 2245 return ret_cnt; 2246 } 2247 2248 static const struct file_operations fops_fw_checksums = { 2249 .read = ath10k_debug_fw_checksums_read, 2250 .open = simple_open, 2251 .owner = THIS_MODULE, 2252 .llseek = default_llseek, 2253 }; 2254 2255 static ssize_t ath10k_sta_tid_stats_mask_read(struct file *file, 2256 char __user *user_buf, 2257 size_t count, loff_t *ppos) 2258 { 2259 struct ath10k *ar = file->private_data; 2260 char buf[32]; 2261 size_t len; 2262 2263 len = scnprintf(buf, sizeof(buf), "0x%08x\n", ar->sta_tid_stats_mask); 2264 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 2265 } 2266 2267 static ssize_t ath10k_sta_tid_stats_mask_write(struct file *file, 2268 const char __user *user_buf, 2269 size_t count, loff_t *ppos) 2270 { 2271 struct ath10k *ar = file->private_data; 2272 ssize_t ret; 2273 u32 mask; 2274 2275 ret = kstrtoint_from_user(user_buf, count, 0, &mask); 2276 if (ret) 2277 return ret; 2278 2279 ar->sta_tid_stats_mask = mask; 2280 2281 return count; 2282 } 2283 2284 static const struct file_operations fops_sta_tid_stats_mask = { 2285 .read = ath10k_sta_tid_stats_mask_read, 2286 .write = ath10k_sta_tid_stats_mask_write, 2287 .open = simple_open, 2288 .owner = THIS_MODULE, 2289 .llseek = default_llseek, 2290 }; 2291 2292 static int ath10k_debug_tpc_stats_final_request(struct ath10k *ar) 2293 { 2294 int ret; 2295 unsigned long time_left; 2296 2297 lockdep_assert_held(&ar->conf_mutex); 2298 2299 reinit_completion(&ar->debug.tpc_complete); 2300 2301 ret = ath10k_wmi_pdev_get_tpc_table_cmdid(ar, WMI_TPC_CONFIG_PARAM); 2302 if (ret) { 2303 ath10k_warn(ar, "failed to request tpc table cmdid: %d\n", ret); 2304 return ret; 2305 } 2306 2307 time_left = wait_for_completion_timeout(&ar->debug.tpc_complete, 2308 1 * HZ); 2309 if (time_left == 0) 2310 return -ETIMEDOUT; 2311 2312 return 0; 2313 } 2314 2315 static int ath10k_tpc_stats_final_open(struct inode *inode, struct file *file) 2316 { 2317 struct ath10k *ar = inode->i_private; 2318 void *buf; 2319 int ret; 2320 2321 mutex_lock(&ar->conf_mutex); 2322 2323 if (ar->state != ATH10K_STATE_ON) { 2324 ret = -ENETDOWN; 2325 goto err_unlock; 2326 } 2327 2328 buf = vmalloc(ATH10K_TPC_CONFIG_BUF_SIZE); 2329 if (!buf) { 2330 ret = -ENOMEM; 2331 goto err_unlock; 2332 } 2333 2334 ret = ath10k_debug_tpc_stats_final_request(ar); 2335 if (ret) { 2336 ath10k_warn(ar, "failed to request tpc stats final: %d\n", 2337 ret); 2338 goto err_free; 2339 } 2340 2341 ath10k_tpc_stats_fill(ar, ar->debug.tpc_stats, buf); 2342 file->private_data = buf; 2343 2344 mutex_unlock(&ar->conf_mutex); 2345 return 0; 2346 2347 err_free: 2348 vfree(buf); 2349 2350 err_unlock: 2351 mutex_unlock(&ar->conf_mutex); 2352 return ret; 2353 } 2354 2355 static int ath10k_tpc_stats_final_release(struct inode *inode, 2356 struct file *file) 2357 { 2358 vfree(file->private_data); 2359 2360 return 0; 2361 } 2362 2363 static ssize_t ath10k_tpc_stats_final_read(struct file *file, 2364 char __user *user_buf, 2365 size_t count, loff_t *ppos) 2366 { 2367 const char *buf = file->private_data; 2368 unsigned int len = strlen(buf); 2369 2370 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 2371 } 2372 2373 static const struct file_operations fops_tpc_stats_final = { 2374 .open = ath10k_tpc_stats_final_open, 2375 .release = ath10k_tpc_stats_final_release, 2376 .read = ath10k_tpc_stats_final_read, 2377 .owner = THIS_MODULE, 2378 .llseek = default_llseek, 2379 }; 2380 2381 static ssize_t ath10k_write_warm_hw_reset(struct file *file, 2382 const char __user *user_buf, 2383 size_t count, loff_t *ppos) 2384 { 2385 struct ath10k *ar = file->private_data; 2386 int ret; 2387 bool val; 2388 2389 if (kstrtobool_from_user(user_buf, count, &val)) 2390 return -EFAULT; 2391 2392 if (!val) 2393 return -EINVAL; 2394 2395 mutex_lock(&ar->conf_mutex); 2396 2397 if (ar->state != ATH10K_STATE_ON) { 2398 ret = -ENETDOWN; 2399 goto exit; 2400 } 2401 2402 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->pdev_reset, 2403 WMI_RST_MODE_WARM_RESET); 2404 2405 if (ret) { 2406 ath10k_warn(ar, "failed to enable warm hw reset: %d\n", ret); 2407 goto exit; 2408 } 2409 2410 ret = count; 2411 2412 exit: 2413 mutex_unlock(&ar->conf_mutex); 2414 return ret; 2415 } 2416 2417 static const struct file_operations fops_warm_hw_reset = { 2418 .write = ath10k_write_warm_hw_reset, 2419 .open = simple_open, 2420 .owner = THIS_MODULE, 2421 .llseek = default_llseek, 2422 }; 2423 2424 static void ath10k_peer_ps_state_disable(void *data, 2425 struct ieee80211_sta *sta) 2426 { 2427 struct ath10k *ar = data; 2428 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv; 2429 2430 spin_lock_bh(&ar->data_lock); 2431 arsta->peer_ps_state = WMI_PEER_PS_STATE_DISABLED; 2432 spin_unlock_bh(&ar->data_lock); 2433 } 2434 2435 static ssize_t ath10k_write_ps_state_enable(struct file *file, 2436 const char __user *user_buf, 2437 size_t count, loff_t *ppos) 2438 { 2439 struct ath10k *ar = file->private_data; 2440 int ret; 2441 u32 param; 2442 u8 ps_state_enable; 2443 2444 if (kstrtou8_from_user(user_buf, count, 0, &ps_state_enable)) 2445 return -EINVAL; 2446 2447 if (ps_state_enable > 1) 2448 return -EINVAL; 2449 2450 mutex_lock(&ar->conf_mutex); 2451 2452 if (ar->ps_state_enable == ps_state_enable) { 2453 ret = count; 2454 goto exit; 2455 } 2456 2457 param = ar->wmi.pdev_param->peer_sta_ps_statechg_enable; 2458 ret = ath10k_wmi_pdev_set_param(ar, param, ps_state_enable); 2459 if (ret) { 2460 ath10k_warn(ar, "failed to enable ps_state_enable: %d\n", 2461 ret); 2462 goto exit; 2463 } 2464 ar->ps_state_enable = ps_state_enable; 2465 2466 if (!ar->ps_state_enable) 2467 ieee80211_iterate_stations_atomic(ar->hw, 2468 ath10k_peer_ps_state_disable, 2469 ar); 2470 2471 ret = count; 2472 2473 exit: 2474 mutex_unlock(&ar->conf_mutex); 2475 2476 return ret; 2477 } 2478 2479 static ssize_t ath10k_read_ps_state_enable(struct file *file, 2480 char __user *user_buf, 2481 size_t count, loff_t *ppos) 2482 { 2483 struct ath10k *ar = file->private_data; 2484 int len = 0; 2485 char buf[32]; 2486 2487 mutex_lock(&ar->conf_mutex); 2488 len = scnprintf(buf, sizeof(buf) - len, "%d\n", 2489 ar->ps_state_enable); 2490 mutex_unlock(&ar->conf_mutex); 2491 2492 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 2493 } 2494 2495 static const struct file_operations fops_ps_state_enable = { 2496 .read = ath10k_read_ps_state_enable, 2497 .write = ath10k_write_ps_state_enable, 2498 .open = simple_open, 2499 .owner = THIS_MODULE, 2500 .llseek = default_llseek, 2501 }; 2502 2503 static ssize_t ath10k_write_reset_htt_stats(struct file *file, 2504 const char __user *user_buf, 2505 size_t count, loff_t *ppos) 2506 { 2507 struct ath10k *ar = file->private_data; 2508 unsigned long reset; 2509 int ret; 2510 2511 ret = kstrtoul_from_user(user_buf, count, 0, &reset); 2512 if (ret) 2513 return ret; 2514 2515 if (reset == 0 || reset > 0x1ffff) 2516 return -EINVAL; 2517 2518 mutex_lock(&ar->conf_mutex); 2519 2520 ar->debug.reset_htt_stats = reset; 2521 2522 ret = ath10k_debug_htt_stats_req(ar); 2523 if (ret) 2524 goto out; 2525 2526 ar->debug.reset_htt_stats = 0; 2527 ret = count; 2528 2529 out: 2530 mutex_unlock(&ar->conf_mutex); 2531 return ret; 2532 } 2533 2534 static const struct file_operations fops_reset_htt_stats = { 2535 .write = ath10k_write_reset_htt_stats, 2536 .owner = THIS_MODULE, 2537 .open = simple_open, 2538 .llseek = default_llseek, 2539 }; 2540 2541 int ath10k_debug_create(struct ath10k *ar) 2542 { 2543 ar->debug.cal_data = vzalloc(ATH10K_DEBUG_CAL_DATA_LEN); 2544 if (!ar->debug.cal_data) 2545 return -ENOMEM; 2546 2547 INIT_LIST_HEAD(&ar->debug.fw_stats.pdevs); 2548 INIT_LIST_HEAD(&ar->debug.fw_stats.vdevs); 2549 INIT_LIST_HEAD(&ar->debug.fw_stats.peers); 2550 INIT_LIST_HEAD(&ar->debug.fw_stats.peers_extd); 2551 2552 return 0; 2553 } 2554 2555 void ath10k_debug_destroy(struct ath10k *ar) 2556 { 2557 vfree(ar->debug.cal_data); 2558 ar->debug.cal_data = NULL; 2559 2560 ath10k_debug_fw_stats_reset(ar); 2561 2562 kfree(ar->debug.tpc_stats); 2563 kfree(ar->debug.tpc_stats_final); 2564 } 2565 2566 int ath10k_debug_register(struct ath10k *ar) 2567 { 2568 ar->debug.debugfs_phy = debugfs_create_dir("ath10k", 2569 ar->hw->wiphy->debugfsdir); 2570 if (IS_ERR_OR_NULL(ar->debug.debugfs_phy)) { 2571 if (IS_ERR(ar->debug.debugfs_phy)) 2572 return PTR_ERR(ar->debug.debugfs_phy); 2573 2574 return -ENOMEM; 2575 } 2576 2577 INIT_DELAYED_WORK(&ar->debug.htt_stats_dwork, 2578 ath10k_debug_htt_stats_dwork); 2579 2580 init_completion(&ar->debug.tpc_complete); 2581 init_completion(&ar->debug.fw_stats_complete); 2582 2583 debugfs_create_file("fw_stats", 0400, ar->debug.debugfs_phy, ar, 2584 &fops_fw_stats); 2585 2586 debugfs_create_file("fw_reset_stats", 0400, ar->debug.debugfs_phy, ar, 2587 &fops_fw_reset_stats); 2588 2589 debugfs_create_file("wmi_services", 0400, ar->debug.debugfs_phy, ar, 2590 &fops_wmi_services); 2591 2592 debugfs_create_file("simulate_fw_crash", 0600, ar->debug.debugfs_phy, ar, 2593 &fops_simulate_fw_crash); 2594 2595 debugfs_create_file("reg_addr", 0600, ar->debug.debugfs_phy, ar, 2596 &fops_reg_addr); 2597 2598 debugfs_create_file("reg_value", 0600, ar->debug.debugfs_phy, ar, 2599 &fops_reg_value); 2600 2601 debugfs_create_file("mem_value", 0600, ar->debug.debugfs_phy, ar, 2602 &fops_mem_value); 2603 2604 debugfs_create_file("chip_id", 0400, ar->debug.debugfs_phy, ar, 2605 &fops_chip_id); 2606 2607 debugfs_create_file("htt_stats_mask", 0600, ar->debug.debugfs_phy, ar, 2608 &fops_htt_stats_mask); 2609 2610 debugfs_create_file("htt_max_amsdu_ampdu", 0600, ar->debug.debugfs_phy, ar, 2611 &fops_htt_max_amsdu_ampdu); 2612 2613 debugfs_create_file("fw_dbglog", 0600, ar->debug.debugfs_phy, ar, 2614 &fops_fw_dbglog); 2615 2616 if (!test_bit(ATH10K_FW_FEATURE_NON_BMI, 2617 ar->normal_mode_fw.fw_file.fw_features)) { 2618 debugfs_create_file("cal_data", 0400, ar->debug.debugfs_phy, ar, 2619 &fops_cal_data); 2620 2621 debugfs_create_file("nf_cal_period", 0600, ar->debug.debugfs_phy, ar, 2622 &fops_nf_cal_period); 2623 } 2624 2625 debugfs_create_file("ani_enable", 0600, ar->debug.debugfs_phy, ar, 2626 &fops_ani_enable); 2627 2628 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED)) { 2629 debugfs_create_file("dfs_simulate_radar", 0200, ar->debug.debugfs_phy, 2630 ar, &fops_simulate_radar); 2631 2632 debugfs_create_bool("dfs_block_radar_events", 0200, 2633 ar->debug.debugfs_phy, 2634 &ar->dfs_block_radar_events); 2635 2636 debugfs_create_file("dfs_stats", 0400, ar->debug.debugfs_phy, ar, 2637 &fops_dfs_stats); 2638 } 2639 2640 debugfs_create_file("pktlog_filter", 0644, ar->debug.debugfs_phy, ar, 2641 &fops_pktlog_filter); 2642 2643 if (test_bit(WMI_SERVICE_THERM_THROT, ar->wmi.svc_map)) 2644 debugfs_create_file("quiet_period", 0644, ar->debug.debugfs_phy, ar, 2645 &fops_quiet_period); 2646 2647 debugfs_create_file("tpc_stats", 0400, ar->debug.debugfs_phy, ar, 2648 &fops_tpc_stats); 2649 2650 if (test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map)) 2651 debugfs_create_file("btcoex", 0644, ar->debug.debugfs_phy, ar, 2652 &fops_btcoex); 2653 2654 if (test_bit(WMI_SERVICE_PEER_STATS, ar->wmi.svc_map)) { 2655 debugfs_create_file("peer_stats", 0644, ar->debug.debugfs_phy, ar, 2656 &fops_peer_stats); 2657 2658 debugfs_create_file("enable_extd_tx_stats", 0644, 2659 ar->debug.debugfs_phy, ar, 2660 &fops_enable_extd_tx_stats); 2661 } 2662 2663 debugfs_create_file("fw_checksums", 0400, ar->debug.debugfs_phy, ar, 2664 &fops_fw_checksums); 2665 2666 if (IS_ENABLED(CONFIG_MAC80211_DEBUGFS)) 2667 debugfs_create_file("sta_tid_stats_mask", 0600, 2668 ar->debug.debugfs_phy, 2669 ar, &fops_sta_tid_stats_mask); 2670 2671 if (test_bit(WMI_SERVICE_TPC_STATS_FINAL, ar->wmi.svc_map)) 2672 debugfs_create_file("tpc_stats_final", 0400, 2673 ar->debug.debugfs_phy, ar, 2674 &fops_tpc_stats_final); 2675 2676 if (test_bit(WMI_SERVICE_RESET_CHIP, ar->wmi.svc_map)) 2677 debugfs_create_file("warm_hw_reset", 0600, 2678 ar->debug.debugfs_phy, ar, 2679 &fops_warm_hw_reset); 2680 2681 debugfs_create_file("ps_state_enable", 0600, ar->debug.debugfs_phy, ar, 2682 &fops_ps_state_enable); 2683 2684 debugfs_create_file("reset_htt_stats", 0200, ar->debug.debugfs_phy, ar, 2685 &fops_reset_htt_stats); 2686 2687 return 0; 2688 } 2689 2690 void ath10k_debug_unregister(struct ath10k *ar) 2691 { 2692 cancel_delayed_work_sync(&ar->debug.htt_stats_dwork); 2693 } 2694 2695 #endif /* CONFIG_ATH10K_DEBUGFS */ 2696 2697 #ifdef CONFIG_ATH10K_DEBUG 2698 void __ath10k_dbg(struct ath10k *ar, enum ath10k_debug_mask mask, 2699 const char *fmt, ...) 2700 { 2701 struct va_format vaf; 2702 va_list args; 2703 2704 va_start(args, fmt); 2705 2706 vaf.fmt = fmt; 2707 vaf.va = &args; 2708 2709 if (ath10k_debug_mask & mask) 2710 #if defined(__linux__) 2711 dev_printk(KERN_DEBUG, ar->dev, "%pV", &vaf); 2712 #elif defined(__FreeBSD__) 2713 { 2714 char *str; 2715 vasprintf(&str, M_KMALLOC, fmt, args); 2716 dev_printk(KERN_DEBUG, ar->dev, "%s", str); 2717 free(str, M_KMALLOC); 2718 } 2719 #endif 2720 2721 trace_ath10k_log_dbg(ar, mask, &vaf); 2722 2723 va_end(args); 2724 } 2725 EXPORT_SYMBOL(__ath10k_dbg); 2726 2727 void ath10k_dbg_dump(struct ath10k *ar, 2728 enum ath10k_debug_mask mask, 2729 const char *msg, const char *prefix, 2730 const void *buf, size_t len) 2731 { 2732 #if defined(__linux__) 2733 char linebuf[256]; 2734 size_t linebuflen; 2735 const void *ptr; 2736 #elif defined(__FreeBSD__) 2737 struct sbuf *sb; 2738 int rc; 2739 #endif 2740 2741 if (ath10k_debug_mask & mask) { 2742 if (msg) 2743 __ath10k_dbg(ar, mask, "%s\n", msg); 2744 2745 #if defined(__linux__) 2746 for (ptr = buf; (ptr - buf) < len; ptr += 16) { 2747 linebuflen = 0; 2748 linebuflen += scnprintf(linebuf + linebuflen, 2749 sizeof(linebuf) - linebuflen, 2750 "%s%08x: ", 2751 (prefix ? prefix : ""), 2752 (unsigned int)(ptr - buf)); 2753 hex_dump_to_buffer(ptr, len - (ptr - buf), 16, 1, 2754 linebuf + linebuflen, 2755 sizeof(linebuf) - linebuflen, true); 2756 dev_printk(KERN_DEBUG, ar->dev, "%s\n", linebuf); 2757 } 2758 #elif defined(__FreeBSD__) 2759 sb = sbuf_new_auto(); 2760 if (sb == NULL) 2761 goto trace; 2762 2763 sbuf_hexdump(sb, buf, len, prefix, 0); 2764 sbuf_trim(sb); 2765 rc = sbuf_finish(sb); 2766 if (rc == 0) 2767 dev_printk(KERN_DEBUG, ar->dev, "%s\n", sbuf_data(sb)); 2768 sbuf_delete(sb); 2769 trace: ; 2770 #endif 2771 } 2772 2773 /* tracing code doesn't like null strings :/ */ 2774 trace_ath10k_log_dbg_dump(ar, msg ? msg : "", prefix ? prefix : "", 2775 buf, len); 2776 } 2777 EXPORT_SYMBOL(ath10k_dbg_dump); 2778 2779 #endif /* CONFIG_ATH10K_DEBUG */ 2780