From 52181cceb1bc8b654c0a9afde4f69089e2d2a1bf Mon Sep 17 00:00:00 2001 From: sumedh baikady Date: Tue, 22 Feb 2022 12:44:15 -0800 Subject: [PATCH] qcacmn: Fix Reo qref issues 1. Since peer id is reused for reconnection in MLO case, old entries for queue desc addr is cleared. Clear the reo internal storage and reset it back on client connection. 2. Send Qref feature WMI cmd to FW to enable the feature. Change-Id: I6705ce121c8c25d9a2ace039dab21312fa5ea4b1 CRs-Fixed: 3156642 --- dp/wifi3.0/dp_peer.c | 3 +++ hal/wifi3.0/be/hal_be_generic_api.h | 27 ++++++++++++++++++++++++ hal/wifi3.0/hal_internal.h | 1 + hal/wifi3.0/hal_rx.h | 23 ++++++++++++++++++++ hal/wifi3.0/qcn9224/hal_9224.c | 1 + target_if/core/inc/target_if.h | 14 ++++++++++++ target_if/init_deinit/src/init_cmd_api.c | 2 ++ wmi/inc/wmi_unified_param.h | 2 ++ wmi/src/wmi_unified_tlv.c | 4 ++++ 9 files changed, 77 insertions(+) diff --git a/dp/wifi3.0/dp_peer.c b/dp/wifi3.0/dp_peer.c index 200b25590c..f281246afd 100644 --- a/dp/wifi3.0/dp_peer.c +++ b/dp/wifi3.0/dp_peer.c @@ -3925,6 +3925,9 @@ void dp_peer_rx_init(struct dp_pdev *pdev, struct dp_peer *peer) peer->hw_buffer_size = 0; peer->kill_256_sessions = 0; + if (hal_reo_shared_qaddr_is_enable(pdev->soc->hal_soc)) + hal_reo_shared_qaddr_cache_clear(pdev->soc->hal_soc); + /* Setup default (non-qos) rx tid queue */ dp_rx_tid_setup_wifi3(peer, DP_NON_QOS_TID, 1, 0); diff --git a/hal/wifi3.0/be/hal_be_generic_api.h b/hal/wifi3.0/be/hal_be_generic_api.h index 5dbab8f017..cc5c76714a 100644 --- a/hal/wifi3.0/be/hal_be_generic_api.h +++ b/hal/wifi3.0/be/hal_be_generic_api.h @@ -666,6 +666,33 @@ static void hal_reo_shared_qaddr_write_be(hal_soc_handle_t hal_soc_hdl, reo_qref->rx_reo_queue_desc_addr_39_32); } +static void hal_reo_shared_qaddr_cache_clear_be(hal_soc_handle_t hal_soc_hdl) +{ + struct hal_soc *hal = (struct hal_soc *)hal_soc_hdl; + uint32_t reg_val = 0; + + /* Set Qdesc clear bit to erase REO internal storage for Qdesc pointers + * of 37 peer/tids + */ + reg_val = HAL_REG_READ(hal, HWIO_REO_R0_QDESC_ADDR_READ_ADDR(REO_REG_REG_BASE)); + reg_val |= HAL_SM(HWIO_REO_R0_QDESC_ADDR_READ, CLEAR_QDESC_ARRAY, 1); + HAL_REG_WRITE(hal, + HWIO_REO_R0_QDESC_ADDR_READ_ADDR(REO_REG_REG_BASE), + reg_val); + + /* Clear Qdesc clear bit to erase REO internal storage for Qdesc pointers + * of 37 peer/tids + */ + reg_val &= ~(HAL_SM(HWIO_REO_R0_QDESC_ADDR_READ, CLEAR_QDESC_ARRAY, 1)); + HAL_REG_WRITE(hal, + HWIO_REO_R0_QDESC_ADDR_READ_ADDR(REO_REG_REG_BASE), + reg_val); + + hal_verbose_debug("hal_soc: %pK :Setting CLEAR_DESC_ARRAY field of" + "WCSS_UMAC_REO_R0_QDESC_ADDR_READ and resetting back" + "to erase stale entries in reo storage: regval:%x", hal, reg_val); +} + /** * hal_reo_shared_qaddr_setup() - Allocate MLO and Non MLO reo queue * reference table shared between SW and HW and initialize in Qdesc Base0 diff --git a/hal/wifi3.0/hal_internal.h b/hal/wifi3.0/hal_internal.h index 4a7fe5420a..bd4b33845c 100644 --- a/hal/wifi3.0/hal_internal.h +++ b/hal/wifi3.0/hal_internal.h @@ -1074,6 +1074,7 @@ struct hal_hw_txrx_ops { #ifdef WLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET uint8_t (*hal_get_first_wow_wakeup_packet)(uint8_t *buf); #endif + void (*hal_reo_shared_qaddr_cache_clear)(hal_soc_handle_t hal_soc_hdl); }; /** diff --git a/hal/wifi3.0/hal_rx.h b/hal/wifi3.0/hal_rx.h index 2590b07b06..ee9bb72ea3 100644 --- a/hal/wifi3.0/hal_rx.h +++ b/hal/wifi3.0/hal_rx.h @@ -2934,6 +2934,26 @@ hal_reo_shared_qaddr_init(hal_soc_handle_t hal_soc_hdl) return hal_soc->ops->hal_reo_shared_qaddr_init(hal_soc_hdl); } +/** + * hal_reo_shared_qaddr_cache_clear(): Set and unset 'clear_qdesc_array' + * bit in reo reg for shared qref feature. This is done for every MLO + * connection to clear HW reo internal storage for clearing stale entry + * of prev peer having same peer id + * + * @hal_soc: Hal soc pointer + * + * Write MLO and Non MLO table start addr to HW reg + * + * Return: void + */ +static inline void hal_reo_shared_qaddr_cache_clear(hal_soc_handle_t hal_soc_hdl) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + if (hal_soc->ops->hal_reo_shared_qaddr_cache_clear) + return hal_soc->ops->hal_reo_shared_qaddr_cache_clear(hal_soc_hdl); +} + #else static inline void hal_reo_shared_qaddr_write(hal_soc_handle_t hal_soc_hdl, @@ -2943,6 +2963,9 @@ hal_reo_shared_qaddr_write(hal_soc_handle_t hal_soc_hdl, static inline void hal_reo_shared_qaddr_init(hal_soc_handle_t hal_soc_hdl) {} +static inline void +hal_reo_shared_qaddr_cache_clear(hal_soc_handle_t hal_soc_hdl) {} + #endif /* REO_SHARED_QREF_TABLE_EN */ static inline uint8_t diff --git a/hal/wifi3.0/qcn9224/hal_9224.c b/hal/wifi3.0/qcn9224/hal_9224.c index c11a9d457f..eef091fb6b 100644 --- a/hal/wifi3.0/qcn9224/hal_9224.c +++ b/hal/wifi3.0/qcn9224/hal_9224.c @@ -1931,6 +1931,7 @@ static void hal_hw_txrx_ops_attach_qcn9224(struct hal_soc *hal_soc) hal_soc->ops->hal_reo_shared_qaddr_init = hal_reo_shared_qaddr_init_be; hal_soc->ops->hal_reo_shared_qaddr_detach = hal_reo_shared_qaddr_detach_be; hal_soc->ops->hal_reo_shared_qaddr_write = hal_reo_shared_qaddr_write_be; + hal_soc->ops->hal_reo_shared_qaddr_cache_clear = hal_reo_shared_qaddr_cache_clear_be; #endif /* Overwrite the default BE ops */ hal_soc->ops->hal_get_reo_qdesc_size = hal_qcn9224_get_reo_qdesc_size; diff --git a/target_if/core/inc/target_if.h b/target_if/core/inc/target_if.h index 8c093e5d65..d508d84a16 100644 --- a/target_if/core/inc/target_if.h +++ b/target_if/core/inc/target_if.h @@ -2774,4 +2774,18 @@ QDF_STATUS target_if_mlo_teardown_req(struct wlan_objmgr_pdev **pdev, uint8_t num_pdevs, uint32_t reason); #endif /*WLAN_FEATURE_11BE_MLO && WLAN_MLO_MULTI_CHIP*/ +#ifdef REO_SHARED_QREF_TABLE_EN +static inline void target_if_set_reo_shared_qref_feature(struct wlan_objmgr_psoc *psoc, + struct tgt_info *info) +{ + info->wlan_res_cfg.reo_qdesc_shared_addr_table_enabled = true; +} +#else +static inline void target_if_set_reo_shared_qref_feature(struct wlan_objmgr_psoc *psoc, + struct tgt_info *info) +{ + info->wlan_res_cfg.reo_qdesc_shared_addr_table_enabled = false; +} +#endif + #endif diff --git a/target_if/init_deinit/src/init_cmd_api.c b/target_if/init_deinit/src/init_cmd_api.c index 073a8a272a..1d06bd11ad 100644 --- a/target_if/init_deinit/src/init_cmd_api.c +++ b/target_if/init_deinit/src/init_cmd_api.c @@ -488,6 +488,8 @@ void init_deinit_prepare_send_init_cmd( target_if_ext_res_cfg_enable(psoc, tgt_hdl, NULL); + target_if_set_reo_shared_qref_feature(psoc, info); + wmi_unified_init_cmd_send(wmi_handle, &init_param); /* Set Max scans allowed */ diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h index e99b389234..13b251ac05 100644 --- a/wmi/inc/wmi_unified_param.h +++ b/wmi/inc/wmi_unified_param.h @@ -5748,6 +5748,7 @@ struct wmi_host_fw_abi_ver { * @afc_timer_check_disable: Disables AFC Timer related checks in FW * @afc_req_id_check_disable: Disables AFC Request ID check in FW * @carrier_profile_config: Configuration for per-carrier profile + * @reo_qdesc_shared_addr_table_enabled: Reo shared qref enhancement enabled */ typedef struct { uint32_t num_vdevs; @@ -5869,6 +5870,7 @@ typedef struct { bool afc_req_id_check_disable; uint32_t carrier_profile_config; bool sawf; + bool reo_qdesc_shared_addr_table_enabled; } target_resource_config; /** diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index 3933b50c0d..adbfd1b8ec 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -8100,6 +8100,10 @@ void wmi_copy_resource_config(wmi_resource_config *resource_cfg, WMI_RSRC_CFG_HOST_SERVICE_FLAG_STA_TWT_SYNC_EVT_SUPPORT_SET( resource_cfg->host_service_flags, 1); + if (tgt_res_cfg->reo_qdesc_shared_addr_table_enabled) + WMI_RSRC_CFG_HOST_SERVICE_FLAG_REO_QREF_FEATURE_SUPPORT_SET( + resource_cfg->host_service_flags, 1); + WMI_RSRC_CFG_FLAGS2_RX_PEER_METADATA_VERSION_SET(resource_cfg->flags2, tgt_res_cfg->target_cap_flags); }