| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: ISC |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (c) 2014-2017 Qualcomm Atheros, Inc. |
|---|
| 3 | 4 | * Copyright (c) 2018, The Linux Foundation. All rights reserved. |
|---|
| 4 | | - * |
|---|
| 5 | | - * Permission to use, copy, modify, and/or distribute this software for any |
|---|
| 6 | | - * purpose with or without fee is hereby granted, provided that the above |
|---|
| 7 | | - * copyright notice and this permission notice appear in all copies. |
|---|
| 8 | | - * |
|---|
| 9 | | - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
|---|
| 10 | | - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
|---|
| 11 | | - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
|---|
| 12 | | - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|---|
| 13 | | - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|---|
| 14 | | - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
|---|
| 15 | | - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|---|
| 16 | 5 | */ |
|---|
| 17 | 6 | |
|---|
| 18 | 7 | #include "core.h" |
|---|
| .. | .. |
|---|
| 87 | 76 | } |
|---|
| 88 | 77 | |
|---|
| 89 | 78 | void ath10k_sta_update_rx_tid_stats(struct ath10k *ar, u8 *first_hdr, |
|---|
| 90 | | - unsigned long int num_msdus, |
|---|
| 79 | + unsigned long num_msdus, |
|---|
| 91 | 80 | enum ath10k_pkt_rx_err err, |
|---|
| 92 | | - unsigned long int unchain_cnt, |
|---|
| 93 | | - unsigned long int drop_cnt, |
|---|
| 94 | | - unsigned long int drop_cnt_filter, |
|---|
| 95 | | - unsigned long int queued_msdus) |
|---|
| 81 | + unsigned long unchain_cnt, |
|---|
| 82 | + unsigned long drop_cnt, |
|---|
| 83 | + unsigned long drop_cnt_filter, |
|---|
| 84 | + unsigned long queued_msdus) |
|---|
| 96 | 85 | { |
|---|
| 97 | 86 | struct ieee80211_sta *sta; |
|---|
| 98 | 87 | struct ath10k_sta *arsta; |
|---|
| .. | .. |
|---|
| 441 | 430 | } |
|---|
| 442 | 431 | |
|---|
| 443 | 432 | ret = ath10k_wmi_peer_set_param(ar, arsta->arvif->vdev_id, sta->addr, |
|---|
| 444 | | - WMI_PEER_DEBUG, peer_debug_trigger); |
|---|
| 433 | + ar->wmi.peer_param->debug, peer_debug_trigger); |
|---|
| 445 | 434 | if (ret) { |
|---|
| 446 | 435 | ath10k_warn(ar, "failed to set param to trigger peer tid logs for station ret: %d\n", |
|---|
| 447 | 436 | ret); |
|---|
| .. | .. |
|---|
| 456 | 445 | .open = simple_open, |
|---|
| 457 | 446 | .read = ath10k_dbg_sta_read_peer_debug_trigger, |
|---|
| 458 | 447 | .write = ath10k_dbg_sta_write_peer_debug_trigger, |
|---|
| 448 | + .owner = THIS_MODULE, |
|---|
| 449 | + .llseek = default_llseek, |
|---|
| 450 | +}; |
|---|
| 451 | + |
|---|
| 452 | +static ssize_t ath10k_dbg_sta_read_peer_ps_state(struct file *file, |
|---|
| 453 | + char __user *user_buf, |
|---|
| 454 | + size_t count, loff_t *ppos) |
|---|
| 455 | +{ |
|---|
| 456 | + struct ieee80211_sta *sta = file->private_data; |
|---|
| 457 | + struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv; |
|---|
| 458 | + struct ath10k *ar = arsta->arvif->ar; |
|---|
| 459 | + char buf[20]; |
|---|
| 460 | + int len = 0; |
|---|
| 461 | + |
|---|
| 462 | + spin_lock_bh(&ar->data_lock); |
|---|
| 463 | + |
|---|
| 464 | + len = scnprintf(buf, sizeof(buf) - len, "%d\n", |
|---|
| 465 | + arsta->peer_ps_state); |
|---|
| 466 | + |
|---|
| 467 | + spin_unlock_bh(&ar->data_lock); |
|---|
| 468 | + |
|---|
| 469 | + return simple_read_from_buffer(user_buf, count, ppos, buf, len); |
|---|
| 470 | +} |
|---|
| 471 | + |
|---|
| 472 | +static const struct file_operations fops_peer_ps_state = { |
|---|
| 473 | + .open = simple_open, |
|---|
| 474 | + .read = ath10k_dbg_sta_read_peer_ps_state, |
|---|
| 459 | 475 | .owner = THIS_MODULE, |
|---|
| 460 | 476 | .llseek = default_llseek, |
|---|
| 461 | 477 | }; |
|---|
| .. | .. |
|---|
| 626 | 642 | .llseek = default_llseek, |
|---|
| 627 | 643 | }; |
|---|
| 628 | 644 | |
|---|
| 645 | +static ssize_t ath10k_dbg_sta_dump_tx_stats(struct file *file, |
|---|
| 646 | + char __user *user_buf, |
|---|
| 647 | + size_t count, loff_t *ppos) |
|---|
| 648 | +{ |
|---|
| 649 | + struct ieee80211_sta *sta = file->private_data; |
|---|
| 650 | + struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv; |
|---|
| 651 | + struct ath10k *ar = arsta->arvif->ar; |
|---|
| 652 | + struct ath10k_htt_data_stats *stats; |
|---|
| 653 | + const char *str_name[ATH10K_STATS_TYPE_MAX] = {"succ", "fail", |
|---|
| 654 | + "retry", "ampdu"}; |
|---|
| 655 | + const char *str[ATH10K_COUNTER_TYPE_MAX] = {"bytes", "packets"}; |
|---|
| 656 | + int len = 0, i, j, k, retval = 0; |
|---|
| 657 | + const int size = 16 * 4096; |
|---|
| 658 | + char *buf; |
|---|
| 659 | + |
|---|
| 660 | + buf = kzalloc(size, GFP_KERNEL); |
|---|
| 661 | + if (!buf) |
|---|
| 662 | + return -ENOMEM; |
|---|
| 663 | + |
|---|
| 664 | + mutex_lock(&ar->conf_mutex); |
|---|
| 665 | + |
|---|
| 666 | + if (!arsta->tx_stats) { |
|---|
| 667 | + ath10k_warn(ar, "failed to get tx stats"); |
|---|
| 668 | + mutex_unlock(&ar->conf_mutex); |
|---|
| 669 | + kfree(buf); |
|---|
| 670 | + return 0; |
|---|
| 671 | + } |
|---|
| 672 | + |
|---|
| 673 | + spin_lock_bh(&ar->data_lock); |
|---|
| 674 | + for (k = 0; k < ATH10K_STATS_TYPE_MAX; k++) { |
|---|
| 675 | + for (j = 0; j < ATH10K_COUNTER_TYPE_MAX; j++) { |
|---|
| 676 | + stats = &arsta->tx_stats->stats[k]; |
|---|
| 677 | + len += scnprintf(buf + len, size - len, "%s_%s\n", |
|---|
| 678 | + str_name[k], |
|---|
| 679 | + str[j]); |
|---|
| 680 | + len += scnprintf(buf + len, size - len, |
|---|
| 681 | + " VHT MCS %s\n", |
|---|
| 682 | + str[j]); |
|---|
| 683 | + for (i = 0; i < ATH10K_VHT_MCS_NUM; i++) |
|---|
| 684 | + len += scnprintf(buf + len, size - len, |
|---|
| 685 | + " %llu ", |
|---|
| 686 | + stats->vht[j][i]); |
|---|
| 687 | + len += scnprintf(buf + len, size - len, "\n"); |
|---|
| 688 | + len += scnprintf(buf + len, size - len, " HT MCS %s\n", |
|---|
| 689 | + str[j]); |
|---|
| 690 | + for (i = 0; i < ATH10K_HT_MCS_NUM; i++) |
|---|
| 691 | + len += scnprintf(buf + len, size - len, |
|---|
| 692 | + " %llu ", stats->ht[j][i]); |
|---|
| 693 | + len += scnprintf(buf + len, size - len, "\n"); |
|---|
| 694 | + len += scnprintf(buf + len, size - len, |
|---|
| 695 | + " BW %s (20,5,10,40,80,160 MHz)\n", str[j]); |
|---|
| 696 | + len += scnprintf(buf + len, size - len, |
|---|
| 697 | + " %llu %llu %llu %llu %llu %llu\n", |
|---|
| 698 | + stats->bw[j][0], stats->bw[j][1], |
|---|
| 699 | + stats->bw[j][2], stats->bw[j][3], |
|---|
| 700 | + stats->bw[j][4], stats->bw[j][5]); |
|---|
| 701 | + len += scnprintf(buf + len, size - len, |
|---|
| 702 | + " NSS %s (1x1,2x2,3x3,4x4)\n", str[j]); |
|---|
| 703 | + len += scnprintf(buf + len, size - len, |
|---|
| 704 | + " %llu %llu %llu %llu\n", |
|---|
| 705 | + stats->nss[j][0], stats->nss[j][1], |
|---|
| 706 | + stats->nss[j][2], stats->nss[j][3]); |
|---|
| 707 | + len += scnprintf(buf + len, size - len, |
|---|
| 708 | + " GI %s (LGI,SGI)\n", |
|---|
| 709 | + str[j]); |
|---|
| 710 | + len += scnprintf(buf + len, size - len, " %llu %llu\n", |
|---|
| 711 | + stats->gi[j][0], stats->gi[j][1]); |
|---|
| 712 | + len += scnprintf(buf + len, size - len, |
|---|
| 713 | + " legacy rate %s (1,2 ... Mbps)\n ", |
|---|
| 714 | + str[j]); |
|---|
| 715 | + for (i = 0; i < ATH10K_LEGACY_NUM; i++) |
|---|
| 716 | + len += scnprintf(buf + len, size - len, "%llu ", |
|---|
| 717 | + stats->legacy[j][i]); |
|---|
| 718 | + len += scnprintf(buf + len, size - len, "\n"); |
|---|
| 719 | + len += scnprintf(buf + len, size - len, |
|---|
| 720 | + " Rate table %s (1,2 ... Mbps)\n ", |
|---|
| 721 | + str[j]); |
|---|
| 722 | + for (i = 0; i < ATH10K_RATE_TABLE_NUM; i++) { |
|---|
| 723 | + len += scnprintf(buf + len, size - len, "%llu ", |
|---|
| 724 | + stats->rate_table[j][i]); |
|---|
| 725 | + if (!((i + 1) % 8)) |
|---|
| 726 | + len += |
|---|
| 727 | + scnprintf(buf + len, size - len, "\n "); |
|---|
| 728 | + } |
|---|
| 729 | + } |
|---|
| 730 | + } |
|---|
| 731 | + |
|---|
| 732 | + len += scnprintf(buf + len, size - len, |
|---|
| 733 | + "\nTX duration\n %llu usecs\n", |
|---|
| 734 | + arsta->tx_stats->tx_duration); |
|---|
| 735 | + len += scnprintf(buf + len, size - len, |
|---|
| 736 | + "BA fails\n %llu\n", arsta->tx_stats->ba_fails); |
|---|
| 737 | + len += scnprintf(buf + len, size - len, |
|---|
| 738 | + "ack fails\n %llu\n", arsta->tx_stats->ack_fails); |
|---|
| 739 | + spin_unlock_bh(&ar->data_lock); |
|---|
| 740 | + |
|---|
| 741 | + if (len > size) |
|---|
| 742 | + len = size; |
|---|
| 743 | + retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); |
|---|
| 744 | + kfree(buf); |
|---|
| 745 | + |
|---|
| 746 | + mutex_unlock(&ar->conf_mutex); |
|---|
| 747 | + return retval; |
|---|
| 748 | +} |
|---|
| 749 | + |
|---|
| 750 | +static const struct file_operations fops_tx_stats = { |
|---|
| 751 | + .read = ath10k_dbg_sta_dump_tx_stats, |
|---|
| 752 | + .open = simple_open, |
|---|
| 753 | + .owner = THIS_MODULE, |
|---|
| 754 | + .llseek = default_llseek, |
|---|
| 755 | +}; |
|---|
| 756 | + |
|---|
| 629 | 757 | void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
|---|
| 630 | 758 | struct ieee80211_sta *sta, struct dentry *dir) |
|---|
| 631 | 759 | { |
|---|
| 760 | + struct ath10k *ar = hw->priv; |
|---|
| 761 | + |
|---|
| 632 | 762 | debugfs_create_file("aggr_mode", 0644, dir, sta, &fops_aggr_mode); |
|---|
| 633 | 763 | debugfs_create_file("addba", 0200, dir, sta, &fops_addba); |
|---|
| 634 | 764 | debugfs_create_file("addba_resp", 0200, dir, sta, &fops_addba_resp); |
|---|
| .. | .. |
|---|
| 637 | 767 | &fops_peer_debug_trigger); |
|---|
| 638 | 768 | debugfs_create_file("dump_tid_stats", 0400, dir, sta, |
|---|
| 639 | 769 | &fops_tid_stats_dump); |
|---|
| 770 | + |
|---|
| 771 | + if (ath10k_peer_stats_enabled(ar) && |
|---|
| 772 | + ath10k_debug_is_extd_tx_stats_enabled(ar)) |
|---|
| 773 | + debugfs_create_file("tx_stats", 0400, dir, sta, |
|---|
| 774 | + &fops_tx_stats); |
|---|
| 775 | + debugfs_create_file("peer_ps_state", 0400, dir, sta, |
|---|
| 776 | + &fops_peer_ps_state); |
|---|
| 640 | 777 | } |
|---|