1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 /* 3 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. 4 */ 5 6 #include <linux/vmalloc.h> 7 #include "core.h" 8 #include "debug.h" 9 #include "wmi.h" 10 #include "hal_rx.h" 11 #include "dp_tx.h" 12 #include "debug_htt_stats.h" 13 #include "peer.h" 14 15 static const char *htt_bp_umac_ring[HTT_SW_UMAC_RING_IDX_MAX] = { 16 "REO2SW1_RING", 17 "REO2SW2_RING", 18 "REO2SW3_RING", 19 "REO2SW4_RING", 20 "WBM2REO_LINK_RING", 21 "REO2TCL_RING", 22 "REO2FW_RING", 23 "RELEASE_RING", 24 "PPE_RELEASE_RING", 25 "TCL2TQM_RING", 26 "TQM_RELEASE_RING", 27 "REO_RELEASE_RING", 28 "WBM2SW0_RELEASE_RING", 29 "WBM2SW1_RELEASE_RING", 30 "WBM2SW2_RELEASE_RING", 31 "WBM2SW3_RELEASE_RING", 32 "REO_CMD_RING", 33 "REO_STATUS_RING", 34 }; 35 36 static const char *htt_bp_lmac_ring[HTT_SW_LMAC_RING_IDX_MAX] = { 37 "FW2RXDMA_BUF_RING", 38 "FW2RXDMA_STATUS_RING", 39 "FW2RXDMA_LINK_RING", 40 "SW2RXDMA_BUF_RING", 41 "WBM2RXDMA_LINK_RING", 42 "RXDMA2FW_RING", 43 "RXDMA2SW_RING", 44 "RXDMA2RELEASE_RING", 45 "RXDMA2REO_RING", 46 "MONITOR_STATUS_RING", 47 "MONITOR_BUF_RING", 48 "MONITOR_DESC_RING", 49 "MONITOR_DEST_RING", 50 }; 51 52 void ath11k_info(struct ath11k_base *ab, const char *fmt, ...) 53 { 54 struct va_format vaf = { 55 .fmt = fmt, 56 }; 57 va_list args; 58 59 va_start(args, fmt); 60 vaf.va = &args; 61 dev_info(ab->dev, "%pV", &vaf); 62 /* TODO: Trace the log */ 63 va_end(args); 64 } 65 EXPORT_SYMBOL(ath11k_info); 66 67 void ath11k_err(struct ath11k_base *ab, const char *fmt, ...) 68 { 69 struct va_format vaf = { 70 .fmt = fmt, 71 }; 72 va_list args; 73 74 va_start(args, fmt); 75 vaf.va = &args; 76 dev_err(ab->dev, "%pV", &vaf); 77 /* TODO: Trace the log */ 78 va_end(args); 79 } 80 EXPORT_SYMBOL(ath11k_err); 81 82 void ath11k_warn(struct ath11k_base *ab, const char *fmt, ...) 83 { 84 struct va_format vaf = { 85 .fmt = fmt, 86 }; 87 va_list args; 88 89 va_start(args, fmt); 90 vaf.va = &args; 91 dev_warn_ratelimited(ab->dev, "%pV", &vaf); 92 /* TODO: Trace the log */ 93 va_end(args); 94 } 95 EXPORT_SYMBOL(ath11k_warn); 96 97 #ifdef CONFIG_ATH11K_DEBUG 98 void __ath11k_dbg(struct ath11k_base *ab, enum ath11k_debug_mask mask, 99 const char *fmt, ...) 100 { 101 struct va_format vaf; 102 va_list args; 103 104 va_start(args, fmt); 105 106 vaf.fmt = fmt; 107 vaf.va = &args; 108 109 if (ath11k_debug_mask & mask) 110 dev_printk(KERN_DEBUG, ab->dev, "%pV", &vaf); 111 112 /* TODO: trace log */ 113 114 va_end(args); 115 } 116 EXPORT_SYMBOL(__ath11k_dbg); 117 118 void ath11k_dbg_dump(struct ath11k_base *ab, 119 enum ath11k_debug_mask mask, 120 const char *msg, const char *prefix, 121 const void *buf, size_t len) 122 { 123 char linebuf[256]; 124 size_t linebuflen; 125 const void *ptr; 126 127 if (ath11k_debug_mask & mask) { 128 if (msg) 129 __ath11k_dbg(ab, mask, "%s\n", msg); 130 131 for (ptr = buf; (ptr - buf) < len; ptr += 16) { 132 linebuflen = 0; 133 linebuflen += scnprintf(linebuf + linebuflen, 134 sizeof(linebuf) - linebuflen, 135 "%s%08x: ", 136 (prefix ? prefix : ""), 137 (unsigned int)(ptr - buf)); 138 hex_dump_to_buffer(ptr, len - (ptr - buf), 16, 1, 139 linebuf + linebuflen, 140 sizeof(linebuf) - linebuflen, true); 141 dev_printk(KERN_DEBUG, ab->dev, "%s\n", linebuf); 142 } 143 } 144 } 145 EXPORT_SYMBOL(ath11k_dbg_dump); 146 147 #endif 148 149 #ifdef CONFIG_ATH11K_DEBUGFS 150 static void ath11k_fw_stats_pdevs_free(struct list_head *head) 151 { 152 struct ath11k_fw_stats_pdev *i, *tmp; 153 154 list_for_each_entry_safe(i, tmp, head, list) { 155 list_del(&i->list); 156 kfree(i); 157 } 158 } 159 160 static void ath11k_fw_stats_vdevs_free(struct list_head *head) 161 { 162 struct ath11k_fw_stats_vdev *i, *tmp; 163 164 list_for_each_entry_safe(i, tmp, head, list) { 165 list_del(&i->list); 166 kfree(i); 167 } 168 } 169 170 static void ath11k_fw_stats_bcn_free(struct list_head *head) 171 { 172 struct ath11k_fw_stats_bcn *i, *tmp; 173 174 list_for_each_entry_safe(i, tmp, head, list) { 175 list_del(&i->list); 176 kfree(i); 177 } 178 } 179 180 static void ath11k_debug_fw_stats_reset(struct ath11k *ar) 181 { 182 spin_lock_bh(&ar->data_lock); 183 ar->debug.fw_stats_done = false; 184 ath11k_fw_stats_pdevs_free(&ar->debug.fw_stats.pdevs); 185 ath11k_fw_stats_vdevs_free(&ar->debug.fw_stats.vdevs); 186 spin_unlock_bh(&ar->data_lock); 187 } 188 189 void ath11k_debug_fw_stats_process(struct ath11k_base *ab, struct sk_buff *skb) 190 { 191 struct ath11k_fw_stats stats = {}; 192 struct ath11k *ar; 193 struct ath11k_pdev *pdev; 194 bool is_end; 195 static unsigned int num_vdev, num_bcn; 196 size_t total_vdevs_started = 0; 197 int i, ret; 198 199 INIT_LIST_HEAD(&stats.pdevs); 200 INIT_LIST_HEAD(&stats.vdevs); 201 INIT_LIST_HEAD(&stats.bcn); 202 203 ret = ath11k_wmi_pull_fw_stats(ab, skb, &stats); 204 if (ret) { 205 ath11k_warn(ab, "failed to pull fw stats: %d\n", ret); 206 goto free; 207 } 208 209 rcu_read_lock(); 210 ar = ath11k_mac_get_ar_by_pdev_id(ab, stats.pdev_id); 211 if (!ar) { 212 rcu_read_unlock(); 213 ath11k_warn(ab, "failed to get ar for pdev_id %d: %d\n", 214 stats.pdev_id, ret); 215 goto free; 216 } 217 218 spin_lock_bh(&ar->data_lock); 219 220 if (stats.stats_id == WMI_REQUEST_PDEV_STAT) { 221 list_splice_tail_init(&stats.pdevs, &ar->debug.fw_stats.pdevs); 222 ar->debug.fw_stats_done = true; 223 goto complete; 224 } 225 226 if (stats.stats_id == WMI_REQUEST_VDEV_STAT) { 227 if (list_empty(&stats.vdevs)) { 228 ath11k_warn(ab, "empty vdev stats"); 229 goto complete; 230 } 231 /* FW sends all the active VDEV stats irrespective of PDEV, 232 * hence limit until the count of all VDEVs started 233 */ 234 for (i = 0; i < ab->num_radios; i++) { 235 pdev = rcu_dereference(ab->pdevs_active[i]); 236 if (pdev && pdev->ar) 237 total_vdevs_started += ar->num_started_vdevs; 238 } 239 240 is_end = ((++num_vdev) == total_vdevs_started); 241 242 list_splice_tail_init(&stats.vdevs, 243 &ar->debug.fw_stats.vdevs); 244 245 if (is_end) { 246 ar->debug.fw_stats_done = true; 247 num_vdev = 0; 248 } 249 goto complete; 250 } 251 252 if (stats.stats_id == WMI_REQUEST_BCN_STAT) { 253 if (list_empty(&stats.bcn)) { 254 ath11k_warn(ab, "empty bcn stats"); 255 goto complete; 256 } 257 /* Mark end until we reached the count of all started VDEVs 258 * within the PDEV 259 */ 260 is_end = ((++num_bcn) == ar->num_started_vdevs); 261 262 list_splice_tail_init(&stats.bcn, 263 &ar->debug.fw_stats.bcn); 264 265 if (is_end) { 266 ar->debug.fw_stats_done = true; 267 num_bcn = 0; 268 } 269 } 270 complete: 271 complete(&ar->debug.fw_stats_complete); 272 rcu_read_unlock(); 273 spin_unlock_bh(&ar->data_lock); 274 275 free: 276 ath11k_fw_stats_pdevs_free(&stats.pdevs); 277 ath11k_fw_stats_vdevs_free(&stats.vdevs); 278 ath11k_fw_stats_bcn_free(&stats.bcn); 279 } 280 281 static int ath11k_debug_fw_stats_request(struct ath11k *ar, 282 struct stats_request_params *req_param) 283 { 284 struct ath11k_base *ab = ar->ab; 285 unsigned long timeout, time_left; 286 int ret; 287 288 lockdep_assert_held(&ar->conf_mutex); 289 290 /* FW stats can get split when exceeding the stats data buffer limit. 291 * In that case, since there is no end marking for the back-to-back 292 * received 'update stats' event, we keep a 3 seconds timeout in case, 293 * fw_stats_done is not marked yet 294 */ 295 timeout = jiffies + msecs_to_jiffies(3 * HZ); 296 297 ath11k_debug_fw_stats_reset(ar); 298 299 reinit_completion(&ar->debug.fw_stats_complete); 300 301 ret = ath11k_wmi_send_stats_request_cmd(ar, req_param); 302 303 if (ret) { 304 ath11k_warn(ab, "could not request fw stats (%d)\n", 305 ret); 306 return ret; 307 } 308 309 time_left = 310 wait_for_completion_timeout(&ar->debug.fw_stats_complete, 311 1 * HZ); 312 if (!time_left) 313 return -ETIMEDOUT; 314 315 for (;;) { 316 if (time_after(jiffies, timeout)) 317 break; 318 319 spin_lock_bh(&ar->data_lock); 320 if (ar->debug.fw_stats_done) { 321 spin_unlock_bh(&ar->data_lock); 322 break; 323 } 324 spin_unlock_bh(&ar->data_lock); 325 } 326 return 0; 327 } 328 329 static int ath11k_open_pdev_stats(struct inode *inode, struct file *file) 330 { 331 struct ath11k *ar = inode->i_private; 332 struct ath11k_base *ab = ar->ab; 333 struct stats_request_params req_param; 334 void *buf = NULL; 335 int ret; 336 337 mutex_lock(&ar->conf_mutex); 338 339 if (ar->state != ATH11K_STATE_ON) { 340 ret = -ENETDOWN; 341 goto err_unlock; 342 } 343 344 buf = vmalloc(ATH11K_FW_STATS_BUF_SIZE); 345 if (!buf) { 346 ret = -ENOMEM; 347 goto err_unlock; 348 } 349 350 req_param.pdev_id = ar->pdev->pdev_id; 351 req_param.vdev_id = 0; 352 req_param.stats_id = WMI_REQUEST_PDEV_STAT; 353 354 ret = ath11k_debug_fw_stats_request(ar, &req_param); 355 if (ret) { 356 ath11k_warn(ab, "failed to request fw pdev stats: %d\n", ret); 357 goto err_free; 358 } 359 360 ath11k_wmi_fw_stats_fill(ar, &ar->debug.fw_stats, req_param.stats_id, 361 buf); 362 363 file->private_data = buf; 364 365 mutex_unlock(&ar->conf_mutex); 366 return 0; 367 368 err_free: 369 vfree(buf); 370 371 err_unlock: 372 mutex_unlock(&ar->conf_mutex); 373 return ret; 374 } 375 376 static int ath11k_release_pdev_stats(struct inode *inode, struct file *file) 377 { 378 vfree(file->private_data); 379 380 return 0; 381 } 382 383 static ssize_t ath11k_read_pdev_stats(struct file *file, 384 char __user *user_buf, 385 size_t count, loff_t *ppos) 386 { 387 const char *buf = file->private_data; 388 size_t len = strlen(buf); 389 390 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 391 } 392 393 static const struct file_operations fops_pdev_stats = { 394 .open = ath11k_open_pdev_stats, 395 .release = ath11k_release_pdev_stats, 396 .read = ath11k_read_pdev_stats, 397 .owner = THIS_MODULE, 398 .llseek = default_llseek, 399 }; 400 401 static int ath11k_open_vdev_stats(struct inode *inode, struct file *file) 402 { 403 struct ath11k *ar = inode->i_private; 404 struct stats_request_params req_param; 405 void *buf = NULL; 406 int ret; 407 408 mutex_lock(&ar->conf_mutex); 409 410 if (ar->state != ATH11K_STATE_ON) { 411 ret = -ENETDOWN; 412 goto err_unlock; 413 } 414 415 buf = vmalloc(ATH11K_FW_STATS_BUF_SIZE); 416 if (!buf) { 417 ret = -ENOMEM; 418 goto err_unlock; 419 } 420 421 req_param.pdev_id = ar->pdev->pdev_id; 422 /* VDEV stats is always sent for all active VDEVs from FW */ 423 req_param.vdev_id = 0; 424 req_param.stats_id = WMI_REQUEST_VDEV_STAT; 425 426 ret = ath11k_debug_fw_stats_request(ar, &req_param); 427 if (ret) { 428 ath11k_warn(ar->ab, "failed to request fw vdev stats: %d\n", ret); 429 goto err_free; 430 } 431 432 ath11k_wmi_fw_stats_fill(ar, &ar->debug.fw_stats, req_param.stats_id, 433 buf); 434 435 file->private_data = buf; 436 437 mutex_unlock(&ar->conf_mutex); 438 return 0; 439 440 err_free: 441 vfree(buf); 442 443 err_unlock: 444 mutex_unlock(&ar->conf_mutex); 445 return ret; 446 } 447 448 static int ath11k_release_vdev_stats(struct inode *inode, struct file *file) 449 { 450 vfree(file->private_data); 451 452 return 0; 453 } 454 455 static ssize_t ath11k_read_vdev_stats(struct file *file, 456 char __user *user_buf, 457 size_t count, loff_t *ppos) 458 { 459 const char *buf = file->private_data; 460 size_t len = strlen(buf); 461 462 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 463 } 464 465 static const struct file_operations fops_vdev_stats = { 466 .open = ath11k_open_vdev_stats, 467 .release = ath11k_release_vdev_stats, 468 .read = ath11k_read_vdev_stats, 469 .owner = THIS_MODULE, 470 .llseek = default_llseek, 471 }; 472 473 static int ath11k_open_bcn_stats(struct inode *inode, struct file *file) 474 { 475 struct ath11k *ar = inode->i_private; 476 struct ath11k_vif *arvif; 477 struct stats_request_params req_param; 478 void *buf = NULL; 479 int ret; 480 481 mutex_lock(&ar->conf_mutex); 482 483 if (ar->state != ATH11K_STATE_ON) { 484 ret = -ENETDOWN; 485 goto err_unlock; 486 } 487 488 buf = vmalloc(ATH11K_FW_STATS_BUF_SIZE); 489 if (!buf) { 490 ret = -ENOMEM; 491 goto err_unlock; 492 } 493 494 req_param.stats_id = WMI_REQUEST_BCN_STAT; 495 req_param.pdev_id = ar->pdev->pdev_id; 496 497 /* loop all active VDEVs for bcn stats */ 498 list_for_each_entry(arvif, &ar->arvifs, list) { 499 if (!arvif->is_up) 500 continue; 501 502 req_param.vdev_id = arvif->vdev_id; 503 ret = ath11k_debug_fw_stats_request(ar, &req_param); 504 if (ret) { 505 ath11k_warn(ar->ab, "failed to request fw bcn stats: %d\n", ret); 506 goto err_free; 507 } 508 } 509 510 ath11k_wmi_fw_stats_fill(ar, &ar->debug.fw_stats, req_param.stats_id, 511 buf); 512 513 /* since beacon stats request is looped for all active VDEVs, saved fw 514 * stats is not freed for each request until done for all active VDEVs 515 */ 516 spin_lock_bh(&ar->data_lock); 517 ath11k_fw_stats_bcn_free(&ar->debug.fw_stats.bcn); 518 spin_unlock_bh(&ar->data_lock); 519 520 file->private_data = buf; 521 522 mutex_unlock(&ar->conf_mutex); 523 return 0; 524 525 err_free: 526 vfree(buf); 527 528 err_unlock: 529 mutex_unlock(&ar->conf_mutex); 530 return ret; 531 } 532 533 static int ath11k_release_bcn_stats(struct inode *inode, struct file *file) 534 { 535 vfree(file->private_data); 536 537 return 0; 538 } 539 540 static ssize_t ath11k_read_bcn_stats(struct file *file, 541 char __user *user_buf, 542 size_t count, loff_t *ppos) 543 { 544 const char *buf = file->private_data; 545 size_t len = strlen(buf); 546 547 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 548 } 549 550 static const struct file_operations fops_bcn_stats = { 551 .open = ath11k_open_bcn_stats, 552 .release = ath11k_release_bcn_stats, 553 .read = ath11k_read_bcn_stats, 554 .owner = THIS_MODULE, 555 .llseek = default_llseek, 556 }; 557 558 static ssize_t ath11k_read_simulate_fw_crash(struct file *file, 559 char __user *user_buf, 560 size_t count, loff_t *ppos) 561 { 562 const char buf[] = 563 "To simulate firmware crash write one of the keywords to this file:\n" 564 "`assert` - this will send WMI_FORCE_FW_HANG_CMDID to firmware to cause assert.\n" 565 "`hw-restart` - this will simply queue hw restart without fw/hw actually crashing.\n"; 566 567 return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf)); 568 } 569 570 /* Simulate firmware crash: 571 * 'soft': Call wmi command causing firmware hang. This firmware hang is 572 * recoverable by warm firmware reset. 573 * 'hard': Force firmware crash by setting any vdev parameter for not allowed 574 * vdev id. This is hard firmware crash because it is recoverable only by cold 575 * firmware reset. 576 */ 577 static ssize_t ath11k_write_simulate_fw_crash(struct file *file, 578 const char __user *user_buf, 579 size_t count, loff_t *ppos) 580 { 581 struct ath11k_base *ab = file->private_data; 582 struct ath11k_pdev *pdev; 583 struct ath11k *ar = ab->pdevs[0].ar; 584 char buf[32] = {0}; 585 ssize_t rc; 586 int i, ret, radioup = 0; 587 588 for (i = 0; i < ab->num_radios; i++) { 589 pdev = &ab->pdevs[i]; 590 ar = pdev->ar; 591 if (ar && ar->state == ATH11K_STATE_ON) { 592 radioup = 1; 593 break; 594 } 595 } 596 /* filter partial writes and invalid commands */ 597 if (*ppos != 0 || count >= sizeof(buf) || count == 0) 598 return -EINVAL; 599 600 rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); 601 if (rc < 0) 602 return rc; 603 604 /* drop the possible '\n' from the end */ 605 if (buf[*ppos - 1] == '\n') 606 buf[*ppos - 1] = '\0'; 607 608 if (radioup == 0) { 609 ret = -ENETDOWN; 610 goto exit; 611 } 612 613 if (!strcmp(buf, "assert")) { 614 ath11k_info(ab, "simulating firmware assert crash\n"); 615 ret = ath11k_wmi_force_fw_hang_cmd(ar, 616 ATH11K_WMI_FW_HANG_ASSERT_TYPE, 617 ATH11K_WMI_FW_HANG_DELAY); 618 } else { 619 ret = -EINVAL; 620 goto exit; 621 } 622 623 if (ret) { 624 ath11k_warn(ab, "failed to simulate firmware crash: %d\n", ret); 625 goto exit; 626 } 627 628 ret = count; 629 630 exit: 631 return ret; 632 } 633 634 static const struct file_operations fops_simulate_fw_crash = { 635 .read = ath11k_read_simulate_fw_crash, 636 .write = ath11k_write_simulate_fw_crash, 637 .open = simple_open, 638 .owner = THIS_MODULE, 639 .llseek = default_llseek, 640 }; 641 642 static ssize_t ath11k_write_enable_extd_tx_stats(struct file *file, 643 const char __user *ubuf, 644 size_t count, loff_t *ppos) 645 { 646 struct ath11k *ar = file->private_data; 647 u32 filter; 648 int ret; 649 650 if (kstrtouint_from_user(ubuf, count, 0, &filter)) 651 return -EINVAL; 652 653 mutex_lock(&ar->conf_mutex); 654 655 if (ar->state != ATH11K_STATE_ON) { 656 ret = -ENETDOWN; 657 goto out; 658 } 659 660 if (filter == ar->debug.extd_tx_stats) { 661 ret = count; 662 goto out; 663 } 664 665 ar->debug.extd_tx_stats = filter; 666 ret = count; 667 668 out: 669 mutex_unlock(&ar->conf_mutex); 670 return ret; 671 } 672 673 static ssize_t ath11k_read_enable_extd_tx_stats(struct file *file, 674 char __user *ubuf, 675 size_t count, loff_t *ppos) 676 677 { 678 char buf[32] = {0}; 679 struct ath11k *ar = file->private_data; 680 int len = 0; 681 682 mutex_lock(&ar->conf_mutex); 683 len = scnprintf(buf, sizeof(buf) - len, "%08x\n", 684 ar->debug.extd_tx_stats); 685 mutex_unlock(&ar->conf_mutex); 686 687 return simple_read_from_buffer(ubuf, count, ppos, buf, len); 688 } 689 690 static const struct file_operations fops_extd_tx_stats = { 691 .read = ath11k_read_enable_extd_tx_stats, 692 .write = ath11k_write_enable_extd_tx_stats, 693 .open = simple_open 694 }; 695 696 static ssize_t ath11k_write_extd_rx_stats(struct file *file, 697 const char __user *ubuf, 698 size_t count, loff_t *ppos) 699 { 700 struct ath11k *ar = file->private_data; 701 struct ath11k_base *ab = ar->ab; 702 struct htt_rx_ring_tlv_filter tlv_filter = {0}; 703 u32 enable, rx_filter = 0, ring_id; 704 int i; 705 int ret; 706 707 if (kstrtouint_from_user(ubuf, count, 0, &enable)) 708 return -EINVAL; 709 710 mutex_lock(&ar->conf_mutex); 711 712 if (ar->state != ATH11K_STATE_ON) { 713 ret = -ENETDOWN; 714 goto exit; 715 } 716 717 if (enable > 1) { 718 ret = -EINVAL; 719 goto exit; 720 } 721 722 if (enable == ar->debug.extd_rx_stats) { 723 ret = count; 724 goto exit; 725 } 726 727 if (enable) { 728 rx_filter = HTT_RX_FILTER_TLV_FLAGS_MPDU_START; 729 rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_START; 730 rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END; 731 rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS; 732 rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT; 733 rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE; 734 735 tlv_filter.rx_filter = rx_filter; 736 tlv_filter.pkt_filter_flags0 = HTT_RX_FP_MGMT_FILTER_FLAGS0; 737 tlv_filter.pkt_filter_flags1 = HTT_RX_FP_MGMT_FILTER_FLAGS1; 738 tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_FILTER_FLASG2; 739 tlv_filter.pkt_filter_flags3 = HTT_RX_FP_CTRL_FILTER_FLASG3 | 740 HTT_RX_FP_DATA_FILTER_FLASG3; 741 } else { 742 tlv_filter = ath11k_mac_mon_status_filter_default; 743 } 744 745 ar->debug.rx_filter = tlv_filter.rx_filter; 746 747 for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) { 748 ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id; 749 ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, ar->dp.mac_id, 750 HAL_RXDMA_MONITOR_STATUS, 751 DP_RX_BUFFER_SIZE, &tlv_filter); 752 753 if (ret) { 754 ath11k_warn(ar->ab, "failed to set rx filter for monitor status ring\n"); 755 goto exit; 756 } 757 } 758 759 ar->debug.extd_rx_stats = enable; 760 ret = count; 761 exit: 762 mutex_unlock(&ar->conf_mutex); 763 return ret; 764 } 765 766 static ssize_t ath11k_read_extd_rx_stats(struct file *file, 767 char __user *ubuf, 768 size_t count, loff_t *ppos) 769 { 770 struct ath11k *ar = file->private_data; 771 char buf[32]; 772 int len = 0; 773 774 mutex_lock(&ar->conf_mutex); 775 len = scnprintf(buf, sizeof(buf) - len, "%d\n", 776 ar->debug.extd_rx_stats); 777 mutex_unlock(&ar->conf_mutex); 778 779 return simple_read_from_buffer(ubuf, count, ppos, buf, len); 780 } 781 782 static const struct file_operations fops_extd_rx_stats = { 783 .read = ath11k_read_extd_rx_stats, 784 .write = ath11k_write_extd_rx_stats, 785 .open = simple_open, 786 }; 787 788 static int ath11k_fill_bp_stats(struct ath11k_base *ab, 789 struct ath11k_bp_stats *bp_stats, 790 char *buf, int len, int size) 791 { 792 lockdep_assert_held(&ab->base_lock); 793 794 len += scnprintf(buf + len, size - len, "count: %u\n", 795 bp_stats->count); 796 len += scnprintf(buf + len, size - len, "hp: %u\n", 797 bp_stats->hp); 798 len += scnprintf(buf + len, size - len, "tp: %u\n", 799 bp_stats->tp); 800 len += scnprintf(buf + len, size - len, "seen before: %ums\n\n", 801 jiffies_to_msecs(jiffies - bp_stats->jiffies)); 802 return len; 803 } 804 805 static ssize_t ath11k_debug_dump_soc_ring_bp_stats(struct ath11k_base *ab, 806 char *buf, int size) 807 { 808 struct ath11k_bp_stats *bp_stats; 809 bool stats_rxd = false; 810 u8 i, pdev_idx; 811 int len = 0; 812 813 len += scnprintf(buf + len, size - len, "\nBackpressure Stats\n"); 814 len += scnprintf(buf + len, size - len, "==================\n"); 815 816 spin_lock_bh(&ab->base_lock); 817 for (i = 0; i < HTT_SW_UMAC_RING_IDX_MAX; i++) { 818 bp_stats = &ab->soc_stats.bp_stats.umac_ring_bp_stats[i]; 819 820 if (!bp_stats->count) 821 continue; 822 823 len += scnprintf(buf + len, size - len, "Ring: %s\n", 824 htt_bp_umac_ring[i]); 825 len = ath11k_fill_bp_stats(ab, bp_stats, buf, len, size); 826 stats_rxd = true; 827 } 828 829 for (i = 0; i < HTT_SW_LMAC_RING_IDX_MAX; i++) { 830 for (pdev_idx = 0; pdev_idx < MAX_RADIOS; pdev_idx++) { 831 bp_stats = 832 &ab->soc_stats.bp_stats.lmac_ring_bp_stats[i][pdev_idx]; 833 834 if (!bp_stats->count) 835 continue; 836 837 len += scnprintf(buf + len, size - len, "Ring: %s\n", 838 htt_bp_lmac_ring[i]); 839 len += scnprintf(buf + len, size - len, "pdev: %d\n", 840 pdev_idx); 841 len = ath11k_fill_bp_stats(ab, bp_stats, buf, len, size); 842 stats_rxd = true; 843 } 844 } 845 spin_unlock_bh(&ab->base_lock); 846 847 if (!stats_rxd) 848 len += scnprintf(buf + len, size - len, 849 "No Ring Backpressure stats received\n\n"); 850 851 return len; 852 } 853 854 static ssize_t ath11k_debug_dump_soc_dp_stats(struct file *file, 855 char __user *user_buf, 856 size_t count, loff_t *ppos) 857 { 858 struct ath11k_base *ab = file->private_data; 859 struct ath11k_soc_dp_stats *soc_stats = &ab->soc_stats; 860 int len = 0, i, retval; 861 const int size = 4096; 862 static const char *rxdma_err[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX] = { 863 "Overflow", "MPDU len", "FCS", "Decrypt", "TKIP MIC", 864 "Unencrypt", "MSDU len", "MSDU limit", "WiFi parse", 865 "AMSDU parse", "SA timeout", "DA timeout", 866 "Flow timeout", "Flush req"}; 867 static const char *reo_err[HAL_REO_DEST_RING_ERROR_CODE_MAX] = { 868 "Desc addr zero", "Desc inval", "AMPDU in non BA", 869 "Non BA dup", "BA dup", "Frame 2k jump", "BAR 2k jump", 870 "Frame OOR", "BAR OOR", "No BA session", 871 "Frame SN equal SSN", "PN check fail", "2k err", 872 "PN err", "Desc blocked"}; 873 874 char *buf; 875 876 buf = kzalloc(size, GFP_KERNEL); 877 if (!buf) 878 return -ENOMEM; 879 880 len += scnprintf(buf + len, size - len, "SOC RX STATS:\n\n"); 881 len += scnprintf(buf + len, size - len, "err ring pkts: %u\n", 882 soc_stats->err_ring_pkts); 883 len += scnprintf(buf + len, size - len, "Invalid RBM: %u\n\n", 884 soc_stats->invalid_rbm); 885 len += scnprintf(buf + len, size - len, "RXDMA errors:\n"); 886 for (i = 0; i < HAL_REO_ENTR_RING_RXDMA_ECODE_MAX; i++) 887 len += scnprintf(buf + len, size - len, "%s: %u\n", 888 rxdma_err[i], soc_stats->rxdma_error[i]); 889 890 len += scnprintf(buf + len, size - len, "\nREO errors:\n"); 891 for (i = 0; i < HAL_REO_DEST_RING_ERROR_CODE_MAX; i++) 892 len += scnprintf(buf + len, size - len, "%s: %u\n", 893 reo_err[i], soc_stats->reo_error[i]); 894 895 len += scnprintf(buf + len, size - len, "\nHAL REO errors:\n"); 896 len += scnprintf(buf + len, size - len, 897 "ring0: %u\nring1: %u\nring2: %u\nring3: %u\n", 898 soc_stats->hal_reo_error[0], 899 soc_stats->hal_reo_error[1], 900 soc_stats->hal_reo_error[2], 901 soc_stats->hal_reo_error[3]); 902 903 len += scnprintf(buf + len, size - len, "\nSOC TX STATS:\n"); 904 len += scnprintf(buf + len, size - len, "\nTCL Ring Full Failures:\n"); 905 906 for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) 907 len += scnprintf(buf + len, size - len, "ring%d: %u\n", 908 i, soc_stats->tx_err.desc_na[i]); 909 910 len += scnprintf(buf + len, size - len, 911 "\nMisc Transmit Failures: %d\n", 912 atomic_read(&soc_stats->tx_err.misc_fail)); 913 914 len += ath11k_debug_dump_soc_ring_bp_stats(ab, buf + len, size - len); 915 916 if (len > size) 917 len = size; 918 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 919 kfree(buf); 920 921 return retval; 922 } 923 924 static const struct file_operations fops_soc_dp_stats = { 925 .read = ath11k_debug_dump_soc_dp_stats, 926 .open = simple_open, 927 .owner = THIS_MODULE, 928 .llseek = default_llseek, 929 }; 930 931 int ath11k_debug_pdev_create(struct ath11k_base *ab) 932 { 933 if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)) 934 return 0; 935 936 ab->debugfs_soc = debugfs_create_dir(ab->hw_params.name, ab->debugfs_ath11k); 937 938 if (IS_ERR_OR_NULL(ab->debugfs_soc)) { 939 if (IS_ERR(ab->debugfs_soc)) 940 return PTR_ERR(ab->debugfs_soc); 941 return -ENOMEM; 942 } 943 944 debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab, 945 &fops_simulate_fw_crash); 946 947 debugfs_create_file("soc_dp_stats", 0600, ab->debugfs_soc, ab, 948 &fops_soc_dp_stats); 949 950 return 0; 951 } 952 953 void ath11k_debug_pdev_destroy(struct ath11k_base *ab) 954 { 955 debugfs_remove_recursive(ab->debugfs_ath11k); 956 ab->debugfs_ath11k = NULL; 957 } 958 959 int ath11k_debug_soc_create(struct ath11k_base *ab) 960 { 961 ab->debugfs_ath11k = debugfs_create_dir("ath11k", NULL); 962 963 if (IS_ERR_OR_NULL(ab->debugfs_ath11k)) { 964 if (IS_ERR(ab->debugfs_ath11k)) 965 return PTR_ERR(ab->debugfs_ath11k); 966 return -ENOMEM; 967 } 968 969 return 0; 970 } 971 972 void ath11k_debug_soc_destroy(struct ath11k_base *ab) 973 { 974 debugfs_remove_recursive(ab->debugfs_soc); 975 ab->debugfs_soc = NULL; 976 } 977 978 void ath11k_debug_fw_stats_init(struct ath11k *ar) 979 { 980 struct dentry *fwstats_dir = debugfs_create_dir("fw_stats", 981 ar->debug.debugfs_pdev); 982 983 ar->debug.fw_stats.debugfs_fwstats = fwstats_dir; 984 985 /* all stats debugfs files created are under "fw_stats" directory 986 * created per PDEV 987 */ 988 debugfs_create_file("pdev_stats", 0600, fwstats_dir, ar, 989 &fops_pdev_stats); 990 debugfs_create_file("vdev_stats", 0600, fwstats_dir, ar, 991 &fops_vdev_stats); 992 debugfs_create_file("beacon_stats", 0600, fwstats_dir, ar, 993 &fops_bcn_stats); 994 995 INIT_LIST_HEAD(&ar->debug.fw_stats.pdevs); 996 INIT_LIST_HEAD(&ar->debug.fw_stats.vdevs); 997 INIT_LIST_HEAD(&ar->debug.fw_stats.bcn); 998 999 init_completion(&ar->debug.fw_stats_complete); 1000 } 1001 1002 static ssize_t ath11k_write_pktlog_filter(struct file *file, 1003 const char __user *ubuf, 1004 size_t count, loff_t *ppos) 1005 { 1006 struct ath11k *ar = file->private_data; 1007 struct ath11k_base *ab = ar->ab; 1008 struct htt_rx_ring_tlv_filter tlv_filter = {0}; 1009 u32 rx_filter = 0, ring_id, filter, mode; 1010 u8 buf[128] = {0}; 1011 int i, ret; 1012 ssize_t rc; 1013 1014 mutex_lock(&ar->conf_mutex); 1015 if (ar->state != ATH11K_STATE_ON) { 1016 ret = -ENETDOWN; 1017 goto out; 1018 } 1019 1020 rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count); 1021 if (rc < 0) { 1022 ret = rc; 1023 goto out; 1024 } 1025 buf[rc] = '\0'; 1026 1027 ret = sscanf(buf, "0x%x %u", &filter, &mode); 1028 if (ret != 2) { 1029 ret = -EINVAL; 1030 goto out; 1031 } 1032 1033 if (filter) { 1034 ret = ath11k_wmi_pdev_pktlog_enable(ar, filter); 1035 if (ret) { 1036 ath11k_warn(ar->ab, 1037 "failed to enable pktlog filter %x: %d\n", 1038 ar->debug.pktlog_filter, ret); 1039 goto out; 1040 } 1041 } else { 1042 ret = ath11k_wmi_pdev_pktlog_disable(ar); 1043 if (ret) { 1044 ath11k_warn(ar->ab, "failed to disable pktlog: %d\n", ret); 1045 goto out; 1046 } 1047 } 1048 1049 #define HTT_RX_FILTER_TLV_LITE_MODE \ 1050 (HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \ 1051 HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \ 1052 HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS | \ 1053 HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT | \ 1054 HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE | \ 1055 HTT_RX_FILTER_TLV_FLAGS_MPDU_START) 1056 1057 if (mode == ATH11K_PKTLOG_MODE_FULL) { 1058 rx_filter = HTT_RX_FILTER_TLV_LITE_MODE | 1059 HTT_RX_FILTER_TLV_FLAGS_MSDU_START | 1060 HTT_RX_FILTER_TLV_FLAGS_MSDU_END | 1061 HTT_RX_FILTER_TLV_FLAGS_MPDU_END | 1062 HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER | 1063 HTT_RX_FILTER_TLV_FLAGS_ATTENTION; 1064 } else if (mode == ATH11K_PKTLOG_MODE_LITE) { 1065 ret = ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar, 1066 HTT_PPDU_STATS_TAG_PKTLOG); 1067 if (ret) { 1068 ath11k_err(ar->ab, "failed to enable pktlog lite: %d\n", ret); 1069 goto out; 1070 } 1071 1072 rx_filter = HTT_RX_FILTER_TLV_LITE_MODE; 1073 } else { 1074 ret = ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar, 1075 HTT_PPDU_STATS_TAG_DEFAULT); 1076 if (ret) { 1077 ath11k_err(ar->ab, "failed to send htt ppdu stats req: %d\n", 1078 ret); 1079 goto out; 1080 } 1081 } 1082 1083 tlv_filter.rx_filter = rx_filter; 1084 if (rx_filter) { 1085 tlv_filter.pkt_filter_flags0 = HTT_RX_FP_MGMT_FILTER_FLAGS0; 1086 tlv_filter.pkt_filter_flags1 = HTT_RX_FP_MGMT_FILTER_FLAGS1; 1087 tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_FILTER_FLASG2; 1088 tlv_filter.pkt_filter_flags3 = HTT_RX_FP_CTRL_FILTER_FLASG3 | 1089 HTT_RX_FP_DATA_FILTER_FLASG3; 1090 } 1091 1092 for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) { 1093 ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id; 1094 ret = ath11k_dp_tx_htt_rx_filter_setup(ab, ring_id, 1095 ar->dp.mac_id + i, 1096 HAL_RXDMA_MONITOR_STATUS, 1097 DP_RX_BUFFER_SIZE, &tlv_filter); 1098 1099 if (ret) { 1100 ath11k_warn(ab, "failed to set rx filter for moniter status ring\n"); 1101 goto out; 1102 } 1103 } 1104 1105 ath11k_dbg(ab, ATH11K_DBG_WMI, "pktlog filter %d mode %s\n", 1106 filter, ((mode == ATH11K_PKTLOG_MODE_FULL) ? "full" : "lite")); 1107 1108 ar->debug.pktlog_filter = filter; 1109 ar->debug.pktlog_mode = mode; 1110 ret = count; 1111 1112 out: 1113 mutex_unlock(&ar->conf_mutex); 1114 return ret; 1115 } 1116 1117 static ssize_t ath11k_read_pktlog_filter(struct file *file, 1118 char __user *ubuf, 1119 size_t count, loff_t *ppos) 1120 1121 { 1122 char buf[32] = {0}; 1123 struct ath11k *ar = file->private_data; 1124 int len = 0; 1125 1126 mutex_lock(&ar->conf_mutex); 1127 len = scnprintf(buf, sizeof(buf) - len, "%08x %08x\n", 1128 ar->debug.pktlog_filter, 1129 ar->debug.pktlog_mode); 1130 mutex_unlock(&ar->conf_mutex); 1131 1132 return simple_read_from_buffer(ubuf, count, ppos, buf, len); 1133 } 1134 1135 static const struct file_operations fops_pktlog_filter = { 1136 .read = ath11k_read_pktlog_filter, 1137 .write = ath11k_write_pktlog_filter, 1138 .open = simple_open 1139 }; 1140 1141 static ssize_t ath11k_write_simulate_radar(struct file *file, 1142 const char __user *user_buf, 1143 size_t count, loff_t *ppos) 1144 { 1145 struct ath11k *ar = file->private_data; 1146 int ret; 1147 1148 ret = ath11k_wmi_simulate_radar(ar); 1149 if (ret) 1150 return ret; 1151 1152 return count; 1153 } 1154 1155 static const struct file_operations fops_simulate_radar = { 1156 .write = ath11k_write_simulate_radar, 1157 .open = simple_open 1158 }; 1159 1160 int ath11k_debug_register(struct ath11k *ar) 1161 { 1162 struct ath11k_base *ab = ar->ab; 1163 char pdev_name[5]; 1164 char buf[100] = {0}; 1165 1166 snprintf(pdev_name, sizeof(pdev_name), "%s%d", "mac", ar->pdev_idx); 1167 1168 ar->debug.debugfs_pdev = debugfs_create_dir(pdev_name, ab->debugfs_soc); 1169 1170 if (IS_ERR_OR_NULL(ar->debug.debugfs_pdev)) { 1171 if (IS_ERR(ar->debug.debugfs_pdev)) 1172 return PTR_ERR(ar->debug.debugfs_pdev); 1173 1174 return -ENOMEM; 1175 } 1176 1177 /* Create a symlink under ieee80211/phy* */ 1178 snprintf(buf, 100, "../../ath11k/%pd2", ar->debug.debugfs_pdev); 1179 debugfs_create_symlink("ath11k", ar->hw->wiphy->debugfsdir, buf); 1180 1181 ath11k_debug_htt_stats_init(ar); 1182 1183 ath11k_debug_fw_stats_init(ar); 1184 1185 debugfs_create_file("ext_tx_stats", 0644, 1186 ar->debug.debugfs_pdev, ar, 1187 &fops_extd_tx_stats); 1188 debugfs_create_file("ext_rx_stats", 0644, 1189 ar->debug.debugfs_pdev, ar, 1190 &fops_extd_rx_stats); 1191 debugfs_create_file("pktlog_filter", 0644, 1192 ar->debug.debugfs_pdev, ar, 1193 &fops_pktlog_filter); 1194 1195 if (ar->hw->wiphy->bands[NL80211_BAND_5GHZ]) { 1196 debugfs_create_file("dfs_simulate_radar", 0200, 1197 ar->debug.debugfs_pdev, ar, 1198 &fops_simulate_radar); 1199 debugfs_create_bool("dfs_block_radar_events", 0200, 1200 ar->debug.debugfs_pdev, 1201 &ar->dfs_block_radar_events); 1202 } 1203 1204 return 0; 1205 } 1206 1207 void ath11k_debug_unregister(struct ath11k *ar) 1208 { 1209 } 1210 #endif /* CONFIG_ATH11K_DEBUGFS */ 1211