diff --git a/dp/wifi3.0/be/dp_be.c b/dp/wifi3.0/be/dp_be.c index 0a6ffbf819..5bdccd4057 100644 --- a/dp/wifi3.0/be/dp_be.c +++ b/dp/wifi3.0/be/dp_be.c @@ -1464,12 +1464,20 @@ static QDF_STATUS dp_soc_ppe_srng_init(struct dp_soc *soc) struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx; hal_soc_handle_t hal_soc = soc->hal_soc; + struct dp_ppe_ds_idxs idx = {0}; + soc_cfg_ctx = soc->wlan_cfg_ctx; if (!wlan_cfg_get_dp_soc_is_ppe_enabled(soc_cfg_ctx)) return QDF_STATUS_SUCCESS; - if (dp_srng_init(soc, &be_soc->reo2ppe_ring, REO2PPE, 0, 0)) { + if (dp_ppeds_register_soc_be(be_soc, &idx)) { + dp_err("%pK: ppeds registration failed", soc); + goto fail; + } + + if (dp_srng_init_idx(soc, &be_soc->reo2ppe_ring, REO2PPE, 0, 0, + idx.reo2ppe_start_idx)) { dp_err("%pK: dp_srng_init failed for reo2ppe", soc); goto fail; } @@ -1482,7 +1490,8 @@ static QDF_STATUS dp_soc_ppe_srng_init(struct dp_soc *soc) hal_reo_config_reo2ppe_dest_info(hal_soc); - if (dp_srng_init(soc, &be_soc->ppe2tcl_ring, PPE2TCL, 0, 0)) { + if (dp_srng_init_idx(soc, &be_soc->ppe2tcl_ring, PPE2TCL, 0, 0, + idx.ppe2tcl_start_idx)) { dp_err("%pK: dp_srng_init failed for ppe2tcl_ring", soc); goto fail; } @@ -1493,6 +1502,10 @@ static QDF_STATUS dp_soc_ppe_srng_init(struct dp_soc *soc) WLAN_MD_DP_SRNG_PPE2TCL, "ppe2tcl_ring"); + hal_tx_config_rbm_mapping_be(soc->hal_soc, + be_soc->ppe2tcl_ring.hal_srng, + WBM2_SW_PPE_REL_MAP_ID); + if (dp_srng_init(soc, &be_soc->ppe_release_ring, PPE_RELEASE, 0, 0)) { dp_err("%pK: dp_srng_init failed for ppe_release_ring", soc); goto fail; @@ -1516,11 +1529,6 @@ static QDF_STATUS dp_soc_ppe_srng_init(struct dp_soc *soc) WLAN_MD_DP_SRNG_PPE_WBM2SW_RELEASE, "ppe_wbm_release_ring"); - if (dp_ppeds_register_soc_be(be_soc)) { - dp_err("%pK: ppeds registration failed", soc); - goto fail; - } - return QDF_STATUS_SUCCESS; fail: dp_soc_ppe_srng_deinit(soc); diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index a2689429ad..05c36c2d83 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -2331,17 +2331,19 @@ static bool dp_check_umac_reset_in_progress(struct dp_soc *soc) #endif /* - * dp_srng_init() - Initialize SRNG + * dp_srng_init_idx() - Initialize SRNG * @soc : Data path soc handle * @srng : SRNG pointer * @ring_type : Ring Type * @ring_num: Ring number * @mac_id: mac_id + * @idx: ring index * * return: QDF_STATUS */ -QDF_STATUS dp_srng_init(struct dp_soc *soc, struct dp_srng *srng, - int ring_type, int ring_num, int mac_id) +QDF_STATUS dp_srng_init_idx(struct dp_soc *soc, struct dp_srng *srng, + int ring_type, int ring_num, int mac_id, + uint32_t idx) { bool idle_check; @@ -2392,8 +2394,9 @@ QDF_STATUS dp_srng_init(struct dp_soc *soc, struct dp_srng *srng, idle_check = dp_check_umac_reset_in_progress(soc); - srng->hal_srng = hal_srng_setup(hal_soc, ring_type, ring_num, - mac_id, &ring_params, idle_check); + srng->hal_srng = hal_srng_setup_idx(hal_soc, ring_type, ring_num, + mac_id, &ring_params, idle_check, + idx); if (!srng->hal_srng) { dp_srng_free(soc, srng); @@ -2403,8 +2406,25 @@ QDF_STATUS dp_srng_init(struct dp_soc *soc, struct dp_srng *srng, return QDF_STATUS_SUCCESS; } -qdf_export_symbol(dp_srng_init); +qdf_export_symbol(dp_srng_init_idx); +/* + * dp_srng_init() - Initialize SRNG + * @soc : Data path soc handle + * @srng : SRNG pointer + * @ring_type : Ring Type + * @ring_num: Ring number + * @mac_id: mac_id + * + * return: QDF_STATUS + */ +QDF_STATUS dp_srng_init(struct dp_soc *soc, struct dp_srng *srng, int ring_type, + int ring_num, int mac_id) +{ + return dp_srng_init_idx(soc, srng, ring_type, ring_num, mac_id, 0); +} + +qdf_export_symbol(dp_srng_init); /* * dp_srng_alloc() - Allocate memory for SRNG * @soc : Data path soc handle diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 673d4a9da7..00a3ba4548 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -4541,6 +4541,9 @@ QDF_STATUS dp_srng_alloc(struct dp_soc *soc, struct dp_srng *srng, void dp_srng_free(struct dp_soc *soc, struct dp_srng *srng); QDF_STATUS dp_srng_init(struct dp_soc *soc, struct dp_srng *srng, int ring_type, int ring_num, int mac_id); +QDF_STATUS dp_srng_init_idx(struct dp_soc *soc, struct dp_srng *srng, + int ring_type, int ring_num, int mac_id, + uint32_t idx); void dp_srng_deinit(struct dp_soc *soc, struct dp_srng *srng, int ring_type, int ring_num); void dp_print_peer_txrx_stats_be(struct cdp_peer_stats *peer_stats, diff --git a/hal/wifi3.0/hal_api.h b/hal/wifi3.0/hal_api.h index 351c86048b..e84e0dfc3a 100644 --- a/hal/wifi3.0/hal_api.h +++ b/hal/wifi3.0/hal_api.h @@ -1102,7 +1102,34 @@ bool hal_srng_is_near_full_irq_supported(hal_soc_handle_t hal_soc, * NULL on failure (if given ring is not available) */ extern void *hal_srng_setup(void *hal_soc, int ring_type, int ring_num, - int mac_id, struct hal_srng_params *ring_params, bool idle_check); + int mac_id, struct hal_srng_params *ring_params, + bool idle_check); + +/** + * hal_srng_setup_idx - Initialize HW SRNG ring. + * + * @hal_soc: Opaque HAL SOC handle + * @ring_type: one of the types from hal_ring_type + * @ring_num: Ring number if there are multiple rings of + * same type (staring from 0) + * @mac_id: valid MAC Id should be passed if ring type is one of lmac rings + * @ring_params: SRNG ring params in hal_srng_params structure. + * @idle_check: Check if ring is idle + * @idx: Ring index + + * Callers are expected to allocate contiguous ring memory of size + * 'num_entries * entry_size' bytes and pass the physical and virtual base + * addresses through 'ring_base_paddr' and 'ring_base_vaddr' in hal_srng_params + * structure. Ring base address should be 8 byte aligned and size of each ring + * entry should be queried using the API hal_srng_get_entrysize + * + * Return: Opaque pointer to ring on success + * NULL on failure (if given ring is not available) + */ +extern void *hal_srng_setup_idx(void *hal_soc, int ring_type, int ring_num, + int mac_id, struct hal_srng_params *ring_params, + bool idle_check, uint32_t idx); + /* Remapping ids of REO rings */ #define REO_REMAP_TCL 0 @@ -2712,11 +2739,13 @@ uint32_t hal_get_target_type(hal_soc_handle_t hal_soc_hdl); * @hal_soc: HAL SOC handle * @srng: SRNG ring pointer * @idle_check: Check if ring is idle + * @idx: Ring index */ static inline void hal_srng_dst_hw_init(struct hal_soc *hal, - struct hal_srng *srng, bool idle_check) + struct hal_srng *srng, bool idle_check, + uint16_t idx) { - hal->ops->hal_srng_dst_hw_init(hal, srng, idle_check); + hal->ops->hal_srng_dst_hw_init(hal, srng, idle_check, idx); } /** @@ -2725,11 +2754,13 @@ static inline void hal_srng_dst_hw_init(struct hal_soc *hal, * @hal_soc: HAL SOC handle * @srng: SRNG ring pointer * @idle_check: Check if ring is idle + * @idx: Ring index */ static inline void hal_srng_src_hw_init(struct hal_soc *hal, - struct hal_srng *srng, bool idle_check) + struct hal_srng *srng, bool idle_check, + uint16_t idx) { - hal->ops->hal_srng_src_hw_init(hal, srng, idle_check); + hal->ops->hal_srng_src_hw_init(hal, srng, idle_check, idx); } /** diff --git a/hal/wifi3.0/hal_generic_api.h b/hal/wifi3.0/hal_generic_api.h index 93a6c5320b..9afdb9f6ad 100644 --- a/hal/wifi3.0/hal_generic_api.h +++ b/hal/wifi3.0/hal_generic_api.h @@ -235,10 +235,12 @@ void hal_srng_src_hw_write_cons_prefetch_timer(struct hal_srng *srng, * @hal_soc: HAL SOC handle * @srng: SRNG ring pointer * @idle_check: Check if ring is idle + * @idx: ring index */ static inline void hal_srng_src_hw_init_generic(struct hal_soc *hal, - struct hal_srng *srng, bool idle_check) + struct hal_srng *srng, bool idle_check, + uint32_t idx) { uint32_t reg_val = 0; uint64_t tp_addr = 0; @@ -256,6 +258,11 @@ void hal_srng_src_hw_init_generic(struct hal_soc *hal, hal_debug("hw_init srng %d", srng->ring_id); + reg_val = SRNG_SRC_REG_READ(srng, MISC) & ~(SRNG_ENABLE_BIT); + SRNG_SRC_REG_WRITE(srng, MISC, reg_val); + + reg_val = 0; + if (srng->flags & HAL_SRNG_MSI_INTR) { SRNG_SRC_REG_WRITE(srng, MSI1_BASE_LSB, srng->msi_addr & 0xffffffff); @@ -332,9 +339,10 @@ void hal_srng_src_hw_init_generic(struct hal_soc *hal, } /* Initilaize head and tail pointers to indicate ring is empty */ - SRNG_SRC_REG_WRITE(srng, HP, 0); - SRNG_SRC_REG_WRITE(srng, TP, 0); - *(srng->u.src_ring.tp_addr) = 0; + SRNG_SRC_REG_WRITE(srng, HP, idx * srng->entry_size); + SRNG_SRC_REG_WRITE(srng, TP, idx * srng->entry_size); + *srng->u.src_ring.tp_addr = idx * srng->entry_size; + srng->u.src_ring.hp = idx * srng->entry_size; reg_val |= ((srng->flags & HAL_SRNG_DATA_TLV_SWAP) ? SRNG_SM(SRNG_SRC_FLD(MISC, DATA_TLV_SWAP_BIT), 1) : 0) | @@ -422,10 +430,12 @@ static inline void hal_srng_dst_near_full_int_setup(struct hal_srng *srng) * @hal_soc: HAL SOC handle * @srng: SRNG ring pointer * @idle_check: Check if ring is idle + * @idx: Ring index */ static inline void hal_srng_dst_hw_init_generic(struct hal_soc *hal, - struct hal_srng *srng, bool idle_check) + struct hal_srng *srng, bool idle_check, + uint32_t idx) { uint32_t reg_val = 0; uint64_t hp_addr = 0; @@ -440,6 +450,12 @@ void hal_srng_dst_hw_init_generic(struct hal_soc *hal, hal_debug("hw_init srng %d", srng->ring_id); + reg_val = SRNG_DST_REG_READ(srng, MISC) & ~(SRNG_ENABLE_BIT); + + SRNG_DST_REG_WRITE(srng, MISC, reg_val); + + reg_val = 0; + if (srng->flags & HAL_SRNG_MSI_INTR) { SRNG_DST_REG_WRITE(srng, MSI1_BASE_LSB, srng->msi_addr & 0xffffffff); @@ -501,9 +517,10 @@ void hal_srng_dst_hw_init_generic(struct hal_soc *hal, SRNG_DST_REG_WRITE(srng, HP_ADDR_MSB, hp_addr >> 32); /* Initilaize head and tail pointers to indicate ring is empty */ - SRNG_DST_REG_WRITE(srng, HP, 0); - SRNG_DST_REG_WRITE(srng, TP, 0); - *(srng->u.dst_ring.hp_addr) = 0; + SRNG_DST_REG_WRITE(srng, HP, idx * srng->entry_size); + SRNG_DST_REG_WRITE(srng, TP, idx * srng->entry_size); + *srng->u.dst_ring.hp_addr = idx * srng->entry_size; + srng->u.dst_ring.tp = idx * srng->entry_size; reg_val = ((srng->flags & HAL_SRNG_DATA_TLV_SWAP) ? SRNG_SM(SRNG_DST_FLD(MISC, DATA_TLV_SWAP_BIT), 1) : 0) | diff --git a/hal/wifi3.0/hal_internal.h b/hal/wifi3.0/hal_internal.h index a040887a64..a7efd2e9bb 100644 --- a/hal/wifi3.0/hal_internal.h +++ b/hal/wifi3.0/hal_internal.h @@ -823,9 +823,11 @@ struct hal_rx_pkt_capture_flags { struct hal_hw_txrx_ops { /* init and setup */ void (*hal_srng_dst_hw_init)(struct hal_soc *hal, - struct hal_srng *srng, bool idle_check); + struct hal_srng *srng, bool idle_check, + uint32_t idx); void (*hal_srng_src_hw_init)(struct hal_soc *hal, - struct hal_srng *srng, bool idle_check); + struct hal_srng *srng, bool idle_check, + uint32_t idx); void (*hal_srng_hw_disable)(struct hal_soc *hal, struct hal_srng *srng); @@ -1217,6 +1219,9 @@ struct hal_hw_txrx_ops { QDF_STATUS (*hal_srng_set_msi_config)(hal_ring_handle_t ring_hdl, void *ring_params); #endif + void (*hal_tx_ring_halt_set)(hal_soc_handle_t hal_soc_hdl); + void (*hal_tx_ring_halt_reset)(hal_soc_handle_t hal_soc_hdl); + bool (*hal_tx_ring_halt_poll)(hal_soc_handle_t hal_soc_hdl); }; /** diff --git a/hal/wifi3.0/hal_srng.c b/hal/wifi3.0/hal_srng.c index 8f9d027569..e71a5f776f 100644 --- a/hal/wifi3.0/hal_srng.c +++ b/hal/wifi3.0/hal_srng.c @@ -1420,14 +1420,15 @@ qdf_export_symbol(hal_srng_dst_init_hp); * @hal_soc: HAL SOC handle * @srng: SRNG ring pointer * @idle_check: Check if ring is idle + * @idx: ring index */ static inline void hal_srng_hw_init(struct hal_soc *hal, - struct hal_srng *srng, bool idle_check) + struct hal_srng *srng, bool idle_check, uint32_t idx) { if (srng->ring_dir == HAL_SRNG_SRC_RING) - hal_srng_src_hw_init(hal, srng, idle_check); + hal_srng_src_hw_init(hal, srng, idle_check, idx); else - hal_srng_dst_hw_init(hal, srng, idle_check); + hal_srng_dst_hw_init(hal, srng, idle_check, idx); } #ifdef WLAN_FEATURE_NEAR_FULL_IRQ @@ -1569,7 +1570,7 @@ static inline void hal_srng_update_high_wm_thresholds(struct hal_srng *srng) #endif /** - * hal_srng_setup - Initialize HW SRNG ring. + * hal_srng_setup_idx - Initialize HW SRNG ring. * @hal_soc: Opaque HAL SOC handle * @ring_type: one of the types from hal_ring_type * @ring_num: Ring number if there are multiple rings of same type (staring @@ -1577,6 +1578,7 @@ static inline void hal_srng_update_high_wm_thresholds(struct hal_srng *srng) * @mac_id: valid MAC Id should be passed if ring type is one of lmac rings * @ring_params: SRNG ring params in hal_srng_params structure. * @idle_check: Check if ring is idle + * @idx: Ring index to be programmed as init value in HP/TP based on srng type * * Callers are expected to allocate contiguous ring memory of size * 'num_entries * entry_size' bytes and pass the physical and virtual base @@ -1588,11 +1590,13 @@ static inline void hal_srng_update_high_wm_thresholds(struct hal_srng *srng) * Return: Opaque pointer to ring on success * NULL on failure (if given ring is not available) */ -void *hal_srng_setup(void *hal_soc, int ring_type, int ring_num, - int mac_id, struct hal_srng_params *ring_params, bool idle_check) +void *hal_srng_setup_idx(void *hal_soc, int ring_type, int ring_num, int mac_id, + struct hal_srng_params *ring_params, bool idle_check, + uint32_t idx) { int ring_id; struct hal_soc *hal = (struct hal_soc *)hal_soc; + hal_soc_handle_t hal_hdl = (hal_soc_handle_t)hal; struct hal_srng *srng; struct hal_hw_srng_config *ring_config = HAL_SRNG_CONFIG(hal, ring_type); @@ -1758,7 +1762,18 @@ void *hal_srng_setup(void *hal_soc, int ring_type, int ring_num, } if (!(ring_config->lmac_ring)) { - hal_srng_hw_init(hal, srng, idle_check); + if (idx) { + hal->ops->hal_tx_ring_halt_set(hal_hdl); + do { + hal_info("Waiting for ring reset\n"); + } while (!(hal->ops->hal_tx_ring_halt_poll(hal_hdl))); + } + hal_srng_hw_init(hal, srng, idle_check, idx); + + if (idx) { + hal->ops->hal_tx_ring_halt_reset(hal_hdl); + } + if (ring_type == CE_DST) { srng->u.dst_ring.max_buffer_length = ring_params->max_buffer_length; @@ -1774,6 +1789,35 @@ void *hal_srng_setup(void *hal_soc, int ring_type, int ring_num, return (void *)srng; } +qdf_export_symbol(hal_srng_setup_idx); + +/** + * hal_srng_setup - Initialize HW SRNG ring. + * @hal_soc: Opaque HAL SOC handle + * @ring_type: one of the types from hal_ring_type + * @ring_num: Ring number if there are multiple rings of same type (staring + * from 0) + * @mac_id: valid MAC Id should be passed if ring type is one of lmac rings + * @ring_params: SRNG ring params in hal_srng_params structure. + * @idle_check: Check if ring is idle + * + * Callers are expected to allocate contiguous ring memory of size + * 'num_entries * entry_size' bytes and pass the physical and virtual base + * addresses through 'ring_base_paddr' and 'ring_base_vaddr' in + * hal_srng_params structure. Ring base address should be 8 byte aligned + * and size of each ring entry should be queried using the API + * hal_srng_get_entrysize + * + * Return: Opaque pointer to ring on success + * NULL on failure (if given ring is not available) + */ +void *hal_srng_setup(void *hal_soc, int ring_type, int ring_num, + int mac_id, struct hal_srng_params *ring_params, + bool idle_check) +{ + return hal_srng_setup_idx(hal_soc, ring_type, ring_num, mac_id, + ring_params, idle_check, 0); +} qdf_export_symbol(hal_srng_setup); /** diff --git a/hal/wifi3.0/qcn9224/hal_9224.h b/hal/wifi3.0/qcn9224/hal_9224.h index a865a83be4..56a4e85547 100644 --- a/hal/wifi3.0/qcn9224/hal_9224.h +++ b/hal/wifi3.0/qcn9224/hal_9224.h @@ -1835,6 +1835,11 @@ static void hal_hw_txrx_ops_attach_qcn9224(struct hal_soc *hal_soc) hal_get_tsf2_scratch_reg_qcn9224; hal_soc->ops->hal_get_tqm_scratch_reg = hal_get_tqm_scratch_reg_qcn9224; + hal_soc->ops->hal_tx_ring_halt_set = hal_tx_ppe2tcl_ring_halt_set_9224; + hal_soc->ops->hal_tx_ring_halt_reset = + hal_tx_ppe2tcl_ring_halt_reset_9224; + hal_soc->ops->hal_tx_ring_halt_poll = + hal_tx_ppe2tcl_ring_halt_done_9224; }; /** diff --git a/hal/wifi3.0/qcn9224/hal_9224_tx.h b/hal/wifi3.0/qcn9224/hal_9224_tx.h index 83c98d1703..69a0a77819 100644 --- a/hal/wifi3.0/qcn9224/hal_9224_tx.h +++ b/hal/wifi3.0/qcn9224/hal_9224_tx.h @@ -32,6 +32,74 @@ #define NUM_WORDS_PER_DSCP_TID_TABLE (DSCP_TID_TABLE_SIZE / 4) #define HAL_TX_NUM_DSCP_REGISTER_SIZE 32 +/** + * hal_tx_ppe2tcl_ring_halt_set() - Enable ring halt for the ppe2tcl ring + * @hal_soc: HAL SoC context + * + * Return: none + */ +static void hal_tx_ppe2tcl_ring_halt_set_9224(hal_soc_handle_t hal_soc) +{ + uint32_t cmn_reg_addr; + uint32_t regval; + struct hal_soc *soc = (struct hal_soc *)hal_soc; + + cmn_reg_addr = + HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_ADDR(MAC_TCL_REG_REG_BASE); + + /* Enable RING_HALT */ + regval = HAL_REG_READ(soc, cmn_reg_addr); + regval |= + (1 << + HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_PPE2TCL1_RNG_HALT_SHFT); + + HAL_REG_WRITE(soc, cmn_reg_addr, regval); +} + +/** + * hal_tx_ppe2tcl_ring_halt_reset() - Disable ring halt for the ppe2tcl ring + * @hal_soc: HAL SoC context + * + * Return: none + */ +static void hal_tx_ppe2tcl_ring_halt_reset_9224(hal_soc_handle_t hal_soc) +{ + uint32_t cmn_reg_addr; + uint32_t regval; + struct hal_soc *soc = (struct hal_soc *)hal_soc; + + cmn_reg_addr = + HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_ADDR(MAC_TCL_REG_REG_BASE); + + /* Disable RING_HALT */ + regval = HAL_REG_READ(soc, cmn_reg_addr); + regval &= ~(1 << + HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_PPE2TCL1_RNG_HALT_SHFT); + + HAL_REG_WRITE(soc, cmn_reg_addr, regval); +} + +/** + * hal_tx_ppe2tcl_ring_halt_done() - Check if ring halt is done for ppe2tcl ring + * @hal_soc: HAL SoC context + * + * Return: true if halt done + */ +static bool hal_tx_ppe2tcl_ring_halt_done_9224(hal_soc_handle_t hal_soc) +{ + uint32_t cmn_reg_addr; + uint32_t regval; + struct hal_soc *soc = (struct hal_soc *)hal_soc; + + cmn_reg_addr = + HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_ADDR(MAC_TCL_REG_REG_BASE); + + regval = HAL_REG_READ(soc, cmn_reg_addr); + regval &= (1 << HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_PPE2TCL1_RNG_HALT_STAT_SHFT); + + return(!!regval); +} + /** * hal_tx_set_dscp_tid_map_9224() - Configure default DSCP to TID map table * @soc: HAL SoC context