On 11/4/2024 8:54 PM, Roopni Devanathan wrote: > From: Dinesh Karthikeyan <quic_dinek@xxxxxxxxxxx> > > 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@xxxxxxxxxxx> > Signed-off-by: Roopni Devanathan <quic_rdevanat@xxxxxxxxxxx> > --- > .../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"); > +