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