diff --git a/dp/wifi3.0/monitor/2.0/dp_mon_2.0.c b/dp/wifi3.0/monitor/2.0/dp_mon_2.0.c index 05beeae264..6117485287 100644 --- a/dp/wifi3.0/monitor/2.0/dp_mon_2.0.c +++ b/dp/wifi3.0/monitor/2.0/dp_mon_2.0.c @@ -1309,6 +1309,96 @@ static void dp_mon_register_intr_ops_2_0(struct dp_soc *soc) dp_mon_ppdu_stats_handler_register(mon_soc); } +#ifdef MONITOR_TLV_RECORDING_ENABLE +/* + * dp_mon_pdev_tlv_logger_init() - initializes struct dp_mon_tlv_logger + * + * @mon_pdev: pointer to dp_mon_pdev + * + * Return: QDF_STATUS + */ +static +QDF_STATUS dp_mon_pdev_tlv_logger_init(struct dp_mon_pdev *mon_pdev) +{ + struct dp_mon_tlv_logger *tlv_log = NULL; + + if (!mon_pdev) + return QDF_STATUS_E_INVAL; + + tlv_log = qdf_mem_malloc(sizeof(struct dp_mon_tlv_logger)); + if (!tlv_log) { + qdf_err("Memory allocation failed"); + return QDF_STATUS_E_NOMEM; + } + + tlv_log->curr_ppdu_pos = 0; + tlv_log->wrap_flag = 0; + tlv_log->ppdu_start_idx = 0; + tlv_log->mpdu_idx = MAX_PPDU_START_TLV_NUM; + tlv_log->ppdu_end_idx = MAX_PPDU_START_TLV_NUM + MAX_MPDU_TLV_NUM; + tlv_log->max_ppdu_start_idx = MAX_PPDU_START_TLV_NUM - 1; + tlv_log->max_mpdu_idx = MAX_PPDU_START_TLV_NUM + MAX_MPDU_TLV_NUM - 1; + tlv_log->max_ppdu_end_idx = MAX_TLVS_PER_PPDU - 1; + + tlv_log->buff = qdf_mem_malloc(MAX_TLV_LOGGING_SIZE * + sizeof(struct dp_mon_tlv_info)); + if (!tlv_log->buff) { + qdf_err("Memory allocation failed"); + qdf_mem_free(tlv_log); + tlv_log = NULL; + return QDF_STATUS_E_NOMEM; + } + + tlv_log->tlv_logging_enable = 1; + + mon_pdev->rx_tlv_log = tlv_log; + + return QDF_STATUS_SUCCESS; +} + +/* + * dp_mon_pdev_tlv_logger_deinit() - deinitializes struct dp_mon_tlv_logger + * + * @mon_pdev: pointer to dp_mon_pdev + * + * Return: QDF_STATUS + */ +static +QDF_STATUS dp_mon_pdev_tlv_logger_deinit(struct dp_mon_pdev *mon_pdev) +{ + struct dp_mon_tlv_logger *tlv_log = NULL; + + if (!mon_pdev) + return QDF_STATUS_E_INVAL; + + tlv_log = mon_pdev->rx_tlv_log; + if (!tlv_log || !(tlv_log->buff)) + return QDF_STATUS_E_INVAL; + + tlv_log->tlv_logging_enable = 0; + qdf_mem_free(tlv_log->buff); + tlv_log->buff = NULL; + qdf_mem_free(tlv_log); + + return QDF_STATUS_SUCCESS; +} + +#else + +static inline +QDF_STATUS dp_mon_pdev_tlv_logger_init(struct dp_mon_pdev *mon_pdev) +{ + return QDF_STATUS_SUCCESS; +} + +static inline +QDF_STATUS dp_mon_pdev_tlv_logger_deinit(struct dp_mon_pdev *mon_pdev) +{ + return QDF_STATUS_SUCCESS; +} + +#endif + /** * dp_mon_register_feature_ops_2_0() - register feature ops * @@ -1544,6 +1634,8 @@ struct dp_mon_ops monitor_ops_2_0 = { .mon_lite_mon_is_rx_adv_filter_enable = dp_lite_mon_is_rx_adv_filter_enable, .mon_rx_ppdu_info_cache_create = dp_rx_mon_ppdu_info_cache_create, .mon_rx_ppdu_info_cache_destroy = dp_rx_mon_ppdu_info_cache_destroy, + .mon_rx_pdev_tlv_logger_init = dp_mon_pdev_tlv_logger_init, + .mon_rx_pdev_tlv_logger_deinit = dp_mon_pdev_tlv_logger_deinit, }; struct cdp_mon_ops dp_ops_mon_2_0 = { diff --git a/dp/wifi3.0/monitor/2.0/dp_mon_2.0.h b/dp/wifi3.0/monitor/2.0/dp_mon_2.0.h index 024fea1eee..1a14291439 100644 --- a/dp/wifi3.0/monitor/2.0/dp_mon_2.0.h +++ b/dp/wifi3.0/monitor/2.0/dp_mon_2.0.h @@ -38,6 +38,17 @@ #define DP_MON_DECAP_FORMAT_INVALID 0xff #define DP_MON_MIN_FRAGS_FOR_RESTITCH 2 +#ifdef MONITOR_TLV_RECORDING_ENABLE +#define MAX_TLV_LOGGING_SIZE 1024 + +#define MAX_PPDU_START_TLV_NUM 38 +#define MAX_MPDU_TLV_NUM 160 +#define MAX_PPDU_END_TLV_NUM 57 + +#define MAX_NUM_PPDU_RECORD 4 +#define MAX_TLVS_PER_PPDU 255 +#endif + /* monitor frame filter modes */ enum dp_mon_frm_filter_mode { /* mode filter pass */ diff --git a/dp/wifi3.0/monitor/2.0/dp_rx_mon_2.0.c b/dp/wifi3.0/monitor/2.0/dp_rx_mon_2.0.c index c5a423d1b4..e0b3320329 100644 --- a/dp/wifi3.0/monitor/2.0/dp_rx_mon_2.0.c +++ b/dp/wifi3.0/monitor/2.0/dp_rx_mon_2.0.c @@ -362,6 +362,222 @@ void dp_rx_mon_pf_tag_to_buf_headroom_2_0(void *nbuf, #endif +#ifdef MONITOR_TLV_RECORDING_ENABLE +/** + * dp_mon_record_index_update() - update the indexes of dp_mon_tlv_logger + * to store next tlv + * + * @mon_pdev: pointer to dp_mon_pdev + * + * Return + */ +void +dp_mon_record_index_update(struct dp_mon_pdev *mon_pdev) { + struct dp_mon_tlv_logger *tlv_log = NULL; + struct dp_mon_tlv_info *tlv_info = NULL; + + tlv_log = mon_pdev->rx_tlv_log; + tlv_info = (struct dp_mon_tlv_info *)tlv_log->buff; + + (tlv_log->curr_ppdu_pos + 1 == MAX_NUM_PPDU_RECORD) ? + tlv_log->curr_ppdu_pos = 0 : + tlv_log->curr_ppdu_pos++; + + tlv_log->wrap_flag = 0; + tlv_log->ppdu_start_idx = tlv_log->curr_ppdu_pos * + MAX_TLVS_PER_PPDU; + tlv_log->mpdu_idx = tlv_log->ppdu_start_idx + + MAX_PPDU_START_TLV_NUM; + tlv_log->ppdu_end_idx = tlv_log->mpdu_idx + MAX_MPDU_TLV_NUM; + tlv_log->max_ppdu_start_idx = tlv_log->ppdu_start_idx + + MAX_PPDU_START_TLV_NUM - 1; + tlv_log->max_mpdu_idx = tlv_log->mpdu_idx + + MAX_MPDU_TLV_NUM - 1; + tlv_log->max_ppdu_end_idx = tlv_log->ppdu_end_idx + + MAX_PPDU_END_TLV_NUM - 1; +} + +/** + * dp_mon_record_tlv() - Store the contents of the tlv in buffer + * + * @mon_pdev: pointe to dp_mon_pdev + * @ppdu_info: struct hal_rx_ppdu_info + * + * Return + */ +void +dp_mon_record_tlv(struct dp_mon_pdev *mon_pdev, + struct hal_rx_ppdu_info *ppdu_info) { + struct dp_mon_tlv_logger *tlv_log = NULL; + struct dp_mon_tlv_info *tlv_info = NULL; + uint32_t tlv_tag; + uint16_t *ppdu_start_idx = NULL; + uint16_t *mpdu_idx = NULL; + uint16_t *ppdu_end_idx = NULL; + + if (!mon_pdev || !(mon_pdev->rx_tlv_log)) + return; + + tlv_log = mon_pdev->rx_tlv_log; + if (!tlv_log->tlv_logging_enable || !(tlv_log->buff)) + return; + + tlv_info = (struct dp_mon_tlv_info *)tlv_log->buff; + ppdu_start_idx = &tlv_log->ppdu_start_idx; + mpdu_idx = &tlv_log->mpdu_idx; + ppdu_end_idx = &tlv_log->ppdu_end_idx; + + tlv_tag = ppdu_info->rx_tlv_info.tlv_tag; + if (ppdu_info->rx_tlv_info.tlv_category == CATEGORY_PPDU_START) { + tlv_info[*ppdu_start_idx].tlv_tag = tlv_tag; + switch (tlv_tag) { + case WIFIRX_PPDU_START_E: + tlv_info[*ppdu_start_idx]. + data.ppdu_start.ppdu_id = + ppdu_info->com_info.ppdu_id; + break; + case WIFIRX_PPDU_START_USER_INFO_E: + tlv_info[*ppdu_start_idx]. + data.ppdu_start_user_info.user_id = + ppdu_info->user_id; + tlv_info[*ppdu_start_idx]. + data.ppdu_start_user_info.rate_mcs = + ppdu_info->rx_status.mcs; + tlv_info[*ppdu_start_idx]. + data.ppdu_start_user_info.nss = + ppdu_info->rx_status.nss; + tlv_info[*ppdu_start_idx]. + data.ppdu_start_user_info.reception_type = + ppdu_info->rx_status.reception_type; + tlv_info[*ppdu_start_idx]. + data.ppdu_start_user_info.sgi = + ppdu_info->rx_status.sgi; + break; + } + if (*ppdu_start_idx < tlv_log->max_ppdu_start_idx) + (*ppdu_start_idx)++; + } else if (ppdu_info->rx_tlv_info.tlv_category == CATEGORY_MPDU) { + tlv_info[*mpdu_idx].tlv_tag = tlv_tag; + switch (tlv_tag) { + case WIFIRX_MPDU_START_E: + tlv_info[*mpdu_idx]. + data.mpdu_start.user_id = + ppdu_info->user_id; + tlv_info[*mpdu_idx]. + data.mpdu_start.wrap_flag = + tlv_log->wrap_flag; + break; + case WIFIRX_MPDU_END_E: + tlv_info[*mpdu_idx]. + data.mpdu_end.user_id = + ppdu_info->user_id; + tlv_info[*mpdu_idx]. + data.mpdu_end.fcs_err = + ppdu_info->fcs_err; + tlv_info[*mpdu_idx]. + data.mpdu_end.wrap_flag = + tlv_log->wrap_flag; + break; + case WIFIRX_HEADER_E: + tlv_info[*mpdu_idx]. + data.header.wrap_flag = + tlv_log->wrap_flag; + break; + case WIFIRX_MSDU_END_E: + tlv_info[*mpdu_idx]. + data.msdu_end.user_id = + ppdu_info->user_id; + tlv_info[*mpdu_idx]. + data.msdu_end.wrap_flag = + tlv_log->wrap_flag; + break; + case WIFIMON_BUFFER_ADDR_E: + tlv_info[*mpdu_idx]. + data.mon_buffer_addr.dma_length = + ppdu_info->packet_info.dma_length; + tlv_info[*mpdu_idx]. + data.mon_buffer_addr.truncation = + ppdu_info->packet_info.truncated; + tlv_info[*mpdu_idx]. + data.mon_buffer_addr.continuation = + ppdu_info->packet_info.msdu_continuation; + tlv_info[*mpdu_idx]. + data.mon_buffer_addr.wrap_flag = + tlv_log->wrap_flag; + break; + } + if (*mpdu_idx < tlv_log->max_mpdu_idx) { + (*mpdu_idx)++; + } else { + *mpdu_idx = *mpdu_idx - MAX_MPDU_TLV_NUM + 1; + tlv_log->wrap_flag ^= 1; + } + } else if (ppdu_info->rx_tlv_info.tlv_category == CATEGORY_PPDU_END) { + tlv_info[*ppdu_end_idx].tlv_tag = tlv_tag; + switch (tlv_tag) { + case WIFIRX_USER_PPDU_END_E: + break; + case WIFIRX_PPDU_END_E: + break; + case WIFIPHYRX_RSSI_LEGACY_E: + break; + case WIFIPHYRX_L_SIG_B_E: + break; + case WIFIPHYRX_COMMON_USER_INFO_E: + break; + case WIFIPHYRX_DATA_DONE_E: + break; + case WIFIPHYRX_PKT_END_PART1_E: + break; + case WIFIPHYRX_PKT_END_E: + break; + case WIFIRXPCU_PPDU_END_INFO_E: + break; + case WIFIRX_PPDU_END_USER_STATS_E: + break; + case WIFIRX_PPDU_END_STATUS_DONE_E: + break; + } + if (*ppdu_end_idx < tlv_log->max_ppdu_end_idx) + (*ppdu_end_idx)++; + } +} + +/** + * dp_mon_record_clear_buffer() - Clear the buffer to record next PPDU + * + * @mon_pdev: pointer to dp_mon_pdev + * + * Return + */ +void +dp_mon_record_clear_buffer(struct dp_mon_pdev *mon_pdev) { + struct dp_mon_tlv_logger *rx_tlv_log = NULL; + struct dp_mon_tlv_info *tlv_info = NULL; + + rx_tlv_log = mon_pdev->rx_tlv_log; + tlv_info = (struct dp_mon_tlv_info *)rx_tlv_log->buff; + qdf_mem_zero(&tlv_info[rx_tlv_log->ppdu_start_idx], + MAX_TLVS_PER_PPDU * sizeof(struct dp_mon_tlv_info)); +} + +#else + +void +dp_mon_record_index_update(struct dp_mon_pdev *mon_pdev) { +} + +void +dp_mon_record_tlv(struct dp_mon_pdev *mon_pdev, + struct hal_rx_ppdu_info *ppdu_info) { +} + +void +dp_mon_record_clear_buffer(struct dp_mon_pdev *mon_pdev) { +} + +#endif + /** * dp_rx_mon_free_mpdu_queue() - Free MPDU queue * @mon_pdev: monitor pdev @@ -1563,12 +1779,14 @@ dp_rx_mon_process_status_tlv(struct dp_pdev *pdev) rx_tlv = buf; rx_tlv_start = buf; + dp_mon_record_clear_buffer(mon_pdev); + do { tlv_status = hal_rx_status_get_tlv_info(rx_tlv, ppdu_info, pdev->soc->hal_soc, buf); - + dp_mon_record_tlv(mon_pdev, ppdu_info); work_done += dp_rx_mon_process_tlv_status(pdev, ppdu_info, buf, @@ -1598,6 +1816,7 @@ dp_rx_mon_process_status_tlv(struct dp_pdev *pdev) qdf_frag_free(buf); DP_STATS_INC(mon_soc, frag_free, 1); mon_pdev->rx_mon_stats.status_buf_count++; + dp_mon_record_index_update(mon_pdev); } dp_mon_rx_stats_update_rssi_dbm_params(mon_pdev, ppdu_info); diff --git a/dp/wifi3.0/monitor/dp_mon.c b/dp/wifi3.0/monitor/dp_mon.c index ee195266f9..197def5140 100644 --- a/dp/wifi3.0/monitor/dp_mon.c +++ b/dp/wifi3.0/monitor/dp_mon.c @@ -5886,6 +5886,9 @@ QDF_STATUS dp_mon_pdev_init(struct dp_pdev *pdev) if (mon_ops->mon_pdev_ext_init) mon_ops->mon_pdev_ext_init(pdev); + if (mon_ops->mon_rx_pdev_tlv_logger_init) + mon_ops->mon_rx_pdev_tlv_logger_init(pdev->monitor_pdev); + mon_pdev->is_dp_mon_pdev_initialized = true; return QDF_STATUS_SUCCESS; @@ -5933,6 +5936,10 @@ QDF_STATUS dp_mon_pdev_deinit(struct dp_pdev *pdev) if (mon_ops->mon_pdev_ext_deinit) mon_ops->mon_pdev_ext_deinit(pdev); + if (mon_ops->mon_rx_pdev_tlv_logger_deinit) + mon_ops->mon_rx_pdev_tlv_logger_deinit( + pdev->monitor_pdev); + /* detach monitor function */ dp_monitor_tx_ppdu_stats_detach(pdev); diff --git a/dp/wifi3.0/monitor/dp_mon.h b/dp/wifi3.0/monitor/dp_mon.h index b359baff7a..57c6e5c5b1 100644 --- a/dp/wifi3.0/monitor/dp_mon.h +++ b/dp/wifi3.0/monitor/dp_mon.h @@ -100,6 +100,132 @@ static inline bool dp_is_monitor_mode_using_poll(struct dp_soc *soc) } #endif +#ifdef MONITOR_TLV_RECORDING_ENABLE +/* + * struct dp_mon_tlv_info - recorded information of each TLV + * @tlv_tag: tlv tag + * @data: other fields recorded for a TLV + * + * Tag and its corresponding important fields are stored in this struct + */ +struct ppdu_start_tlv_record { + uint32_t ppdu_id:10; +}; + +struct ppdu_start_user_info_tlv_record { + uint32_t user_id:6, + rate_mcs:4, + nss:3, + reception_type:3, + sgi:2; +}; + +struct mpdu_start_tlv_record { + uint32_t user_id:6, + wrap_flag:1; +}; + +struct mpdu_end_tlv_record { + uint32_t user_id:6, + fcs_err:1, + wrap_flag:1; +}; + +struct header_tlv_record { + uint32_t wrap_flag:1; +}; + +struct msdu_end_tlv_record { + uint32_t user_id:6, + msdu_num:8, + tid:4, + tcp_proto:1, + udp_proto:1, + wrap_flag:1; +}; + +struct mon_buffer_addr_tlv_record { + uint32_t dma_length:12, + truncation:1, + continuation:1, + wrap_flag:1; +}; + +struct phy_location_tlv_record { + uint32_t rtt_cfr_status:8, + rtt_num_streams:8, + rx_location_info_valid:1; +}; + +struct ppdu_end_user_stats_tlv_record { + uint32_t ast_index:16, + pkt_type:4; +}; + +struct pcu_ppdu_end_info_tlv_record { + uint32_t dialog_topken:8, + bb_captured_reason:3, + bb_captured_channel:1, + bb_captured_timeout:1, + mpdu_delimiter_error_seen:1; +}; + +struct phy_rx_ht_sig_tlv_record { + uint32_t crc:8, + mcs:7, + stbc:2, + aggregation:1, + short_gi:1, + fes_coding:1, + cbw:1; +}; + +struct dp_mon_tlv_info { + uint32_t tlv_tag:10; + union { + struct ppdu_start_tlv_record ppdu_start; + struct ppdu_start_user_info_tlv_record ppdu_start_user_info; + struct mpdu_start_tlv_record mpdu_start; + struct mpdu_end_tlv_record mpdu_end; + struct header_tlv_record header; + struct msdu_end_tlv_record msdu_end; + struct mon_buffer_addr_tlv_record mon_buffer_addr; + struct phy_location_tlv_record phy_location; + struct ppdu_end_user_stats_tlv_record ppdu_end_user_stats; + struct pcu_ppdu_end_info_tlv_record pcu_ppdu_end_info; + struct phy_rx_ht_sig_tlv_record phy_rx_ht_sig; + uint32_t data; + } data; +}; + +/** + * struct dp_mon_tlv_logger - contains indexes and other data of the buffer + * @buff: buffer in which TLVs are stored + * @curr_ppdu_pos: position of the next ppdu to be written + * @ppdu_start_idx: starting index form which PPDU start level TLVs are stored for a ppdu + * @mpdu_idx: starting index form which MPDU TLVs are stored for a ppdu + * @ppdu_end_idx: starting index form which PPDU end level TLVs are stored for a ppdu + * @max_ppdu_start_idx: ending index for PPDU start level TLVs for a ppdu + * @max_mpdu_idx: ending index for MPDU level TLVs for a ppdu + * @max_ppdu_end_idx: ending index for PPDU end level TLVs for a ppdu + * @wrap_flag: flag toggle between consecutive PPDU + * @tlv_logging_enable: check is tlv logging is enabled + * + */ +struct dp_mon_tlv_logger { + void *buff; + uint16_t curr_ppdu_pos; + uint16_t ppdu_start_idx; + uint16_t mpdu_idx; + uint16_t ppdu_end_idx; + uint16_t max_ppdu_start_idx; + uint16_t max_ppdu_end_idx; + uint16_t max_mpdu_idx; + uint8_t wrap_flag; + bool tlv_logging_enable; +}; +#endif + /** * dp_mon_soc_attach() - DP monitor soc attach * @soc: Datapath SOC handle @@ -824,6 +950,8 @@ struct dp_mon_ops { #endif QDF_STATUS (*mon_pdev_ext_init)(struct dp_pdev *pdev); QDF_STATUS (*mon_pdev_ext_deinit)(struct dp_pdev *pdev); + QDF_STATUS (*mon_rx_pdev_tlv_logger_init)(struct dp_mon_pdev *mon_pdev); + QDF_STATUS (*mon_rx_pdev_tlv_logger_deinit)(struct dp_mon_pdev *mon_pdev); QDF_STATUS (*mon_lite_mon_alloc)(struct dp_pdev *pdev); void (*mon_lite_mon_dealloc)(struct dp_pdev *pdev); void (*mon_lite_mon_vdev_delete)(struct dp_pdev *pdev, @@ -1001,6 +1129,11 @@ struct dp_mon_pdev { uint16_t mo_data_filter; uint16_t md_data_filter; +#ifdef MONITOR_TLV_RECORDING_ENABLE + /*Rx TLV logger*/ + struct dp_mon_tlv_logger *rx_tlv_log; +#endif + #ifdef WLAN_TX_PKT_CAPTURE_ENH struct dp_pdev_tx_capture tx_capture; bool stop_tx_capture_work_q_timer; diff --git a/hal/wifi3.0/be/hal_be_api_mon.h b/hal/wifi3.0/be/hal_be_api_mon.h index 305002f383..1975c80771 100644 --- a/hal/wifi3.0/be/hal_be_api_mon.h +++ b/hal/wifi3.0/be/hal_be_api_mon.h @@ -1074,6 +1074,21 @@ enum txmon_generated_response { TXMON_GEN_RESP_SELFGEN_NDP_LMR }; +#ifdef MONITOR_TLV_RECORDING_ENABLE +/* + * enum ppdu_tlv_category - Categories of TLV + * @PPDU_START: PPDU start level TLV + * @MPDU: MPDU level TLV + * @PPDU_END: PPDU end level TLV + * + */ +enum ppdu_tlv_category { + CATEGORY_PPDU_START = 1, + CATEGORY_MPDU, + CATEGORY_PPDU_END +}; +#endif + #define IS_MULTI_USERS(num_users) (!!(0xFFFE & num_users)) #define TXMON_HAL(hal_tx_ppdu_info, field) \ @@ -2224,6 +2239,52 @@ hal_update_rx_ctrl_frame_stats(struct hal_rx_ppdu_info *ppdu_info, } #endif /* WLAN_SUPPORT_CTRL_FRAME_STATS */ +#ifdef MONITOR_TLV_RECORDING_ENABLE +/** + * hal_rx_record_tlv_info() - Record received TLV info + * @ppdu_info: pointer to ppdu_info + * @tlv_tag: TLV tag of the TLV to record + * + * Return + */ +static inline void +hal_rx_record_tlv_info(struct hal_rx_ppdu_info *ppdu_info, uint32_t tlv_tag) { + ppdu_info->rx_tlv_info.tlv_tag = tlv_tag; + switch (tlv_tag) { + case WIFIRX_PPDU_START_E: + case WIFIRX_PPDU_START_USER_INFO_E: + ppdu_info->rx_tlv_info.tlv_category = CATEGORY_PPDU_START; + break; + + case WIFIRX_HEADER_E: + case WIFIRX_MPDU_START_E: + case WIFIMON_BUFFER_ADDR_E: + case WIFIRX_MSDU_END_E: + case WIFIRX_MPDU_END_E: + ppdu_info->rx_tlv_info.tlv_category = CATEGORY_MPDU; + break; + + case WIFIRX_USER_PPDU_END_E: + case WIFIRX_PPDU_END_E: + case WIFIPHYRX_RSSI_LEGACY_E: + case WIFIPHYRX_L_SIG_B_E: + case WIFIPHYRX_COMMON_USER_INFO_E: + case WIFIPHYRX_DATA_DONE_E: + case WIFIPHYRX_PKT_END_PART1_E: + case WIFIPHYRX_PKT_END_E: + case WIFIRXPCU_PPDU_END_INFO_E: + case WIFIRX_PPDU_END_USER_STATS_E: + case WIFIRX_PPDU_END_STATUS_DONE_E: + ppdu_info->rx_tlv_info.tlv_category = CATEGORY_PPDU_END; + break; + } +} +#else +static inline void +hal_rx_record_tlv_info(struct hal_rx_ppdu_info *ppdu_info, uint32_t tlv_tag) { +} +#endif + /** * hal_rx_status_get_tlv_info_generic_be() - process receive info TLV * @rx_tlv_hdr: pointer to TLV header @@ -2465,12 +2526,14 @@ hal_rx_status_get_tlv_info_generic_be(void *rx_tlv_hdr, void *ppduinfo, break; case WIFIRX_PPDU_END_STATUS_DONE_E: + hal_rx_record_tlv_info(ppdu_info, tlv_tag); return HAL_TLV_STATUS_PPDU_DONE; case WIFIPHYRX_PKT_END_E: break; case WIFIDUMMY_E: + hal_rx_record_tlv_info(ppdu_info, tlv_tag); return HAL_TLV_STATUS_BUF_DONE; case WIFIPHYRX_HT_SIG_E: @@ -3258,6 +3321,7 @@ hal_rx_status_get_tlv_info_generic_be(void *rx_tlv_hdr, void *ppduinfo, /* for every RX_HEADER TLV increment mpdu_cnt */ com_info->mpdu_cnt++; + hal_rx_record_tlv_info(ppdu_info, tlv_tag); return HAL_TLV_STATUS_HEADER; } case WIFIRX_MPDU_START_E: @@ -3327,6 +3391,7 @@ hal_rx_status_get_tlv_info_generic_be(void *rx_tlv_hdr, void *ppduinfo, ppdu_info->mpdu_info[user_id].decap_type = rx_mpdu_start->rx_mpdu_info_details.decap_type; + hal_rx_record_tlv_info(ppdu_info, tlv_tag); return HAL_TLV_STATUS_MPDU_START; } case WIFIRX_MPDU_END_E: @@ -3334,6 +3399,8 @@ hal_rx_status_get_tlv_info_generic_be(void *rx_tlv_hdr, void *ppduinfo, ppdu_info->fcs_err = HAL_RX_GET_64(rx_tlv, RX_MPDU_END, FCS_ERR); + + hal_rx_record_tlv_info(ppdu_info, tlv_tag); return HAL_TLV_STATUS_MPDU_END; case WIFIRX_MSDU_END_E: { hal_rx_mon_msdu_end_t *rx_msdu_end = rx_tlv; @@ -3360,26 +3427,31 @@ hal_rx_status_get_tlv_info_generic_be(void *rx_tlv_hdr, void *ppduinfo, ppdu_info->msdu[user_id].reception_type = rx_msdu_end->reception_type; } + hal_rx_record_tlv_info(ppdu_info, tlv_tag); return HAL_TLV_STATUS_MSDU_END; } case WIFIMON_BUFFER_ADDR_E: hal_rx_status_get_mon_buf_addr(rx_tlv, ppdu_info); - + hal_rx_record_tlv_info(ppdu_info, tlv_tag); return HAL_TLV_STATUS_MON_BUF_ADDR; case WIFIMON_DROP_E: hal_rx_update_ppdu_drop_cnt(rx_tlv, ppdu_info); + hal_rx_record_tlv_info(ppdu_info, tlv_tag); return HAL_TLV_STATUS_MON_DROP; case 0: + hal_rx_record_tlv_info(ppdu_info, tlv_tag); return HAL_TLV_STATUS_PPDU_DONE; case WIFIRX_STATUS_BUFFER_DONE_E: case WIFIPHYRX_DATA_DONE_E: case WIFIPHYRX_PKT_END_PART1_E: + hal_rx_record_tlv_info(ppdu_info, tlv_tag); return HAL_TLV_STATUS_PPDU_NOT_DONE; default: hal_debug("unhandled tlv tag %d", tlv_tag); } + hal_rx_record_tlv_info(ppdu_info, tlv_tag); qdf_trace_hex_dump(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, rx_tlv, tlv_len); diff --git a/hal/wifi3.0/hal_api_mon.h b/hal/wifi3.0/hal_api_mon.h index 7dc06b6bdd..4e6322d038 100644 --- a/hal/wifi3.0/hal_api_mon.h +++ b/hal/wifi3.0/hal_api_mon.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. 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 @@ -1248,6 +1248,19 @@ struct hal_rx_user_ctrl_frm_info { struct hal_rx_user_ctrl_frm_info {}; #endif /* WLAN_SUPPORT_CTRL_FRAME_STATS */ +#ifdef MONITOR_TLV_RECORDING_ENABLE +/* + * struct hal_rx_tlv_info - TLV info to pass to dp layer + * @tlv_tag: Tag of the TLV + * @tlv_category: Category of TLV + * + */ +struct hal_rx_tlv_info { + uint32_t tlv_tag; + uint8_t tlv_category; +}; +#endif + struct hal_rx_ppdu_info { struct hal_rx_ppdu_common_info com_info; struct hal_rx_u_sig_info u_sig_info; @@ -1320,6 +1333,10 @@ struct hal_rx_ppdu_info { uint8_t start_user_info_cnt; /* PPDU drop cnt */ struct hal_rx_ppdu_drop_cnt drop_cnt; +#ifdef MONITOR_TLV_RECORDING_ENABLE + /*TLV Recording*/ + struct hal_rx_tlv_info rx_tlv_info; +#endif }; static inline uint32_t