diff --git a/dp/inc/cdp_txrx_cmn_struct.h b/dp/inc/cdp_txrx_cmn_struct.h index 3d0e707482a9..a5b9875867df 100644 --- a/dp/inc/cdp_txrx_cmn_struct.h +++ b/dp/inc/cdp_txrx_cmn_struct.h @@ -534,10 +534,10 @@ struct cdp_soc_t { /* * cdp_pdev_param_type: different types of parameters * to set values in pdev - * @CDP_ENABLE_TX_CAPTURE: Enable Tx capture feature + * @CDP_CONFIG_DEBUG_SNIFFER: Enable debug sniffer feature */ enum cdp_pdev_param_type { - CDP_CONFIG_TX_CAPTURE, + CDP_CONFIG_DEBUG_SNIFFER, }; /* diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 17704591065d..5414da3611f1 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -4635,14 +4635,14 @@ dp_ppdu_ring_cfg(struct dp_pdev *pdev) } /* - * dp_config_tx_capture()- API to enable/disable tx capture + * dp_config_debug_sniffer()- API to enable/disable debug sniffer * @pdev_handle: DP_PDEV handle * @val: user provided value * * Return: void */ static void -dp_config_tx_capture(struct cdp_pdev *pdev_handle, int val) +dp_config_debug_sniffer(struct cdp_pdev *pdev_handle, int val) { struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; @@ -4650,6 +4650,7 @@ dp_config_tx_capture(struct cdp_pdev *pdev_handle, int val) case 0: pdev->tx_sniffer_enable = 0; pdev->am_copy_mode = 0; + pdev->soc->process_tx_status = 0; if (!pdev->enhanced_stats_en) dp_h2t_cfg_stats_msg_send(pdev, 0); @@ -4658,11 +4659,14 @@ dp_config_tx_capture(struct cdp_pdev *pdev_handle, int val) case 1: pdev->tx_sniffer_enable = 1; pdev->am_copy_mode = 0; + pdev->soc->process_tx_status = 1; dp_h2t_cfg_stats_msg_send(pdev, DP_PPDU_STATS_CFG_ALL); break; case 2: pdev->am_copy_mode = 1; pdev->tx_sniffer_enable = 0; + pdev->soc->process_tx_status = 1; + dp_ppdu_ring_cfg(pdev); dp_h2t_cfg_stats_msg_send(pdev, DP_PPDU_STATS_CFG_ALL); break; default: @@ -4762,8 +4766,8 @@ static void dp_set_pdev_param(struct cdp_pdev *pdev_handle, enum cdp_pdev_param_type param, uint8_t val) { switch (param) { - case CDP_CONFIG_TX_CAPTURE: - dp_config_tx_capture(pdev_handle, val); + case CDP_CONFIG_DEBUG_SNIFFER: + dp_config_debug_sniffer(pdev_handle, val); break; default: break; diff --git a/dp/wifi3.0/dp_rx_mon_status.c b/dp/wifi3.0/dp_rx_mon_status.c index b31fab379b74..ff3b5ed82865 100644 --- a/dp/wifi3.0/dp_rx_mon_status.c +++ b/dp/wifi3.0/dp_rx_mon_status.c @@ -167,6 +167,47 @@ static void dp_rx_stats_update(struct dp_soc *soc, struct dp_peer *peer, } #endif +/** +* dp_rx_handle_am_copy_mode() - Allocate and deliver first MSDU payload +* @soc: core txrx main context +* @pdev: pdev strcuture +* @ppdu_info: structure for rx ppdu ring +* +* Return: QDF_STATUS_SUCCESS - If nbuf to be freed by caller +* QDF_STATUS_E_ALREADY - If nbuf not to be freed by caller +*/ +#ifdef FEATURE_PERPKT_INFO +static inline QDF_STATUS +dp_rx_handle_am_copy_mode(struct dp_soc *soc, struct dp_pdev *pdev, + struct hal_rx_ppdu_info *ppdu_info, qdf_nbuf_t nbuf) +{ + uint8_t size = 0; + + if (ppdu_info->first_msdu_payload == NULL) + return QDF_STATUS_SUCCESS; + + if (pdev->am_copy_id.rx_ppdu_id == ppdu_info->com_info.ppdu_id) + return QDF_STATUS_SUCCESS; + + pdev->am_copy_id.rx_ppdu_id = ppdu_info->com_info.ppdu_id; + + size = ppdu_info->first_msdu_payload - qdf_nbuf_data(nbuf); + ppdu_info->first_msdu_payload = NULL; + qdf_nbuf_pull_head(nbuf, size); + dp_wdi_event_handler(WDI_EVENT_RX_DATA, soc, + nbuf, HTT_INVALID_PEER, WDI_NO_VAL, pdev->pdev_id); + return QDF_STATUS_E_ALREADY; +} +#else +static inline QDF_STATUS +dp_rx_handle_am_copy_mode(struct dp_soc *soc, struct dp_pdev *pdev, + struct hal_rx_ppdu_info *ppdu_info, qdf_nbuf_t nbuf) +{ + return QDF_STATUS_SUCCESS; +} +#endif + + /** * dp_rx_handle_ppdu_stats() - Allocate and deliver ppdu stats to cdp layer * @soc: core txrx main context @@ -228,6 +269,7 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id, uint8_t *rx_tlv; uint8_t *rx_tlv_start; uint32_t tlv_status = HAL_TLV_STATUS_BUF_DONE; + QDF_STATUS am_copy_status = QDF_STATUS_SUCCESS; ppdu_info = &pdev->ppdu_info; @@ -239,14 +281,14 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id, status_nbuf = qdf_nbuf_queue_remove(&pdev->rx_status_q); rx_tlv = qdf_nbuf_data(status_nbuf); rx_tlv_start = rx_tlv; - #if defined(CONFIG_WIN) && WDI_EVENT_ENABLE #ifndef REMOVE_PKT_LOG dp_wdi_event_handler(WDI_EVENT_RX_DESC, soc, status_nbuf, HTT_INVALID_PEER, WDI_NO_VAL, mac_id); #endif #endif - if ((pdev->monitor_vdev != NULL) || (pdev->enhanced_stats_en)) { + if ((pdev->monitor_vdev != NULL) || (pdev->enhanced_stats_en) + || (pdev->am_copy_mode)) { do { tlv_status = hal_rx_status_get_tlv_info(rx_tlv, @@ -258,11 +300,20 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id, } while (tlv_status == HAL_TLV_STATUS_PPDU_NOT_DONE); } - qdf_nbuf_free(status_nbuf); + + if (pdev->am_copy_mode) { + am_copy_status = dp_rx_handle_am_copy_mode(soc, + pdev, ppdu_info, status_nbuf); + if (am_copy_status == QDF_STATUS_SUCCESS) + qdf_nbuf_free(status_nbuf); + } else { + qdf_nbuf_free(status_nbuf); + } if (tlv_status == HAL_TLV_STATUS_PPDU_DONE) { if (pdev->enhanced_stats_en) dp_rx_handle_ppdu_stats(soc, pdev, ppdu_info); + pdev->mon_ppdu_status = DP_PPDU_STATUS_DONE; dp_rx_mon_dest_process(soc, mac_id, quota); pdev->mon_ppdu_status = DP_PPDU_STATUS_START; diff --git a/dp/wifi3.0/dp_tx.c b/dp/wifi3.0/dp_tx.c index 36a4c87da6bc..cec94752ec28 100644 --- a/dp/wifi3.0/dp_tx.c +++ b/dp/wifi3.0/dp_tx.c @@ -1793,7 +1793,7 @@ dp_send_compl_to_stack(struct dp_soc *soc, struct dp_pdev *pdev, struct tx_capture_hdr *ppdu_hdr; struct dp_peer *peer = NULL; - if (qdf_unlikely(!pdev->tx_sniffer_enable || !pdev->am_copy_mode)) + if (qdf_unlikely(!pdev->tx_sniffer_enable && !pdev->am_copy_mode)) return QDF_STATUS_E_NOSUPPORT; peer = (peer_id == HTT_INVALID_PEER) ? NULL : diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 22e30d0afea6..4e6dbf954fa7 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -1055,6 +1055,7 @@ struct dp_pdev { struct { uint16_t tx_ppdu_id; uint16_t tx_peer_id; + uint16_t rx_ppdu_id; } am_copy_id; }; diff --git a/hal/wifi3.0/hal_api_mon.h b/hal/wifi3.0/hal_api_mon.h index 1c316387257c..06cc1df40243 100644 --- a/hal/wifi3.0/hal_api_mon.h +++ b/hal/wifi3.0/hal_api_mon.h @@ -428,6 +428,7 @@ struct hal_rx_ppdu_info { struct hal_rx_ppdu_common_info com_info; struct hal_rx_ppdu_user_info user_info[HAL_MAX_UL_MU_USERS]; struct mon_rx_status rx_status; + uint8_t *first_msdu_payload; }; static inline uint32_t @@ -466,7 +467,6 @@ hal_rx_status_get_tlv_info(void *rx_tlv, struct hal_rx_ppdu_info *ppdu_info) tlv_len = HAL_RX_GET_USER_TLV32_LEN(rx_tlv); rx_tlv = (uint8_t *) rx_tlv + HAL_RX_TLV32_HDR_SIZE; - switch (tlv_tag) { case WIFIRX_PPDU_START_E: @@ -773,6 +773,8 @@ hal_rx_status_get_tlv_info(void *rx_tlv, struct hal_rx_ppdu_info *ppdu_info) "RSSI_EXT80_HIGH20_CHAIN0: %d\n", value); break; } + case WIFIRX_HEADER_E: + ppdu_info->first_msdu_payload = rx_tlv; case 0: return HAL_TLV_STATUS_PPDU_DONE; diff --git a/hal/wifi3.0/hal_internal.h b/hal/wifi3.0/hal_internal.h index 6c81f38ac57d..8f5b635e5860 100644 --- a/hal/wifi3.0/hal_internal.h +++ b/hal/wifi3.0/hal_internal.h @@ -82,6 +82,10 @@ #include "pld_common.h" #include "rx_msdu_link.h" +#ifdef FEATURE_PERPKT_INFO +#include "rx_header.h" +#endif /* FEATURE_PERPKT_INFO */ + /* TBD: This should be movded to shared HW header file */ enum hal_srng_ring_id { /* UMAC rings */