From 783e0382230e5ad321e150312b38084b6310411f Mon Sep 17 00:00:00 2001 From: Kai Chen Date: Thu, 25 Jan 2018 16:29:08 -0800 Subject: [PATCH] qcacmn: Add monitor mode ppdu and mpdu stats Add monitor mode status ring ppdu stats and destination ring ppdu/mpdu stats Change-Id: I702172f40ffc0915b630dd3781a697199bdd20fd --- dp/inc/cdp_txrx_cmn_struct.h | 2 + dp/inc/cdp_txrx_mon_struct.h | 32 +++++++++++- dp/wifi3.0/dp_main.c | 33 +++++++++++- dp/wifi3.0/dp_rx_mon.h | 97 +++++++++++++++++++++++++++++++++++ dp/wifi3.0/dp_rx_mon_dest.c | 5 ++ dp/wifi3.0/dp_rx_mon_status.c | 14 +++++ dp/wifi3.0/dp_types.h | 2 + hal/wifi3.0/hal_api_mon.h | 14 +++++ 8 files changed, 196 insertions(+), 3 deletions(-) diff --git a/dp/inc/cdp_txrx_cmn_struct.h b/dp/inc/cdp_txrx_cmn_struct.h index d34920d29c..ec939b938b 100644 --- a/dp/inc/cdp_txrx_cmn_struct.h +++ b/dp/inc/cdp_txrx_cmn_struct.h @@ -184,6 +184,7 @@ enum htt_cmn_dbg_stats_type { * @TXRX_RX_HOST_STATS: Print host Rx stats * @TXRX_CLEAR_STATS: clear all host stats * @TXRX_SRNG_PTR_STATS: Print SRNG pointer stats + * @TXRX_RX_MON_STATS: Print monitor mode stats */ enum cdp_host_txrx_stats { TXRX_HOST_STATS_INVALID = -1, @@ -194,6 +195,7 @@ enum cdp_host_txrx_stats { TXRX_RX_HOST_STATS = 4, TXRX_AST_STATS = 5, TXRX_SRNG_PTR_STATS = 6, + TXRX_RX_MON_STATS = 7, TXRX_HOST_STATS_MAX, }; diff --git a/dp/inc/cdp_txrx_mon_struct.h b/dp/inc/cdp_txrx_mon_struct.h index 9023b67ead..7fbc75886e 100644 --- a/dp/inc/cdp_txrx_mon_struct.h +++ b/dp/inc/cdp_txrx_mon_struct.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -196,4 +196,34 @@ struct cdp_mon_status { }; +enum { + CDP_MON_PPDU_START = 0, + CDP_MON_PPDU_END, +}; + +/** + * struct cdp_pdev_mon_stats + * @status_ppdu_state: state on PPDU start and end + * @status_ppdu_start: status ring PPDU start TLV count + * @status_ppdu_end: status ring PPDU end TLV count + * @status_ppdu_compl: status ring matching start and end count on PPDU + * @status_ppdu_start_mis: status ring missing start TLV count on PPDU + * @status_ppdu_end_mis: status ring missing end TLV count on PPDU + * @status_ppdu_done: status ring PPDU done TLV count + * @dest_ppdu_done: destination ring PPDU count + * @dest_mpdu_done: destination ring MPDU count + */ +struct cdp_pdev_mon_stats { +#ifndef REMOVE_MON_DBG_STATS + uint32_t status_ppdu_state; + uint32_t status_ppdu_start; + uint32_t status_ppdu_end; + uint32_t status_ppdu_compl; + uint32_t status_ppdu_start_mis; + uint32_t status_ppdu_end_mis; +#endif + uint32_t status_ppdu_done; + uint32_t dest_ppdu_done; + uint32_t dest_mpdu_done; +}; #endif diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 41b0f0dad7..9224c9c985 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -284,6 +284,7 @@ const int dp_stats_mapping_table[][STATS_TYPE_MAX] = { {TXRX_FW_STATS_INVALID, TXRX_RX_HOST_STATS}, {TXRX_FW_STATS_INVALID, TXRX_AST_STATS}, {TXRX_FW_STATS_INVALID, TXRX_SRNG_PTR_STATS}, + {TXRX_FW_STATS_INVALID, TXRX_RX_MON_STATS}, }; static int dp_peer_add_ast_wifi3(struct cdp_soc_t *soc_hdl, @@ -5197,6 +5198,31 @@ dp_print_pdev_rx_stats(struct dp_pdev *pdev) } +/** + * dp_print_pdev_rx_mon_stats(): Print Pdev level RX monitor stats + * @pdev: DP_PDEV Handle + * + * Return: void + */ +static inline void +dp_print_pdev_rx_mon_stats(struct dp_pdev *pdev) +{ + struct cdp_pdev_mon_stats *rx_mon_stats; + + rx_mon_stats = &pdev->rx_mon_stats; + + DP_PRINT_STATS("PDEV Rx Monitor Stats:\n"); + + dp_rx_mon_print_dbg_ppdu_stats(rx_mon_stats); + + DP_PRINT_STATS("status_ppdu_done_cnt = %d", + rx_mon_stats->status_ppdu_done); + DP_PRINT_STATS("dest_ppdu_done_cnt = %d", + rx_mon_stats->dest_ppdu_done); + DP_PRINT_STATS("dest_mpdu_done_cnt = %d", + rx_mon_stats->dest_mpdu_done); +} + /** * dp_print_soc_tx_stats(): Print SOC level stats * @soc DP_SOC Handle @@ -5810,8 +5836,11 @@ dp_print_host_stats(struct cdp_vdev *vdev_handle, enum cdp_host_txrx_stats type) dp_print_peer_table(vdev); break; case TXRX_SRNG_PTR_STATS: - dp_print_ring_stats(pdev); - break; + dp_print_ring_stats(pdev); + break; + case TXRX_RX_MON_STATS: + dp_print_pdev_rx_mon_stats(pdev); + break; default: DP_TRACE(FATAL, "Wrong Input For TxRx Host Stats"); break; diff --git a/dp/wifi3.0/dp_rx_mon.h b/dp/wifi3.0/dp_rx_mon.h index 52fb06437d..8269c34450 100644 --- a/dp/wifi3.0/dp_rx_mon.h +++ b/dp/wifi3.0/dp_rx_mon.h @@ -50,4 +50,101 @@ QDF_STATUS dp_rx_mon_deliver(struct dp_soc *soc, uint32_t mac_id, uint32_t dp_rxdma_err_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota); + +#ifndef REMOVE_MON_DBG_STATS +/* + * dp_rx_mon_update_dbg_ppdu_stats() - Update status ring TLV count + * @ppdu_info: HAL RX PPDU info retrieved from status ring TLV + * @rx_mon_stats: monitor mode status/destination ring PPDU and MPDU count + * + * Update status ring PPDU start and end count. Keep track TLV state on + * PPDU start and end to find out if start and end is matching. Keep + * track missing PPDU start and end count. Keep track matching PPDU + * start and end count. + * + * Return: None + */ +static inline void +dp_rx_mon_update_dbg_ppdu_stats(struct hal_rx_ppdu_info *ppdu_info, + struct cdp_pdev_mon_stats *rx_mon_stats) +{ + if (ppdu_info->rx_state == + HAL_RX_MON_PPDU_START) { + rx_mon_stats->status_ppdu_start++; + if (rx_mon_stats->status_ppdu_state + != CDP_MON_PPDU_END) + rx_mon_stats->status_ppdu_end_mis++; + rx_mon_stats->status_ppdu_state + = CDP_MON_PPDU_START; + } else if (ppdu_info->rx_state == + HAL_RX_MON_PPDU_END) { + rx_mon_stats->status_ppdu_end++; + if (rx_mon_stats->status_ppdu_state + != CDP_MON_PPDU_START) + rx_mon_stats->status_ppdu_start_mis++; + else + rx_mon_stats->status_ppdu_compl++; + rx_mon_stats->status_ppdu_state + = CDP_MON_PPDU_END; + } +} + +/* + * dp_rx_mon_init_dbg_ppdu_stats() - initialization for monitor mode stats + * @ppdu_info: HAL RX PPDU info retrieved from status ring TLV + * @rx_mon_stats: monitor mode status/destination ring PPDU and MPDU count + * + * Return: None + */ +static inline void +dp_rx_mon_init_dbg_ppdu_stats(struct hal_rx_ppdu_info *ppdu_info, + struct cdp_pdev_mon_stats *rx_mon_stats) +{ + ppdu_info->rx_state = HAL_RX_MON_PPDU_END; + rx_mon_stats->status_ppdu_state + = CDP_MON_PPDU_END; +} + +/* + * dp_rx_mon_dbg_dbg_ppdu_stats() - Print monitor mode status ring stats + * @ppdu_info: HAL RX PPDU info retrieved from status ring TLV + * @rx_mon_stats: monitor mode status/destination ring PPDU and MPDU count + * + * Print monitor mode PPDU start and end TLV count + * Return: None + */ +static inline void +dp_rx_mon_print_dbg_ppdu_stats(struct cdp_pdev_mon_stats *rx_mon_stats) +{ + DP_PRINT_STATS("status_ppdu_compl_cnt = %d", + rx_mon_stats->status_ppdu_compl); + DP_PRINT_STATS("status_ppdu_start_cnt = %d", + rx_mon_stats->status_ppdu_start); + DP_PRINT_STATS("status_ppdu_end_cnt = %d", + rx_mon_stats->status_ppdu_end); + DP_PRINT_STATS("status_ppdu_start_mis_cnt = %d", + rx_mon_stats->status_ppdu_start_mis); + DP_PRINT_STATS("status_ppdu_end_mis_cnt = %d", + rx_mon_stats->status_ppdu_end_mis); +} + +#else +static inline void +dp_rx_mon_update_dbg_ppdu_stats(struct hal_rx_ppdu_info *ppdu_info, + struct cdp_pdev_mon_stats *rx_mon_stats) +{ +} + +static inline void +dp_rx_mon_init_dbg_ppdu_stats(struct hal_rx_ppdu_info *ppdu_info, + struct cdp_pdev_mon_stats *rx_mon_stats) +{ +} + +static inline void +dp_rx_mon_print_dbg_ppdu_stats(struct hal_rx_ppdu_info *ppdu_info, + struct cdp_pdev_mon_stats *rx_mon_stats) +{ +} +#endif #endif diff --git a/dp/wifi3.0/dp_rx_mon_dest.c b/dp/wifi3.0/dp_rx_mon_dest.c index a3408e52a3..d3401db9df 100644 --- a/dp/wifi3.0/dp_rx_mon_dest.c +++ b/dp/wifi3.0/dp_rx_mon_dest.c @@ -742,6 +742,7 @@ void dp_rx_mon_dest_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) uint32_t ppdu_id; uint32_t rx_bufs_used; int mac_for_pdev = dp_get_mac_id_for_mac(soc, mac_id); + struct cdp_pdev_mon_stats *rx_mon_stats; mon_dst_srng = pdev->rxdma_mon_dst_ring[mac_for_pdev].hal_srng; @@ -771,6 +772,7 @@ void dp_rx_mon_dest_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) ppdu_id = pdev->ppdu_info.com_info.ppdu_id; rx_bufs_used = 0; + rx_mon_stats = &pdev->rx_mon_stats; while (qdf_likely(rxdma_dst_ring_desc = hal_srng_dst_peek(hal_soc, mon_dst_srng))) { @@ -804,6 +806,8 @@ void dp_rx_mon_dest_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) __func__, __LINE__); break; } + + rx_mon_stats->dest_mpdu_done++; dp_rx_mon_deliver(soc, mac_id, head_msdu, tail_msdu); rxdma_dst_ring_desc = hal_srng_dst_get_next(hal_soc, @@ -814,6 +818,7 @@ void dp_rx_mon_dest_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) qdf_spin_unlock_bh(&pdev->mon_lock); if (rx_bufs_used) { + rx_mon_stats->dest_ppdu_done++; dp_rx_buffers_replenish(soc, mac_id, &pdev->rxdma_mon_buf_ring[mac_for_pdev], &soc->rx_desc_mon[mac_id], rx_bufs_used, &head, &tail); diff --git a/dp/wifi3.0/dp_rx_mon_status.c b/dp/wifi3.0/dp_rx_mon_status.c index 20d022bfb8..70431df62c 100644 --- a/dp/wifi3.0/dp_rx_mon_status.c +++ b/dp/wifi3.0/dp_rx_mon_status.c @@ -332,8 +332,10 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id, uint8_t *rx_tlv_start; uint32_t tlv_status = HAL_TLV_STATUS_BUF_DONE; QDF_STATUS m_copy_status = QDF_STATUS_SUCCESS; + struct cdp_pdev_mon_stats *rx_mon_stats; ppdu_info = &pdev->ppdu_info; + rx_mon_stats = &pdev->rx_mon_stats; if (pdev->mon_ppdu_status != DP_PPDU_STATUS_START) return; @@ -356,6 +358,10 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id, do { tlv_status = hal_rx_status_get_tlv_info(rx_tlv, ppdu_info); + + dp_rx_mon_update_dbg_ppdu_stats(ppdu_info, + rx_mon_stats); + rx_tlv = hal_rx_status_get_next_tlv(rx_tlv); if ((rx_tlv - rx_tlv_start) >= RX_BUFFER_SIZE) @@ -374,6 +380,7 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id, } if (tlv_status == HAL_TLV_STATUS_PPDU_DONE) { + rx_mon_stats->status_ppdu_done++; if (pdev->enhanced_stats_en || pdev->mcopy_mode) dp_rx_handle_ppdu_stats(soc, pdev, ppdu_info); @@ -831,8 +838,15 @@ dp_rx_pdev_mon_status_attach(struct dp_pdev *pdev, int ring_id) { pdev->mon_ppdu_status = DP_PPDU_STATUS_START; pdev->ppdu_info.com_info.last_ppdu_id = 0; + qdf_mem_zero(&(pdev->ppdu_info.rx_status), sizeof(pdev->ppdu_info.rx_status)); + qdf_mem_zero(&pdev->rx_mon_stats, + sizeof(pdev->rx_mon_stats)); + + dp_rx_mon_init_dbg_ppdu_stats(&pdev->ppdu_info, + &pdev->rx_mon_stats); + return QDF_STATUS_SUCCESS; } diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 99adf72bee..18dd6c0380 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -1102,6 +1102,8 @@ struct dp_pdev { qdf_nbuf_queue_t rx_status_q; uint32_t mon_ppdu_status; struct cdp_mon_status rx_mon_recv_status; + /* monitor mode status/destination ring PPDU and MPDU count */ + struct cdp_pdev_mon_stats rx_mon_stats; /* pool addr for mcast enhance buff */ struct { diff --git a/hal/wifi3.0/hal_api_mon.h b/hal/wifi3.0/hal_api_mon.h index 1b8454c501..9388f64515 100644 --- a/hal/wifi3.0/hal_api_mon.h +++ b/hal/wifi3.0/hal_api_mon.h @@ -388,6 +388,16 @@ enum { HAL_RX_TYPE_MU_OFDMA_MIMO, }; +/** + * enum + * @HAL_RX_MON_PPDU_START: PPDU start TLV is decoded in HAL + * @HAL_RX_MON_PPDU_END: PPDU end TLV is decided in HAL + */ +enum { + HAL_RX_MON_PPDU_START = 0, + HAL_RX_MON_PPDU_END, +}; + /** * hal_rx_mon_hw_desc_get_mpdu_status: Retrieve MPDU status * @@ -450,6 +460,8 @@ struct hal_rx_ppdu_info { struct hal_rx_ppdu_user_info user_info[HAL_MAX_UL_MU_USERS]; struct mon_rx_status rx_status; struct hal_rx_msdu_payload_info msdu_info; + /* status ring PPDU start and end state */ + uint32_t rx_state; }; static inline uint32_t @@ -508,6 +520,7 @@ hal_rx_status_get_tlv_info(void *rx_tlv, struct hal_rx_ppdu_info *ppdu_info) ppdu_info->com_info.ppdu_timestamp = HAL_RX_GET(rx_tlv, RX_PPDU_START_2, PPDU_START_TIMESTAMP); + ppdu_info->rx_state = HAL_RX_MON_PPDU_START; break; case WIFIRX_PPDU_START_USER_INFO_E: @@ -518,6 +531,7 @@ hal_rx_status_get_tlv_info(void *rx_tlv, struct hal_rx_ppdu_info *ppdu_info) "[%s][%d] ppdu_end_e len=%d", __func__, __LINE__, tlv_len); /* This is followed by sub-TLVs of PPDU_END */ + ppdu_info->rx_state = HAL_RX_MON_PPDU_END; break; case WIFIRXPCU_PPDU_END_INFO_E: