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