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