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 /drivers/net/wireless/ath/ath10k | |
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>
Diffstat (limited to 'drivers/net/wireless/ath/ath10k')
-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; | ||
1450 | |||
1442 | void ath10k_wmi_tlv_attach(struct ath10k *ar); | 1451 | void ath10k_wmi_tlv_attach(struct ath10k *ar); |
1443 | 1452 | ||
1444 | #endif | 1453 | #endif |