[PATCH v3 4/4] wifi: ath12k: Support Transmit PER Rate Stats
Jeff Johnson
quic_jjohnson at quicinc.com
Tue Nov 5 15:03:30 PST 2024
On 11/4/2024 8:54 PM, Roopni Devanathan wrote:
> From: Dinesh Karthikeyan <quic_dinek at quicinc.com>
>
> Add support to request per rate stats through HTT stats type
> 40. These stats give information about rates of PPDUs and
> MPDUs for single user and for OFDMA and MUMIMO technologies
> corresponding to multiple users.
>
> Sample output:
> -------------
> echo 40 > /sys/kernel/debug/ath12k/pci-0000\:06\:00.0/mac0/htt_stats_type
> cat /sys/kernel/debug/ath12k/pci-0000\:06\:00.0/mac0/htt_stats
> HTT_TX_PER_STATS:
>
> PER_STATS_SU:
>
> PER per BW:
> ppdus_tried_su = 0:0 1:0 2:0 3:0 4:0
> ppdus_ack_failed_su = 0:0 1:0 2:0 3:0 4:0
> mpdus_tried_su = 0:0 1:0 2:0 3:0 4:0
> mpdus_failed_su = 0:0 1:0 2:0 3:0 4:0
>
> PER per NSS:
> ppdus_tried_su = 0:0 1:0 2:0 3:0 4:0 5:0 6:0 7:0
> ppdus_ack_failed_su = 0:0 1:0 2:0 3:0 4:0 5:0 6:0 7:0
> mpdus_tried_su = 0:0 1:0 2:0 3:0 4:0 5:0 6:0 7:0
> mpdus_failed_su = 0:0 1:0 2:0 3:0 4:0 5:0 6:0 7:0
>
> PER per MCS:
> ppdus_tried_su = 0:0 1:0 2:0 3:0 4:0 5:0 6:0 7:0 8:0 9:0 10:0 11:0 12:0 13:0
> ppdus_ack_failed_su = 0:0 1:0 2:0 3:0 4:0 5:0 6:0 7:0 8:0 9:0 10:0 11:0 12:0 13:0
> mpdus_tried_su = 0:0 1:0 2:0 3:0 4:0 5:0 6:0 7:0 8:0 9:0 10:0 11:0 12:0 13:0
> mpdus_failed_su = 0:0 1:0 2:0 3:0 4:0 5:0 6:0 7:0 8:0 9:0 10:0 11:0 12:0 13:0
> .....
>
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4
>
> Signed-off-by: Dinesh Karthikeyan <quic_dinek at quicinc.com>
> Signed-off-by: Roopni Devanathan <quic_rdevanat at quicinc.com>
> ---
> .../wireless/ath/ath12k/debugfs_htt_stats.c | 269 +++++++++++++++++-
> .../wireless/ath/ath12k/debugfs_htt_stats.h | 68 ++++-
> 2 files changed, 334 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.c b/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.c
> index 8f89ba2db8c7..e185d4971e79 100644
> --- a/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.c
> +++ b/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.c
> @@ -48,6 +48,28 @@ print_array_to_buf(u8 *buf, u32 offset, const char *header,
> footer);
> }
>
> +static const char *ath12k_htt_ax_tx_rx_ru_size_to_str(u8 ru_size)
> +{
> + switch (ru_size) {
> + case ATH12K_HTT_TX_RX_PDEV_STATS_AX_RU_SIZE_26:
> + return "26";
> + case ATH12K_HTT_TX_RX_PDEV_STATS_AX_RU_SIZE_52:
> + return "52";
> + case ATH12K_HTT_TX_RX_PDEV_STATS_AX_RU_SIZE_106:
> + return "106";
> + case ATH12K_HTT_TX_RX_PDEV_STATS_AX_RU_SIZE_242:
> + return "242";
> + case ATH12K_HTT_TX_RX_PDEV_STATS_AX_RU_SIZE_484:
> + return "484";
> + case ATH12K_HTT_TX_RX_PDEV_STATS_AX_RU_SIZE_996:
> + return "996";
> + case ATH12K_HTT_TX_RX_PDEV_STATS_AX_RU_SIZE_996x2:
> + return "996x2";
> + default:
> + return "unknown";
> + }
> +}
> +
> static const char *ath12k_htt_be_tx_rx_ru_size_to_str(u8 ru_size)
> {
> switch (ru_size) {
> @@ -88,6 +110,17 @@ static const char *ath12k_htt_be_tx_rx_ru_size_to_str(u8 ru_size)
> }
> }
>
> +static const char*
> +ath12k_tx_ru_size_to_str(enum ath12k_htt_stats_ru_type ru_type, u8 ru_size)
> +{
> + if (ru_type == ATH12K_HTT_STATS_RU_TYPE_SINGLE_RU_ONLY)
> + return ath12k_htt_ax_tx_rx_ru_size_to_str(ru_size);
> + else if (ru_type == ATH12K_HTT_STATS_RU_TYPE_SINGLE_AND_MULTI_RU)
> + return ath12k_htt_be_tx_rx_ru_size_to_str(ru_size);
> + else
> + return "unknown";
> +}
> +
> static void
> htt_print_tx_pdev_stats_cmn_tlv(const void *tag_buf, u16 tag_len,
> struct debug_htt_stats_req *stats_req)
> @@ -2879,6 +2912,237 @@ ath12k_htt_print_soc_txrx_stats_common_tlv(const void *tag_buf, u16 tag_len,
> stats_req->buf_len = len;
> }
>
> +static void
> +ath12k_htt_print_tx_per_rate_stats_tlv(const void *tag_buf, u16 tag_len,
> + struct debug_htt_stats_req *stats_req)
> +{
> + const struct ath12k_htt_tx_per_rate_stats_tlv *stats_buf = tag_buf;
> + u8 *buf = stats_req->buf;
> + u32 len = stats_req->buf_len;
> + u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
> + const char *mode_prefix;
> + int i;
> + u32 ru_size_cnt = 0;
> + u32 rc_mode;
> + u32 ru_type;
> +
> + if (tag_len < sizeof(*stats_buf))
> + return;
> +
> + rc_mode = le32_to_cpu(stats_buf->rc_mode);
> + ru_type = le32_to_cpu(stats_buf->ru_type);
> +
> + switch (rc_mode) {
> + case ATH12K_HTT_STATS_RC_MODE_DLSU:
> + len += scnprintf(buf + len, buf_len - len, "HTT_TX_PER_STATS:\n");
> + len += scnprintf(buf + len, buf_len - len, "\nPER_STATS_SU:\n");
> + mode_prefix = "su";
> + break;
> + case ATH12K_HTT_STATS_RC_MODE_DLMUMIMO:
> + len += scnprintf(buf + len, buf_len - len, "\nPER_STATS_DL_MUMIMO:\n");
> + mode_prefix = "mu";
> + break;
> + case ATH12K_HTT_STATS_RC_MODE_DLOFDMA:
> + len += scnprintf(buf + len, buf_len - len, "\nPER_STATS_DL_OFDMA:\n");
> + mode_prefix = "ofdma";
> + if (ru_type == ATH12K_HTT_STATS_RU_TYPE_SINGLE_RU_ONLY)
> + ru_size_cnt = ATH12K_HTT_TX_RX_PDEV_STATS_NUM_AX_RU_SIZE_CNTRS;
> + else if (ru_type == ATH12K_HTT_STATS_RU_TYPE_SINGLE_AND_MULTI_RU)
> + ru_size_cnt = ATH12K_HTT_TX_RX_PDEV_NUM_BE_RU_SIZE_CNTRS;
> + break;
> + case ATH12K_HTT_STATS_RC_MODE_ULMUMIMO:
> + len += scnprintf(buf + len, buf_len - len, "HTT_RX_PER_STATS:\n");
> + len += scnprintf(buf + len, buf_len - len, "\nPER_STATS_UL_MUMIMO:\n");
> + mode_prefix = "ulmu";
> + break;
> + case ATH12K_HTT_STATS_RC_MODE_ULOFDMA:
> + len += scnprintf(buf + len, buf_len - len, "\nPER_STATS_UL_OFDMA:\n");
> + mode_prefix = "ulofdma";
> + if (ru_type == ATH12K_HTT_STATS_RU_TYPE_SINGLE_RU_ONLY)
> + ru_size_cnt = ATH12K_HTT_TX_RX_PDEV_STATS_NUM_AX_RU_SIZE_CNTRS;
> + else if (ru_type == ATH12K_HTT_STATS_RU_TYPE_SINGLE_AND_MULTI_RU)
> + ru_size_cnt = ATH12K_HTT_TX_RX_PDEV_NUM_BE_RU_SIZE_CNTRS;
> + break;
> + default:
> + return;
> + }
> +
> + len += scnprintf(buf + len, buf_len - len, "\nPER per BW:\n");
> + if (rc_mode == ATH12K_HTT_STATS_RC_MODE_ULOFDMA ||
> + rc_mode == ATH12K_HTT_STATS_RC_MODE_ULMUMIMO)
> + len += scnprintf(buf + len, buf_len - len, "data_ppdus_%s = ",
> + mode_prefix);
> + else
> + len += scnprintf(buf + len, buf_len - len, "ppdus_tried_%s = ",
> + mode_prefix);
> + for (i = 0; i < ATH12K_HTT_TX_PDEV_STATS_NUM_BW_CNTRS; i++)
> + len += scnprintf(buf + len, buf_len - len, " %u:%u ", i,
> + le32_to_cpu(stats_buf->per_bw[i].ppdus_tried));
> + len += scnprintf(buf + len, buf_len - len, " %u:%u\n", i,
> + le32_to_cpu(stats_buf->per_bw320.ppdus_tried));
> +
> + if (rc_mode == ATH12K_HTT_STATS_RC_MODE_ULOFDMA ||
> + rc_mode == ATH12K_HTT_STATS_RC_MODE_ULMUMIMO)
> + len += scnprintf(buf + len, buf_len - len, "non_data_ppdus_%s = ",
> + mode_prefix);
> + else
> + len += scnprintf(buf + len, buf_len - len, "ppdus_ack_failed_%s = ",
> + mode_prefix);
> + for (i = 0; i < ATH12K_HTT_TX_PDEV_STATS_NUM_BW_CNTRS; i++)
> + len += scnprintf(buf + len, buf_len - len, " %u:%u ", i,
> + le32_to_cpu(stats_buf->per_bw[i].ppdus_ack_failed));
> + len += scnprintf(buf + len, buf_len - len, " %u:%u\n", i,
> + le32_to_cpu(stats_buf->per_bw320.ppdus_ack_failed));
> +
> + len += scnprintf(buf + len, buf_len - len, "mpdus_tried_%s = ", mode_prefix);
> + for (i = 0; i < ATH12K_HTT_TX_PDEV_STATS_NUM_BW_CNTRS; i++)
> + len += scnprintf(buf + len, buf_len - len, " %u:%u ", i,
> + le32_to_cpu(stats_buf->per_bw[i].mpdus_tried));
> + len += scnprintf(buf + len, buf_len - len, " %u:%u\n", i,
> + le32_to_cpu(stats_buf->per_bw320.mpdus_tried));
> +
> + len += scnprintf(buf + len, buf_len - len, "mpdus_failed_%s = ", mode_prefix);
> + for (i = 0; i < ATH12K_HTT_TX_PDEV_STATS_NUM_BW_CNTRS; i++)
> + len += scnprintf(buf + len, buf_len - len, " %u:%u", i,
> + le32_to_cpu(stats_buf->per_bw[i].mpdus_failed));
> + len += scnprintf(buf + len, buf_len - len, " %u:%u\n", i,
> + le32_to_cpu(stats_buf->per_bw320.mpdus_failed));
> +
> + len += scnprintf(buf + len, buf_len - len, "\nPER per NSS:\n");
> + if (rc_mode == ATH12K_HTT_STATS_RC_MODE_ULOFDMA ||
> + rc_mode == ATH12K_HTT_STATS_RC_MODE_ULMUMIMO)
> + len += scnprintf(buf + len, buf_len - len, "data_ppdus_%s = ",
> + mode_prefix);
> + else
> + len += scnprintf(buf + len, buf_len - len, "ppdus_tried_%s = ",
> + mode_prefix);
> + for (i = 0; i < ATH12K_HTT_PDEV_STAT_NUM_SPATIAL_STREAMS; i++)
> + len += scnprintf(buf + len, buf_len - len, " %u:%u ", i,
should this use i + 1 since index 0 is for NSS 1?
are there other counters that could use a similar change?
> + le32_to_cpu(stats_buf->per_nss[i].ppdus_tried));
> + len += scnprintf(buf + len, buf_len - len, "\n");
> +
> + if (rc_mode == ATH12K_HTT_STATS_RC_MODE_ULOFDMA ||
> + rc_mode == ATH12K_HTT_STATS_RC_MODE_ULMUMIMO)
> + len += scnprintf(buf + len, buf_len - len, "non_data_ppdus_%s = ",
> + mode_prefix);
> + else
> + len += scnprintf(buf + len, buf_len - len, "ppdus_ack_failed_%s = ",
> + mode_prefix);
> + for (i = 0; i < ATH12K_HTT_PDEV_STAT_NUM_SPATIAL_STREAMS; i++)
> + len += scnprintf(buf + len, buf_len - len, " %u:%u ", i,
here too?
> + le32_to_cpu(stats_buf->per_nss[i].ppdus_ack_failed));
> + len += scnprintf(buf + len, buf_len - len, "\n");
> +
> + len += scnprintf(buf + len, buf_len - len, "mpdus_tried_%s = ", mode_prefix);
> + for (i = 0; i < ATH12K_HTT_PDEV_STAT_NUM_SPATIAL_STREAMS; i++)
> + len += scnprintf(buf + len, buf_len - len, " %u:%u ", i,
here too?
> + le32_to_cpu(stats_buf->per_nss[i].mpdus_tried));
> + len += scnprintf(buf + len, buf_len - len, "\n");
> +
> + len += scnprintf(buf + len, buf_len - len, "mpdus_failed_%s = ", mode_prefix);
> + for (i = 0; i < ATH12K_HTT_PDEV_STAT_NUM_SPATIAL_STREAMS; i++)
> + len += scnprintf(buf + len, buf_len - len, " %u:%u ", i,
here too?
> + le32_to_cpu(stats_buf->per_nss[i].mpdus_failed));
> + len += scnprintf(buf + len, buf_len - len, "\n");
> +
More information about the ath12k
mailing list