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