diff --git a/dp/inc/cdp_txrx_cmn_struct.h b/dp/inc/cdp_txrx_cmn_struct.h index 2a6ffc806f..8e8bf64948 100644 --- a/dp/inc/cdp_txrx_cmn_struct.h +++ b/dp/inc/cdp_txrx_cmn_struct.h @@ -64,6 +64,12 @@ #define OL_TXRX_INVALID_PDEV_ID 0xff #define OL_TXRX_INVALID_LOCAL_PEER_ID 0xffff #define CDP_INVALID_VDEV_ID 0xff + +/* Max vdev_stats_id(48) is as per the max vdevs supported by HW */ +#define CDP_MAX_VDEV_STATS_ID 0x30 +/* Invalid vdev_stats_id */ +#define CDP_INVALID_VDEV_STATS_ID 0xFF + /* Options for Dump Statistics */ #define CDP_HDD_STATS 0 #define CDP_TXRX_PATH_STATS 1 @@ -687,6 +693,7 @@ enum wlan_op_subtype { * struct cdp_vdev_info - Vdev information * @vdev_mac_addr: mac address of the vdev * @vdev_id: ID of the vdev + * @vdev_stats_id: Stats ID of the vdev * @op_mode: Operation mode of the vdev * @subtype: subtype of the vdev * @mld_mac_addr: MLD mac addr of the current vdev. @@ -694,6 +701,7 @@ enum wlan_op_subtype { struct cdp_vdev_info { uint8_t *vdev_mac_addr; uint8_t vdev_id; + uint8_t vdev_stats_id; enum wlan_op_mode op_mode; enum wlan_op_subtype subtype; #ifdef WLAN_FEATURE_11BE_MLO diff --git a/dp/inc/cdp_txrx_ctrl.h b/dp/inc/cdp_txrx_ctrl.h index c9112e5782..c9cbc2eb7a 100644 --- a/dp/inc/cdp_txrx_ctrl.h +++ b/dp/inc/cdp_txrx_ctrl.h @@ -404,6 +404,41 @@ cdp_txrx_get_psoc_param(ol_txrx_soc_handle soc, return soc->ops->ctrl_ops->txrx_get_psoc_param(soc, type, val); } +static inline +QDF_STATUS cdp_vdev_alloc_vdev_stats_id(ol_txrx_soc_handle soc, + uint8_t *vdev_stats_id) +{ + if (!soc || !soc->ops) { + dp_cdp_debug("Invalid Instance:"); + QDF_BUG(0); + return QDF_STATUS_E_FAILURE; + } + + if (!soc->ops->host_stats_ops || + !soc->ops->host_stats_ops->txrx_alloc_vdev_stats_id) + return QDF_STATUS_E_FAILURE; + + return soc->ops->host_stats_ops->txrx_alloc_vdev_stats_id + (soc, vdev_stats_id); +} + +static inline +void cdp_vdev_reset_vdev_stats_id(ol_txrx_soc_handle soc, + uint8_t vdev_stats_id) +{ + if (!soc || !soc->ops) { + dp_cdp_debug("Invalid Instance:"); + QDF_BUG(0); + return; + } + + if (!soc->ops->host_stats_ops || + !soc->ops->host_stats_ops->txrx_reset_vdev_stats_id) + return; + + soc->ops->host_stats_ops->txrx_reset_vdev_stats_id(soc, vdev_stats_id); +} + #ifdef VDEV_PEER_PROTOCOL_COUNT /** * cdp_set_vdev_peer_protocol_count() - set per-peer protocol count tracking diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index 9ee5869847..ab98e87ed5 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -1036,6 +1036,13 @@ struct cdp_host_stats_ops { (*txrx_get_peer_jitter_stats)(struct cdp_soc_t *soc, uint8_t pdev_id, uint8_t vdev_id, uint8_t *peer_mac, struct cdp_peer_tid_stats *tid_stats); + + QDF_STATUS + (*txrx_alloc_vdev_stats_id)(struct cdp_soc_t *soc, + uint8_t *vdev_stats_id); + + void (*txrx_reset_vdev_stats_id)(struct cdp_soc_t *soc, + uint8_t vdev_stats_id); }; struct cdp_wds_ops { diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 2bbeea3d9e..8b34472fab 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -6052,6 +6052,7 @@ static QDF_STATUS dp_vdev_attach_wifi3(struct cdp_soc_t *cdp_soc, uint8_t vdev_id = vdev_info->vdev_id; enum wlan_op_mode op_mode = vdev_info->op_mode; enum wlan_op_subtype subtype = vdev_info->subtype; + uint8_t vdev_stats_id = vdev_info->vdev_stats_id; vdev_context_size = soc->arch_ops.txrx_get_context_size(DP_CONTEXT_TYPE_VDEV); @@ -6075,6 +6076,7 @@ static QDF_STATUS dp_vdev_attach_wifi3(struct cdp_soc_t *cdp_soc, vdev->pdev = pdev; vdev->vdev_id = vdev_id; + vdev->vdev_stats_id = vdev_stats_id; vdev->opmode = op_mode; vdev->subtype = subtype; vdev->osdev = soc->osdev; @@ -6332,6 +6334,60 @@ static void dp_vdev_flush_peers(struct cdp_vdev *vdev_handle, bool unmap_only) } +#ifdef QCA_VDEV_STATS_HW_OFFLOAD_SUPPORT +/* + * dp_txrx_alloc_vdev_stats_id()- Allocate vdev_stats_id + * @soc_hdl: Datapath soc handle + * @vdev_stats_id: Address of vdev_stats_id + * + * Return: QDF_STATUS + */ +static QDF_STATUS dp_txrx_alloc_vdev_stats_id(struct cdp_soc_t *soc_hdl, + uint8_t *vdev_stats_id) +{ + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + uint8_t id = 0; + + if (!wlan_cfg_get_vdev_stats_hw_offload_config(soc->wlan_cfg_ctx)) { + *vdev_stats_id = DP_INVALID_VDEV_STATS_ID; + return QDF_STATUS_E_FAILURE; + } + + while (id < DP_MAX_VDEV_STATS_ID) { + if (!qdf_atomic_test_and_set_bit(id, &soc->vdev_stats_id_map)) { + *vdev_stats_id = id; + return QDF_STATUS_SUCCESS; + } + id++; + } + + *vdev_stats_id = DP_INVALID_VDEV_STATS_ID; + return QDF_STATUS_E_FAILURE; +} + +/* + * dp_txrx_reset_vdev_stats_id() - Reset vdev_stats_id in dp_soc + * @soc_hdl: Datapath soc handle + * @vdev_stats_id: vdev_stats_id to reset in dp_soc + * + * Return: none + */ +static void dp_txrx_reset_vdev_stats_id(struct cdp_soc_t *soc_hdl, + uint8_t vdev_stats_id) +{ + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + + if ((!wlan_cfg_get_vdev_stats_hw_offload_config(soc->wlan_cfg_ctx)) || + (vdev_stats_id >= DP_MAX_VDEV_STATS_ID)) + return; + + qdf_atomic_clear_bit(vdev_stats_id, &soc->vdev_stats_id_map); +} +#else +static void dp_txrx_reset_vdev_stats_id(struct cdp_soc_t *soc, + uint8_t vdev_stats_id) +{} +#endif /* * dp_vdev_detach_wifi3() - Detach txrx vdev * @cdp_soc: Datapath soc handle @@ -6396,6 +6452,8 @@ static QDF_STATUS dp_vdev_detach_wifi3(struct cdp_soc_t *cdp_soc, dp_monitor_neighbour_peer_list_remove(pdev, vdev, peer); + dp_txrx_reset_vdev_stats_id(cdp_soc, vdev->vdev_stats_id); + dp_tx_vdev_multipass_deinit(vdev); if (vdev->vdev_dp_ext_handle) { @@ -11696,6 +11754,10 @@ static struct cdp_host_stats_ops dp_ops_host_stats = { .txrx_update_vdev_stats = dp_txrx_update_vdev_host_stats, .txrx_get_peer_delay_stats = dp_txrx_get_peer_delay_stats, .txrx_get_peer_jitter_stats = dp_txrx_get_peer_jitter_stats, +#ifdef QCA_VDEV_STATS_HW_OFFLOAD_SUPPORT + .txrx_alloc_vdev_stats_id = dp_txrx_alloc_vdev_stats_id, + .txrx_reset_vdev_stats_id = dp_txrx_reset_vdev_stats_id, +#endif /* TODO */ }; @@ -12852,6 +12914,8 @@ void *dp_soc_init(struct dp_soc *soc, HTC_HANDLE htc_handle, qdf_heap_mem_stats_read(), qdf_skb_total_mem_stats_read()); + soc->vdev_stats_id_map = 0; + return soc; fail6: htt_soc_htc_dealloc(soc->htt_handle); diff --git a/dp/wifi3.0/dp_peer.c b/dp/wifi3.0/dp_peer.c index d9aacafd59..5bc89d13d9 100644 --- a/dp/wifi3.0/dp_peer.c +++ b/dp/wifi3.0/dp_peer.c @@ -3315,7 +3315,8 @@ try_desc_alloc: } hal_reo_qdesc_setup(soc->hal_soc, tid, ba_window_size, start_seq, - hw_qdesc_vaddr, rx_tid->hw_qdesc_paddr, hal_pn_type); + hw_qdesc_vaddr, rx_tid->hw_qdesc_paddr, hal_pn_type, + vdev->vdev_stats_id); qdf_mem_map_nbytes_single(soc->osdev, hw_qdesc_vaddr, QDF_DMA_BIDIRECTIONAL, rx_tid->hw_qdesc_alloc_size, diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 3e3a158785..49a26bcc2d 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -164,6 +164,9 @@ #define DP_SKIP_BAR_UPDATE_TIMEOUT 5000 #endif +#define DP_MAX_VDEV_STATS_ID CDP_MAX_VDEV_STATS_ID +#define DP_INVALID_VDEV_STATS_ID CDP_INVALID_VDEV_STATS_ID + enum rx_pktlog_mode { DP_RX_PKTLOG_DISABLED = 0, DP_RX_PKTLOG_FULL, @@ -2264,6 +2267,8 @@ struct dp_soc { /* Buffer manager ID for idle link descs */ uint8_t idle_link_bm_id; qdf_atomic_t ref_count; + + unsigned long vdev_stats_id_map; }; #ifdef IPA_OFFLOAD @@ -3084,6 +3089,9 @@ struct dp_vdev { /* accumulative number of packets delay has accumulated */ qdf_atomic_t ul_pkts_accum; #endif /* WLAN_FEATURE_TSF_UPLINK_DELAY */ + + /* vdev_stats_id - ID used for stats collection by FW from HW*/ + uint8_t vdev_stats_id; }; enum { diff --git a/hal/wifi3.0/be/hal_be_api.h b/hal/wifi3.0/be/hal_be_api.h index e462f51cca..f4ad7cc508 100644 --- a/hal/wifi3.0/be/hal_be_api.h +++ b/hal/wifi3.0/be/hal_be_api.h @@ -101,13 +101,13 @@ void hal_rx_wbm_err_info_get_generic_be(void *wbm_desc, void *wbm_er_info1); * @hw_qdesc_vaddr: Virtual address of REO queue descriptor memory * @hw_qdesc_paddr: Physical address of REO queue descriptor memory * @pn_type: PN type (one of the types defined in 'enum hal_pn_type') - * + * @vdev_stats_id: vdev_stats_id to be programmed in REO Queue Descriptor */ void hal_reo_qdesc_setup_be(hal_soc_handle_t hal_soc_hdl, int tid, uint32_t ba_window_size, uint32_t start_seq, void *hw_qdesc_vaddr, qdf_dma_addr_t hw_qdesc_paddr, - int pn_type); + int pn_type, uint8_t vdev_stats_id); /** * hal_cookie_conversion_reg_cfg_be() - set cookie conversion relevant register diff --git a/hal/wifi3.0/be/hal_be_reo.c b/hal/wifi3.0/be/hal_be_reo.c index 053b61a69f..36d3f8268f 100644 --- a/hal/wifi3.0/be/hal_be_reo.c +++ b/hal/wifi3.0/be/hal_be_reo.c @@ -43,7 +43,7 @@ void hal_reo_qdesc_setup_be(hal_soc_handle_t hal_soc_hdl, int tid, uint32_t ba_window_size, uint32_t start_seq, void *hw_qdesc_vaddr, qdf_dma_addr_t hw_qdesc_paddr, - int pn_type) + int pn_type, uint8_t vdev_stats_id) { uint32_t *reo_queue_desc = (uint32_t *)hw_qdesc_vaddr; uint32_t *reo_queue_ext_desc; @@ -147,6 +147,8 @@ void hal_reo_qdesc_setup_be(hal_soc_handle_t hal_soc_hdl, int tid, */ HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE, SVLD, 0); + hal_update_stats_counter_index(reo_queue_desc, vdev_stats_id); + /* TODO: Check if we should set start PN for WAPI */ /* TODO: HW queue descriptors are currently allocated for max BA diff --git a/hal/wifi3.0/be/hal_be_reo.h b/hal/wifi3.0/be/hal_be_reo.h index a3ebdf1aea..01bfa74925 100644 --- a/hal/wifi3.0/be/hal_be_reo.h +++ b/hal/wifi3.0/be/hal_be_reo.h @@ -28,6 +28,22 @@ #define HAL_MAX_REO2SW_RINGS 8 #define HAL_NUM_RX_RING_PER_IX_MAP 8 +#ifdef QCA_VDEV_STATS_HW_OFFLOAD_SUPPORT +static inline void hal_update_stats_counter_index(uint32_t *reo_queue_desc, + uint8_t vdev_stats_id) +{ +#ifdef RX_REO_QUEUE_STATISTICS_COUNTER_INDEX_MASK + HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE, + STATISTICS_COUNTER_INDEX, vdev_stats_id); +#endif +} +#else +static inline void hal_update_stats_counter_index(uint32_t *reo_queue_desc, + uint8_t vdev_stats_id) +{ +} +#endif + /* Proto-types */ void hal_get_ba_aging_timeout_be(hal_soc_handle_t hal_soc_hdl, uint8_t ac, uint32_t *value); diff --git a/hal/wifi3.0/hal_internal.h b/hal/wifi3.0/hal_internal.h index d1f58d38e9..76b8824e7c 100644 --- a/hal/wifi3.0/hal_internal.h +++ b/hal/wifi3.0/hal_internal.h @@ -752,7 +752,7 @@ struct hal_hw_txrx_ops { uint32_t ba_window_size, uint32_t start_seq, void *hw_qdesc_vaddr, qdf_dma_addr_t hw_qdesc_paddr, - int pn_type); + int pn_type, uint8_t vdev_stats_id); uint32_t (*hal_gen_reo_remap_val)(enum hal_reo_remap_reg, uint8_t *ix0_map); diff --git a/hal/wifi3.0/hal_reo.h b/hal/wifi3.0/hal_reo.h index b124417373..b508e70a9b 100644 --- a/hal/wifi3.0/hal_reo.h +++ b/hal/wifi3.0/hal_reo.h @@ -613,7 +613,7 @@ static inline void hal_reo_qdesc_setup(hal_soc_handle_t hal_soc_hdl, int tid, uint32_t ba_window_size, uint32_t start_seq, void *hw_qdesc_vaddr, qdf_dma_addr_t hw_qdesc_paddr, - int pn_type) + int pn_type, uint8_t vdev_stats_id) { struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; @@ -627,7 +627,8 @@ static inline void hal_reo_qdesc_setup(hal_soc_handle_t hal_soc_hdl, int tid, hal_soc->ops->hal_reo_qdesc_setup(hal_soc_hdl, tid, ba_window_size, start_seq, hw_qdesc_vaddr, - hw_qdesc_paddr, pn_type); + hw_qdesc_paddr, pn_type, + vdev_stats_id); } /** diff --git a/hal/wifi3.0/li/hal_li_api.h b/hal/wifi3.0/li/hal_li_api.h index 208bb6a7a7..6db420479e 100644 --- a/hal/wifi3.0/li/hal_li_api.h +++ b/hal/wifi3.0/li/hal_li_api.h @@ -66,12 +66,12 @@ uint8_t hal_rx_ret_buf_manager_get_li(hal_ring_desc_t ring_desc); * @hw_qdesc_vaddr: Virtual address of REO queue descriptor memory * @hw_qdesc_paddr: Physical address of REO queue descriptor memory * @pn_type: PN type (one of the types defined in 'enum hal_pn_type') - * + * @vdev_stats_id: vdev_stats_id */ void hal_reo_qdesc_setup_li(hal_soc_handle_t hal_soc_hdl, int tid, uint32_t ba_window_size, uint32_t start_seq, void *hw_qdesc_vaddr, qdf_dma_addr_t hw_qdesc_paddr, - int pn_type); + int pn_type, uint8_t vdev_stats_id); #endif /* _HAL_LI_API_H_ */ diff --git a/hal/wifi3.0/li/hal_li_reo.c b/hal/wifi3.0/li/hal_li_reo.c index 2efbd906b5..6a0574f3b2 100644 --- a/hal/wifi3.0/li/hal_li_reo.c +++ b/hal/wifi3.0/li/hal_li_reo.c @@ -42,7 +42,7 @@ void hal_reo_qdesc_setup_li(hal_soc_handle_t hal_soc_hdl, int tid, uint32_t ba_window_size, uint32_t start_seq, void *hw_qdesc_vaddr, qdf_dma_addr_t hw_qdesc_paddr, - int pn_type) + int pn_type, uint8_t vdev_stats_id) { uint32_t *reo_queue_desc = (uint32_t *)hw_qdesc_vaddr; uint32_t *reo_queue_ext_desc;