ath10k: fix vdev stats for 10.4 firmware

Currently vdev stats displayed in fw_stats are applicable
only for TLV based firmware and fix it for 10.4 firmware
as of now. The vdev stats in 10.4 firmware is split into two
parts (vdev_stats, vdev_stats_extended). The actual stats
are captured only in extended vdev stats. In order to enable
vdev stats, appropriate feature bit will be set on extended
resource config. As FTM related counters are available only on
newer 10.4 based firmware, these counters will be displayed
only on valid data.

Signed-off-by: Rajkumar Manoharan <rmanohar@codeaurora.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Цей коміт міститься в:
Rajkumar Manoharan
2018-03-28 12:40:24 +03:00
зафіксовано Kalle Valo
джерело 91493e8e10
коміт 1b3fdb50f8
4 змінених файлів з 184 додано та 21 видалено

Переглянути файл

@@ -2708,6 +2708,28 @@ ath10k_wmi_10_4_pull_peer_stats(const struct wmi_10_4_peer_stats *src,
dst->peer_rx_rate = __le32_to_cpu(src->peer_rx_rate);
}
static void
ath10k_wmi_10_4_pull_vdev_stats(const struct wmi_vdev_stats_extd *src,
struct ath10k_fw_stats_vdev_extd *dst)
{
dst->vdev_id = __le32_to_cpu(src->vdev_id);
dst->ppdu_aggr_cnt = __le32_to_cpu(src->ppdu_aggr_cnt);
dst->ppdu_noack = __le32_to_cpu(src->ppdu_noack);
dst->mpdu_queued = __le32_to_cpu(src->mpdu_queued);
dst->ppdu_nonaggr_cnt = __le32_to_cpu(src->ppdu_nonaggr_cnt);
dst->mpdu_sw_requeued = __le32_to_cpu(src->mpdu_sw_requeued);
dst->mpdu_suc_retry = __le32_to_cpu(src->mpdu_suc_retry);
dst->mpdu_suc_multitry = __le32_to_cpu(src->mpdu_suc_multitry);
dst->mpdu_fail_retry = __le32_to_cpu(src->mpdu_fail_retry);
dst->tx_ftm_suc = __le32_to_cpu(src->tx_ftm_suc);
dst->tx_ftm_suc_retry = __le32_to_cpu(src->tx_ftm_suc_retry);
dst->tx_ftm_fail = __le32_to_cpu(src->tx_ftm_fail);
dst->rx_ftmr_cnt = __le32_to_cpu(src->rx_ftmr_cnt);
dst->rx_ftmr_dup_cnt = __le32_to_cpu(src->rx_ftmr_dup_cnt);
dst->rx_iftmr_cnt = __le32_to_cpu(src->rx_iftmr_cnt);
dst->rx_iftmr_dup_cnt = __le32_to_cpu(src->rx_iftmr_dup_cnt);
}
static int ath10k_wmi_main_op_pull_fw_stats(struct ath10k *ar,
struct sk_buff *skb,
struct ath10k_fw_stats *stats)
@@ -3047,7 +3069,16 @@ static int ath10k_wmi_10_4_op_pull_fw_stats(struct ath10k *ar,
*/
}
/* fw doesn't implement vdev stats */
for (i = 0; i < num_vdev_stats; i++) {
const struct wmi_vdev_stats *src;
/* Ignore vdev stats here as it has only vdev id. Actual vdev
* stats will be retrieved from vdev extended stats.
*/
src = (void *)skb->data;
if (!skb_pull(skb, sizeof(*src)))
return -EPROTO;
}
for (i = 0; i < num_peer_stats; i++) {
const struct wmi_10_4_peer_stats *src;
@@ -3079,26 +3110,43 @@ static int ath10k_wmi_10_4_op_pull_fw_stats(struct ath10k *ar,
*/
}
if ((stats_id & WMI_10_4_STAT_PEER_EXTD) == 0)
return 0;
if (stats_id & WMI_10_4_STAT_PEER_EXTD) {
stats->extended = true;
stats->extended = true;
for (i = 0; i < num_peer_stats; i++) {
const struct wmi_10_4_peer_extd_stats *src;
struct ath10k_fw_extd_stats_peer *dst;
for (i = 0; i < num_peer_stats; i++) {
const struct wmi_10_4_peer_extd_stats *src;
struct ath10k_fw_extd_stats_peer *dst;
src = (void *)skb->data;
if (!skb_pull(skb, sizeof(*src)))
return -EPROTO;
src = (void *)skb->data;
if (!skb_pull(skb, sizeof(*src)))
return -EPROTO;
dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
if (!dst)
continue;
dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
if (!dst)
continue;
ether_addr_copy(dst->peer_macaddr,
src->peer_macaddr.addr);
dst->rx_duration = __le32_to_cpu(src->rx_duration);
list_add_tail(&dst->list, &stats->peers_extd);
}
}
ether_addr_copy(dst->peer_macaddr, src->peer_macaddr.addr);
dst->rx_duration = __le32_to_cpu(src->rx_duration);
list_add_tail(&dst->list, &stats->peers_extd);
if (stats_id & WMI_10_4_STAT_VDEV_EXTD) {
for (i = 0; i < num_vdev_stats; i++) {
const struct wmi_vdev_stats_extd *src;
struct ath10k_fw_stats_vdev_extd *dst;
src = (void *)skb->data;
if (!skb_pull(skb, sizeof(*src)))
return -EPROTO;
dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
if (!dst)
continue;
ath10k_wmi_10_4_pull_vdev_stats(src, dst);
list_add_tail(&dst->list, &stats->vdevs);
}
}
return 0;
@@ -8004,6 +8052,72 @@ ath10k_wmi_op_gen_pdev_enable_adaptive_cca(struct ath10k *ar, u8 enable,
return skb;
}
static void
ath10k_wmi_fw_vdev_stats_extd_fill(const struct ath10k_fw_stats_vdev_extd *vdev,
char *buf, u32 *length)
{
u32 len = *length;
u32 buf_len = ATH10K_FW_STATS_BUF_SIZE;
u32 val;
len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
"vdev id", vdev->vdev_id);
len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
"ppdu aggr count", vdev->ppdu_aggr_cnt);
len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
"ppdu noack", vdev->ppdu_noack);
len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
"mpdu queued", vdev->mpdu_queued);
len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
"ppdu nonaggr count", vdev->ppdu_nonaggr_cnt);
len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
"mpdu sw requeued", vdev->mpdu_sw_requeued);
len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
"mpdu success retry", vdev->mpdu_suc_retry);
len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
"mpdu success multitry", vdev->mpdu_suc_multitry);
len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
"mpdu fail retry", vdev->mpdu_fail_retry);
val = vdev->tx_ftm_suc;
if (val & WMI_VDEV_STATS_FTM_COUNT_VALID)
len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
"tx ftm success",
MS(val, WMI_VDEV_STATS_FTM_COUNT));
val = vdev->tx_ftm_suc_retry;
if (val & WMI_VDEV_STATS_FTM_COUNT_VALID)
len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
"tx ftm success retry",
MS(val, WMI_VDEV_STATS_FTM_COUNT));
val = vdev->tx_ftm_fail;
if (val & WMI_VDEV_STATS_FTM_COUNT_VALID)
len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
"tx ftm fail",
MS(val, WMI_VDEV_STATS_FTM_COUNT));
val = vdev->rx_ftmr_cnt;
if (val & WMI_VDEV_STATS_FTM_COUNT_VALID)
len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
"rx ftm request count",
MS(val, WMI_VDEV_STATS_FTM_COUNT));
val = vdev->rx_ftmr_dup_cnt;
if (val & WMI_VDEV_STATS_FTM_COUNT_VALID)
len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
"rx ftm request dup count",
MS(val, WMI_VDEV_STATS_FTM_COUNT));
val = vdev->rx_iftmr_cnt;
if (val & WMI_VDEV_STATS_FTM_COUNT_VALID)
len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
"rx initial ftm req count",
MS(val, WMI_VDEV_STATS_FTM_COUNT));
val = vdev->rx_iftmr_dup_cnt;
if (val & WMI_VDEV_STATS_FTM_COUNT_VALID)
len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
"rx initial ftm req dup cnt",
MS(val, WMI_VDEV_STATS_FTM_COUNT));
len += scnprintf(buf + len, buf_len - len, "\n");
*length = len;
}
void ath10k_wmi_10_4_op_fw_stats_fill(struct ath10k *ar,
struct ath10k_fw_stats *fw_stats,
char *buf)
@@ -8011,7 +8125,7 @@ void ath10k_wmi_10_4_op_fw_stats_fill(struct ath10k *ar,
u32 len = 0;
u32 buf_len = ATH10K_FW_STATS_BUF_SIZE;
const struct ath10k_fw_stats_pdev *pdev;
const struct ath10k_fw_stats_vdev *vdev;
const struct ath10k_fw_stats_vdev_extd *vdev;
const struct ath10k_fw_stats_peer *peer;
size_t num_peers;
size_t num_vdevs;
@@ -8064,9 +8178,8 @@ void ath10k_wmi_10_4_op_fw_stats_fill(struct ath10k *ar,
"ath10k VDEV stats", num_vdevs);
len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
"=================");
list_for_each_entry(vdev, &fw_stats->vdevs, list) {
ath10k_wmi_fw_vdev_stats_fill(vdev, buf, &len);
ath10k_wmi_fw_vdev_stats_extd_fill(vdev, buf, &len);
}
len += scnprintf(buf + len, buf_len - len, "\n");