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