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