aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath10k/wmi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath10k/wmi.c')
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.c379
1 files changed, 379 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 063469b69d5f..6e7d7a7f6a97 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -6621,6 +6621,381 @@ ath10k_wmi_10_2_4_op_gen_pdev_get_tpc_config(struct ath10k *ar, u32 param)
6621 return skb; 6621 return skb;
6622} 6622}
6623 6623
6624size_t ath10k_wmi_fw_stats_num_peers(struct list_head *head)
6625{
6626 struct ath10k_fw_stats_peer *i;
6627 size_t num = 0;
6628
6629 list_for_each_entry(i, head, list)
6630 ++num;
6631
6632 return num;
6633}
6634
6635size_t ath10k_wmi_fw_stats_num_vdevs(struct list_head *head)
6636{
6637 struct ath10k_fw_stats_vdev *i;
6638 size_t num = 0;
6639
6640 list_for_each_entry(i, head, list)
6641 ++num;
6642
6643 return num;
6644}
6645
6646static void
6647ath10k_wmi_fw_pdev_base_stats_fill(const struct ath10k_fw_stats_pdev *pdev,
6648 char *buf, u32 *length)
6649{
6650 u32 len = *length;
6651 u32 buf_len = ATH10K_FW_STATS_BUF_SIZE;
6652
6653 len += scnprintf(buf + len, buf_len - len, "\n");
6654 len += scnprintf(buf + len, buf_len - len, "%30s\n",
6655 "ath10k PDEV stats");
6656 len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
6657 "=================");
6658
6659 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6660 "Channel noise floor", pdev->ch_noise_floor);
6661 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6662 "Channel TX power", pdev->chan_tx_power);
6663 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6664 "TX frame count", pdev->tx_frame_count);
6665 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6666 "RX frame count", pdev->rx_frame_count);
6667 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6668 "RX clear count", pdev->rx_clear_count);
6669 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6670 "Cycle count", pdev->cycle_count);
6671 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6672 "PHY error count", pdev->phy_err_count);
6673
6674 *length = len;
6675}
6676
6677static void
6678ath10k_wmi_fw_pdev_extra_stats_fill(const struct ath10k_fw_stats_pdev *pdev,
6679 char *buf, u32 *length)
6680{
6681 u32 len = *length;
6682 u32 buf_len = ATH10K_FW_STATS_BUF_SIZE;
6683
6684 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6685 "RTS bad count", pdev->rts_bad);
6686 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6687 "RTS good count", pdev->rts_good);
6688 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6689 "FCS bad count", pdev->fcs_bad);
6690 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6691 "No beacon count", pdev->no_beacons);
6692 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
6693 "MIB int count", pdev->mib_int_count);
6694
6695 len += scnprintf(buf + len, buf_len - len, "\n");
6696 *length = len;
6697}
6698
6699static void
6700ath10k_wmi_fw_pdev_tx_stats_fill(const struct ath10k_fw_stats_pdev *pdev,
6701 char *buf, u32 *length)
6702{
6703 u32 len = *length;
6704 u32 buf_len = ATH10K_FW_STATS_BUF_SIZE;
6705
6706 len += scnprintf(buf + len, buf_len - len, "\n%30s\n",
6707 "ath10k PDEV TX stats");
6708 len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
6709 "=================");
6710
6711 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6712 "HTT cookies queued", pdev->comp_queued);
6713 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6714 "HTT cookies disp.", pdev->comp_delivered);
6715 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6716 "MSDU queued", pdev->msdu_enqued);
6717 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6718 "MPDU queued", pdev->mpdu_enqued);
6719 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6720 "MSDUs dropped", pdev->wmm_drop);
6721 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6722 "Local enqued", pdev->local_enqued);
6723 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6724 "Local freed", pdev->local_freed);
6725 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6726 "HW queued", pdev->hw_queued);
6727 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6728 "PPDUs reaped", pdev->hw_reaped);
6729 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6730 "Num underruns", pdev->underrun);
6731 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6732 "PPDUs cleaned", pdev->tx_abort);
6733 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6734 "MPDUs requed", pdev->mpdus_requed);
6735 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6736 "Excessive retries", pdev->tx_ko);
6737 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6738 "HW rate", pdev->data_rc);
6739 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6740 "Sched self tiggers", pdev->self_triggers);
6741 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6742 "Dropped due to SW retries",
6743 pdev->sw_retry_failure);
6744 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6745 "Illegal rate phy errors",
6746 pdev->illgl_rate_phy_err);
6747 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6748 "Pdev continuous xretry", pdev->pdev_cont_xretry);
6749 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6750 "TX timeout", pdev->pdev_tx_timeout);
6751 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6752 "PDEV resets", pdev->pdev_resets);
6753 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6754 "PHY underrun", pdev->phy_underrun);
6755 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6756 "MPDU is more than txop limit", pdev->txop_ovf);
6757 *length = len;
6758}
6759
6760static void
6761ath10k_wmi_fw_pdev_rx_stats_fill(const struct ath10k_fw_stats_pdev *pdev,
6762 char *buf, u32 *length)
6763{
6764 u32 len = *length;
6765 u32 buf_len = ATH10K_FW_STATS_BUF_SIZE;
6766
6767 len += scnprintf(buf + len, buf_len - len, "\n%30s\n",
6768 "ath10k PDEV RX stats");
6769 len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
6770 "=================");
6771
6772 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6773 "Mid PPDU route change",
6774 pdev->mid_ppdu_route_change);
6775 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6776 "Tot. number of statuses", pdev->status_rcvd);
6777 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6778 "Extra frags on rings 0", pdev->r0_frags);
6779 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6780 "Extra frags on rings 1", pdev->r1_frags);
6781 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6782 "Extra frags on rings 2", pdev->r2_frags);
6783 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6784 "Extra frags on rings 3", pdev->r3_frags);
6785 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6786 "MSDUs delivered to HTT", pdev->htt_msdus);
6787 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6788 "MPDUs delivered to HTT", pdev->htt_mpdus);
6789 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6790 "MSDUs delivered to stack", pdev->loc_msdus);
6791 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6792 "MPDUs delivered to stack", pdev->loc_mpdus);
6793 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6794 "Oversized AMSUs", pdev->oversize_amsdu);
6795 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6796 "PHY errors", pdev->phy_errs);
6797 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6798 "PHY errors drops", pdev->phy_err_drop);
6799 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
6800 "MPDU errors (FCS, MIC, ENC)", pdev->mpdu_errs);
6801 *length = len;
6802}
6803
6804static void
6805ath10k_wmi_fw_vdev_stats_fill(const struct ath10k_fw_stats_vdev *vdev,
6806 char *buf, u32 *length)
6807{
6808 u32 len = *length;
6809 u32 buf_len = ATH10K_FW_STATS_BUF_SIZE;
6810 int i;
6811
6812 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
6813 "vdev id", vdev->vdev_id);
6814 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
6815 "beacon snr", vdev->beacon_snr);
6816 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
6817 "data snr", vdev->data_snr);
6818 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
6819 "num rx frames", vdev->num_rx_frames);
6820 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
6821 "num rts fail", vdev->num_rts_fail);
6822 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
6823 "num rts success", vdev->num_rts_success);
6824 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
6825 "num rx err", vdev->num_rx_err);
6826 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
6827 "num rx discard", vdev->num_rx_discard);
6828 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
6829 "num tx not acked", vdev->num_tx_not_acked);
6830
6831 for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames); i++)
6832 len += scnprintf(buf + len, buf_len - len,
6833 "%25s [%02d] %u\n",
6834 "num tx frames", i,
6835 vdev->num_tx_frames[i]);
6836
6837 for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames_retries); i++)
6838 len += scnprintf(buf + len, buf_len - len,
6839 "%25s [%02d] %u\n",
6840 "num tx frames retries", i,
6841 vdev->num_tx_frames_retries[i]);
6842
6843 for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames_failures); i++)
6844 len += scnprintf(buf + len, buf_len - len,
6845 "%25s [%02d] %u\n",
6846 "num tx frames failures", i,
6847 vdev->num_tx_frames_failures[i]);
6848
6849 for (i = 0 ; i < ARRAY_SIZE(vdev->tx_rate_history); i++)
6850 len += scnprintf(buf + len, buf_len - len,
6851 "%25s [%02d] 0x%08x\n",
6852 "tx rate history", i,
6853 vdev->tx_rate_history[i]);
6854
6855 for (i = 0 ; i < ARRAY_SIZE(vdev->beacon_rssi_history); i++)
6856 len += scnprintf(buf + len, buf_len - len,
6857 "%25s [%02d] %u\n",
6858 "beacon rssi history", i,
6859 vdev->beacon_rssi_history[i]);
6860
6861 len += scnprintf(buf + len, buf_len - len, "\n");
6862 *length = len;
6863}
6864
6865static void
6866ath10k_wmi_fw_peer_stats_fill(const struct ath10k_fw_stats_peer *peer,
6867 char *buf, u32 *length)
6868{
6869 u32 len = *length;
6870 u32 buf_len = ATH10K_FW_STATS_BUF_SIZE;
6871
6872 len += scnprintf(buf + len, buf_len - len, "%30s %pM\n",
6873 "Peer MAC address", peer->peer_macaddr);
6874 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
6875 "Peer RSSI", peer->peer_rssi);
6876 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
6877 "Peer TX rate", peer->peer_tx_rate);
6878 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
6879 "Peer RX rate", peer->peer_rx_rate);
6880 len += scnprintf(buf + len, buf_len - len, "\n");
6881 *length = len;
6882}
6883
6884void ath10k_wmi_main_op_fw_stats_fill(struct ath10k *ar,
6885 struct ath10k_fw_stats *fw_stats,
6886 char *buf)
6887{
6888 u32 len = 0;
6889 u32 buf_len = ATH10K_FW_STATS_BUF_SIZE;
6890 const struct ath10k_fw_stats_pdev *pdev;
6891 const struct ath10k_fw_stats_vdev *vdev;
6892 const struct ath10k_fw_stats_peer *peer;
6893 size_t num_peers;
6894 size_t num_vdevs;
6895
6896 spin_lock_bh(&ar->data_lock);
6897
6898 pdev = list_first_entry_or_null(&fw_stats->pdevs,
6899 struct ath10k_fw_stats_pdev, list);
6900 if (!pdev) {
6901 ath10k_warn(ar, "failed to get pdev stats\n");
6902 goto unlock;
6903 }
6904
6905 num_peers = ath10k_wmi_fw_stats_num_peers(&fw_stats->peers);
6906 num_vdevs = ath10k_wmi_fw_stats_num_vdevs(&fw_stats->vdevs);
6907
6908 ath10k_wmi_fw_pdev_base_stats_fill(pdev, buf, &len);
6909 ath10k_wmi_fw_pdev_tx_stats_fill(pdev, buf, &len);
6910 ath10k_wmi_fw_pdev_rx_stats_fill(pdev, buf, &len);
6911
6912 len += scnprintf(buf + len, buf_len - len, "\n");
6913 len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n",
6914 "ath10k VDEV stats", num_vdevs);
6915 len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
6916 "=================");
6917
6918 list_for_each_entry(vdev, &fw_stats->vdevs, list) {
6919 ath10k_wmi_fw_vdev_stats_fill(vdev, buf, &len);
6920 }
6921
6922 len += scnprintf(buf + len, buf_len - len, "\n");
6923 len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n",
6924 "ath10k PEER stats", num_peers);
6925 len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
6926 "=================");
6927
6928 list_for_each_entry(peer, &fw_stats->peers, list) {
6929 ath10k_wmi_fw_peer_stats_fill(peer, buf, &len);
6930 }
6931
6932unlock:
6933 spin_unlock_bh(&ar->data_lock);
6934
6935 if (len >= buf_len)
6936 buf[len - 1] = 0;
6937 else
6938 buf[len] = 0;
6939}
6940
6941void ath10k_wmi_10x_op_fw_stats_fill(struct ath10k *ar,
6942 struct ath10k_fw_stats *fw_stats,
6943 char *buf)
6944{
6945 unsigned int len = 0;
6946 unsigned int buf_len = ATH10K_FW_STATS_BUF_SIZE;
6947 const struct ath10k_fw_stats_pdev *pdev;
6948 const struct ath10k_fw_stats_vdev *vdev;
6949 const struct ath10k_fw_stats_peer *peer;
6950 size_t num_peers;
6951 size_t num_vdevs;
6952
6953 spin_lock_bh(&ar->data_lock);
6954
6955 pdev = list_first_entry_or_null(&fw_stats->pdevs,
6956 struct ath10k_fw_stats_pdev, list);
6957 if (!pdev) {
6958 ath10k_warn(ar, "failed to get pdev stats\n");
6959 goto unlock;
6960 }
6961
6962 num_peers = ath10k_wmi_fw_stats_num_peers(&fw_stats->peers);
6963 num_vdevs = ath10k_wmi_fw_stats_num_vdevs(&fw_stats->vdevs);
6964
6965 ath10k_wmi_fw_pdev_base_stats_fill(pdev, buf, &len);
6966 ath10k_wmi_fw_pdev_extra_stats_fill(pdev, buf, &len);
6967 ath10k_wmi_fw_pdev_tx_stats_fill(pdev, buf, &len);
6968 ath10k_wmi_fw_pdev_rx_stats_fill(pdev, buf, &len);
6969
6970 len += scnprintf(buf + len, buf_len - len, "\n");
6971 len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n",
6972 "ath10k VDEV stats", num_vdevs);
6973 len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
6974 "=================");
6975
6976 list_for_each_entry(vdev, &fw_stats->vdevs, list) {
6977 ath10k_wmi_fw_vdev_stats_fill(vdev, buf, &len);
6978 }
6979
6980 len += scnprintf(buf + len, buf_len - len, "\n");
6981 len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n",
6982 "ath10k PEER stats", num_peers);
6983 len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
6984 "=================");
6985
6986 list_for_each_entry(peer, &fw_stats->peers, list) {
6987 ath10k_wmi_fw_peer_stats_fill(peer, buf, &len);
6988 }
6989
6990unlock:
6991 spin_unlock_bh(&ar->data_lock);
6992
6993 if (len >= buf_len)
6994 buf[len - 1] = 0;
6995 else
6996 buf[len] = 0;
6997}
6998
6624static const struct wmi_ops wmi_ops = { 6999static const struct wmi_ops wmi_ops = {
6625 .rx = ath10k_wmi_op_rx, 7000 .rx = ath10k_wmi_op_rx,
6626 .map_svc = wmi_main_svc_map, 7001 .map_svc = wmi_main_svc_map,
@@ -6679,6 +7054,7 @@ static const struct wmi_ops wmi_ops = {
6679 .gen_addba_send = ath10k_wmi_op_gen_addba_send, 7054 .gen_addba_send = ath10k_wmi_op_gen_addba_send,
6680 .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp, 7055 .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp,
6681 .gen_delba_send = ath10k_wmi_op_gen_delba_send, 7056 .gen_delba_send = ath10k_wmi_op_gen_delba_send,
7057 .fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill,
6682 /* .gen_bcn_tmpl not implemented */ 7058 /* .gen_bcn_tmpl not implemented */
6683 /* .gen_prb_tmpl not implemented */ 7059 /* .gen_prb_tmpl not implemented */
6684 /* .gen_p2p_go_bcn_ie not implemented */ 7060 /* .gen_p2p_go_bcn_ie not implemented */
@@ -6744,6 +7120,7 @@ static const struct wmi_ops wmi_10_1_ops = {
6744 .gen_addba_send = ath10k_wmi_op_gen_addba_send, 7120 .gen_addba_send = ath10k_wmi_op_gen_addba_send,
6745 .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp, 7121 .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp,
6746 .gen_delba_send = ath10k_wmi_op_gen_delba_send, 7122 .gen_delba_send = ath10k_wmi_op_gen_delba_send,
7123 .fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill,
6747 /* .gen_bcn_tmpl not implemented */ 7124 /* .gen_bcn_tmpl not implemented */
6748 /* .gen_prb_tmpl not implemented */ 7125 /* .gen_prb_tmpl not implemented */
6749 /* .gen_p2p_go_bcn_ie not implemented */ 7126 /* .gen_p2p_go_bcn_ie not implemented */
@@ -6810,6 +7187,7 @@ static const struct wmi_ops wmi_10_2_ops = {
6810 .gen_addba_send = ath10k_wmi_op_gen_addba_send, 7187 .gen_addba_send = ath10k_wmi_op_gen_addba_send,
6811 .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp, 7188 .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp,
6812 .gen_delba_send = ath10k_wmi_op_gen_delba_send, 7189 .gen_delba_send = ath10k_wmi_op_gen_delba_send,
7190 .fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill,
6813}; 7191};
6814 7192
6815static const struct wmi_ops wmi_10_2_4_ops = { 7193static const struct wmi_ops wmi_10_2_4_ops = {
@@ -6872,6 +7250,7 @@ static const struct wmi_ops wmi_10_2_4_ops = {
6872 .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp, 7250 .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp,
6873 .gen_delba_send = ath10k_wmi_op_gen_delba_send, 7251 .gen_delba_send = ath10k_wmi_op_gen_delba_send,
6874 .gen_pdev_get_tpc_config = ath10k_wmi_10_2_4_op_gen_pdev_get_tpc_config, 7252 .gen_pdev_get_tpc_config = ath10k_wmi_10_2_4_op_gen_pdev_get_tpc_config,
7253 .fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill,
6875 /* .gen_bcn_tmpl not implemented */ 7254 /* .gen_bcn_tmpl not implemented */
6876 /* .gen_prb_tmpl not implemented */ 7255 /* .gen_prb_tmpl not implemented */
6877 /* .gen_p2p_go_bcn_ie not implemented */ 7256 /* .gen_p2p_go_bcn_ie not implemented */