diff options
| author | Michal Kazior <michal.kazior@tieto.com> | 2015-02-15 09:50:41 -0500 |
|---|---|---|
| committer | Kalle Valo <kvalo@qca.qualcomm.com> | 2015-02-15 09:50:41 -0500 |
| commit | 7777d8c7ef6fc12e9336ac29289d83ff54974f8f (patch) | |
| tree | c47dd9b23a12884a8b429505546daa3f24238fdc | |
| parent | eed55411d32a2f253290c430b1ff8ecdded588a6 (diff) | |
ath10k: implement fw stats for wmi-tlv
This processes and pushes fw stats to the debug
module (if enabled).
Changing the generic ath10k_wmi_requests_stats()
call to use more stat bits has no effect on older
firmware binaries.
Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
| -rw-r--r-- | drivers/net/wireless/ath/ath10k/debug.c | 5 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ath10k/wmi-tlv.c | 112 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ath10k/wmi-tlv.h | 9 |
3 files changed, 122 insertions, 4 deletions
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index cafe38aac0c4..301081db1ef6 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c | |||
| @@ -395,7 +395,10 @@ static int ath10k_debug_fw_stats_request(struct ath10k *ar) | |||
| 395 | 395 | ||
| 396 | reinit_completion(&ar->debug.fw_stats_complete); | 396 | reinit_completion(&ar->debug.fw_stats_complete); |
| 397 | 397 | ||
| 398 | ret = ath10k_wmi_request_stats(ar, WMI_STAT_PEER); | 398 | ret = ath10k_wmi_request_stats(ar, |
| 399 | WMI_STAT_PDEV | | ||
| 400 | WMI_STAT_VDEV | | ||
| 401 | WMI_STAT_PEER); | ||
| 399 | if (ret) { | 402 | if (ret) { |
| 400 | ath10k_warn(ar, "could not request stats (%d)\n", ret); | 403 | ath10k_warn(ar, "could not request stats (%d)\n", ret); |
| 401 | return ret; | 404 | return ret; |
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c index f995d8e120fb..f34baa0c9e87 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c | |||
| @@ -869,16 +869,57 @@ static int ath10k_wmi_tlv_op_pull_rdy_ev(struct ath10k *ar, | |||
| 869 | return 0; | 869 | return 0; |
| 870 | } | 870 | } |
| 871 | 871 | ||
| 872 | static void ath10k_wmi_tlv_pull_vdev_stats(const struct wmi_tlv_vdev_stats *src, | ||
| 873 | struct ath10k_fw_stats_vdev *dst) | ||
| 874 | { | ||
| 875 | int i; | ||
| 876 | |||
| 877 | dst->vdev_id = __le32_to_cpu(src->vdev_id); | ||
| 878 | dst->beacon_snr = __le32_to_cpu(src->beacon_snr); | ||
| 879 | dst->data_snr = __le32_to_cpu(src->data_snr); | ||
| 880 | dst->num_rx_frames = __le32_to_cpu(src->num_rx_frames); | ||
| 881 | dst->num_rts_fail = __le32_to_cpu(src->num_rts_fail); | ||
| 882 | dst->num_rts_success = __le32_to_cpu(src->num_rts_success); | ||
| 883 | dst->num_rx_err = __le32_to_cpu(src->num_rx_err); | ||
| 884 | dst->num_rx_discard = __le32_to_cpu(src->num_rx_discard); | ||
| 885 | dst->num_tx_not_acked = __le32_to_cpu(src->num_tx_not_acked); | ||
| 886 | |||
| 887 | for (i = 0; i < ARRAY_SIZE(src->num_tx_frames); i++) | ||
| 888 | dst->num_tx_frames[i] = | ||
| 889 | __le32_to_cpu(src->num_tx_frames[i]); | ||
| 890 | |||
| 891 | for (i = 0; i < ARRAY_SIZE(src->num_tx_frames_retries); i++) | ||
| 892 | dst->num_tx_frames_retries[i] = | ||
| 893 | __le32_to_cpu(src->num_tx_frames_retries[i]); | ||
| 894 | |||
| 895 | for (i = 0; i < ARRAY_SIZE(src->num_tx_frames_failures); i++) | ||
| 896 | dst->num_tx_frames_failures[i] = | ||
| 897 | __le32_to_cpu(src->num_tx_frames_failures[i]); | ||
| 898 | |||
| 899 | for (i = 0; i < ARRAY_SIZE(src->tx_rate_history); i++) | ||
| 900 | dst->tx_rate_history[i] = | ||
| 901 | __le32_to_cpu(src->tx_rate_history[i]); | ||
| 902 | |||
| 903 | for (i = 0; i < ARRAY_SIZE(src->beacon_rssi_history); i++) | ||
| 904 | dst->beacon_rssi_history[i] = | ||
| 905 | __le32_to_cpu(src->beacon_rssi_history[i]); | ||
| 906 | } | ||
| 907 | |||
| 872 | static int ath10k_wmi_tlv_op_pull_fw_stats(struct ath10k *ar, | 908 | static int ath10k_wmi_tlv_op_pull_fw_stats(struct ath10k *ar, |
| 873 | struct sk_buff *skb, | 909 | struct sk_buff *skb, |
| 874 | struct ath10k_fw_stats *stats) | 910 | struct ath10k_fw_stats *stats) |
| 875 | { | 911 | { |
| 876 | const void **tb; | 912 | const void **tb; |
| 877 | const struct wmi_stats_event *ev; | 913 | const struct wmi_tlv_stats_ev *ev; |
| 878 | const void *data; | 914 | const void *data; |
| 879 | u32 num_pdev_stats, num_vdev_stats, num_peer_stats; | 915 | u32 num_pdev_stats; |
| 916 | u32 num_vdev_stats; | ||
| 917 | u32 num_peer_stats; | ||
| 918 | u32 num_bcnflt_stats; | ||
| 919 | u32 num_chan_stats; | ||
| 880 | size_t data_len; | 920 | size_t data_len; |
| 881 | int ret; | 921 | int ret; |
| 922 | int i; | ||
| 882 | 923 | ||
| 883 | tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); | 924 | tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); |
| 884 | if (IS_ERR(tb)) { | 925 | if (IS_ERR(tb)) { |
| @@ -899,8 +940,73 @@ static int ath10k_wmi_tlv_op_pull_fw_stats(struct ath10k *ar, | |||
| 899 | num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats); | 940 | num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats); |
| 900 | num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats); | 941 | num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats); |
| 901 | num_peer_stats = __le32_to_cpu(ev->num_peer_stats); | 942 | num_peer_stats = __le32_to_cpu(ev->num_peer_stats); |
| 943 | num_bcnflt_stats = __le32_to_cpu(ev->num_bcnflt_stats); | ||
| 944 | num_chan_stats = __le32_to_cpu(ev->num_chan_stats); | ||
| 902 | 945 | ||
| 903 | WARN_ON(1); /* FIXME: not implemented yet */ | 946 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
| 947 | "wmi tlv stats update pdev %i vdev %i peer %i bcnflt %i chan %i\n", | ||
| 948 | num_pdev_stats, num_vdev_stats, num_peer_stats, | ||
| 949 | num_bcnflt_stats, num_chan_stats); | ||
| 950 | |||
| 951 | for (i = 0; i < num_pdev_stats; i++) { | ||
| 952 | const struct wmi_pdev_stats *src; | ||
| 953 | struct ath10k_fw_stats_pdev *dst; | ||
| 954 | |||
| 955 | src = data; | ||
| 956 | if (data_len < sizeof(*src)) | ||
| 957 | return -EPROTO; | ||
| 958 | |||
| 959 | data += sizeof(*src); | ||
| 960 | data_len -= sizeof(*src); | ||
| 961 | |||
| 962 | dst = kzalloc(sizeof(*dst), GFP_ATOMIC); | ||
| 963 | if (!dst) | ||
| 964 | continue; | ||
| 965 | |||
| 966 | ath10k_wmi_pull_pdev_stats_base(&src->base, dst); | ||
| 967 | ath10k_wmi_pull_pdev_stats_tx(&src->tx, dst); | ||
| 968 | ath10k_wmi_pull_pdev_stats_rx(&src->rx, dst); | ||
| 969 | list_add_tail(&dst->list, &stats->pdevs); | ||
| 970 | } | ||
| 971 | |||
| 972 | for (i = 0; i < num_vdev_stats; i++) { | ||
| 973 | const struct wmi_tlv_vdev_stats *src; | ||
| 974 | struct ath10k_fw_stats_vdev *dst; | ||
| 975 | |||
| 976 | src = data; | ||
| 977 | if (data_len < sizeof(*src)) | ||
| 978 | return -EPROTO; | ||
| 979 | |||
| 980 | data += sizeof(*src); | ||
| 981 | data_len -= sizeof(*src); | ||
| 982 | |||
| 983 | dst = kzalloc(sizeof(*dst), GFP_ATOMIC); | ||
| 984 | if (!dst) | ||
| 985 | continue; | ||
| 986 | |||
| 987 | ath10k_wmi_tlv_pull_vdev_stats(src, dst); | ||
| 988 | list_add_tail(&dst->list, &stats->vdevs); | ||
| 989 | } | ||
| 990 | |||
| 991 | for (i = 0; i < num_peer_stats; i++) { | ||
| 992 | const struct wmi_10x_peer_stats *src; | ||
| 993 | struct ath10k_fw_stats_peer *dst; | ||
| 994 | |||
| 995 | src = data; | ||
| 996 | if (data_len < sizeof(*src)) | ||
| 997 | return -EPROTO; | ||
| 998 | |||
| 999 | data += sizeof(*src); | ||
| 1000 | data_len -= sizeof(*src); | ||
| 1001 | |||
| 1002 | dst = kzalloc(sizeof(*dst), GFP_ATOMIC); | ||
| 1003 | if (!dst) | ||
| 1004 | continue; | ||
| 1005 | |||
| 1006 | ath10k_wmi_pull_peer_stats(&src->old, dst); | ||
| 1007 | dst->peer_rx_rate = __le32_to_cpu(src->peer_rx_rate); | ||
| 1008 | list_add_tail(&dst->list, &stats->peers); | ||
| 1009 | } | ||
| 904 | 1010 | ||
| 905 | kfree(tb); | 1011 | kfree(tb); |
| 906 | return 0; | 1012 | return 0; |
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.h b/drivers/net/wireless/ath/ath10k/wmi-tlv.h index de68fe76eae6..d7a31e15910d 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.h +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h | |||
| @@ -1439,6 +1439,15 @@ struct wmi_tlv_sta_keepalive_cmd { | |||
| 1439 | __le32 interval; /* in seconds */ | 1439 | __le32 interval; /* in seconds */ |
| 1440 | } __packed; | 1440 | } __packed; |
| 1441 | 1441 | ||
| 1442 | struct wmi_tlv_stats_ev { | ||
| 1443 | __le32 stats_id; /* WMI_STAT_ */ | ||
| 1444 | __le32 num_pdev_stats; | ||
| 1445 | __le32 num_vdev_stats; | ||
| 1446 | __le32 num_peer_stats; | ||
| 1447 | __le32 num_bcnflt_stats; | ||
| 1448 | __le32 num_chan_stats; | ||
| 1449 | } __packed; | ||
