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 void ath11k_debugfs_add_dbring_entry(struct ath11k *ar, 56 enum wmi_direct_buffer_module id, 57 enum ath11k_dbg_dbr_event event, 58 struct hal_srng *srng) 59 { 60 struct ath11k_debug_dbr *dbr_debug; 61 struct ath11k_dbg_dbr_data *dbr_data; 62 struct ath11k_dbg_dbr_entry *entry; 63 64 if (id >= WMI_DIRECT_BUF_MAX || event >= ATH11K_DBG_DBR_EVENT_MAX) 65 return; 66 67 dbr_debug = ar->debug.dbr_debug[id]; 68 if (!dbr_debug) 69 return; 70 71 if (!dbr_debug->dbr_debug_enabled) 72 return; 73 74 dbr_data = &dbr_debug->dbr_dbg_data; 75 76 spin_lock_bh(&dbr_data->lock); 77 78 if (dbr_data->entries) { 79 entry = &dbr_data->entries[dbr_data->dbr_debug_idx]; 80 entry->hp = srng->u.src_ring.hp; 81 entry->tp = *srng->u.src_ring.tp_addr; 82 entry->timestamp = jiffies; 83 entry->event = event; 84 85 dbr_data->dbr_debug_idx++; 86 if (dbr_data->dbr_debug_idx == 87 dbr_data->num_ring_debug_entries) 88 dbr_data->dbr_debug_idx = 0; 89 } 90 91 spin_unlock_bh(&dbr_data->lock); 92 } 93 94 static void ath11k_fw_stats_pdevs_free(struct list_head *head) 95 { 96 struct ath11k_fw_stats_pdev *i, *tmp; 97 98 list_for_each_entry_safe(i, tmp, head, list) { 99 list_del(&i->list); 100 kfree(i); 101 } 102 } 103 104 static void ath11k_fw_stats_vdevs_free(struct list_head *head) 105 { 106 struct ath11k_fw_stats_vdev *i, *tmp; 107 108 list_for_each_entry_safe(i, tmp, head, list) { 109 list_del(&i->list); 110 kfree(i); 111 } 112 } 113 114 static void ath11k_fw_stats_bcn_free(struct list_head *head) 115 { 116 struct ath11k_fw_stats_bcn *i, *tmp; 117 118 list_for_each_entry_safe(i, tmp, head, list) { 119 list_del(&i->list); 120 kfree(i); 121 } 122 } 123 124 static void ath11k_debugfs_fw_stats_reset(struct ath11k *ar) 125 { 126 spin_lock_bh(&ar->data_lock); 127 ar->debug.fw_stats_done = false; 128 ath11k_fw_stats_pdevs_free(&ar->debug.fw_stats.pdevs); 129 ath11k_fw_stats_vdevs_free(&ar->debug.fw_stats.vdevs); 130 spin_unlock_bh(&ar->data_lock); 131 } 132 133 void ath11k_debugfs_fw_stats_process(struct ath11k_base *ab, struct sk_buff *skb) 134 { 135 struct ath11k_fw_stats stats = {}; 136 struct ath11k *ar; 137 struct ath11k_pdev *pdev; 138 bool is_end; 139 static unsigned int num_vdev, num_bcn; 140 size_t total_vdevs_started = 0; 141 int i, ret; 142 143 INIT_LIST_HEAD(&stats.pdevs); 144 INIT_LIST_HEAD(&stats.vdevs); 145 INIT_LIST_HEAD(&stats.bcn); 146 147 ret = ath11k_wmi_pull_fw_stats(ab, skb, &stats); 148 if (ret) { 149 ath11k_warn(ab, "failed to pull fw stats: %d\n", ret); 150 goto free; 151 } 152 153 rcu_read_lock(); 154 ar = ath11k_mac_get_ar_by_pdev_id(ab, stats.pdev_id); 155 if (!ar) { 156 rcu_read_unlock(); 157 ath11k_warn(ab, "failed to get ar for pdev_id %d: %d\n", 158 stats.pdev_id, ret); 159 goto free; 160 } 161 162 spin_lock_bh(&ar->data_lock); 163 164 if (stats.stats_id == WMI_REQUEST_PDEV_STAT) { 165 list_splice_tail_init(&stats.pdevs, &ar->debug.fw_stats.pdevs); 166 ar->debug.fw_stats_done = true; 167 goto complete; 168 } 169 170 if (stats.stats_id == WMI_REQUEST_RSSI_PER_CHAIN_STAT) { 171 ar->debug.fw_stats_done = true; 172 goto complete; 173 } 174 175 if (stats.stats_id == WMI_REQUEST_VDEV_STAT) { 176 if (list_empty(&stats.vdevs)) { 177 ath11k_warn(ab, "empty vdev stats"); 178 goto complete; 179 } 180 /* FW sends all the active VDEV stats irrespective of PDEV, 181 * hence limit until the count of all VDEVs started 182 */ 183 for (i = 0; i < ab->num_radios; i++) { 184 pdev = rcu_dereference(ab->pdevs_active[i]); 185 if (pdev && pdev->ar) 186 total_vdevs_started += ar->num_started_vdevs; 187 } 188 189 is_end = ((++num_vdev) == total_vdevs_started); 190 191 list_splice_tail_init(&stats.vdevs, 192 &ar->debug.fw_stats.vdevs); 193 194 if (is_end) { 195 ar->debug.fw_stats_done = true; 196 num_vdev = 0; 197 } 198 goto complete; 199 } 200 201 if (stats.stats_id == WMI_REQUEST_BCN_STAT) { 202 if (list_empty(&stats.bcn)) { 203 ath11k_warn(ab, "empty bcn stats"); 204 goto complete; 205 } 206 /* Mark end until we reached the count of all started VDEVs 207 * within the PDEV 208 */ 209 is_end = ((++num_bcn) == ar->num_started_vdevs); 210 211 list_splice_tail_init(&stats.bcn, 212 &ar->debug.fw_stats.bcn); 213 214 if (is_end) { 215 ar->debug.fw_stats_done = true; 216 num_bcn = 0; 217 } 218 } 219 complete: 220 complete(&ar->debug.fw_stats_complete); 221 rcu_read_unlock(); 222 spin_unlock_bh(&ar->data_lock); 223 224 free: 225 ath11k_fw_stats_pdevs_free(&stats.pdevs); 226 ath11k_fw_stats_vdevs_free(&stats.vdevs); 227 ath11k_fw_stats_bcn_free(&stats.bcn); 228 } 229 230 static int ath11k_debugfs_fw_stats_request(struct ath11k *ar, 231 struct stats_request_params *req_param) 232 { 233 struct ath11k_base *ab = ar->ab; 234 unsigned long timeout, time_left; 235 int ret; 236 237 lockdep_assert_held(&ar->conf_mutex); 238 239 /* FW stats can get split when exceeding the stats data buffer limit. 240 * In that case, since there is no end marking for the back-to-back 241 * received 'update stats' event, we keep a 3 seconds timeout in case, 242 * fw_stats_done is not marked yet 243 */ 244 timeout = jiffies + msecs_to_jiffies(3 * 1000); 245 246 ath11k_debugfs_fw_stats_reset(ar); 247 248 reinit_completion(&ar->debug.fw_stats_complete); 249 250 ret = ath11k_wmi_send_stats_request_cmd(ar, req_param); 251 252 if (ret) { 253 ath11k_warn(ab, "could not request fw stats (%d)\n", 254 ret); 255 return ret; 256 } 257 258 time_left = 259 wait_for_completion_timeout(&ar->debug.fw_stats_complete, 260 1 * HZ); 261 if (!time_left) 262 return -ETIMEDOUT; 263 264 for (;;) { 265 if (time_after(jiffies, timeout)) 266 break; 267 268 spin_lock_bh(&ar->data_lock); 269 if (ar->debug.fw_stats_done) { 270 spin_unlock_bh(&ar->data_lock); 271 break; 272 } 273 spin_unlock_bh(&ar->data_lock); 274 } 275 return 0; 276 } 277 278 int ath11k_debugfs_get_fw_stats(struct ath11k *ar, u32 pdev_id, 279 u32 vdev_id, u32 stats_id) 280 { 281 struct ath11k_base *ab = ar->ab; 282 struct stats_request_params req_param; 283 int ret; 284 285 mutex_lock(&ar->conf_mutex); 286 287 if (ar->state != ATH11K_STATE_ON) { 288 ret = -ENETDOWN; 289 goto err_unlock; 290 } 291 292 req_param.pdev_id = pdev_id; 293 req_param.vdev_id = vdev_id; 294 req_param.stats_id = stats_id; 295 296 ret = ath11k_debugfs_fw_stats_request(ar, &req_param); 297 if (ret) 298 ath11k_warn(ab, "failed to request fw stats: %d\n", ret); 299 300 ath11k_dbg(ab, ATH11K_DBG_WMI, 301 "debug get fw stat pdev id %d vdev id %d stats id 0x%x\n", 302 pdev_id, vdev_id, stats_id); 303 304 err_unlock: 305 mutex_unlock(&ar->conf_mutex); 306 307 return ret; 308 } 309 310 static int ath11k_open_pdev_stats(struct inode *inode, struct file *file) 311 { 312 struct ath11k *ar = inode->i_private; 313 struct ath11k_base *ab = ar->ab; 314 struct stats_request_params req_param; 315 void *buf = NULL; 316 int ret; 317 318 mutex_lock(&ar->conf_mutex); 319 320 if (ar->state != ATH11K_STATE_ON) { 321 ret = -ENETDOWN; 322 goto err_unlock; 323 } 324 325 buf = vmalloc(ATH11K_FW_STATS_BUF_SIZE); 326 if (!buf) { 327 ret = -ENOMEM; 328 goto err_unlock; 329 } 330 331 req_param.pdev_id = ar->pdev->pdev_id; 332 req_param.vdev_id = 0; 333 req_param.stats_id = WMI_REQUEST_PDEV_STAT; 334 335 ret = ath11k_debugfs_fw_stats_request(ar, &req_param); 336 if (ret) { 337 ath11k_warn(ab, "failed to request fw pdev stats: %d\n", ret); 338 goto err_free; 339 } 340 341 ath11k_wmi_fw_stats_fill(ar, &ar->debug.fw_stats, req_param.stats_id, 342 buf); 343 344 file->private_data = buf; 345 346 mutex_unlock(&ar->conf_mutex); 347 return 0; 348 349 err_free: 350 vfree(buf); 351 352 err_unlock: 353 mutex_unlock(&ar->conf_mutex); 354 return ret; 355 } 356 357 static int ath11k_release_pdev_stats(struct inode *inode, struct file *file) 358 { 359 vfree(file->private_data); 360 361 return 0; 362 } 363 364 static ssize_t ath11k_read_pdev_stats(struct file *file, 365 char __user *user_buf, 366 size_t count, loff_t *ppos) 367 { 368 const char *buf = file->private_data; 369 size_t len = strlen(buf); 370 371 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 372 } 373 374 static const struct file_operations fops_pdev_stats = { 375 .open = ath11k_open_pdev_stats, 376 .release = ath11k_release_pdev_stats, 377 .read = ath11k_read_pdev_stats, 378 .owner = THIS_MODULE, 379 .llseek = default_llseek, 380 }; 381 382 static int ath11k_open_vdev_stats(struct inode *inode, struct file *file) 383 { 384 struct ath11k *ar = inode->i_private; 385 struct stats_request_params req_param; 386 void *buf = NULL; 387 int ret; 388 389 mutex_lock(&ar->conf_mutex); 390 391 if (ar->state != ATH11K_STATE_ON) { 392 ret = -ENETDOWN; 393 goto err_unlock; 394 } 395 396 buf = vmalloc(ATH11K_FW_STATS_BUF_SIZE); 397 if (!buf) { 398 ret = -ENOMEM; 399 goto err_unlock; 400 } 401 402 req_param.pdev_id = ar->pdev->pdev_id; 403 /* VDEV stats is always sent for all active VDEVs from FW */ 404 req_param.vdev_id = 0; 405 req_param.stats_id = WMI_REQUEST_VDEV_STAT; 406 407 ret = ath11k_debugfs_fw_stats_request(ar, &req_param); 408 if (ret) { 409 ath11k_warn(ar->ab, "failed to request fw vdev stats: %d\n", ret); 410 goto err_free; 411 } 412 413 ath11k_wmi_fw_stats_fill(ar, &ar->debug.fw_stats, req_param.stats_id, 414 buf); 415 416 file->private_data = buf; 417 418 mutex_unlock(&ar->conf_mutex); 419 return 0; 420 421 err_free: 422 vfree(buf); 423 424 err_unlock: 425 mutex_unlock(&ar->conf_mutex); 426 return ret; 427 } 428 429 static int ath11k_release_vdev_stats(struct inode *inode, struct file *file) 430 { 431 vfree(file->private_data); 432 433 return 0; 434 } 435 436 static ssize_t ath11k_read_vdev_stats(struct file *file, 437 char __user *user_buf, 438 size_t count, loff_t *ppos) 439 { 440 const char *buf = file->private_data; 441 size_t len = strlen(buf); 442 443 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 444 } 445 446 static const struct file_operations fops_vdev_stats = { 447 .open = ath11k_open_vdev_stats, 448 .release = ath11k_release_vdev_stats, 449 .read = ath11k_read_vdev_stats, 450 .owner = THIS_MODULE, 451 .llseek = default_llseek, 452 }; 453 454 static int ath11k_open_bcn_stats(struct inode *inode, struct file *file) 455 { 456 struct ath11k *ar = inode->i_private; 457 struct ath11k_vif *arvif; 458 struct stats_request_params req_param; 459 void *buf = NULL; 460 int ret; 461 462 mutex_lock(&ar->conf_mutex); 463 464 if (ar->state != ATH11K_STATE_ON) { 465 ret = -ENETDOWN; 466 goto err_unlock; 467 } 468 469 buf = vmalloc(ATH11K_FW_STATS_BUF_SIZE); 470 if (!buf) { 471 ret = -ENOMEM; 472 goto err_unlock; 473 } 474 475 req_param.stats_id = WMI_REQUEST_BCN_STAT; 476 req_param.pdev_id = ar->pdev->pdev_id; 477 478 /* loop all active VDEVs for bcn stats */ 479 list_for_each_entry(arvif, &ar->arvifs, list) { 480 if (!arvif->is_up) 481 continue; 482 483 req_param.vdev_id = arvif->vdev_id; 484 ret = ath11k_debugfs_fw_stats_request(ar, &req_param); 485 if (ret) { 486 ath11k_warn(ar->ab, "failed to request fw bcn stats: %d\n", ret); 487 goto err_free; 488 } 489 } 490 491 ath11k_wmi_fw_stats_fill(ar, &ar->debug.fw_stats, req_param.stats_id, 492 buf); 493 494 /* since beacon stats request is looped for all active VDEVs, saved fw 495 * stats is not freed for each request until done for all active VDEVs 496 */ 497 spin_lock_bh(&ar->data_lock); 498 ath11k_fw_stats_bcn_free(&ar->debug.fw_stats.bcn); 499 spin_unlock_bh(&ar->data_lock); 500 501 file->private_data = buf; 502 503 mutex_unlock(&ar->conf_mutex); 504 return 0; 505 506 err_free: 507 vfree(buf); 508 509 err_unlock: 510 mutex_unlock(&ar->conf_mutex); 511 return ret; 512 } 513 514 static int ath11k_release_bcn_stats(struct inode *inode, struct file *file) 515 { 516 vfree(file->private_data); 517 518 return 0; 519 } 520 521 static ssize_t ath11k_read_bcn_stats(struct file *file, 522 char __user *user_buf, 523 size_t count, loff_t *ppos) 524 { 525 const char *buf = file->private_data; 526 size_t len = strlen(buf); 527 528 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 529 } 530 531 static const struct file_operations fops_bcn_stats = { 532 .open = ath11k_open_bcn_stats, 533 .release = ath11k_release_bcn_stats, 534 .read = ath11k_read_bcn_stats, 535 .owner = THIS_MODULE, 536 .llseek = default_llseek, 537 }; 538 539 static ssize_t ath11k_read_simulate_fw_crash(struct file *file, 540 char __user *user_buf, 541 size_t count, loff_t *ppos) 542 { 543 const char buf[] = 544 "To simulate firmware crash write one of the keywords to this file:\n" 545 "`assert` - this will send WMI_FORCE_FW_HANG_CMDID to firmware to cause assert.\n" 546 "`hw-restart` - this will simply queue hw restart without fw/hw actually crashing.\n"; 547 548 return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf)); 549 } 550 551 /* Simulate firmware crash: 552 * 'soft': Call wmi command causing firmware hang. This firmware hang is 553 * recoverable by warm firmware reset. 554 * 'hard': Force firmware crash by setting any vdev parameter for not allowed 555 * vdev id. This is hard firmware crash because it is recoverable only by cold 556 * firmware reset. 557 */ 558 static ssize_t ath11k_write_simulate_fw_crash(struct file *file, 559 const char __user *user_buf, 560 size_t count, loff_t *ppos) 561 { 562 struct ath11k_base *ab = file->private_data; 563 struct ath11k_pdev *pdev; 564 struct ath11k *ar = ab->pdevs[0].ar; 565 char buf[32] = {0}; 566 ssize_t rc; 567 int i, ret, radioup = 0; 568 569 for (i = 0; i < ab->num_radios; i++) { 570 pdev = &ab->pdevs[i]; 571 ar = pdev->ar; 572 if (ar && ar->state == ATH11K_STATE_ON) { 573 radioup = 1; 574 break; 575 } 576 } 577 /* filter partial writes and invalid commands */ 578 if (*ppos != 0 || count >= sizeof(buf) || count == 0) 579 return -EINVAL; 580 581 rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); 582 if (rc < 0) 583 return rc; 584 585 /* drop the possible '\n' from the end */ 586 if (buf[*ppos - 1] == '\n') 587 buf[*ppos - 1] = '\0'; 588 589 if (radioup == 0) { 590 ret = -ENETDOWN; 591 goto exit; 592 } 593 594 if (!strcmp(buf, "assert")) { 595 ath11k_info(ab, "simulating firmware assert crash\n"); 596 ret = ath11k_wmi_force_fw_hang_cmd(ar, 597 ATH11K_WMI_FW_HANG_ASSERT_TYPE, 598 ATH11K_WMI_FW_HANG_DELAY); 599 } else { 600 ret = -EINVAL; 601 goto exit; 602 } 603 604 if (ret) { 605 ath11k_warn(ab, "failed to simulate firmware crash: %d\n", ret); 606 goto exit; 607 } 608 609 ret = count; 610 611 exit: 612 return ret; 613 } 614 615 static const struct file_operations fops_simulate_fw_crash = { 616 .read = ath11k_read_simulate_fw_crash, 617 .write = ath11k_write_simulate_fw_crash, 618 .open = simple_open, 619 .owner = THIS_MODULE, 620 .llseek = default_llseek, 621 }; 622 623 static ssize_t ath11k_write_enable_extd_tx_stats(struct file *file, 624 const char __user *ubuf, 625 size_t count, loff_t *ppos) 626 { 627 struct ath11k *ar = file->private_data; 628 u32 filter; 629 int ret; 630 631 if (kstrtouint_from_user(ubuf, count, 0, &filter)) 632 return -EINVAL; 633 634 mutex_lock(&ar->conf_mutex); 635 636 if (ar->state != ATH11K_STATE_ON) { 637 ret = -ENETDOWN; 638 goto out; 639 } 640 641 if (filter == ar->debug.extd_tx_stats) { 642 ret = count; 643 goto out; 644 } 645 646 ar->debug.extd_tx_stats = filter; 647 ret = count; 648 649 out: 650 mutex_unlock(&ar->conf_mutex); 651 return ret; 652 } 653 654 static ssize_t ath11k_read_enable_extd_tx_stats(struct file *file, 655 char __user *ubuf, 656 size_t count, loff_t *ppos) 657 658 { 659 char buf[32] = {0}; 660 struct ath11k *ar = file->private_data; 661 int len = 0; 662 663 mutex_lock(&ar->conf_mutex); 664 len = scnprintf(buf, sizeof(buf) - len, "%08x\n", 665 ar->debug.extd_tx_stats); 666 mutex_unlock(&ar->conf_mutex); 667 668 return simple_read_from_buffer(ubuf, count, ppos, buf, len); 669 } 670 671 static const struct file_operations fops_extd_tx_stats = { 672 .read = ath11k_read_enable_extd_tx_stats, 673 .write = ath11k_write_enable_extd_tx_stats, 674 .open = simple_open 675 }; 676 677 static ssize_t ath11k_write_extd_rx_stats(struct file *file, 678 const char __user *ubuf, 679 size_t count, loff_t *ppos) 680 { 681 struct ath11k *ar = file->private_data; 682 struct ath11k_base *ab = ar->ab; 683 struct htt_rx_ring_tlv_filter tlv_filter = {0}; 684 u32 enable, rx_filter = 0, ring_id; 685 int i; 686 int ret; 687 688 if (kstrtouint_from_user(ubuf, count, 0, &enable)) 689 return -EINVAL; 690 691 mutex_lock(&ar->conf_mutex); 692 693 if (ar->state != ATH11K_STATE_ON) { 694 ret = -ENETDOWN; 695 goto exit; 696 } 697 698 if (enable > 1) { 699 ret = -EINVAL; 700 goto exit; 701 } 702 703 if (enable == ar->debug.extd_rx_stats) { 704 ret = count; 705 goto exit; 706 } 707 708 if (test_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags)) { 709 ar->debug.extd_rx_stats = enable; 710 ret = count; 711 goto exit; 712 } 713 714 if (enable) { 715 rx_filter = HTT_RX_FILTER_TLV_FLAGS_MPDU_START; 716 rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_START; 717 rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END; 718 rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS; 719 rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT; 720 rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE; 721 722 tlv_filter.rx_filter = rx_filter; 723 tlv_filter.pkt_filter_flags0 = HTT_RX_FP_MGMT_FILTER_FLAGS0; 724 tlv_filter.pkt_filter_flags1 = HTT_RX_FP_MGMT_FILTER_FLAGS1; 725 tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_FILTER_FLASG2; 726 tlv_filter.pkt_filter_flags3 = HTT_RX_FP_CTRL_FILTER_FLASG3 | 727 HTT_RX_FP_DATA_FILTER_FLASG3; 728 } else { 729 tlv_filter = ath11k_mac_mon_status_filter_default; 730 } 731 732 ar->debug.rx_filter = tlv_filter.rx_filter; 733 734 for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) { 735 ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id; 736 ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, ar->dp.mac_id, 737 HAL_RXDMA_MONITOR_STATUS, 738 DP_RX_BUFFER_SIZE, &tlv_filter); 739 740 if (ret) { 741 ath11k_warn(ar->ab, "failed to set rx filter for monitor status ring\n"); 742 goto exit; 743 } 744 } 745 746 ar->debug.extd_rx_stats = enable; 747 ret = count; 748 exit: 749 mutex_unlock(&ar->conf_mutex); 750 return ret; 751 } 752 753 static ssize_t ath11k_read_extd_rx_stats(struct file *file, 754 char __user *ubuf, 755 size_t count, loff_t *ppos) 756 { 757 struct ath11k *ar = file->private_data; 758 char buf[32]; 759 int len = 0; 760 761 mutex_lock(&ar->conf_mutex); 762 len = scnprintf(buf, sizeof(buf) - len, "%d\n", 763 ar->debug.extd_rx_stats); 764 mutex_unlock(&ar->conf_mutex); 765 766 return simple_read_from_buffer(ubuf, count, ppos, buf, len); 767 } 768 769 static const struct file_operations fops_extd_rx_stats = { 770 .read = ath11k_read_extd_rx_stats, 771 .write = ath11k_write_extd_rx_stats, 772 .open = simple_open, 773 }; 774 775 static int ath11k_fill_bp_stats(struct ath11k_base *ab, 776 struct ath11k_bp_stats *bp_stats, 777 char *buf, int len, int size) 778 { 779 lockdep_assert_held(&ab->base_lock); 780 781 len += scnprintf(buf + len, size - len, "count: %u\n", 782 bp_stats->count); 783 len += scnprintf(buf + len, size - len, "hp: %u\n", 784 bp_stats->hp); 785 len += scnprintf(buf + len, size - len, "tp: %u\n", 786 bp_stats->tp); 787 len += scnprintf(buf + len, size - len, "seen before: %ums\n\n", 788 jiffies_to_msecs(jiffies - bp_stats->jiffies)); 789 return len; 790 } 791 792 static ssize_t ath11k_debugfs_dump_soc_ring_bp_stats(struct ath11k_base *ab, 793 char *buf, int size) 794 { 795 struct ath11k_bp_stats *bp_stats; 796 bool stats_rxd = false; 797 u8 i, pdev_idx; 798 int len = 0; 799 800 len += scnprintf(buf + len, size - len, "\nBackpressure Stats\n"); 801 len += scnprintf(buf + len, size - len, "==================\n"); 802 803 spin_lock_bh(&ab->base_lock); 804 for (i = 0; i < HTT_SW_UMAC_RING_IDX_MAX; i++) { 805 bp_stats = &ab->soc_stats.bp_stats.umac_ring_bp_stats[i]; 806 807 if (!bp_stats->count) 808 continue; 809 810 len += scnprintf(buf + len, size - len, "Ring: %s\n", 811 htt_bp_umac_ring[i]); 812 len = ath11k_fill_bp_stats(ab, bp_stats, buf, len, size); 813 stats_rxd = true; 814 } 815 816 for (i = 0; i < HTT_SW_LMAC_RING_IDX_MAX; i++) { 817 for (pdev_idx = 0; pdev_idx < MAX_RADIOS; pdev_idx++) { 818 bp_stats = 819 &ab->soc_stats.bp_stats.lmac_ring_bp_stats[i][pdev_idx]; 820 821 if (!bp_stats->count) 822 continue; 823 824 len += scnprintf(buf + len, size - len, "Ring: %s\n", 825 htt_bp_lmac_ring[i]); 826 len += scnprintf(buf + len, size - len, "pdev: %d\n", 827 pdev_idx); 828 len = ath11k_fill_bp_stats(ab, bp_stats, buf, len, size); 829 stats_rxd = true; 830 } 831 } 832 spin_unlock_bh(&ab->base_lock); 833 834 if (!stats_rxd) 835 len += scnprintf(buf + len, size - len, 836 "No Ring Backpressure stats received\n\n"); 837 838 return len; 839 } 840 841 static ssize_t ath11k_debugfs_dump_soc_dp_stats(struct file *file, 842 char __user *user_buf, 843 size_t count, loff_t *ppos) 844 { 845 struct ath11k_base *ab = file->private_data; 846 struct ath11k_soc_dp_stats *soc_stats = &ab->soc_stats; 847 int len = 0, i, retval; 848 const int size = 4096; 849 static const char *rxdma_err[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX] = { 850 "Overflow", "MPDU len", "FCS", "Decrypt", "TKIP MIC", 851 "Unencrypt", "MSDU len", "MSDU limit", "WiFi parse", 852 "AMSDU parse", "SA timeout", "DA timeout", 853 "Flow timeout", "Flush req"}; 854 static const char *reo_err[HAL_REO_DEST_RING_ERROR_CODE_MAX] = { 855 "Desc addr zero", "Desc inval", "AMPDU in non BA", 856 "Non BA dup", "BA dup", "Frame 2k jump", "BAR 2k jump", 857 "Frame OOR", "BAR OOR", "No BA session", 858 "Frame SN equal SSN", "PN check fail", "2k err", 859 "PN err", "Desc blocked"}; 860 861 char *buf; 862 863 buf = kzalloc(size, GFP_KERNEL); 864 if (!buf) 865 return -ENOMEM; 866 867 len += scnprintf(buf + len, size - len, "SOC RX STATS:\n\n"); 868 len += scnprintf(buf + len, size - len, "err ring pkts: %u\n", 869 soc_stats->err_ring_pkts); 870 len += scnprintf(buf + len, size - len, "Invalid RBM: %u\n\n", 871 soc_stats->invalid_rbm); 872 len += scnprintf(buf + len, size - len, "RXDMA errors:\n"); 873 for (i = 0; i < HAL_REO_ENTR_RING_RXDMA_ECODE_MAX; i++) 874 len += scnprintf(buf + len, size - len, "%s: %u\n", 875 rxdma_err[i], soc_stats->rxdma_error[i]); 876 877 len += scnprintf(buf + len, size - len, "\nREO errors:\n"); 878 for (i = 0; i < HAL_REO_DEST_RING_ERROR_CODE_MAX; i++) 879 len += scnprintf(buf + len, size - len, "%s: %u\n", 880 reo_err[i], soc_stats->reo_error[i]); 881 882 len += scnprintf(buf + len, size - len, "\nHAL REO errors:\n"); 883 len += scnprintf(buf + len, size - len, 884 "ring0: %u\nring1: %u\nring2: %u\nring3: %u\n", 885 soc_stats->hal_reo_error[0], 886 soc_stats->hal_reo_error[1], 887 soc_stats->hal_reo_error[2], 888 soc_stats->hal_reo_error[3]); 889 890 len += scnprintf(buf + len, size - len, "\nSOC TX STATS:\n"); 891 len += scnprintf(buf + len, size - len, "\nTCL Ring Full Failures:\n"); 892 893 for (i = 0; i < ab->hw_params.max_tx_ring; i++) 894 len += scnprintf(buf + len, size - len, "ring%d: %u\n", 895 i, soc_stats->tx_err.desc_na[i]); 896 897 len += scnprintf(buf + len, size - len, 898 "\nMisc Transmit Failures: %d\n", 899 atomic_read(&soc_stats->tx_err.misc_fail)); 900 901 len += ath11k_debugfs_dump_soc_ring_bp_stats(ab, buf + len, size - len); 902 903 if (len > size) 904 len = size; 905 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 906 kfree(buf); 907 908 return retval; 909 } 910 911 static const struct file_operations fops_soc_dp_stats = { 912 .read = ath11k_debugfs_dump_soc_dp_stats, 913 .open = simple_open, 914 .owner = THIS_MODULE, 915 .llseek = default_llseek, 916 }; 917 918 static ssize_t ath11k_write_fw_dbglog(struct file *file, 919 const char __user *user_buf, 920 size_t count, loff_t *ppos) 921 { 922 struct ath11k *ar = file->private_data; 923 char buf[128] = {0}; 924 struct ath11k_fw_dbglog dbglog; 925 unsigned int param, mod_id_index, is_end; 926 u64 value; 927 int ret, num; 928 929 ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, 930 user_buf, count); 931 if (ret <= 0) 932 return ret; 933 934 num = sscanf(buf, "%u %llx %u %u", ¶m, &value, &mod_id_index, &is_end); 935 936 if (num < 2) 937 return -EINVAL; 938 939 mutex_lock(&ar->conf_mutex); 940 if (param == WMI_DEBUG_LOG_PARAM_MOD_ENABLE_BITMAP || 941 param == WMI_DEBUG_LOG_PARAM_WOW_MOD_ENABLE_BITMAP) { 942 if (num != 4 || mod_id_index > (MAX_MODULE_ID_BITMAP_WORDS - 1)) { 943 ret = -EINVAL; 944 goto out; 945 } 946 ar->debug.module_id_bitmap[mod_id_index] = upper_32_bits(value); 947 if (!is_end) { 948 ret = count; 949 goto out; 950 } 951 } else { 952 if (num != 2) { 953 ret = -EINVAL; 954 goto out; 955 } 956 } 957 958 dbglog.param = param; 959 dbglog.value = lower_32_bits(value); 960 ret = ath11k_wmi_fw_dbglog_cfg(ar, ar->debug.module_id_bitmap, &dbglog); 961 if (ret) { 962 ath11k_warn(ar->ab, "fw dbglog config failed from debugfs: %d\n", 963 ret); 964 goto out; 965 } 966 967 ret = count; 968 969 out: 970 mutex_unlock(&ar->conf_mutex); 971 return ret; 972 } 973 974 static const struct file_operations fops_fw_dbglog = { 975 .write = ath11k_write_fw_dbglog, 976 .open = simple_open, 977 .owner = THIS_MODULE, 978 .llseek = default_llseek, 979 }; 980 981 int ath11k_debugfs_pdev_create(struct ath11k_base *ab) 982 { 983 if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)) 984 return 0; 985 986 ab->debugfs_soc = debugfs_create_dir(ab->hw_params.name, ab->debugfs_ath11k); 987 if (IS_ERR(ab->debugfs_soc)) 988 return PTR_ERR(ab->debugfs_soc); 989 990 debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab, 991 &fops_simulate_fw_crash); 992 993 debugfs_create_file("soc_dp_stats", 0600, ab->debugfs_soc, ab, 994 &fops_soc_dp_stats); 995 996 return 0; 997 } 998 999 void ath11k_debugfs_pdev_destroy(struct ath11k_base *ab) 1000 { 1001 debugfs_remove_recursive(ab->debugfs_soc); 1002 ab->debugfs_soc = NULL; 1003 } 1004 1005 int ath11k_debugfs_soc_create(struct ath11k_base *ab) 1006 { 1007 ab->debugfs_ath11k = debugfs_create_dir("ath11k", NULL); 1008 1009 return PTR_ERR_OR_ZERO(ab->debugfs_ath11k); 1010 } 1011 1012 void ath11k_debugfs_soc_destroy(struct ath11k_base *ab) 1013 { 1014 debugfs_remove_recursive(ab->debugfs_ath11k); 1015 ab->debugfs_ath11k = NULL; 1016 } 1017 EXPORT_SYMBOL(ath11k_debugfs_soc_destroy); 1018 1019 void ath11k_debugfs_fw_stats_init(struct ath11k *ar) 1020 { 1021 struct dentry *fwstats_dir = debugfs_create_dir("fw_stats", 1022 ar->debug.debugfs_pdev); 1023 1024 ar->debug.fw_stats.debugfs_fwstats = fwstats_dir; 1025 1026 /* all stats debugfs files created are under "fw_stats" directory 1027 * created per PDEV 1028 */ 1029 debugfs_create_file("pdev_stats", 0600, fwstats_dir, ar, 1030 &fops_pdev_stats); 1031 debugfs_create_file("vdev_stats", 0600, fwstats_dir, ar, 1032 &fops_vdev_stats); 1033 debugfs_create_file("beacon_stats", 0600, fwstats_dir, ar, 1034 &fops_bcn_stats); 1035 1036 INIT_LIST_HEAD(&ar->debug.fw_stats.pdevs); 1037 INIT_LIST_HEAD(&ar->debug.fw_stats.vdevs); 1038 INIT_LIST_HEAD(&ar->debug.fw_stats.bcn); 1039 1040 init_completion(&ar->debug.fw_stats_complete); 1041 } 1042 1043 static ssize_t ath11k_write_pktlog_filter(struct file *file, 1044 const char __user *ubuf, 1045 size_t count, loff_t *ppos) 1046 { 1047 struct ath11k *ar = file->private_data; 1048 struct ath11k_base *ab = ar->ab; 1049 struct htt_rx_ring_tlv_filter tlv_filter = {0}; 1050 u32 rx_filter = 0, ring_id, filter, mode; 1051 u8 buf[128] = {0}; 1052 int i, ret, rx_buf_sz = 0; 1053 ssize_t rc; 1054 1055 mutex_lock(&ar->conf_mutex); 1056 if (ar->state != ATH11K_STATE_ON) { 1057 ret = -ENETDOWN; 1058 goto out; 1059 } 1060 1061 rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count); 1062 if (rc < 0) { 1063 ret = rc; 1064 goto out; 1065 } 1066 buf[rc] = '\0'; 1067 1068 ret = sscanf(buf, "0x%x %u", &filter, &mode); 1069 if (ret != 2) { 1070 ret = -EINVAL; 1071 goto out; 1072 } 1073 1074 if (filter) { 1075 ret = ath11k_wmi_pdev_pktlog_enable(ar, filter); 1076 if (ret) { 1077 ath11k_warn(ar->ab, 1078 "failed to enable pktlog filter %x: %d\n", 1079 ar->debug.pktlog_filter, ret); 1080 goto out; 1081 } 1082 } else { 1083 ret = ath11k_wmi_pdev_pktlog_disable(ar); 1084 if (ret) { 1085 ath11k_warn(ar->ab, "failed to disable pktlog: %d\n", ret); 1086 goto out; 1087 } 1088 } 1089 1090 /* Clear rx filter set for monitor mode and rx status */ 1091 for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) { 1092 ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id; 1093 ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, ar->dp.mac_id, 1094 HAL_RXDMA_MONITOR_STATUS, 1095 rx_buf_sz, &tlv_filter); 1096 if (ret) { 1097 ath11k_warn(ar->ab, "failed to set rx filter for monitor status ring\n"); 1098 goto out; 1099 } 1100 } 1101 #define HTT_RX_FILTER_TLV_LITE_MODE \ 1102 (HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \ 1103 HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \ 1104 HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS | \ 1105 HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT | \ 1106 HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE | \ 1107 HTT_RX_FILTER_TLV_FLAGS_MPDU_START) 1108 1109 if (mode == ATH11K_PKTLOG_MODE_FULL) { 1110 rx_filter = HTT_RX_FILTER_TLV_LITE_MODE | 1111 HTT_RX_FILTER_TLV_FLAGS_MSDU_START | 1112 HTT_RX_FILTER_TLV_FLAGS_MSDU_END | 1113 HTT_RX_FILTER_TLV_FLAGS_MPDU_END | 1114 HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER | 1115 HTT_RX_FILTER_TLV_FLAGS_ATTENTION; 1116 rx_buf_sz = DP_RX_BUFFER_SIZE; 1117 } else if (mode == ATH11K_PKTLOG_MODE_LITE) { 1118 ret = ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar, 1119 HTT_PPDU_STATS_TAG_PKTLOG); 1120 if (ret) { 1121 ath11k_err(ar->ab, "failed to enable pktlog lite: %d\n", ret); 1122 goto out; 1123 } 1124 1125 rx_filter = HTT_RX_FILTER_TLV_LITE_MODE; 1126 rx_buf_sz = DP_RX_BUFFER_SIZE_LITE; 1127 } else { 1128 rx_buf_sz = DP_RX_BUFFER_SIZE; 1129 tlv_filter = ath11k_mac_mon_status_filter_default; 1130 rx_filter = tlv_filter.rx_filter; 1131 1132 ret = ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar, 1133 HTT_PPDU_STATS_TAG_DEFAULT); 1134 if (ret) { 1135 ath11k_err(ar->ab, "failed to send htt ppdu stats req: %d\n", 1136 ret); 1137 goto out; 1138 } 1139 } 1140 1141 tlv_filter.rx_filter = rx_filter; 1142 if (rx_filter) { 1143 tlv_filter.pkt_filter_flags0 = HTT_RX_FP_MGMT_FILTER_FLAGS0; 1144 tlv_filter.pkt_filter_flags1 = HTT_RX_FP_MGMT_FILTER_FLAGS1; 1145 tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_FILTER_FLASG2; 1146 tlv_filter.pkt_filter_flags3 = HTT_RX_FP_CTRL_FILTER_FLASG3 | 1147 HTT_RX_FP_DATA_FILTER_FLASG3; 1148 } 1149 1150 for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) { 1151 ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id; 1152 ret = ath11k_dp_tx_htt_rx_filter_setup(ab, ring_id, 1153 ar->dp.mac_id + i, 1154 HAL_RXDMA_MONITOR_STATUS, 1155 rx_buf_sz, &tlv_filter); 1156 1157 if (ret) { 1158 ath11k_warn(ab, "failed to set rx filter for monitor status ring\n"); 1159 goto out; 1160 } 1161 } 1162 1163 ath11k_info(ab, "pktlog mode %s\n", 1164 ((mode == ATH11K_PKTLOG_MODE_FULL) ? "full" : "lite")); 1165 1166 ar->debug.pktlog_filter = filter; 1167 ar->debug.pktlog_mode = mode; 1168 ret = count; 1169 1170 out: 1171 mutex_unlock(&ar->conf_mutex); 1172 return ret; 1173 } 1174 1175 static ssize_t ath11k_read_pktlog_filter(struct file *file, 1176 char __user *ubuf, 1177 size_t count, loff_t *ppos) 1178 1179 { 1180 char buf[32] = {0}; 1181 struct ath11k *ar = file->private_data; 1182 int len = 0; 1183 1184 mutex_lock(&ar->conf_mutex); 1185 len = scnprintf(buf, sizeof(buf) - len, "%08x %08x\n", 1186 ar->debug.pktlog_filter, 1187 ar->debug.pktlog_mode); 1188 mutex_unlock(&ar->conf_mutex); 1189 1190 return simple_read_from_buffer(ubuf, count, ppos, buf, len); 1191 } 1192 1193 static const struct file_operations fops_pktlog_filter = { 1194 .read = ath11k_read_pktlog_filter, 1195 .write = ath11k_write_pktlog_filter, 1196 .open = simple_open 1197 }; 1198 1199 static ssize_t ath11k_write_simulate_radar(struct file *file, 1200 const char __user *user_buf, 1201 size_t count, loff_t *ppos) 1202 { 1203 struct ath11k *ar = file->private_data; 1204 int ret; 1205 1206 ret = ath11k_wmi_simulate_radar(ar); 1207 if (ret) 1208 return ret; 1209 1210 return count; 1211 } 1212 1213 static const struct file_operations fops_simulate_radar = { 1214 .write = ath11k_write_simulate_radar, 1215 .open = simple_open 1216 }; 1217 1218 static ssize_t ath11k_debug_dump_dbr_entries(struct file *file, 1219 char __user *user_buf, 1220 size_t count, loff_t *ppos) 1221 { 1222 struct ath11k_dbg_dbr_data *dbr_dbg_data = file->private_data; 1223 static const char * const event_id_to_string[] = {"empty", "Rx", "Replenish"}; 1224 int size = ATH11K_DEBUG_DBR_ENTRIES_MAX * 100; 1225 char *buf; 1226 int i, ret; 1227 int len = 0; 1228 1229 buf = kzalloc(size, GFP_KERNEL); 1230 if (!buf) 1231 return -ENOMEM; 1232 1233 len += scnprintf(buf + len, size - len, 1234 "-----------------------------------------\n"); 1235 len += scnprintf(buf + len, size - len, 1236 "| idx | hp | tp | timestamp | event |\n"); 1237 len += scnprintf(buf + len, size - len, 1238 "-----------------------------------------\n"); 1239 1240 spin_lock_bh(&dbr_dbg_data->lock); 1241 1242 for (i = 0; i < dbr_dbg_data->num_ring_debug_entries; i++) { 1243 len += scnprintf(buf + len, size - len, 1244 "|%4u|%8u|%8u|%11llu|%8s|\n", i, 1245 dbr_dbg_data->entries[i].hp, 1246 dbr_dbg_data->entries[i].tp, 1247 dbr_dbg_data->entries[i].timestamp, 1248 event_id_to_string[dbr_dbg_data->entries[i].event]); 1249 } 1250 1251 spin_unlock_bh(&dbr_dbg_data->lock); 1252 1253 ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); 1254 kfree(buf); 1255 1256 return ret; 1257 } 1258 1259 static const struct file_operations fops_debug_dump_dbr_entries = { 1260 .read = ath11k_debug_dump_dbr_entries, 1261 .open = simple_open, 1262 .owner = THIS_MODULE, 1263 .llseek = default_llseek, 1264 }; 1265 1266 static void ath11k_debugfs_dbr_dbg_destroy(struct ath11k *ar, int dbr_id) 1267 { 1268 struct ath11k_debug_dbr *dbr_debug; 1269 struct ath11k_dbg_dbr_data *dbr_dbg_data; 1270 1271 if (!ar->debug.dbr_debug[dbr_id]) 1272 return; 1273 1274 dbr_debug = ar->debug.dbr_debug[dbr_id]; 1275 dbr_dbg_data = &dbr_debug->dbr_dbg_data; 1276 1277 debugfs_remove_recursive(dbr_debug->dbr_debugfs); 1278 kfree(dbr_dbg_data->entries); 1279 kfree(dbr_debug); 1280 ar->debug.dbr_debug[dbr_id] = NULL; 1281 } 1282 1283 static int ath11k_debugfs_dbr_dbg_init(struct ath11k *ar, int dbr_id) 1284 { 1285 struct ath11k_debug_dbr *dbr_debug; 1286 struct ath11k_dbg_dbr_data *dbr_dbg_data; 1287 static const char * const dbr_id_to_str[] = {"spectral", "CFR"}; 1288 1289 if (ar->debug.dbr_debug[dbr_id]) 1290 return 0; 1291 1292 ar->debug.dbr_debug[dbr_id] = kzalloc(sizeof(*dbr_debug), 1293 GFP_KERNEL); 1294 1295 if (!ar->debug.dbr_debug[dbr_id]) 1296 return -ENOMEM; 1297 1298 dbr_debug = ar->debug.dbr_debug[dbr_id]; 1299 dbr_dbg_data = &dbr_debug->dbr_dbg_data; 1300 1301 if (dbr_debug->dbr_debugfs) 1302 return 0; 1303 1304 dbr_debug->dbr_debugfs = debugfs_create_dir(dbr_id_to_str[dbr_id], 1305 ar->debug.debugfs_pdev); 1306 if (IS_ERR_OR_NULL(dbr_debug->dbr_debugfs)) { 1307 if (IS_ERR(dbr_debug->dbr_debugfs)) 1308 return PTR_ERR(dbr_debug->dbr_debugfs); 1309 return -ENOMEM; 1310 } 1311 1312 dbr_debug->dbr_debug_enabled = true; 1313 dbr_dbg_data->num_ring_debug_entries = ATH11K_DEBUG_DBR_ENTRIES_MAX; 1314 dbr_dbg_data->dbr_debug_idx = 0; 1315 dbr_dbg_data->entries = kcalloc(ATH11K_DEBUG_DBR_ENTRIES_MAX, 1316 sizeof(struct ath11k_dbg_dbr_entry), 1317 GFP_KERNEL); 1318 if (!dbr_dbg_data->entries) 1319 return -ENOMEM; 1320 1321 spin_lock_init(&dbr_dbg_data->lock); 1322 1323 debugfs_create_file("dump_dbr_debug", 0444, dbr_debug->dbr_debugfs, 1324 dbr_dbg_data, &fops_debug_dump_dbr_entries); 1325 1326 return 0; 1327 } 1328 1329 static ssize_t ath11k_debugfs_write_enable_dbr_dbg(struct file *file, 1330 const char __user *ubuf, 1331 size_t count, loff_t *ppos) 1332 { 1333 struct ath11k *ar = file->private_data; 1334 char buf[32] = {0}; 1335 u32 dbr_id, enable; 1336 int ret; 1337 1338 mutex_lock(&ar->conf_mutex); 1339 1340 if (ar->state != ATH11K_STATE_ON) { 1341 ret = -ENETDOWN; 1342 goto out; 1343 } 1344 1345 ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count); 1346 if (ret < 0) 1347 goto out; 1348 1349 buf[ret] = '\0'; 1350 ret = sscanf(buf, "%u %u", &dbr_id, &enable); 1351 if (ret != 2 || dbr_id > 1 || enable > 1) { 1352 ret = -EINVAL; 1353 ath11k_warn(ar->ab, "usage: echo <dbr_id> <val> dbr_id:0-Spectral 1-CFR val:0-disable 1-enable\n"); 1354 goto out; 1355 } 1356 1357 if (enable) { 1358 ret = ath11k_debugfs_dbr_dbg_init(ar, dbr_id); 1359 if (ret) { 1360 ath11k_warn(ar->ab, "db ring module debugfs init failed: %d\n", 1361 ret); 1362 goto out; 1363 } 1364 } else { 1365 ath11k_debugfs_dbr_dbg_destroy(ar, dbr_id); 1366 } 1367 1368 ret = count; 1369 out: 1370 mutex_unlock(&ar->conf_mutex); 1371 return ret; 1372 } 1373 1374 static const struct file_operations fops_dbr_debug = { 1375 .write = ath11k_debugfs_write_enable_dbr_dbg, 1376 .open = simple_open, 1377 .owner = THIS_MODULE, 1378 .llseek = default_llseek, 1379 }; 1380 1381 int ath11k_debugfs_register(struct ath11k *ar) 1382 { 1383 struct ath11k_base *ab = ar->ab; 1384 char pdev_name[5]; 1385 char buf[100] = {0}; 1386 1387 snprintf(pdev_name, sizeof(pdev_name), "%s%d", "mac", ar->pdev_idx); 1388 1389 ar->debug.debugfs_pdev = debugfs_create_dir(pdev_name, ab->debugfs_soc); 1390 if (IS_ERR(ar->debug.debugfs_pdev)) 1391 return PTR_ERR(ar->debug.debugfs_pdev); 1392 1393 /* Create a symlink under ieee80211/phy* */ 1394 snprintf(buf, 100, "../../ath11k/%pd2", ar->debug.debugfs_pdev); 1395 debugfs_create_symlink("ath11k", ar->hw->wiphy->debugfsdir, buf); 1396 1397 ath11k_debugfs_htt_stats_init(ar); 1398 1399 ath11k_debugfs_fw_stats_init(ar); 1400 1401 debugfs_create_file("ext_tx_stats", 0644, 1402 ar->debug.debugfs_pdev, ar, 1403 &fops_extd_tx_stats); 1404 debugfs_create_file("ext_rx_stats", 0644, 1405 ar->debug.debugfs_pdev, ar, 1406 &fops_extd_rx_stats); 1407 debugfs_create_file("pktlog_filter", 0644, 1408 ar->debug.debugfs_pdev, ar, 1409 &fops_pktlog_filter); 1410 debugfs_create_file("fw_dbglog_config", 0600, 1411 ar->debug.debugfs_pdev, ar, 1412 &fops_fw_dbglog); 1413 1414 if (ar->hw->wiphy->bands[NL80211_BAND_5GHZ]) { 1415 debugfs_create_file("dfs_simulate_radar", 0200, 1416 ar->debug.debugfs_pdev, ar, 1417 &fops_simulate_radar); 1418 debugfs_create_bool("dfs_block_radar_events", 0200, 1419 ar->debug.debugfs_pdev, 1420 &ar->dfs_block_radar_events); 1421 } 1422 1423 if (ab->hw_params.dbr_debug_support) 1424 debugfs_create_file("enable_dbr_debug", 0200, ar->debug.debugfs_pdev, 1425 ar, &fops_dbr_debug); 1426 1427 return 0; 1428 } 1429 1430 void ath11k_debugfs_unregister(struct ath11k *ar) 1431 { 1432 struct ath11k_debug_dbr *dbr_debug; 1433 struct ath11k_dbg_dbr_data *dbr_dbg_data; 1434 int i; 1435 1436 for (i = 0; i < WMI_DIRECT_BUF_MAX; i++) { 1437 dbr_debug = ar->debug.dbr_debug[i]; 1438 if (!dbr_debug) 1439 continue; 1440 1441 dbr_dbg_data = &dbr_debug->dbr_dbg_data; 1442 kfree(dbr_dbg_data->entries); 1443 debugfs_remove_recursive(dbr_debug->dbr_debugfs); 1444 kfree(dbr_debug); 1445 ar->debug.dbr_debug[i] = NULL; 1446 } 1447 } 1448 1449 static ssize_t ath11k_write_twt_add_dialog(struct file *file, 1450 const char __user *ubuf, 1451 size_t count, loff_t *ppos) 1452 { 1453 struct ath11k_vif *arvif = file->private_data; 1454 struct wmi_twt_add_dialog_params params = { 0 }; 1455 u8 buf[128] = {0}; 1456 int ret; 1457 1458 if (arvif->ar->twt_enabled == 0) { 1459 ath11k_err(arvif->ar->ab, "twt support is not enabled\n"); 1460 return -EOPNOTSUPP; 1461 } 1462 1463 ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count); 1464 if (ret < 0) 1465 return ret; 1466 1467 buf[ret] = '\0'; 1468 ret = sscanf(buf, 1469 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u %u %u %u %u %hhu %hhu %hhu %hhu %hhu", 1470 ¶ms.peer_macaddr[0], 1471 ¶ms.peer_macaddr[1], 1472 ¶ms.peer_macaddr[2], 1473 ¶ms.peer_macaddr[3], 1474 ¶ms.peer_macaddr[4], 1475 ¶ms.peer_macaddr[5], 1476 ¶ms.dialog_id, 1477 ¶ms.wake_intvl_us, 1478 ¶ms.wake_intvl_mantis, 1479 ¶ms.wake_dura_us, 1480 ¶ms.sp_offset_us, 1481 ¶ms.twt_cmd, 1482 ¶ms.flag_bcast, 1483 ¶ms.flag_trigger, 1484 ¶ms.flag_flow_type, 1485 ¶ms.flag_protection); 1486 if (ret != 16) 1487 return -EINVAL; 1488 1489 params.vdev_id = arvif->vdev_id; 1490 1491 ret = ath11k_wmi_send_twt_add_dialog_cmd(arvif->ar, ¶ms); 1492 if (ret) 1493 return ret; 1494 1495 return count; 1496 } 1497 1498 static ssize_t ath11k_write_twt_del_dialog(struct file *file, 1499 const char __user *ubuf, 1500 size_t count, loff_t *ppos) 1501 { 1502 struct ath11k_vif *arvif = file->private_data; 1503 struct wmi_twt_del_dialog_params params = { 0 }; 1504 u8 buf[64] = {0}; 1505 int ret; 1506 1507 if (arvif->ar->twt_enabled == 0) { 1508 ath11k_err(arvif->ar->ab, "twt support is not enabled\n"); 1509 return -EOPNOTSUPP; 1510 } 1511 1512 ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count); 1513 if (ret < 0) 1514 return ret; 1515 1516 buf[ret] = '\0'; 1517 ret = sscanf(buf, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u", 1518 ¶ms.peer_macaddr[0], 1519 ¶ms.peer_macaddr[1], 1520 ¶ms.peer_macaddr[2], 1521 ¶ms.peer_macaddr[3], 1522 ¶ms.peer_macaddr[4], 1523 ¶ms.peer_macaddr[5], 1524 ¶ms.dialog_id); 1525 if (ret != 7) 1526 return -EINVAL; 1527 1528 params.vdev_id = arvif->vdev_id; 1529 1530 ret = ath11k_wmi_send_twt_del_dialog_cmd(arvif->ar, ¶ms); 1531 if (ret) 1532 return ret; 1533 1534 return count; 1535 } 1536 1537 static ssize_t ath11k_write_twt_pause_dialog(struct file *file, 1538 const char __user *ubuf, 1539 size_t count, loff_t *ppos) 1540 { 1541 struct ath11k_vif *arvif = file->private_data; 1542 struct wmi_twt_pause_dialog_params params = { 0 }; 1543 u8 buf[64] = {0}; 1544 int ret; 1545 1546 if (arvif->ar->twt_enabled == 0) { 1547 ath11k_err(arvif->ar->ab, "twt support is not enabled\n"); 1548 return -EOPNOTSUPP; 1549 } 1550 1551 ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count); 1552 if (ret < 0) 1553 return ret; 1554 1555 buf[ret] = '\0'; 1556 ret = sscanf(buf, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u", 1557 ¶ms.peer_macaddr[0], 1558 ¶ms.peer_macaddr[1], 1559 ¶ms.peer_macaddr[2], 1560 ¶ms.peer_macaddr[3], 1561 ¶ms.peer_macaddr[4], 1562 ¶ms.peer_macaddr[5], 1563 ¶ms.dialog_id); 1564 if (ret != 7) 1565 return -EINVAL; 1566 1567 params.vdev_id = arvif->vdev_id; 1568 1569 ret = ath11k_wmi_send_twt_pause_dialog_cmd(arvif->ar, ¶ms); 1570 if (ret) 1571 return ret; 1572 1573 return count; 1574 } 1575 1576 static ssize_t ath11k_write_twt_resume_dialog(struct file *file, 1577 const char __user *ubuf, 1578 size_t count, loff_t *ppos) 1579 { 1580 struct ath11k_vif *arvif = file->private_data; 1581 struct wmi_twt_resume_dialog_params params = { 0 }; 1582 u8 buf[64] = {0}; 1583 int ret; 1584 1585 if (arvif->ar->twt_enabled == 0) { 1586 ath11k_err(arvif->ar->ab, "twt support is not enabled\n"); 1587 return -EOPNOTSUPP; 1588 } 1589 1590 ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count); 1591 if (ret < 0) 1592 return ret; 1593 1594 buf[ret] = '\0'; 1595 ret = sscanf(buf, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u %u %u", 1596 ¶ms.peer_macaddr[0], 1597 ¶ms.peer_macaddr[1], 1598 ¶ms.peer_macaddr[2], 1599 ¶ms.peer_macaddr[3], 1600 ¶ms.peer_macaddr[4], 1601 ¶ms.peer_macaddr[5], 1602 ¶ms.dialog_id, 1603 ¶ms.sp_offset_us, 1604 ¶ms.next_twt_size); 1605 if (ret != 9) 1606 return -EINVAL; 1607 1608 params.vdev_id = arvif->vdev_id; 1609 1610 ret = ath11k_wmi_send_twt_resume_dialog_cmd(arvif->ar, ¶ms); 1611 if (ret) 1612 return ret; 1613 1614 return count; 1615 } 1616 1617 static const struct file_operations ath11k_fops_twt_add_dialog = { 1618 .write = ath11k_write_twt_add_dialog, 1619 .open = simple_open 1620 }; 1621 1622 static const struct file_operations ath11k_fops_twt_del_dialog = { 1623 .write = ath11k_write_twt_del_dialog, 1624 .open = simple_open 1625 }; 1626 1627 static const struct file_operations ath11k_fops_twt_pause_dialog = { 1628 .write = ath11k_write_twt_pause_dialog, 1629 .open = simple_open 1630 }; 1631 1632 static const struct file_operations ath11k_fops_twt_resume_dialog = { 1633 .write = ath11k_write_twt_resume_dialog, 1634 .open = simple_open 1635 }; 1636 1637 int ath11k_debugfs_add_interface(struct ath11k_vif *arvif) 1638 { 1639 if (arvif->vif->type == NL80211_IFTYPE_AP && !arvif->debugfs_twt) { 1640 arvif->debugfs_twt = debugfs_create_dir("twt", 1641 arvif->vif->debugfs_dir); 1642 if (!arvif->debugfs_twt || IS_ERR(arvif->debugfs_twt)) { 1643 ath11k_warn(arvif->ar->ab, 1644 "failed to create directory %p\n", 1645 arvif->debugfs_twt); 1646 arvif->debugfs_twt = NULL; 1647 return -1; 1648 } 1649 1650 debugfs_create_file("add_dialog", 0200, arvif->debugfs_twt, 1651 arvif, &ath11k_fops_twt_add_dialog); 1652 1653 debugfs_create_file("del_dialog", 0200, arvif->debugfs_twt, 1654 arvif, &ath11k_fops_twt_del_dialog); 1655 1656 debugfs_create_file("pause_dialog", 0200, arvif->debugfs_twt, 1657 arvif, &ath11k_fops_twt_pause_dialog); 1658 1659 debugfs_create_file("resume_dialog", 0200, arvif->debugfs_twt, 1660 arvif, &ath11k_fops_twt_resume_dialog); 1661 } 1662 return 0; 1663 } 1664 1665 void ath11k_debugfs_remove_interface(struct ath11k_vif *arvif) 1666 { 1667 debugfs_remove_recursive(arvif->debugfs_twt); 1668 arvif->debugfs_twt = NULL; 1669 } 1670