diff options
author | Michal Kazior <michal.kazior@tieto.com> | 2015-01-24 05:14:49 -0500 |
---|---|---|
committer | Kalle Valo <kvalo@qca.qualcomm.com> | 2015-01-27 09:04:52 -0500 |
commit | 20de2229c634382777eb3b8fc54a34be9669ff8a (patch) | |
tree | e801cf2621b9e39f70d8373cbdf12f70146bf5d0 /drivers/net/wireless | |
parent | b91251fbe88c9db1a7af29cfe49ca50aa4da9cd2 (diff) |
ath10k: fix 10.2 fw stats parsing
Both 10.2 firmware binaries 10.2-00082-4 and
10.2.4.20 have introduced ABI changes to fw_stats
each. This caused fw_stats to output wrong data.
Define new structures and use them to parse the
statistics correctly.
Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/ath/ath10k/wmi.c | 162 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/wmi.h | 52 |
2 files changed, 212 insertions, 2 deletions
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index ce095dac5b44..fb1e2d1f343c 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c | |||
@@ -1871,6 +1871,164 @@ static int ath10k_wmi_10x_op_pull_fw_stats(struct ath10k *ar, | |||
1871 | return 0; | 1871 | return 0; |
1872 | } | 1872 | } |
1873 | 1873 | ||
1874 | static int ath10k_wmi_10_2_op_pull_fw_stats(struct ath10k *ar, | ||
1875 | struct sk_buff *skb, | ||
1876 | struct ath10k_fw_stats *stats) | ||
1877 | { | ||
1878 | const struct wmi_10_2_stats_event *ev = (void *)skb->data; | ||
1879 | u32 num_pdev_stats; | ||
1880 | u32 num_pdev_ext_stats; | ||
1881 | u32 num_vdev_stats; | ||
1882 | u32 num_peer_stats; | ||
1883 | int i; | ||
1884 | |||
1885 | if (!skb_pull(skb, sizeof(*ev))) | ||
1886 | return -EPROTO; | ||
1887 | |||
1888 | num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats); | ||
1889 | num_pdev_ext_stats = __le32_to_cpu(ev->num_pdev_ext_stats); | ||
1890 | num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats); | ||
1891 | num_peer_stats = __le32_to_cpu(ev->num_peer_stats); | ||
1892 | |||
1893 | for (i = 0; i < num_pdev_stats; i++) { | ||
1894 | const struct wmi_10_2_pdev_stats *src; | ||
1895 | struct ath10k_fw_stats_pdev *dst; | ||
1896 | |||
1897 | src = (void *)skb->data; | ||
1898 | if (!skb_pull(skb, sizeof(*src))) | ||
1899 | return -EPROTO; | ||
1900 | |||
1901 | dst = kzalloc(sizeof(*dst), GFP_ATOMIC); | ||
1902 | if (!dst) | ||
1903 | continue; | ||
1904 | |||
1905 | ath10k_wmi_pull_pdev_stats_base(&src->base, dst); | ||
1906 | ath10k_wmi_pull_pdev_stats_tx(&src->tx, dst); | ||
1907 | ath10k_wmi_pull_pdev_stats_rx(&src->rx, dst); | ||
1908 | ath10k_wmi_pull_pdev_stats_extra(&src->extra, dst); | ||
1909 | /* FIXME: expose 10.2 specific values */ | ||
1910 | |||
1911 | list_add_tail(&dst->list, &stats->pdevs); | ||
1912 | } | ||
1913 | |||
1914 | for (i = 0; i < num_pdev_ext_stats; i++) { | ||
1915 | const struct wmi_10_2_pdev_ext_stats *src; | ||
1916 | |||
1917 | src = (void *)skb->data; | ||
1918 | if (!skb_pull(skb, sizeof(*src))) | ||
1919 | return -EPROTO; | ||
1920 | |||
1921 | /* FIXME: expose values to userspace | ||
1922 | * | ||
1923 | * Note: Even though this loop seems to do nothing it is | ||
1924 | * required to parse following sub-structures properly. | ||
1925 | */ | ||
1926 | } | ||
1927 | |||
1928 | /* fw doesn't implement vdev stats */ | ||
1929 | |||
1930 | for (i = 0; i < num_peer_stats; i++) { | ||
1931 | const struct wmi_10_2_peer_stats *src; | ||
1932 | struct ath10k_fw_stats_peer *dst; | ||
1933 | |||
1934 | src = (void *)skb->data; | ||
1935 | if (!skb_pull(skb, sizeof(*src))) | ||
1936 | return -EPROTO; | ||
1937 | |||
1938 | dst = kzalloc(sizeof(*dst), GFP_ATOMIC); | ||
1939 | if (!dst) | ||
1940 | continue; | ||
1941 | |||
1942 | ath10k_wmi_pull_peer_stats(&src->old, dst); | ||
1943 | |||
1944 | dst->peer_rx_rate = __le32_to_cpu(src->peer_rx_rate); | ||
1945 | /* FIXME: expose 10.2 specific values */ | ||
1946 | |||
1947 | list_add_tail(&dst->list, &stats->peers); | ||
1948 | } | ||
1949 | |||
1950 | return 0; | ||
1951 | } | ||
1952 | |||
1953 | static int ath10k_wmi_10_2_4_op_pull_fw_stats(struct ath10k *ar, | ||
1954 | struct sk_buff *skb, | ||
1955 | struct ath10k_fw_stats *stats) | ||
1956 | { | ||
1957 | const struct wmi_10_2_stats_event *ev = (void *)skb->data; | ||
1958 | u32 num_pdev_stats; | ||
1959 | u32 num_pdev_ext_stats; | ||
1960 | u32 num_vdev_stats; | ||
1961 | u32 num_peer_stats; | ||
1962 | int i; | ||
1963 | |||
1964 | if (!skb_pull(skb, sizeof(*ev))) | ||
1965 | return -EPROTO; | ||
1966 | |||
1967 | num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats); | ||
1968 | num_pdev_ext_stats = __le32_to_cpu(ev->num_pdev_ext_stats); | ||
1969 | num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats); | ||
1970 | num_peer_stats = __le32_to_cpu(ev->num_peer_stats); | ||
1971 | |||
1972 | for (i = 0; i < num_pdev_stats; i++) { | ||
1973 | const struct wmi_10_2_pdev_stats *src; | ||
1974 | struct ath10k_fw_stats_pdev *dst; | ||
1975 | |||
1976 | src = (void *)skb->data; | ||
1977 | if (!skb_pull(skb, sizeof(*src))) | ||
1978 | return -EPROTO; | ||
1979 | |||
1980 | dst = kzalloc(sizeof(*dst), GFP_ATOMIC); | ||
1981 | if (!dst) | ||
1982 | continue; | ||
1983 | |||
1984 | ath10k_wmi_pull_pdev_stats_base(&src->base, dst); | ||
1985 | ath10k_wmi_pull_pdev_stats_tx(&src->tx, dst); | ||
1986 | ath10k_wmi_pull_pdev_stats_rx(&src->rx, dst); | ||
1987 | ath10k_wmi_pull_pdev_stats_extra(&src->extra, dst); | ||
1988 | /* FIXME: expose 10.2 specific values */ | ||
1989 | |||
1990 | list_add_tail(&dst->list, &stats->pdevs); | ||
1991 | } | ||
1992 | |||
1993 | for (i = 0; i < num_pdev_ext_stats; i++) { | ||
1994 | const struct wmi_10_2_pdev_ext_stats *src; | ||
1995 | |||
1996 | src = (void *)skb->data; | ||
1997 | if (!skb_pull(skb, sizeof(*src))) | ||
1998 | return -EPROTO; | ||
1999 | |||
2000 | /* FIXME: expose values to userspace | ||
2001 | * | ||
2002 | * Note: Even though this loop seems to do nothing it is | ||
2003 | * required to parse following sub-structures properly. | ||
2004 | */ | ||
2005 | } | ||
2006 | |||
2007 | /* fw doesn't implement vdev stats */ | ||
2008 | |||
2009 | for (i = 0; i < num_peer_stats; i++) { | ||
2010 | const struct wmi_10_2_4_peer_stats *src; | ||
2011 | struct ath10k_fw_stats_peer *dst; | ||
2012 | |||
2013 | src = (void *)skb->data; | ||
2014 | if (!skb_pull(skb, sizeof(*src))) | ||
2015 | return -EPROTO; | ||
2016 | |||
2017 | dst = kzalloc(sizeof(*dst), GFP_ATOMIC); | ||
2018 | if (!dst) | ||
2019 | continue; | ||
2020 | |||
2021 | ath10k_wmi_pull_peer_stats(&src->common.old, dst); | ||
2022 | |||
2023 | dst->peer_rx_rate = __le32_to_cpu(src->common.peer_rx_rate); | ||
2024 | /* FIXME: expose 10.2 specific values */ | ||
2025 | |||
2026 | list_add_tail(&dst->list, &stats->peers); | ||
2027 | } | ||
2028 | |||
2029 | return 0; | ||
2030 | } | ||
2031 | |||
1874 | void ath10k_wmi_event_update_stats(struct ath10k *ar, struct sk_buff *skb) | 2032 | void ath10k_wmi_event_update_stats(struct ath10k *ar, struct sk_buff *skb) |
1875 | { | 2033 | { |
1876 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_UPDATE_STATS_EVENTID\n"); | 2034 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_UPDATE_STATS_EVENTID\n"); |
@@ -5121,6 +5279,7 @@ static const struct wmi_ops wmi_10_1_ops = { | |||
5121 | 5279 | ||
5122 | static const struct wmi_ops wmi_10_2_ops = { | 5280 | static const struct wmi_ops wmi_10_2_ops = { |
5123 | .rx = ath10k_wmi_10_2_op_rx, | 5281 | .rx = ath10k_wmi_10_2_op_rx, |
5282 | .pull_fw_stats = ath10k_wmi_10_2_op_pull_fw_stats, | ||
5124 | .gen_init = ath10k_wmi_10_2_op_gen_init, | 5283 | .gen_init = ath10k_wmi_10_2_op_gen_init, |
5125 | .gen_peer_assoc = ath10k_wmi_10_2_op_gen_peer_assoc, | 5284 | .gen_peer_assoc = ath10k_wmi_10_2_op_gen_peer_assoc, |
5126 | /* .gen_pdev_get_temperature not implemented */ | 5285 | /* .gen_pdev_get_temperature not implemented */ |
@@ -5128,7 +5287,6 @@ static const struct wmi_ops wmi_10_2_ops = { | |||
5128 | /* shared with 10.1 */ | 5287 | /* shared with 10.1 */ |
5129 | .map_svc = wmi_10x_svc_map, | 5288 | .map_svc = wmi_10x_svc_map, |
5130 | .pull_svc_rdy = ath10k_wmi_10x_op_pull_svc_rdy_ev, | 5289 | .pull_svc_rdy = ath10k_wmi_10x_op_pull_svc_rdy_ev, |
5131 | .pull_fw_stats = ath10k_wmi_10x_op_pull_fw_stats, | ||
5132 | .gen_pdev_set_rd = ath10k_wmi_10x_op_gen_pdev_set_rd, | 5290 | .gen_pdev_set_rd = ath10k_wmi_10x_op_gen_pdev_set_rd, |
5133 | .gen_start_scan = ath10k_wmi_10x_op_gen_start_scan, | 5291 | .gen_start_scan = ath10k_wmi_10x_op_gen_start_scan, |
5134 | 5292 | ||
@@ -5180,6 +5338,7 @@ static const struct wmi_ops wmi_10_2_ops = { | |||
5180 | 5338 | ||
5181 | static const struct wmi_ops wmi_10_2_4_ops = { | 5339 | static const struct wmi_ops wmi_10_2_4_ops = { |
5182 | .rx = ath10k_wmi_10_2_op_rx, | 5340 | .rx = ath10k_wmi_10_2_op_rx, |
5341 | .pull_fw_stats = ath10k_wmi_10_2_4_op_pull_fw_stats, | ||
5183 | .gen_init = ath10k_wmi_10_2_op_gen_init, | 5342 | .gen_init = ath10k_wmi_10_2_op_gen_init, |
5184 | .gen_peer_assoc = ath10k_wmi_10_2_op_gen_peer_assoc, | 5343 | .gen_peer_assoc = ath10k_wmi_10_2_op_gen_peer_assoc, |
5185 | .gen_pdev_get_temperature = ath10k_wmi_10_2_op_gen_pdev_get_temperature, | 5344 | .gen_pdev_get_temperature = ath10k_wmi_10_2_op_gen_pdev_get_temperature, |
@@ -5187,7 +5346,6 @@ static const struct wmi_ops wmi_10_2_4_ops = { | |||
5187 | /* shared with 10.1 */ | 5346 | /* shared with 10.1 */ |
5188 | .map_svc = wmi_10x_svc_map, | 5347 | .map_svc = wmi_10x_svc_map, |
5189 | .pull_svc_rdy = ath10k_wmi_10x_op_pull_svc_rdy_ev, | 5348 | .pull_svc_rdy = ath10k_wmi_10x_op_pull_svc_rdy_ev, |
5190 | .pull_fw_stats = ath10k_wmi_10x_op_pull_fw_stats, | ||
5191 | .gen_pdev_set_rd = ath10k_wmi_10x_op_gen_pdev_set_rd, | 5349 | .gen_pdev_set_rd = ath10k_wmi_10x_op_gen_pdev_set_rd, |
5192 | .gen_start_scan = ath10k_wmi_10x_op_gen_start_scan, | 5350 | .gen_start_scan = ath10k_wmi_10x_op_gen_start_scan, |
5193 | 5351 | ||
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index 109ed623b82f..0514b1a525ff 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h | |||
@@ -3121,6 +3121,16 @@ struct wmi_stats_event { | |||
3121 | u8 data[0]; | 3121 | u8 data[0]; |
3122 | } __packed; | 3122 | } __packed; |
3123 | 3123 | ||
3124 | struct wmi_10_2_stats_event { | ||
3125 | __le32 stats_id; /* %WMI_REQUEST_ */ | ||
3126 | __le32 num_pdev_stats; | ||
3127 | __le32 num_pdev_ext_stats; | ||
3128 | __le32 num_vdev_stats; | ||
3129 | __le32 num_peer_stats; | ||
3130 | __le32 num_bcnflt_stats; | ||
3131 | u8 data[0]; | ||
3132 | } __packed; | ||
3133 | |||
3124 | /* | 3134 | /* |
3125 | * PDEV statistics | 3135 | * PDEV statistics |
3126 | * TODO: add all PDEV stats here | 3136 | * TODO: add all PDEV stats here |
@@ -3159,6 +3169,22 @@ struct wmi_10x_pdev_stats { | |||
3159 | struct wmi_pdev_stats_extra extra; | 3169 | struct wmi_pdev_stats_extra extra; |
3160 | } __packed; | 3170 | } __packed; |
3161 | 3171 | ||
3172 | struct wmi_pdev_stats_mem { | ||
3173 | __le32 dram_free; | ||
3174 | __le32 iram_free; | ||
3175 | } __packed; | ||
3176 | |||
3177 | struct wmi_10_2_pdev_stats { | ||
3178 | struct wmi_pdev_stats_base base; | ||
3179 | struct wmi_pdev_stats_tx tx; | ||
3180 | __le32 mc_drop; | ||
3181 | struct wmi_pdev_stats_rx rx; | ||
3182 | __le32 pdev_rx_timeout; | ||
3183 | struct wmi_pdev_stats_mem mem; | ||
3184 | struct wmi_pdev_stats_peer peer; | ||
3185 | struct wmi_pdev_stats_extra extra; | ||
3186 | } __packed; | ||
3187 | |||
3162 | /* | 3188 | /* |
3163 | * VDEV statistics | 3189 | * VDEV statistics |
3164 | * TODO: add all VDEV stats here | 3190 | * TODO: add all VDEV stats here |
@@ -3182,6 +3208,32 @@ struct wmi_10x_peer_stats { | |||
3182 | __le32 peer_rx_rate; | 3208 | __le32 peer_rx_rate; |
3183 | } __packed; | 3209 | } __packed; |
3184 | 3210 | ||
3211 | struct wmi_10_2_peer_stats { | ||
3212 | struct wmi_peer_stats old; | ||
3213 | __le32 peer_rx_rate; | ||
3214 | __le32 current_per; | ||
3215 | __le32 retries; | ||
3216 | __le32 tx_rate_count; | ||
3217 | __le32 max_4ms_frame_len; | ||
3218 | __le32 total_sub_frames; | ||
3219 | __le32 tx_bytes; | ||
3220 | __le32 num_pkt_loss_overflow[4]; | ||
3221 | __le32 num_pkt_loss_excess_retry[4]; | ||
3222 | } __packed; | ||
3223 | |||
3224 | struct wmi_10_2_4_peer_stats { | ||
3225 | struct wmi_10_2_peer_stats common; | ||
3226 | __le32 unknown_value; /* FIXME: what is this word? */ | ||
3227 | } __packed; | ||
3228 | |||
3229 | struct wmi_10_2_pdev_ext_stats { | ||
3230 | __le32 rx_rssi_comb; | ||
3231 | __le32 rx_rssi[4]; | ||
3232 | __le32 rx_mcs[10]; | ||
3233 | __le32 tx_mcs[10]; | ||
3234 | __le32 ack_rssi; | ||
3235 | } __packed; | ||
3236 | |||
3185 | struct wmi_vdev_create_cmd { | 3237 | struct wmi_vdev_create_cmd { |
3186 | __le32 vdev_id; | 3238 | __le32 vdev_id; |
3187 | __le32 vdev_type; | 3239 | __le32 vdev_type; |