.. | .. |
---|
| 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 | } |
---|