diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index e00bb4cb66..0aea2673fb 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -1446,7 +1446,8 @@ void dp_srng_deinit(struct dp_soc *soc, struct dp_srng *srng, ring_num); srng_cleanup: - hal_srng_cleanup(soc->hal_soc, srng->hal_srng); + hal_srng_cleanup(soc->hal_soc, srng->hal_srng, + dp_check_umac_reset_in_progress(soc)); srng->hal_srng = NULL; } diff --git a/hal/wifi3.0/hal_api.h b/hal/wifi3.0/hal_api.h index 05c8bca716..79c24b3dae 100644 --- a/hal/wifi3.0/hal_api.h +++ b/hal/wifi3.0/hal_api.h @@ -1254,8 +1254,10 @@ void hal_srng_dst_init_hp(struct hal_soc_handle *hal_soc, * hal_srng_cleanup() - Deinitialize HW SRNG ring. * @hal_soc: Opaque HAL SOC handle * @hal_ring_hdl: Opaque HAL SRNG pointer + * @umac_reset_inprogress: UMAC reset enabled/disabled. */ -void hal_srng_cleanup(void *hal_soc, hal_ring_handle_t hal_ring_hdl); +void hal_srng_cleanup(void *hal_soc, hal_ring_handle_t hal_ring_hdl, + bool umac_reset_inprogress); static inline bool hal_srng_initialized(hal_ring_handle_t hal_ring_hdl) { diff --git a/hal/wifi3.0/hal_generic_api.h b/hal/wifi3.0/hal_generic_api.h index 68f48e951f..576e47c05a 100644 --- a/hal/wifi3.0/hal_generic_api.h +++ b/hal/wifi3.0/hal_generic_api.h @@ -247,6 +247,8 @@ void hal_srng_src_hw_init_generic(struct hal_soc *hal, uint32_t reg_val = 0; uint64_t tp_addr = 0; + hal_debug("hw_init srng %d", srng->ring_id); + if (idle_check) { reg_val = SRNG_SRC_REG_READ(srng, MISC); if (!(reg_val & SRNG_IDLE_STATE_BIT)) { @@ -256,13 +258,11 @@ void hal_srng_src_hw_init_generic(struct hal_soc *hal, hal_srng_src_hw_write_cons_prefetch_timer(srng, srng->prefetch_timer); + } else { + reg_val = SRNG_SRC_REG_READ(srng, MISC) & ~(SRNG_ENABLE_BIT); + SRNG_SRC_REG_WRITE(srng, MISC, reg_val); } - 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) { @@ -442,20 +442,19 @@ void hal_srng_dst_hw_init_generic(struct hal_soc *hal, uint32_t reg_val = 0; uint64_t hp_addr = 0; + hal_debug("hw_init srng %d", srng->ring_id); + if (idle_check) { reg_val = SRNG_DST_REG_READ(srng, MISC); if (!(reg_val & SRNG_IDLE_STATE_BIT)) { hal_err("ring_id %d not in idle state", srng->ring_id); qdf_assert_always(0); } + } else { + reg_val = SRNG_DST_REG_READ(srng, MISC) & ~(SRNG_ENABLE_BIT); + SRNG_DST_REG_WRITE(srng, MISC, reg_val); } - 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) { diff --git a/hal/wifi3.0/hal_internal.h b/hal/wifi3.0/hal_internal.h index 56cb33fae5..d893811954 100644 --- a/hal/wifi3.0/hal_internal.h +++ b/hal/wifi3.0/hal_internal.h @@ -1454,6 +1454,7 @@ struct hal_hw_txrx_ops { bool (*hal_tx_ring_halt_poll)(hal_soc_handle_t hal_soc_hdl); uint32_t (*hal_tx_get_num_ppe_vp_search_idx_tbl_entries)( hal_soc_handle_t hal_soc_hdl); + uint32_t (*hal_tx_ring_halt_get)(hal_soc_handle_t hal_soc_hdl); }; /** diff --git a/hal/wifi3.0/hal_srng.c b/hal/wifi3.0/hal_srng.c index 368016e432..809a05c366 100644 --- a/hal/wifi3.0/hal_srng.c +++ b/hal/wifi3.0/hal_srng.c @@ -1711,6 +1711,22 @@ void *hal_srng_setup_idx(void *hal_soc, int ring_type, int ring_num, int mac_id, } if (!(ring_config->lmac_ring)) { + /* + * UMAC reset has idle check enabled. + * During UMAC reset Tx ring halt is set + * by Wi-Fi FW during pre-reset stage, + * avoid Tx ring halt again. + */ + if (idle_check && idx) { + if (!hal->ops->hal_tx_ring_halt_get(hal_hdl)) { + qdf_print("\nTx ring halt not set:Ring(%d, %d)", + ring_type, ring_num); + qdf_assert_always(0); + } + hal_srng_hw_init(hal, srng, idle_check, idx); + goto ce_setup; + } + if (idx) { hal->ops->hal_tx_ring_halt_set(hal_hdl); do { @@ -1723,7 +1739,7 @@ void *hal_srng_setup_idx(void *hal_soc, int ring_type, int ring_num, int mac_id, hal->ops->hal_tx_ring_halt_reset(hal_hdl); } - +ce_setup: if (ring_type == CE_DST) { srng->u.dst_ring.max_buffer_length = ring_params->max_buffer_length; hal_ce_dst_setup(hal, srng, ring_num); @@ -1769,12 +1785,14 @@ void *hal_srng_setup(void *hal_soc, int ring_type, int ring_num, } qdf_export_symbol(hal_srng_setup); -void hal_srng_cleanup(void *hal_soc, hal_ring_handle_t hal_ring_hdl) +void hal_srng_cleanup(void *hal_soc, hal_ring_handle_t hal_ring_hdl, + bool umac_reset_inprogress) { struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; SRNG_LOCK_DESTROY(&srng->lock); srng->initialized = 0; - hal_srng_hw_disable(hal_soc, srng); + if (umac_reset_inprogress) + hal_srng_hw_disable(hal_soc, srng); } qdf_export_symbol(hal_srng_cleanup); diff --git a/hal/wifi3.0/qcn9224/hal_9224.h b/hal/wifi3.0/qcn9224/hal_9224.h index 0241c0a542..68a0afe223 100644 --- a/hal/wifi3.0/qcn9224/hal_9224.h +++ b/hal/wifi3.0/qcn9224/hal_9224.h @@ -1821,6 +1821,7 @@ static void hal_hw_txrx_ops_attach_qcn9224(struct hal_soc *hal_soc) hal_tx_ppe2tcl_ring_halt_done_9224; hal_soc->ops->hal_tx_get_num_ppe_vp_search_idx_tbl_entries = hal_tx_get_num_ppe_vp_search_idx_reg_entries_9224; + hal_soc->ops->hal_tx_ring_halt_get = hal_tx_ppe2tcl_ring_halt_get_9224; }; /** diff --git a/hal/wifi3.0/qcn9224/hal_9224_tx.h b/hal/wifi3.0/qcn9224/hal_9224_tx.h index f04342df2b..8276a35125 100644 --- a/hal/wifi3.0/qcn9224/hal_9224_tx.h +++ b/hal/wifi3.0/qcn9224/hal_9224_tx.h @@ -32,6 +32,28 @@ #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_get_9224() - Get ring halt for the ppe2tcl ring + * @hal_soc: HAL SoC context + * + * Return: Ring halt status. + */ +static uint32_t hal_tx_ppe2tcl_ring_halt_get_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); + + /* Get RING_HALT status */ + regval = HAL_REG_READ(soc, cmn_reg_addr); + return (regval & + (1 << + HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_PPE2TCL1_RNG_HALT_SHFT)); +} + /** * hal_tx_ppe2tcl_ring_halt_set_9224() - Enable ring halt for the ppe2tcl ring * @hal_soc: HAL SoC context diff --git a/hif/src/ce/ce_service_srng.c b/hif/src/ce/ce_service_srng.c index 62fc135ea4..b80243c1f3 100644 --- a/hif/src/ce/ce_service_srng.c +++ b/hif/src/ce/ce_service_srng.c @@ -981,7 +981,7 @@ static void ce_ring_cleanup_srng(struct hif_softc *scn, } if (hal_srng) - hal_srng_cleanup(scn->hal_soc, hal_srng); + hal_srng_cleanup(scn->hal_soc, hal_srng, 0); } static void ce_construct_shadow_config_srng(struct hif_softc *scn) diff --git a/target_if/direct_buf_rx/src/target_if_direct_buf_rx_main.c b/target_if/direct_buf_rx/src/target_if_direct_buf_rx_main.c index 59cac1e7a9..0f0209d1b2 100644 --- a/target_if/direct_buf_rx/src/target_if_direct_buf_rx_main.c +++ b/target_if/direct_buf_rx/src/target_if_direct_buf_rx_main.c @@ -2318,7 +2318,7 @@ static QDF_STATUS target_if_dbr_deinit_ring(struct wlan_objmgr_pdev *pdev, dbr_ring_cfg = mod_param->dbr_ring_cfg; if (dbr_ring_cfg) { target_if_dbr_empty_ring(pdev, dbr_psoc_obj, mod_param); - hal_srng_cleanup(dbr_psoc_obj->hal_soc, dbr_ring_cfg->srng); + hal_srng_cleanup(dbr_psoc_obj->hal_soc, dbr_ring_cfg->srng, 0); qdf_mem_free_consistent(dbr_psoc_obj->osdev, dbr_psoc_obj->osdev->dev, dbr_ring_cfg->ring_alloc_size, diff --git a/target_if/wifi_pos/src/target_if_wifi_pos.c b/target_if/wifi_pos/src/target_if_wifi_pos.c index 0e92270aa0..55183507e0 100644 --- a/target_if/wifi_pos/src/target_if_wifi_pos.c +++ b/target_if/wifi_pos/src/target_if_wifi_pos.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -295,7 +295,7 @@ static QDF_STATUS target_if_wifi_pos_deinit_ring(uint8_t ring_idx, { target_if_wifi_pos_empty_ring(ring_idx, priv); priv->dma_buf_pool[ring_idx] = NULL; - hal_srng_cleanup(priv->hal_soc, priv->dma_cfg[ring_idx].srng); + hal_srng_cleanup(priv->hal_soc, priv->dma_cfg[ring_idx].srng, 0); qdf_mem_free_consistent(NULL, NULL, priv->dma_cfg[ring_idx].ring_alloc_size, priv->dma_cfg[ring_idx].base_vaddr_unaligned,