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 06ef26cf0c..e940656c7b 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 @@ -255,6 +255,7 @@ struct dp_mon_desc_pool { * @rx_mon_free_queue: RxMON ppdu info free element queue * @ppdu_info_lock: RxPPDU ppdu info queue lock * @rx_mon_queue_depth: RxMON queue depth + * @ppdu_info_cache: PPDU info cache * @desc_count: reaped status desc count * @status: reaped status buffer per ppdu * @lite_mon_rx_config: rx litemon config @@ -263,7 +264,6 @@ struct dp_mon_desc_pool { * @prev_rxmon_cookie: prev rxmon cookie * @prev_rxmon_pkt_desc: prev packet buff desc * @prev_rxmon_pkt_cookie: prev packet buff desc cookie - * @ppdu_info_cache: PPDU info cache * @total_free_elem: total free element in queue * @rx_tlv_logger: Rx TLV logger struct */ @@ -276,6 +276,7 @@ struct dp_mon_pdev_be { struct dp_pdev_tx_monitor_be tx_monitor_be; struct dp_tx_monitor_drop_stats tx_stats; #endif +#if defined(WLAN_PKT_CAPTURE_RX_2_0) && defined(QCA_MONITOR_2_0_PKT_SUPPORT) qdf_spinlock_t rx_mon_wq_lock; qdf_workqueue_t *rx_mon_workqueue; qdf_work_t rx_mon_work; @@ -283,6 +284,8 @@ struct dp_mon_pdev_be { TAILQ_HEAD(, hal_rx_ppdu_info) rx_mon_queue; TAILQ_HEAD(, hal_rx_ppdu_info) rx_mon_free_queue; qdf_spinlock_t ppdu_info_lock; + qdf_kmem_cache_t ppdu_info_cache; +#endif uint16_t rx_mon_queue_depth; uint16_t desc_count; struct dp_mon_desc *status[DP_MON_MAX_STATUS_BUF]; @@ -294,7 +297,6 @@ struct dp_mon_pdev_be { uint32_t prev_rxmon_cookie; void *prev_rxmon_pkt_desc; uint32_t prev_rxmon_pkt_cookie; - qdf_kmem_cache_t ppdu_info_cache; uint32_t total_free_elem; #ifdef MONITOR_TLV_RECORDING_ENABLE struct dp_mon_tlv_logger *rx_tlv_log; 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 a58fb2ca98..e539cfb46d 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 @@ -41,28 +41,238 @@ #define F_MASK 0xFFFF #define TEST_MASK 0xCBF +#ifdef MONITOR_TLV_RECORDING_ENABLE /** - * dp_rx_mon_free_mpdu_queue() - Free MPDU queue - * @mon_pdev: monitor pdev - * @ppdu_info: PPDU info + * dp_mon_record_index_update() - update the indexes of dp_mon_tlv_logger + * to store next tlv * - * Return: Void + * @mon_pdev_be: pointer to dp_mon_pdev_be + * + * Return */ - -static void dp_rx_mon_free_mpdu_queue(struct dp_mon_pdev *mon_pdev, - struct hal_rx_ppdu_info *ppdu_info) +void +dp_mon_record_index_update(struct dp_mon_pdev_be *mon_pdev_be) { - uint8_t user; - qdf_nbuf_t mpdu; + struct dp_mon_tlv_logger *tlv_log = NULL; + struct dp_mon_tlv_info *tlv_info = NULL; - for (user = 0; user < HAL_MAX_UL_MU_USERS; user++) { - if (!qdf_nbuf_is_queue_empty(&ppdu_info->mpdu_q[user])) { - while ((mpdu = qdf_nbuf_queue_remove(&ppdu_info->mpdu_q[user])) != NULL) - dp_mon_free_parent_nbuf(mon_pdev, mpdu); + if (!mon_pdev_be || !(mon_pdev_be->rx_tlv_log)) + return; + + tlv_log = mon_pdev_be->rx_tlv_log; + if (!tlv_log->tlv_logging_enable || !(tlv_log->buff)) + return; + + 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_be: pointe to dp_mon_pdev_be + * @ppdu_info: struct hal_rx_ppdu_info + * + * Return + */ +void +dp_mon_record_tlv(struct dp_mon_pdev_be *mon_pdev_be, + 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_be || !(mon_pdev_be->rx_tlv_log)) + return; + + tlv_log = mon_pdev_be->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_be: pointer to dp_mon_pdev_be + * + * Return + */ +void +dp_mon_record_clear_buffer(struct dp_mon_pdev_be *mon_pdev_be) +{ + struct dp_mon_tlv_logger *tlv_log = NULL; + struct dp_mon_tlv_info *tlv_info = NULL; + + if (!mon_pdev_be || !(mon_pdev_be->rx_tlv_log)) + return; + + tlv_log = mon_pdev_be->rx_tlv_log; + if (!tlv_log->tlv_logging_enable || !(tlv_log->buff)) + return; + + tlv_info = (struct dp_mon_tlv_info *)tlv_log->buff; + qdf_mem_zero(&tlv_info[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_be *mon_pdev_be) +{ +} + +void +dp_mon_record_tlv(struct dp_mon_pdev_be *mon_pdev_be, + struct hal_rx_ppdu_info *ppdu_info) +{ +} + +void +dp_mon_record_clear_buffer(struct dp_mon_pdev_be *mon_pdev_be) +{ +} + +#endif + /** * dp_rx_mon_update_drop_cnt() - Update drop statistics * @@ -86,112 +296,7 @@ dp_rx_mon_update_drop_cnt(struct dp_mon_pdev *mon_pdev, hal_mon_rx_desc->tlv_drop_count; } -static -void dp_rx_mon_set_zero(qdf_nbuf_t nbuf) -{ - qdf_mem_zero(qdf_nbuf_head(nbuf), DP_RX_MON_TLV_ROOM); -} - -#ifdef QCA_KMEM_CACHE_SUPPORT -/** - * dp_rx_mon_get_ppdu_info() - Get PPDU info from freelist - * - * @mon_pdev: monitor pdev - * - * Return: ppdu_info - */ -struct hal_rx_ppdu_info* -dp_rx_mon_get_ppdu_info(struct dp_mon_pdev *mon_pdev) -{ - struct dp_mon_pdev_be *mon_pdev_be = - dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev); - struct hal_rx_ppdu_info *ppdu_info, *temp_ppdu_info; - - qdf_spin_lock_bh(&mon_pdev_be->ppdu_info_lock); - TAILQ_FOREACH_SAFE(ppdu_info, - &mon_pdev_be->rx_mon_free_queue, - ppdu_free_list_elem, - temp_ppdu_info) { - TAILQ_REMOVE(&mon_pdev_be->rx_mon_free_queue, - ppdu_info, ppdu_free_list_elem); - - if (ppdu_info) { - mon_pdev_be->total_free_elem--; - break; - } - } - qdf_spin_unlock_bh(&mon_pdev_be->ppdu_info_lock); - - return ppdu_info; -} - -void -__dp_rx_mon_free_ppdu_info(struct dp_mon_pdev *mon_pdev, - struct hal_rx_ppdu_info *ppdu_info) -{ - struct dp_mon_pdev_be *mon_pdev_be = - dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev); - - qdf_spin_lock_bh(&mon_pdev_be->ppdu_info_lock); - if (ppdu_info) { - qdf_mem_zero(ppdu_info, sizeof(struct hal_rx_ppdu_info)); - TAILQ_INSERT_TAIL(&mon_pdev_be->rx_mon_free_queue, ppdu_info, - ppdu_free_list_elem); - mon_pdev_be->total_free_elem++; - } - qdf_spin_unlock_bh(&mon_pdev_be->ppdu_info_lock); -} - -/** - * dp_rx_mon_free_ppdu_info() - Free PPDU info - * @pdev: DP pdev - * @ppdu_info: PPDU info - * - * Return: Void - */ -void -dp_rx_mon_free_ppdu_info(struct dp_pdev *pdev, - struct hal_rx_ppdu_info *ppdu_info) -{ - struct dp_mon_pdev *mon_pdev; - - mon_pdev = (struct dp_mon_pdev *)pdev->monitor_pdev; - dp_rx_mon_free_mpdu_queue(mon_pdev, ppdu_info); - __dp_rx_mon_free_ppdu_info(mon_pdev, ppdu_info); -} -#endif - -/** - * dp_rx_mon_nbuf_add_rx_frag() - Add frag to SKB - * - * @nbuf: SKB to which frag is going to be added - * @frag: frag to be added to SKB - * @frag_len: frag length - * @offset: frag offset - * @buf_size: buffer size - * @frag_ref: take frag ref - * - * Return: QDF_STATUS - */ -static inline QDF_STATUS -dp_rx_mon_nbuf_add_rx_frag(qdf_nbuf_t nbuf, qdf_frag_t *frag, - uint16_t frag_len, uint16_t offset, - uint16_t buf_size, bool frag_ref) -{ - uint8_t num_frags; - - num_frags = qdf_nbuf_get_nr_frags(nbuf); - if (num_frags < QDF_NBUF_MAX_FRAGS) { - qdf_nbuf_add_rx_frag(frag, nbuf, - offset, - frag_len, - buf_size, - frag_ref); - return QDF_STATUS_SUCCESS; - } - return QDF_STATUS_E_FAILURE; -} - +#ifdef QCA_MONITOR_2_0_PKT_SUPPORT #if defined(WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG) &&\ defined(WLAN_SUPPORT_RX_TAG_STATISTICS) /** dp_mon_rx_update_rx_protocol_tag_stats() - Update mon protocols's @@ -402,232 +507,678 @@ 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_be: pointer to dp_mon_pdev_be - * - * Return - */ -void -dp_mon_record_index_update(struct dp_mon_pdev_be *mon_pdev_be) { - struct dp_mon_tlv_logger *tlv_log = NULL; - struct dp_mon_tlv_info *tlv_info = NULL; +#ifdef QCA_KMEM_CACHE_SUPPORT +QDF_STATUS dp_rx_mon_ppdu_info_cache_create(struct dp_pdev *pdev) +{ + struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; + struct dp_mon_pdev_be *mon_pdev_be = + dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev); + uint16_t obj; + struct hal_rx_ppdu_info *ppdu_info = NULL; - if (!mon_pdev_be || !(mon_pdev_be->rx_tlv_log)) - return; + mon_pdev_be->ppdu_info_cache = + qdf_kmem_cache_create("rx_mon_ppdu_info_cache", + sizeof(struct hal_rx_ppdu_info)); - tlv_log = mon_pdev_be->rx_tlv_log; - if (!tlv_log->tlv_logging_enable || !(tlv_log->buff)) - return; + if (!mon_pdev_be->ppdu_info_cache) { + dp_mon_err("cache creation failed pdev :%px", pdev); + return QDF_STATUS_E_NOMEM; + } - tlv_info = (struct dp_mon_tlv_info *)tlv_log->buff; + TAILQ_INIT(&mon_pdev_be->rx_mon_free_queue); + for (obj = 0; obj < DP_RX_MON_WQ_THRESHOLD; obj++) { + ppdu_info = (struct hal_rx_ppdu_info *)qdf_kmem_cache_alloc(mon_pdev_be->ppdu_info_cache); - (tlv_log->curr_ppdu_pos + 1 == MAX_NUM_PPDU_RECORD) ? - tlv_log->curr_ppdu_pos = 0 : - tlv_log->curr_ppdu_pos++; + if (ppdu_info) { + qdf_mem_zero(ppdu_info, sizeof(struct hal_rx_ppdu_info)); + TAILQ_INSERT_TAIL(&mon_pdev_be->rx_mon_free_queue, + ppdu_info, + ppdu_free_list_elem); + mon_pdev_be->total_free_elem++; + } + } + qdf_spinlock_create(&mon_pdev_be->ppdu_info_lock); - 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; + return QDF_STATUS_SUCCESS; +} + +void dp_rx_mon_ppdu_info_cache_destroy(struct dp_pdev *pdev) +{ + struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; + struct dp_mon_pdev_be *mon_pdev_be = + dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev); + struct hal_rx_ppdu_info *ppdu_info = NULL, *temp_ppdu_info = NULL; + + qdf_spin_lock(&mon_pdev_be->ppdu_info_lock); + TAILQ_FOREACH_SAFE(ppdu_info, + &mon_pdev_be->rx_mon_free_queue, + ppdu_free_list_elem, + temp_ppdu_info) { + TAILQ_REMOVE(&mon_pdev_be->rx_mon_free_queue, + ppdu_info, ppdu_free_list_elem); + if (ppdu_info) { + mon_pdev_be->total_free_elem--; + qdf_kmem_cache_free(mon_pdev_be->ppdu_info_cache, + ppdu_info); + } + } + qdf_spin_unlock(&mon_pdev_be->ppdu_info_lock); + dp_mon_debug(" total free element: %d", mon_pdev_be->total_free_elem); + qdf_kmem_cache_destroy(mon_pdev_be->ppdu_info_cache); +} +#endif + +static QDF_STATUS dp_rx_mon_init_wq_sm(struct dp_pdev *pdev) +{ + struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; + struct dp_mon_pdev_be *mon_pdev_be = + dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev); + + qdf_create_work(0, &mon_pdev_be->rx_mon_work, + dp_rx_mon_process_ppdu, pdev); + mon_pdev_be->rx_mon_workqueue = + qdf_alloc_unbound_workqueue("rx_mon_work_queue"); + + if (!mon_pdev_be->rx_mon_workqueue) { + dp_mon_err("failed to create rxmon wq mon_pdev: %pK", mon_pdev); + goto fail; + } + TAILQ_INIT(&mon_pdev_be->rx_mon_queue); + + qdf_spinlock_create(&mon_pdev_be->rx_mon_wq_lock); + return QDF_STATUS_SUCCESS; + +fail: + return QDF_STATUS_E_FAILURE; +} + +static QDF_STATUS dp_rx_mon_deinit_wq_sm(struct dp_pdev *pdev) +{ + struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; + struct dp_mon_pdev_be *mon_pdev_be = + dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev); + + if (!mon_pdev_be->rx_mon_workqueue) + return QDF_STATUS_E_FAILURE; + + qdf_err(" total free element: %d", mon_pdev_be->total_free_elem); + qdf_flush_workqueue(0, mon_pdev_be->rx_mon_workqueue); + qdf_destroy_workqueue(0, mon_pdev_be->rx_mon_workqueue); + qdf_flush_work(&mon_pdev_be->rx_mon_work); + qdf_disable_work(&mon_pdev_be->rx_mon_work); + dp_rx_mon_drain_wq(pdev); + mon_pdev_be->rx_mon_workqueue = NULL; + qdf_spinlock_destroy(&mon_pdev_be->rx_mon_wq_lock); + + return QDF_STATUS_SUCCESS; +} + +static +void dp_rx_mon_set_zero(qdf_nbuf_t nbuf) +{ + qdf_mem_zero(qdf_nbuf_head(nbuf), DP_RX_MON_TLV_ROOM); } /** - * dp_mon_record_tlv() - Store the contents of the tlv in buffer + * dp_rx_mon_nbuf_add_rx_frag() - Add frag to SKB * - * @mon_pdev_be: pointe to dp_mon_pdev_be - * @ppdu_info: struct hal_rx_ppdu_info + * @nbuf: SKB to which frag is going to be added + * @frag: frag to be added to SKB + * @frag_len: frag length + * @offset: frag offset + * @buf_size: buffer size + * @frag_ref: take frag ref * - * Return + * Return: QDF_STATUS */ -void -dp_mon_record_tlv(struct dp_mon_pdev_be *mon_pdev_be, - 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; +static inline QDF_STATUS +dp_rx_mon_nbuf_add_rx_frag(qdf_nbuf_t nbuf, qdf_frag_t *frag, + uint16_t frag_len, uint16_t offset, + uint16_t buf_size, bool frag_ref) +{ + uint8_t num_frags; - if (!mon_pdev_be || !(mon_pdev_be->rx_tlv_log)) + num_frags = qdf_nbuf_get_nr_frags(nbuf); + if (num_frags < QDF_NBUF_MAX_FRAGS) { + qdf_nbuf_add_rx_frag(frag, nbuf, + offset, + frag_len, + buf_size, + frag_ref); + return QDF_STATUS_SUCCESS; + } + return QDF_STATUS_E_FAILURE; +} + +/** + * dp_rx_mon_handle_mpdu_end() - Process MPDU_END TLV + * + * @ppdu_info: PPDU info + * + * Return: void + */ +static inline void +dp_rx_mon_handle_mpdu_end(struct hal_rx_ppdu_info *ppdu_info) +{ + struct hal_rx_mon_mpdu_info *mpdu_info, *mpdu_meta; + qdf_nbuf_t nbuf; + uint8_t user_id = ppdu_info->user_id; + uint8_t mpdu_idx = ppdu_info->mpdu_count[user_id]; + + mpdu_info = &ppdu_info->mpdu_info[user_id]; + if (qdf_unlikely(!ppdu_info->rx_hdr_rcvd[user_id])) { + /* reset mpdu info for next mpdu for same user */ + qdf_mem_zero(mpdu_info, sizeof(*mpdu_info)); + dp_mon_debug(" <%d> nbuf is NULL, return user: %d mpdu_idx: %d", + __LINE__, user_id, mpdu_idx); return; - - tlv_log = mon_pdev_be->rx_tlv_log; - if (!tlv_log->tlv_logging_enable || !(tlv_log->buff)) + } + nbuf = qdf_nbuf_queue_last(&ppdu_info->mpdu_q[user_id]); + if (qdf_unlikely(!nbuf)) { + dp_mon_debug("nbuf is NULL"); return; + } + mpdu_meta = (struct hal_rx_mon_mpdu_info *)qdf_nbuf_data(nbuf); + mpdu_meta->mpdu_length_err = mpdu_info->mpdu_length_err; + mpdu_meta->fcs_err = mpdu_info->fcs_err; + mpdu_meta->overflow_err = mpdu_info->overflow_err; + mpdu_meta->decrypt_err = mpdu_info->decrypt_err; + mpdu_meta->full_pkt = mpdu_info->full_pkt; + mpdu_meta->truncated = mpdu_info->truncated; - 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; + /* reset mpdu info for next mpdu for same user */ + qdf_mem_zero(mpdu_info, sizeof(*mpdu_info)); + ppdu_info->mpdu_info[ppdu_info->user_id].mpdu_start_received = false; + ppdu_info->mpdu_count[user_id]++; +} - 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; +/** + * dp_rx_mon_handle_mpdu_start() - Process MPDU_START TLV + * + * @ppdu_info: PPDU info + * + * Return: void + */ +static inline void +dp_rx_mon_handle_mpdu_start(struct hal_rx_ppdu_info *ppdu_info) +{ + struct hal_rx_mon_mpdu_info *mpdu_info, *mpdu_meta; + qdf_nbuf_t nbuf; + uint8_t user_id = ppdu_info->user_id; + uint8_t mpdu_idx = ppdu_info->mpdu_count[user_id]; + + if (qdf_unlikely(!ppdu_info->rx_hdr_rcvd[user_id])) { + dp_mon_debug(" <%d> nbuf is NULL, return user: %d mpdu_idx: %d", __LINE__, user_id, mpdu_idx); + return; + } + nbuf = qdf_nbuf_queue_last(&ppdu_info->mpdu_q[user_id]); + if (qdf_unlikely(!nbuf)) { + dp_mon_debug("nbuf is NULL"); + return; + } + mpdu_meta = (struct hal_rx_mon_mpdu_info *)qdf_nbuf_data(nbuf); + mpdu_info = &ppdu_info->mpdu_info[user_id]; + mpdu_meta->decap_type = mpdu_info->decap_type; + ppdu_info->mpdu_info[ppdu_info->user_id].mpdu_start_received = true; +} + +/** + * dp_rx_mon_handle_msdu_end() - Process MSDU_END TLV + * + * @pdev: DP Pdev + * @ppdu_info: PPDU info + * + * Return: void + */ +static inline void +dp_rx_mon_handle_msdu_end(struct dp_pdev *pdev, + struct hal_rx_ppdu_info *ppdu_info) +{ + qdf_nbuf_t nbuf; + qdf_frag_t addr; + uint16_t num_frags; + struct hal_rx_mon_msdu_info *msdu_info; + struct hal_rx_mon_msdu_info *last_buf_info; + uint8_t user_id = ppdu_info->user_id; + uint8_t mpdu_idx = ppdu_info->mpdu_count[user_id]; + + msdu_info = &ppdu_info->msdu[user_id]; + /* update msdu metadata at last buffer of msdu in MPDU */ + if (qdf_unlikely(!ppdu_info->rx_hdr_rcvd[user_id])) { + /* reset msdu info for next msdu for same user */ + qdf_mem_zero(msdu_info, sizeof(*msdu_info)); + dp_mon_debug(" <%d> nbuf is NULL, return user: %d mpdu_idx: %d", + __LINE__, user_id, mpdu_idx); + return; + } + nbuf = qdf_nbuf_queue_last(&ppdu_info->mpdu_q[user_id]); + if (qdf_unlikely(!nbuf)) { + dp_mon_debug("nbuf is NULL"); + return; + } + num_frags = qdf_nbuf_get_nr_frags(nbuf); + if (ppdu_info->mpdu_info[user_id].decap_type == + HAL_HW_RX_DECAP_FORMAT_RAW) { + return; + } + /* This points to last buffer of MSDU . update metadata here */ + addr = qdf_nbuf_get_frag_addr(nbuf, num_frags - 1) - + DP_RX_MON_PACKET_OFFSET; + last_buf_info = addr; + + last_buf_info->first_msdu = msdu_info->first_msdu; + last_buf_info->last_msdu = msdu_info->last_msdu; + last_buf_info->decap_type = msdu_info->decap_type; + last_buf_info->msdu_index = msdu_info->msdu_index; + last_buf_info->user_rssi = msdu_info->user_rssi; + last_buf_info->reception_type = msdu_info->reception_type; + last_buf_info->msdu_len = msdu_info->msdu_len; + + /* If flow classification is enabled, + * update protocol and flow tag to buf headroom + */ + dp_rx_mon_pf_tag_to_buf_headroom_2_0(nbuf, ppdu_info, pdev, pdev->soc); + + /* reset msdu info for next msdu for same user */ + qdf_mem_zero(msdu_info, sizeof(*msdu_info)); +} + +/** + * dp_rx_mon_handle_mon_buf_addr() - Process MON BUF ADDR TLV + * + * @pdev: DP Pdev + * @ppdu_info: PPDU info + * @desc_list: desc list head + * @tail: desc list tail + * + * Return: number of buffers reaped + */ +static inline uint16_t +dp_rx_mon_handle_mon_buf_addr(struct dp_pdev *pdev, + struct hal_rx_ppdu_info *ppdu_info, + union dp_mon_desc_list_elem_t **desc_list, + union dp_mon_desc_list_elem_t **tail) +{ + struct dp_soc *soc = pdev->soc; + struct dp_mon_soc *mon_soc = soc->monitor_soc; + struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; + struct dp_mon_pdev_be *mon_pdev_be = + dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev); + struct hal_rx_mon_msdu_info *buf_info; + struct hal_mon_packet_info *packet_info = &ppdu_info->packet_info; + struct dp_mon_desc *mon_desc = (struct dp_mon_desc *)(uintptr_t)ppdu_info->packet_info.sw_cookie; + unsigned long long desc = ppdu_info->packet_info.sw_cookie; + struct hal_rx_mon_mpdu_info *mpdu_info; + qdf_nbuf_t nbuf, tmp_nbuf; + qdf_frag_t addr; + uint16_t frag_idx = 0; + uint16_t num_buf_reaped = 0; + uint8_t user_id = ppdu_info->user_id; + bool rx_hdr_valid = true; + uint32_t cookie_2; + + if (!mon_pdev->monitor_configured && + !dp_lite_mon_is_rx_enabled(mon_pdev)) { + return num_buf_reaped; + } + + if (qdf_unlikely(user_id >= HAL_MAX_UL_MU_USERS || + ppdu_info->hdr_len > DP_RX_MON_MAX_RX_HEADER_LEN)) + rx_hdr_valid = false; + + cookie_2 = DP_MON_GET_COOKIE(desc); + mon_desc = DP_MON_GET_DESC(desc); + qdf_assert_always(mon_desc); + + if (mon_desc->cookie_2 != cookie_2) { + mon_pdev->rx_mon_stats.dup_mon_sw_desc++; + qdf_err("duplicate cookie found mon_desc:%pK", mon_desc); + qdf_assert_always(0); + } + + if (mon_desc->magic != DP_MON_DESC_MAGIC) + qdf_assert_always(0); + + /* WAR: sometimes duplicate pkt desc are received + * from HW this check gracefully handles + * such cases. + */ + if ((mon_desc == mon_pdev_be->prev_rxmon_pkt_desc) && + (mon_desc->cookie == mon_pdev_be->prev_rxmon_pkt_cookie)) { + dp_mon_err("duplicate pkt desc found mon_pdev: %pK mon_desc: %pK cookie: %d", + mon_pdev, mon_desc, + mon_desc->cookie); + mon_pdev->rx_mon_stats.dup_mon_buf_cnt++; + return num_buf_reaped; + } + mon_pdev_be->prev_rxmon_pkt_desc = mon_desc; + mon_pdev_be->prev_rxmon_pkt_cookie = mon_desc->cookie; + + addr = mon_desc->buf_addr; + qdf_assert_always(addr); + + if (!mon_desc->unmapped) { + qdf_mem_unmap_page(soc->osdev, + (qdf_dma_addr_t)mon_desc->paddr, + DP_MON_DATA_BUFFER_SIZE, + QDF_DMA_FROM_DEVICE); + mon_desc->unmapped = 1; + } + dp_mon_add_to_free_desc_list(desc_list, tail, mon_desc); + num_buf_reaped++; + + mon_pdev->rx_mon_stats.pkt_buf_count++; + + /* if rx hdr is not valid free pkt buffer and return */ + if (qdf_unlikely(!rx_hdr_valid)) { + DP_STATS_INC(mon_soc, frag_free, 1); + qdf_frag_free(addr); + return num_buf_reaped; + } + + if (qdf_unlikely(!ppdu_info->rx_hdr_rcvd[user_id])) { + /* WAR: RX_HDR is not received for this MPDU, drop this frame */ + mon_pdev->rx_mon_stats.rx_hdr_not_received++; + DP_STATS_INC(mon_soc, frag_free, 1); + qdf_frag_free(addr); + return num_buf_reaped; + } + + if (packet_info->dma_length > + (DP_MON_DATA_BUFFER_SIZE - DP_RX_MON_PACKET_OFFSET)) { + /* WAR: Invalid DMA length is received for this MPDU */ + mon_pdev->rx_mon_stats.invalid_dma_length++; + DP_STATS_INC(mon_soc, frag_free, 1); + qdf_frag_free(addr); + return num_buf_reaped; + } + + nbuf = qdf_nbuf_queue_last(&ppdu_info->mpdu_q[user_id]); + if (qdf_unlikely(!nbuf)) { + dp_mon_debug("nbuf is NULL"); + DP_STATS_INC(mon_soc, frag_free, 1); + DP_STATS_INC(mon_soc, empty_queue, 1); + qdf_frag_free(addr); + return num_buf_reaped; + } + + mpdu_info = &ppdu_info->mpdu_info[user_id]; + if (mpdu_info->decap_type == DP_MON_DECAP_FORMAT_INVALID) { + /* decap type is invalid, drop the frame */ + mon_pdev->rx_mon_stats.mpdu_decap_type_invalid++; + DP_STATS_INC(mon_soc, frag_free, 1); + mon_pdev->rx_mon_stats.parent_buf_free++; + qdf_frag_free(addr); + qdf_nbuf_queue_remove_last(&ppdu_info->mpdu_q[user_id]); + qdf_nbuf_free(nbuf); + /* if invalid decap type handling is disabled, assert */ + if (soc->wlan_cfg_ctx->is_handle_invalid_decap_type_disabled) { + dp_mon_err("Decap type invalid"); + qdf_assert_always(0); } - 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; + ppdu_info->rx_hdr_rcvd[user_id] = false; + return num_buf_reaped; + } + + tmp_nbuf = qdf_get_nbuf_valid_frag(nbuf); + + if (!tmp_nbuf) { + tmp_nbuf = qdf_nbuf_alloc(pdev->soc->osdev, + DP_RX_MON_MAX_MONITOR_HEADER, + DP_RX_MON_MAX_MONITOR_HEADER, + 4, FALSE); + if (qdf_unlikely(!tmp_nbuf)) { + dp_mon_err("nbuf is NULL"); + DP_STATS_INC(mon_soc, frag_free, 1); + mon_pdev->rx_mon_stats.parent_buf_free++; + qdf_frag_free(addr); + /* remove this nbuf from queue */ + qdf_nbuf_queue_remove_last(&ppdu_info->mpdu_q[user_id]); + qdf_nbuf_free(nbuf); + return num_buf_reaped; } - if (*mpdu_idx < tlv_log->max_mpdu_idx) { - (*mpdu_idx)++; + mon_pdev->rx_mon_stats.parent_buf_alloc++; + dp_rx_mon_append_nbuf(nbuf, tmp_nbuf); + } + mpdu_info->full_pkt = true; + + if (mpdu_info->decap_type == HAL_HW_RX_DECAP_FORMAT_RAW) { + if (mpdu_info->first_rx_hdr_rcvd) { + qdf_nbuf_remove_frag(nbuf, frag_idx, DP_MON_DATA_BUFFER_SIZE); + dp_rx_mon_nbuf_add_rx_frag(nbuf, addr, + packet_info->dma_length, + DP_RX_MON_PACKET_OFFSET, + DP_MON_DATA_BUFFER_SIZE, + false); + DP_STATS_INC(mon_soc, frag_free, 1); + mpdu_info->first_rx_hdr_rcvd = false; } else { - *mpdu_idx = *mpdu_idx - MAX_MPDU_TLV_NUM + 1; - tlv_log->wrap_flag ^= 1; + dp_rx_mon_nbuf_add_rx_frag(tmp_nbuf, addr, + packet_info->dma_length, + DP_RX_MON_PACKET_OFFSET, + DP_MON_DATA_BUFFER_SIZE, + false); + DP_STATS_INC(mon_soc, frag_free, 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; + } else { + dp_rx_mon_nbuf_add_rx_frag(tmp_nbuf, addr, + packet_info->dma_length, + DP_RX_MON_PACKET_OFFSET, + DP_MON_DATA_BUFFER_SIZE, + false); + DP_STATS_INC(mon_soc, frag_free, 1); + buf_info = addr; + + if (!ppdu_info->msdu[user_id].first_buffer) { + buf_info->first_buffer = true; + ppdu_info->msdu[user_id].first_buffer = true; + } else { + buf_info->first_buffer = false; + } + + if (packet_info->msdu_continuation) + buf_info->last_buffer = false; + else + buf_info->last_buffer = true; + + buf_info->frag_len = packet_info->dma_length; + } + if (qdf_unlikely(packet_info->truncated)) + mpdu_info->truncated = true; + + return num_buf_reaped; +} + +/** + * dp_rx_mon_handle_rx_hdr() - Process RX_HDR TLV + * + * @pdev: DP pdev + * @ppdu_info: PPDU info + * @status_frag: Status frag + * + * Return: void + */ +static inline void +dp_rx_mon_handle_rx_hdr(struct dp_pdev *pdev, + struct hal_rx_ppdu_info *ppdu_info, + void *status_frag) +{ + struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; + qdf_nbuf_t nbuf, tmp_nbuf; + uint8_t user_id = ppdu_info->user_id; + QDF_STATUS status; + + /* If this is first RX_HEADER for MPDU, allocate skb + * else add frag to already allocated skb + */ + + if (!ppdu_info->mpdu_info[user_id].mpdu_start_received) { + nbuf = qdf_nbuf_alloc(pdev->soc->osdev, + DP_RX_MON_TLV_ROOM + + DP_RX_MON_MAX_RADIO_TAP_HDR, + DP_RX_MON_TLV_ROOM + + DP_RX_MON_MAX_RADIO_TAP_HDR, + 4, FALSE); + + /** + * Set *head_msdu->next as NULL as all msdus are + * mapped via nr frags + **/ + if (qdf_unlikely(!nbuf)) { + dp_mon_debug("malloc failed pdev: %pK ", pdev); + return; + } + + mon_pdev->rx_mon_stats.parent_buf_alloc++; + + dp_rx_mon_set_zero(nbuf); + + qdf_nbuf_set_next(nbuf, NULL); + + qdf_nbuf_queue_add(&ppdu_info->mpdu_q[user_id], nbuf); + + status = dp_rx_mon_nbuf_add_rx_frag(nbuf, status_frag, + ppdu_info->hdr_len - DP_RX_MON_RX_HDR_OFFSET, + ppdu_info->data - (unsigned char *)status_frag + 4, + DP_MON_DATA_BUFFER_SIZE, true); + if (qdf_unlikely(status != QDF_STATUS_SUCCESS)) { + dp_mon_err("num_frags exceeding MAX frags"); + return; + } + ppdu_info->mpdu_info[ppdu_info->user_id].mpdu_start_received = true; + ppdu_info->mpdu_info[user_id].first_rx_hdr_rcvd = true; + /* initialize decap type to invalid, this will be set to appropriate + * value once the mpdu start tlv is received + */ + ppdu_info->mpdu_info[user_id].decap_type = DP_MON_DECAP_FORMAT_INVALID; + } else { + if (ppdu_info->mpdu_info[user_id].decap_type == + HAL_HW_RX_DECAP_FORMAT_RAW) { + return; + } + + if (dp_lite_mon_is_rx_enabled(mon_pdev) && + !dp_lite_mon_is_level_msdu(mon_pdev)) + return; + + nbuf = qdf_nbuf_queue_last(&ppdu_info->mpdu_q[user_id]); + if (qdf_unlikely(!nbuf)) { + dp_mon_debug("nbuf is NULL"); + return; + } + + tmp_nbuf = qdf_get_nbuf_valid_frag(nbuf); + + if (!tmp_nbuf) { + tmp_nbuf = qdf_nbuf_alloc(pdev->soc->osdev, + DP_RX_MON_MAX_MONITOR_HEADER, + DP_RX_MON_MAX_MONITOR_HEADER, + 4, FALSE); + if (qdf_unlikely(!tmp_nbuf)) { + dp_mon_err("nbuf is NULL"); + qdf_assert_always(0); + } + mon_pdev->rx_mon_stats.parent_buf_alloc++; + dp_rx_mon_append_nbuf(nbuf, tmp_nbuf); + } + dp_rx_mon_nbuf_add_rx_frag(tmp_nbuf, status_frag, + ppdu_info->hdr_len - DP_RX_MON_RX_HDR_OFFSET, + ppdu_info->data - (unsigned char *)status_frag + 4, + DP_MON_DATA_BUFFER_SIZE, + true); + } + ppdu_info->rx_hdr_rcvd[user_id] = true; +} + +/** + * dp_rx_mon_free_mpdu_queue() - Free MPDU queue + * @mon_pdev: monitor pdev + * @ppdu_info: PPDU info + * + * Return: Void + */ + +static void dp_rx_mon_free_mpdu_queue(struct dp_mon_pdev *mon_pdev, + struct hal_rx_ppdu_info *ppdu_info) +{ + uint8_t user; + qdf_nbuf_t mpdu; + + for (user = 0; user < HAL_MAX_UL_MU_USERS; user++) { + if (!qdf_nbuf_is_queue_empty(&ppdu_info->mpdu_q[user])) { + while ((mpdu = qdf_nbuf_queue_remove(&ppdu_info->mpdu_q[user])) != NULL) + dp_mon_free_parent_nbuf(mon_pdev, mpdu); } - if (*ppdu_end_idx < tlv_log->max_ppdu_end_idx) - (*ppdu_end_idx)++; } } +#ifdef QCA_KMEM_CACHE_SUPPORT /** - * dp_mon_record_clear_buffer() - Clear the buffer to record next PPDU + * dp_rx_mon_get_ppdu_info() - Get PPDU info from freelist * - * @mon_pdev_be: pointer to dp_mon_pdev_be + * @mon_pdev: monitor pdev * - * Return + * Return: ppdu_info + */ +struct hal_rx_ppdu_info* +dp_rx_mon_get_ppdu_info(struct dp_mon_pdev *mon_pdev) +{ + struct dp_mon_pdev_be *mon_pdev_be = + dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev); + struct hal_rx_ppdu_info *ppdu_info, *temp_ppdu_info; + + qdf_spin_lock_bh(&mon_pdev_be->ppdu_info_lock); + TAILQ_FOREACH_SAFE(ppdu_info, + &mon_pdev_be->rx_mon_free_queue, + ppdu_free_list_elem, + temp_ppdu_info) { + TAILQ_REMOVE(&mon_pdev_be->rx_mon_free_queue, + ppdu_info, ppdu_free_list_elem); + + if (ppdu_info) { + mon_pdev_be->total_free_elem--; + break; + } + } + qdf_spin_unlock_bh(&mon_pdev_be->ppdu_info_lock); + + return ppdu_info; +} + +void +__dp_rx_mon_free_ppdu_info(struct dp_mon_pdev *mon_pdev, + struct hal_rx_ppdu_info *ppdu_info) +{ + struct dp_mon_pdev_be *mon_pdev_be = + dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev); + + qdf_spin_lock_bh(&mon_pdev_be->ppdu_info_lock); + if (ppdu_info) { + qdf_mem_zero(ppdu_info, sizeof(struct hal_rx_ppdu_info)); + TAILQ_INSERT_TAIL(&mon_pdev_be->rx_mon_free_queue, ppdu_info, + ppdu_free_list_elem); + mon_pdev_be->total_free_elem++; + } + qdf_spin_unlock_bh(&mon_pdev_be->ppdu_info_lock); +} + +/** + * dp_rx_mon_free_ppdu_info() - Free PPDU info + * @pdev: DP pdev + * @ppdu_info: PPDU info + * + * Return: Void */ void -dp_mon_record_clear_buffer(struct dp_mon_pdev_be *mon_pdev_be) { - struct dp_mon_tlv_logger *tlv_log = NULL; - struct dp_mon_tlv_info *tlv_info = NULL; +dp_rx_mon_free_ppdu_info(struct dp_pdev *pdev, + struct hal_rx_ppdu_info *ppdu_info) +{ + struct dp_mon_pdev *mon_pdev; - if (!mon_pdev_be || !(mon_pdev_be->rx_tlv_log)) - return; - - tlv_log = mon_pdev_be->rx_tlv_log; - if (!tlv_log->tlv_logging_enable || !(tlv_log->buff)) - return; - - tlv_info = (struct dp_mon_tlv_info *)tlv_log->buff; - qdf_mem_zero(&tlv_info[tlv_log->ppdu_start_idx], - MAX_TLVS_PER_PPDU * sizeof(struct dp_mon_tlv_info)); + mon_pdev = (struct dp_mon_pdev *)pdev->monitor_pdev; + dp_rx_mon_free_mpdu_queue(mon_pdev, ppdu_info); + __dp_rx_mon_free_ppdu_info(mon_pdev, ppdu_info); } - -#else - -void -dp_mon_record_index_update(struct dp_mon_pdev_be *mon_pdev_be) { -} - -void -dp_mon_record_tlv(struct dp_mon_pdev_be *mon_pdev_be, - struct hal_rx_ppdu_info *ppdu_info) { -} - -void -dp_mon_record_clear_buffer(struct dp_mon_pdev_be *mon_pdev_be) { -} - #endif /** @@ -1324,6 +1875,8 @@ end: return work_done; } +#endif + /** * dp_rx_mon_flush_status_buf_queue() - Flush status buffer queue * @@ -1457,20 +2010,10 @@ uint8_t dp_rx_mon_process_tlv_status(struct dp_pdev *pdev, union dp_mon_desc_list_elem_t **desc_list, union dp_mon_desc_list_elem_t **tail) { - struct dp_soc *soc = pdev->soc; - struct dp_mon_soc *mon_soc = soc->monitor_soc; struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; - struct dp_mon_pdev_be *mon_pdev_be = - dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev); - qdf_nbuf_t nbuf, tmp_nbuf; - qdf_frag_t addr; uint8_t user_id = ppdu_info->user_id; - uint8_t mpdu_idx = ppdu_info->mpdu_count[user_id]; - uint16_t num_frags; uint8_t num_buf_reaped = 0; bool rx_hdr_valid = true; - QDF_STATUS status; - uint32_t cookie_2; if (!mon_pdev->monitor_configured && !dp_lite_mon_is_rx_enabled(mon_pdev)) { @@ -1493,366 +2036,36 @@ uint8_t dp_rx_mon_process_tlv_status(struct dp_pdev *pdev, mon_pdev->rx_mon_stats.rx_hdr_invalid_cnt++; return num_buf_reaped; } - - /* If this is first RX_HEADER for MPDU, allocate skb - * else add frag to already allocated skb - */ - - if (!ppdu_info->mpdu_info[user_id].mpdu_start_received) { - - nbuf = qdf_nbuf_alloc(pdev->soc->osdev, - DP_RX_MON_TLV_ROOM + - DP_RX_MON_MAX_RADIO_TAP_HDR, - DP_RX_MON_TLV_ROOM + - DP_RX_MON_MAX_RADIO_TAP_HDR, - 4, FALSE); - - /* Set *head_msdu->next as NULL as all msdus are - * * mapped via nr frags - * */ - if (qdf_unlikely(!nbuf)) { - dp_mon_debug("malloc failed pdev: %pK ", pdev); - return num_buf_reaped; - } - - mon_pdev->rx_mon_stats.parent_buf_alloc++; - - dp_rx_mon_set_zero(nbuf); - - qdf_nbuf_set_next(nbuf, NULL); - - qdf_nbuf_queue_add(&ppdu_info->mpdu_q[user_id], nbuf); - - status = dp_rx_mon_nbuf_add_rx_frag(nbuf, status_frag, - ppdu_info->hdr_len - DP_RX_MON_RX_HDR_OFFSET, - ppdu_info->data - (unsigned char *)status_frag + 4, - DP_MON_DATA_BUFFER_SIZE, true); - if (qdf_unlikely(status != QDF_STATUS_SUCCESS)) { - dp_mon_err("num_frags exceeding MAX frags"); - return num_buf_reaped; - } - ppdu_info->mpdu_info[ppdu_info->user_id].mpdu_start_received = true; - ppdu_info->mpdu_info[user_id].first_rx_hdr_rcvd = true; - /* initialize decap type to invalid, this will be set to appropriate - * value once the mpdu start tlv is received - */ - ppdu_info->mpdu_info[user_id].decap_type = DP_MON_DECAP_FORMAT_INVALID; - } else { - if (ppdu_info->mpdu_info[user_id].decap_type == - HAL_HW_RX_DECAP_FORMAT_RAW) { - return num_buf_reaped; - } - - if (dp_lite_mon_is_rx_enabled(mon_pdev) && - !dp_lite_mon_is_level_msdu(mon_pdev)) - break; - - nbuf = qdf_nbuf_queue_last(&ppdu_info->mpdu_q[user_id]); - if (qdf_unlikely(!nbuf)) { - dp_mon_debug("nbuf is NULL"); - return num_buf_reaped; - } - - tmp_nbuf = qdf_get_nbuf_valid_frag(nbuf); - - if (!tmp_nbuf) { - tmp_nbuf = qdf_nbuf_alloc(pdev->soc->osdev, - DP_RX_MON_MAX_MONITOR_HEADER, - DP_RX_MON_MAX_MONITOR_HEADER, - 4, FALSE); - if (qdf_unlikely(!tmp_nbuf)) { - dp_mon_err("nbuf is NULL"); - qdf_assert_always(0); - } - mon_pdev->rx_mon_stats.parent_buf_alloc++; - dp_rx_mon_append_nbuf(nbuf, tmp_nbuf); - } - dp_rx_mon_nbuf_add_rx_frag(tmp_nbuf, status_frag, - ppdu_info->hdr_len - DP_RX_MON_RX_HDR_OFFSET, - ppdu_info->data - (unsigned char *)status_frag + 4, - DP_MON_DATA_BUFFER_SIZE, - true); - } - ppdu_info->rx_hdr_rcvd[user_id] = true; + dp_rx_mon_handle_rx_hdr(pdev, ppdu_info, status_frag); } break; case HAL_TLV_STATUS_MON_BUF_ADDR: { - struct hal_rx_mon_msdu_info *buf_info; - struct hal_mon_packet_info *packet_info = &ppdu_info->packet_info; - struct dp_mon_desc *mon_desc = (struct dp_mon_desc *)(uintptr_t)ppdu_info->packet_info.sw_cookie; - unsigned long long desc = ppdu_info->packet_info.sw_cookie; - struct hal_rx_mon_mpdu_info *mpdu_info; - uint16_t frag_idx = 0; - - cookie_2 = DP_MON_GET_COOKIE(desc); - mon_desc = DP_MON_GET_DESC(desc); - qdf_assert_always(mon_desc); - - if (mon_desc->cookie_2 != cookie_2) { - mon_pdev->rx_mon_stats.dup_mon_sw_desc++; - qdf_err("duplicate cookie found mon_desc:%pK", mon_desc); - qdf_assert_always(0); - } - - if (mon_desc->magic != DP_MON_DESC_MAGIC) - qdf_assert_always(0); - - /* WAR: sometimes duplicate pkt desc are received - * from HW this check gracefully handles - * such cases. - */ - if ((mon_desc == mon_pdev_be->prev_rxmon_pkt_desc) && - (mon_desc->cookie == - mon_pdev_be->prev_rxmon_pkt_cookie)) { - dp_mon_err("duplicate pkt desc found mon_pdev: %pK mon_desc: %pK cookie: %d", - mon_pdev, mon_desc, - mon_desc->cookie); - mon_pdev->rx_mon_stats.dup_mon_buf_cnt++; - return num_buf_reaped; - } - mon_pdev_be->prev_rxmon_pkt_desc = mon_desc; - mon_pdev_be->prev_rxmon_pkt_cookie = mon_desc->cookie; - - addr = mon_desc->buf_addr; - qdf_assert_always(addr); - - if (!mon_desc->unmapped) { - qdf_mem_unmap_page(soc->osdev, - (qdf_dma_addr_t)mon_desc->paddr, - DP_MON_DATA_BUFFER_SIZE, - QDF_DMA_FROM_DEVICE); - mon_desc->unmapped = 1; - } - dp_mon_add_to_free_desc_list(desc_list, tail, mon_desc); - num_buf_reaped++; - - mon_pdev->rx_mon_stats.pkt_buf_count++; - - /* if rx hdr is not valid free pkt buffer and return */ - if (qdf_unlikely(!rx_hdr_valid)) { - DP_STATS_INC(mon_soc, frag_free, 1); - qdf_frag_free(addr); - return num_buf_reaped; - } - - if (qdf_unlikely(!ppdu_info->rx_hdr_rcvd[user_id])) { - - /* WAR: RX_HDR is not received for this MPDU, drop this frame */ - mon_pdev->rx_mon_stats.rx_hdr_not_received++; - DP_STATS_INC(mon_soc, frag_free, 1); - qdf_frag_free(addr); - return num_buf_reaped; - } - - if (packet_info->dma_length > - (DP_MON_DATA_BUFFER_SIZE - DP_RX_MON_PACKET_OFFSET)) { - /* WAR: Invalid DMA length is received for this MPDU */ - mon_pdev->rx_mon_stats.invalid_dma_length++; - DP_STATS_INC(mon_soc, frag_free, 1); - qdf_frag_free(addr); - return num_buf_reaped; - } - - nbuf = qdf_nbuf_queue_last(&ppdu_info->mpdu_q[user_id]); - if (qdf_unlikely(!nbuf)) { - dp_mon_debug("nbuf is NULL"); - DP_STATS_INC(mon_soc, frag_free, 1); - DP_STATS_INC(mon_soc, empty_queue, 1); - qdf_frag_free(addr); - return num_buf_reaped; - } - - mpdu_info = &ppdu_info->mpdu_info[user_id]; - if (mpdu_info->decap_type == DP_MON_DECAP_FORMAT_INVALID) { - /* decap type is invalid, drop the frame */ - mon_pdev->rx_mon_stats.mpdu_decap_type_invalid++; - DP_STATS_INC(mon_soc, frag_free, 1); - mon_pdev->rx_mon_stats.parent_buf_free++; - qdf_frag_free(addr); - qdf_nbuf_queue_remove_last(&ppdu_info->mpdu_q[user_id]); - qdf_nbuf_free(nbuf); - /* if invalid decap type handling is disabled, assert */ - if (soc->wlan_cfg_ctx->is_handle_invalid_decap_type_disabled) { - dp_mon_err("Decap type invalid"); - qdf_assert_always(0); - } - ppdu_info->rx_hdr_rcvd[user_id] = false; - return num_buf_reaped; - } - - tmp_nbuf = qdf_get_nbuf_valid_frag(nbuf); - - if (!tmp_nbuf) { - tmp_nbuf = qdf_nbuf_alloc(pdev->soc->osdev, - DP_RX_MON_MAX_MONITOR_HEADER, - DP_RX_MON_MAX_MONITOR_HEADER, - 4, FALSE); - if (qdf_unlikely(!tmp_nbuf)) { - dp_mon_err("nbuf is NULL"); - DP_STATS_INC(mon_soc, frag_free, 1); - mon_pdev->rx_mon_stats.parent_buf_free++; - qdf_frag_free(addr); - /* remove this nbuf from queue */ - qdf_nbuf_queue_remove_last(&ppdu_info->mpdu_q[user_id]); - qdf_nbuf_free(nbuf); - return num_buf_reaped; - } - mon_pdev->rx_mon_stats.parent_buf_alloc++; - dp_rx_mon_append_nbuf(nbuf, tmp_nbuf); - } - mpdu_info->full_pkt = true; - - if (mpdu_info->decap_type == HAL_HW_RX_DECAP_FORMAT_RAW) { - if (mpdu_info->first_rx_hdr_rcvd) { - qdf_nbuf_remove_frag(nbuf, frag_idx, DP_MON_DATA_BUFFER_SIZE); - dp_rx_mon_nbuf_add_rx_frag(nbuf, addr, - packet_info->dma_length, - DP_RX_MON_PACKET_OFFSET, - DP_MON_DATA_BUFFER_SIZE, - false); - DP_STATS_INC(mon_soc, frag_free, 1); - mpdu_info->first_rx_hdr_rcvd = false; - } else { - dp_rx_mon_nbuf_add_rx_frag(tmp_nbuf, addr, - packet_info->dma_length, - DP_RX_MON_PACKET_OFFSET, - DP_MON_DATA_BUFFER_SIZE, - false); - DP_STATS_INC(mon_soc, frag_free, 1); - } - } else { - dp_rx_mon_nbuf_add_rx_frag(tmp_nbuf, addr, - packet_info->dma_length, - DP_RX_MON_PACKET_OFFSET, - DP_MON_DATA_BUFFER_SIZE, - false); - DP_STATS_INC(mon_soc, frag_free, 1); - buf_info = addr; - - if (!ppdu_info->msdu[user_id].first_buffer) { - buf_info->first_buffer = true; - ppdu_info->msdu[user_id].first_buffer = true; - } else { - buf_info->first_buffer = false; - } - - if (packet_info->msdu_continuation) - buf_info->last_buffer = false; - else - buf_info->last_buffer = true; - - buf_info->frag_len = packet_info->dma_length; - } - if (qdf_unlikely(packet_info->truncated)) - mpdu_info->truncated = true; + num_buf_reaped = dp_rx_mon_handle_mon_buf_addr(pdev, ppdu_info, desc_list, tail); } break; case HAL_TLV_STATUS_MSDU_END: { - struct hal_rx_mon_msdu_info *msdu_info; - struct hal_rx_mon_msdu_info *last_buf_info; - if (qdf_unlikely(!rx_hdr_valid)) break; - msdu_info = &ppdu_info->msdu[user_id]; - /* update msdu metadata at last buffer of msdu in MPDU */ - if (qdf_unlikely(!ppdu_info->rx_hdr_rcvd[user_id])) { - /* reset msdu info for next msdu for same user */ - qdf_mem_zero(msdu_info, sizeof(*msdu_info)); - dp_mon_debug(" <%d> nbuf is NULL, return user: %d mpdu_idx: %d", - __LINE__, user_id, mpdu_idx); - break; - } - nbuf = qdf_nbuf_queue_last(&ppdu_info->mpdu_q[user_id]); - if (qdf_unlikely(!nbuf)) { - dp_mon_debug("nbuf is NULL"); - break; - } - num_frags = qdf_nbuf_get_nr_frags(nbuf); - if (ppdu_info->mpdu_info[user_id].decap_type == - HAL_HW_RX_DECAP_FORMAT_RAW) { - break; - } - /* This points to last buffer of MSDU . update metadata here */ - addr = qdf_nbuf_get_frag_addr(nbuf, num_frags - 1) - - DP_RX_MON_PACKET_OFFSET; - last_buf_info = addr; - - last_buf_info->first_msdu = msdu_info->first_msdu; - last_buf_info->last_msdu = msdu_info->last_msdu; - last_buf_info->decap_type = msdu_info->decap_type; - last_buf_info->msdu_index = msdu_info->msdu_index; - last_buf_info->user_rssi = msdu_info->user_rssi; - last_buf_info->reception_type = msdu_info->reception_type; - last_buf_info->msdu_len = msdu_info->msdu_len; - - /* If flow classification is enabled, - * update protocol and flow tag to buf headroom - */ - dp_rx_mon_pf_tag_to_buf_headroom_2_0(nbuf, ppdu_info, pdev, - soc); - - /* reset msdu info for next msdu for same user */ - qdf_mem_zero(msdu_info, sizeof(*msdu_info)); + dp_rx_mon_handle_msdu_end(pdev, ppdu_info); } break; case HAL_TLV_STATUS_MPDU_START: { - struct hal_rx_mon_mpdu_info *mpdu_info, *mpdu_meta; - if (qdf_unlikely(!rx_hdr_valid)) break; - if (qdf_unlikely(!ppdu_info->rx_hdr_rcvd[user_id])) { - dp_mon_debug(" <%d> nbuf is NULL, return user: %d mpdu_idx: %d", __LINE__, user_id, mpdu_idx); - break; - } - nbuf = qdf_nbuf_queue_last(&ppdu_info->mpdu_q[user_id]); - if (qdf_unlikely(!nbuf)) { - dp_mon_debug("nbuf is NULL"); - break; - } - mpdu_meta = (struct hal_rx_mon_mpdu_info *)qdf_nbuf_data(nbuf); - mpdu_info = &ppdu_info->mpdu_info[user_id]; - mpdu_meta->decap_type = mpdu_info->decap_type; - ppdu_info->mpdu_info[ppdu_info->user_id].mpdu_start_received = true; + dp_rx_mon_handle_mpdu_start(ppdu_info); break; } case HAL_TLV_STATUS_MPDU_END: { - struct hal_rx_mon_mpdu_info *mpdu_info, *mpdu_meta; - if (qdf_unlikely(!rx_hdr_valid)) break; - mpdu_info = &ppdu_info->mpdu_info[user_id]; - if (qdf_unlikely(!ppdu_info->rx_hdr_rcvd[user_id])) { - /* reset mpdu info for next mpdu for same user */ - qdf_mem_zero(mpdu_info, sizeof(*mpdu_info)); - dp_mon_debug(" <%d> nbuf is NULL, return user: %d mpdu_idx: %d", - __LINE__, user_id, mpdu_idx); - break; - } - nbuf = qdf_nbuf_queue_last(&ppdu_info->mpdu_q[user_id]); - if (qdf_unlikely(!nbuf)) { - dp_mon_debug("nbuf is NULL"); - break; - } - mpdu_meta = (struct hal_rx_mon_mpdu_info *)qdf_nbuf_data(nbuf); - mpdu_meta->mpdu_length_err = mpdu_info->mpdu_length_err; - mpdu_meta->fcs_err = mpdu_info->fcs_err; - mpdu_meta->overflow_err = mpdu_info->overflow_err; - mpdu_meta->decrypt_err = mpdu_info->decrypt_err; - mpdu_meta->full_pkt = mpdu_info->full_pkt; - mpdu_meta->truncated = mpdu_info->truncated; - - /* reset mpdu info for next mpdu for same user */ - qdf_mem_zero(mpdu_info, sizeof(*mpdu_info)); - ppdu_info->mpdu_info[ppdu_info->user_id].mpdu_start_received = false; - ppdu_info->mpdu_count[user_id]++; - ppdu_info->rx_hdr_rcvd[user_id] = false; + dp_rx_mon_handle_mpdu_end(ppdu_info); } break; case HAL_TLV_STATUS_MON_DROP: @@ -2365,67 +2578,6 @@ dp_rx_mon_process_2_0(struct dp_soc *soc, struct dp_intr *int_ctx, return work_done; } -#ifdef QCA_KMEM_CACHE_SUPPORT -QDF_STATUS dp_rx_mon_ppdu_info_cache_create(struct dp_pdev *pdev) -{ - struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; - struct dp_mon_pdev_be *mon_pdev_be = - dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev); - uint16_t obj; - struct hal_rx_ppdu_info *ppdu_info = NULL; - - mon_pdev_be->ppdu_info_cache = - qdf_kmem_cache_create("rx_mon_ppdu_info_cache", - sizeof(struct hal_rx_ppdu_info)); - - if (!mon_pdev_be->ppdu_info_cache) { - dp_mon_err("cache creation failed pdev :%px", pdev); - return QDF_STATUS_E_NOMEM; - } - - TAILQ_INIT(&mon_pdev_be->rx_mon_free_queue); - for (obj = 0; obj < DP_RX_MON_WQ_THRESHOLD; obj++) { - ppdu_info = (struct hal_rx_ppdu_info *)qdf_kmem_cache_alloc(mon_pdev_be->ppdu_info_cache); - - if (ppdu_info) { - qdf_mem_zero(ppdu_info, sizeof(struct hal_rx_ppdu_info)); - TAILQ_INSERT_TAIL(&mon_pdev_be->rx_mon_free_queue, - ppdu_info, - ppdu_free_list_elem); - mon_pdev_be->total_free_elem++; - } - } - qdf_spinlock_create(&mon_pdev_be->ppdu_info_lock); - - return QDF_STATUS_SUCCESS; -} - -void dp_rx_mon_ppdu_info_cache_destroy(struct dp_pdev *pdev) -{ - struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; - struct dp_mon_pdev_be *mon_pdev_be = - dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev); - struct hal_rx_ppdu_info *ppdu_info = NULL, *temp_ppdu_info = NULL; - - qdf_spin_lock(&mon_pdev_be->ppdu_info_lock); - TAILQ_FOREACH_SAFE(ppdu_info, - &mon_pdev_be->rx_mon_free_queue, - ppdu_free_list_elem, - temp_ppdu_info) { - TAILQ_REMOVE(&mon_pdev_be->rx_mon_free_queue, - ppdu_info, ppdu_free_list_elem); - if (ppdu_info) { - mon_pdev_be->total_free_elem--; - qdf_kmem_cache_free(mon_pdev_be->ppdu_info_cache, - ppdu_info); - } - } - qdf_spin_unlock(&mon_pdev_be->ppdu_info_lock); - dp_mon_debug(" total free element: %d", mon_pdev_be->total_free_elem); - qdf_kmem_cache_destroy(mon_pdev_be->ppdu_info_cache); -} -#endif - /** * dp_mon_pdev_ext_init_2_0() - Init pdev ext param * @@ -2436,27 +2588,7 @@ void dp_rx_mon_ppdu_info_cache_destroy(struct dp_pdev *pdev) */ QDF_STATUS dp_mon_pdev_ext_init_2_0(struct dp_pdev *pdev) { - struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; - struct dp_mon_pdev_be *mon_pdev_be = - dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev); - - qdf_create_work(0, &mon_pdev_be->rx_mon_work, - dp_rx_mon_process_ppdu, pdev); - mon_pdev_be->rx_mon_workqueue = - qdf_alloc_unbound_workqueue("rx_mon_work_queue"); - - if (!mon_pdev_be->rx_mon_workqueue) { - dp_mon_err("failed to create rxmon wq mon_pdev: %pK", mon_pdev); - goto fail; - } - TAILQ_INIT(&mon_pdev_be->rx_mon_queue); - - qdf_spinlock_create(&mon_pdev_be->rx_mon_wq_lock); - - return QDF_STATUS_SUCCESS; - -fail: - return QDF_STATUS_E_FAILURE; + return dp_rx_mon_init_wq_sm(pdev); } /** @@ -2468,25 +2600,9 @@ fail: */ QDF_STATUS dp_mon_pdev_ext_deinit_2_0(struct dp_pdev *pdev) { - struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; - struct dp_mon_pdev_be *mon_pdev_be = - dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev); - dp_mon_pdev_flush_desc(pdev); - if (!mon_pdev_be->rx_mon_workqueue) - return QDF_STATUS_E_FAILURE; - - qdf_err(" total free element: %d", mon_pdev_be->total_free_elem); - qdf_flush_workqueue(0, mon_pdev_be->rx_mon_workqueue); - qdf_destroy_workqueue(0, mon_pdev_be->rx_mon_workqueue); - qdf_flush_work(&mon_pdev_be->rx_mon_work); - qdf_disable_work(&mon_pdev_be->rx_mon_work); - dp_rx_mon_drain_wq(pdev); - mon_pdev_be->rx_mon_workqueue = NULL; - qdf_spinlock_destroy(&mon_pdev_be->rx_mon_wq_lock); - - return QDF_STATUS_SUCCESS; + return dp_rx_mon_deinit_wq_sm(pdev); } #ifdef QCA_ENHANCED_STATS_SUPPORT diff --git a/dp/wifi3.0/monitor/2.0/dp_rx_mon_2.0.h b/dp/wifi3.0/monitor/2.0/dp_rx_mon_2.0.h index f428127d7c..729337b4dd 100644 --- a/dp/wifi3.0/monitor/2.0/dp_rx_mon_2.0.h +++ b/dp/wifi3.0/monitor/2.0/dp_rx_mon_2.0.h @@ -20,6 +20,7 @@ #include #include +#include #define DP_RX_MON_PACKET_OFFSET 8 #define DP_RX_MON_RX_HDR_OFFSET 8 @@ -81,6 +82,7 @@ static inline void dp_rx_mon_ppdu_info_cache_destroy(struct dp_pdev *pdev) static inline struct hal_rx_ppdu_info* dp_rx_mon_get_ppdu_info(struct dp_mon_pdev *mon_pdev) { + qdf_mem_zero(&mon_pdev->ppdu_info, sizeof(struct hal_rx_ppdu_info)); return &mon_pdev->ppdu_info; } @@ -202,6 +204,85 @@ dp_rx_mon_populate_ppdu_info_2_0(struct hal_rx_ppdu_info *hal_ppdu_info, QDF_STATUS dp_rx_mon_soc_attach_2_0(struct dp_soc *soc, int lmac_id); void dp_rx_mon_soc_detach_2_0(struct dp_soc *soc, int lmac_id); void dp_rx_mon_soc_deinit_2_0(struct dp_soc *soc, uint32_t lmac_id); + +#ifndef QCA_MONITOR_2_0_PKT_SUPPORT +static inline QDF_STATUS dp_rx_mon_init_wq_sm(struct dp_pdev *pdev) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS dp_rx_mon_deinit_wq_sm(struct dp_pdev *pdev) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS +dp_rx_mon_add_ppdu_info_to_wq(struct dp_pdev *pdev, + struct hal_rx_ppdu_info *ppdu_info) +{ + return QDF_STATUS_SUCCESS; +} + +static inline int +dp_rx_mon_flush_packet_tlv(struct dp_pdev *pdev, void *buf, uint16_t end_offset, + union dp_mon_desc_list_elem_t **desc_list, + union dp_mon_desc_list_elem_t **tail) +{ + return 0; +} + +static inline void +dp_rx_mon_handle_rx_hdr(struct dp_pdev *pdev, + struct hal_rx_ppdu_info *ppdu_info, + void *status_frag) +{ +} + +static inline uint16_t +dp_rx_mon_handle_mon_buf_addr(struct dp_pdev *pdev, + struct hal_rx_ppdu_info *ppdu_info, + union dp_mon_desc_list_elem_t **desc_list, + union dp_mon_desc_list_elem_t **tail) +{ + return 0; +} + +static inline void +dp_rx_mon_handle_msdu_end(struct dp_pdev *pdev, + struct hal_rx_ppdu_info *ppdu_info) +{ +} + +static inline void +dp_rx_mon_reset_mpdu_q(struct hal_rx_ppdu_info *ppdu_info) +{ +} + +static inline void +dp_rx_mon_handle_mpdu_start(struct hal_rx_ppdu_info *ppdu_info) +{ +} + +static inline void +dp_rx_mon_handle_mpdu_end(struct hal_rx_ppdu_info *ppdu_info) +{ +} + +static inline QDF_STATUS +dp_rx_mon_nbuf_add_rx_frag(qdf_nbuf_t nbuf, qdf_frag_t *frag, + uint16_t frag_len, uint16_t offset, + uint16_t buf_size, bool frag_ref) +{ + return 0; +} + +static inline void +dp_rx_mon_pf_tag_to_buf_headroom_2_0(void *nbuf, + struct hal_rx_ppdu_info *ppdu_info, + struct dp_pdev *pdev, struct dp_soc *soc) +{ +} +#endif #else static inline QDF_STATUS dp_mon_pdev_ext_init_2_0(struct dp_pdev *pdev) { diff --git a/hal/wifi3.0/hal_api_mon.h b/hal/wifi3.0/hal_api_mon.h index ae3e62b781..6f23429749 100644 --- a/hal/wifi3.0/hal_api_mon.h +++ b/hal/wifi3.0/hal_api_mon.h @@ -1311,16 +1311,16 @@ struct hal_rx_ppdu_info { struct hal_rx_mon_mpdu_info mpdu_info[HAL_MAX_UL_MU_USERS]; /* placeholder to hold packet buffer info */ struct hal_mon_packet_info packet_info; -#ifdef WLAN_PKT_CAPTURE_RX_2_0 +#if defined(WLAN_PKT_CAPTURE_RX_2_0) && defined(QCA_MONITOR_2_0_PKT_SUPPORT) /* per user per MPDU queue */ qdf_nbuf_queue_t mpdu_q[HAL_MAX_UL_MU_USERS]; -#endif /* ppdu info list element */ TAILQ_ENTRY(hal_rx_ppdu_info) ppdu_list_elem; /* ppdu info free list element */ TAILQ_ENTRY(hal_rx_ppdu_info) ppdu_free_list_elem; /* placeholder to track if RX_HDR is received */ uint8_t rx_hdr_rcvd[HAL_MAX_UL_MU_USERS]; +#endif /* Per user BAR and NDPA bit flag */ struct hal_rx_user_ctrl_frm_info ctrl_frm_info[HAL_MAX_UL_MU_USERS]; /* PPDU end user stats count */