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