diff --git a/components/fw_offload/core/inc/wlan_fw_offload_main.h b/components/fw_offload/core/inc/wlan_fw_offload_main.h index cfa5df462922..7e83d99f6560 100644 --- a/components/fw_offload/core/inc/wlan_fw_offload_main.h +++ b/components/fw_offload/core/inc/wlan_fw_offload_main.h @@ -204,6 +204,7 @@ struct wlan_fwol_neighbor_report_cfg { * @enable_dhcp_server_offload: DHCP Offload is enabled or not * @dhcp_max_num_clients: Max number of DHCP client supported * @dwelltime_params: adaptive dwell time parameters + * @ocl_cfg: OCL mode configuration */ struct wlan_fwol_cfg { /* Add CFG and INI items here */ @@ -254,6 +255,7 @@ struct wlan_fwol_cfg { uint32_t dhcp_max_num_clients; #endif struct adaptive_dwelltime_params dwelltime_params; + uint32_t ocl_cfg; }; /** diff --git a/components/fw_offload/core/src/wlan_fw_offload_main.c b/components/fw_offload/core/src/wlan_fw_offload_main.c index db09ef715c0a..4ef20f4aabd2 100644 --- a/components/fw_offload/core/src/wlan_fw_offload_main.c +++ b/components/fw_offload/core/src/wlan_fw_offload_main.c @@ -540,6 +540,7 @@ QDF_STATUS fwol_cfg_on_psoc_enable(struct wlan_objmgr_psoc *psoc) ucfg_fwol_fetch_tsf_sync_host_gpio_pin(psoc, fwol_cfg); ucfg_fwol_fetch_dhcp_server_settings(psoc, fwol_cfg); fwol_cfg->sap_xlna_bypass = cfg_get(psoc, CFG_SET_SAP_XLNA_BYPASS); + fwol_cfg->ocl_cfg = cfg_get(psoc, CFG_SET_OCL_CFG); return status; } diff --git a/components/fw_offload/dispatcher/inc/cfg_fwol_generic.h b/components/fw_offload/dispatcher/inc/cfg_fwol_generic.h index 403a3eb6a31a..707d440db405 100644 --- a/components/fw_offload/dispatcher/inc/cfg_fwol_generic.h +++ b/components/fw_offload/dispatcher/inc/cfg_fwol_generic.h @@ -728,6 +728,36 @@ 0, \ "SAP xLNA bypass control") +/* + * + * gOclCfg - Enable/Disable OCL mode + * @Min: 0 + * @Max: 2 + * @Default: 2 + * + * This ini is used to set one chain listen (OCL) mode to static or dynamic + * enable/disable during bootup. value 0 disables both static/dynamic OCL. + * value 1 enables static OCL. Once its enabled it stays enabled. value 2 + * enables dynamic OCL. In dynamic OCL mode one chain listen will be + * enabled/disabled by firmware during runtime based on RSSI. + * + * Related: None + * + * Supported Feature: OCL + * + * Usage: Internal + * + * + */ + +#define CFG_SET_OCL_CFG CFG_INI_UINT( \ + "gOclCfg", \ + 0, \ + 2, \ + 2, \ + CFG_VALUE_OR_DEFAULT, \ + "OCL configuration") + #define CFG_FWOL_GENERIC_ALL \ CFG_FWOL_DHCP \ CFG(CFG_ENABLE_ANI) \ @@ -754,6 +784,7 @@ CFG(CFG_ENABLE_GCMP) \ CFG(CFG_TX_SCH_DELAY) \ CFG(CFG_ENABLE_SECONDARY_RATE) \ - CFG(CFG_SET_SAP_XLNA_BYPASS) + CFG(CFG_SET_SAP_XLNA_BYPASS) \ + CFG(CFG_SET_OCL_CFG) #endif diff --git a/components/fw_offload/dispatcher/inc/wlan_fwol_ucfg_api.h b/components/fw_offload/dispatcher/inc/wlan_fwol_ucfg_api.h index b6ed7f7e2ca8..71aa87b457ad 100644 --- a/components/fw_offload/dispatcher/inc/wlan_fwol_ucfg_api.h +++ b/components/fw_offload/dispatcher/inc/wlan_fwol_ucfg_api.h @@ -286,6 +286,16 @@ QDF_STATUS ucfg_fwol_get_enable_fw_module_log_level( QDF_STATUS ucfg_fwol_get_sap_xlna_bypass(struct wlan_objmgr_psoc *psoc, bool *sap_xlna_bypass); +/** + * ucfg_fwol_get_ocl_cfg() - Assigns ocl_cfg value + * @psoc: pointer to the psoc object + * @ocl_cfg: pointer to return ocl_cfg + * + * Return: QDF Status + */ +QDF_STATUS ucfg_fwol_get_ocl_cfg(struct wlan_objmgr_psoc *psoc, + uint32_t *ocl_cfg); + #ifdef FEATURE_WLAN_RA_FILTERING /** * ucfg_fwol_set_is_rate_limit_enabled() - Sets the is_rate_limit_enabled value @@ -741,6 +751,12 @@ ucfg_fwol_get_sap_xlna_bypass(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_FAILURE; } +static inline QDF_STATUS +ucfg_fwol_get_ocl_cfg(struct wlan_objmgr_psoc *psoc, uint32_t *ocl_cfg) +{ + return QDF_STATUS_E_FAILURE; +} + static inline QDF_STATUS ucfg_fwol_get_tsf_gpio_pin(struct wlan_objmgr_psoc *psoc, uint32_t *tsf_gpio_pin) diff --git a/components/fw_offload/dispatcher/src/wlan_fwol_ucfg_api.c b/components/fw_offload/dispatcher/src/wlan_fwol_ucfg_api.c index 83d7eb230b8a..3235d4981e5c 100644 --- a/components/fw_offload/dispatcher/src/wlan_fwol_ucfg_api.c +++ b/components/fw_offload/dispatcher/src/wlan_fwol_ucfg_api.c @@ -520,6 +520,21 @@ QDF_STATUS ucfg_fwol_get_sap_xlna_bypass(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +QDF_STATUS ucfg_fwol_get_ocl_cfg(struct wlan_objmgr_psoc *psoc, + uint32_t *ocl_cfg) +{ + struct wlan_fwol_psoc_obj *fwol_obj; + + fwol_obj = fwol_get_psoc_obj(psoc); + if (!fwol_obj) { + fwol_err("Failed to get FWOL obj"); + return QDF_STATUS_E_FAILURE; + } + + *ocl_cfg = fwol_obj->cfg.ocl_cfg; + return QDF_STATUS_SUCCESS; +} + #ifdef FEATURE_WLAN_RA_FILTERING QDF_STATUS ucfg_fwol_set_is_rate_limit_enabled(struct wlan_objmgr_psoc *psoc, bool is_rate_limit_enabled) diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 4d60ecba2486..be055fc77411 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -4996,6 +4996,58 @@ bool hdd_is_vdev_in_conn_state(struct hdd_adapter *adapter) return 0; } +/** + * hdd_send_ocl_cmd() - Send ocl command to FW + * @hdd_ctx: HDD context + * @adapter: Primary adapter context + * + * This function is used to send OCL mode configuration to FW + * + * Return: 0 on success and -EINVAL on failure + */ +static int hdd_send_ocl_cmd(struct hdd_context *hdd_ctx, + struct hdd_adapter *adapter) +{ + struct ocl_cmd_params ocl_params = {0}; + struct wlan_objmgr_psoc *psoc; + QDF_STATUS status; + + if (!hdd_ctx) { + hdd_err("hdd_ctx is invalid"); + goto err; + } + + if (!adapter) { + hdd_err("adapter is invalid"); + goto err; + } + + psoc = hdd_ctx->psoc; + + if (!psoc) { + hdd_err("HDD psoc is invalid"); + goto err; + } + + status = ucfg_fwol_get_ocl_cfg(psoc, &ocl_params.en_dis_chain); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("Unable to get OCL mode configuration"); + goto err; + } + + ocl_params.vdev_id = adapter->vdev_id; + + status = sme_send_ocl_cmd(&ocl_params); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("Failed to send ocl command"); + goto err; + } + + return 0; +err: + return -EINVAL; +} + int hdd_vdev_create(struct hdd_adapter *adapter) { QDF_STATUS status; @@ -5101,6 +5153,8 @@ int hdd_vdev_create(struct hdd_adapter *adapter) } hdd_store_nss_chains_cfg_in_vdev(adapter); + hdd_send_ocl_cmd(hdd_ctx, adapter); + hdd_nofl_debug("vdev %d created successfully", adapter->vdev_id); return errno; diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index 1958d72194ee..464ddf9ea602 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -2348,6 +2348,14 @@ QDF_STATUS sme_set_sar_power_limits(mac_handle_t mac_handle, */ QDF_STATUS sme_send_coex_config_cmd(struct coex_config_params *coex_cfg_params); +/** + * sme_send_ocl_cmd() - Send OCL command + * @ocl_params: OCL command params + * + * Return: QDF_STATUS + */ +QDF_STATUS sme_send_ocl_cmd(struct ocl_cmd_params *ocl_params); + void sme_set_cc_src(mac_handle_t mac_handle, enum country_src); diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 7adab7b6a0b5..ab4795e18ec3 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -13801,6 +13801,18 @@ QDF_STATUS sme_send_coex_config_cmd(struct coex_config_params *coex_cfg_params) return wma_send_coex_config_cmd(wma_handle, coex_cfg_params); } +QDF_STATUS sme_send_ocl_cmd(struct ocl_cmd_params *ocl_params) +{ + void *wma_handle; + + wma_handle = cds_get_context(QDF_MODULE_ID_WMA); + if (!wma_handle) { + sme_err("wma handle is NULL"); + return QDF_STATUS_E_FAILURE; + } + return wma_send_ocl_cmd(wma_handle, ocl_params); +} + #ifdef WLAN_FEATURE_FIPS QDF_STATUS sme_fips_request(mac_handle_t mac_handle, struct fips_params *param, wma_fips_cb callback, void *context) diff --git a/core/wma/inc/wma_api.h b/core/wma/inc/wma_api.h index e60c7359671d..463cac83ba2a 100644 --- a/core/wma/inc/wma_api.h +++ b/core/wma/inc/wma_api.h @@ -414,6 +414,17 @@ QDF_STATUS wma_set_sar_limit(WMA_HANDLE handle, QDF_STATUS wma_send_coex_config_cmd(WMA_HANDLE wma_handle, struct coex_config_params *coex_cfg_params); +/** + * wma_send_ocl_cmd() - Send OCL command + * @wma_handle: wma handle + * @ocl_params: OCL command params + * + * This function sends WMI command to send OCL mode configuration + * + * Return: QDF_STATUS + */ +QDF_STATUS wma_send_ocl_cmd(WMA_HANDLE wma_handle, + struct ocl_cmd_params *ocl_params); /** * wma_set_qpower_config() - update qpower config in wma * @vdev_id: the Id of the vdev to configure diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c index 328bf257da37..cd18b0f2f42d 100644 --- a/core/wma/src/wma_features.c +++ b/core/wma/src/wma_features.c @@ -4724,6 +4724,25 @@ QDF_STATUS wma_send_coex_config_cmd(WMA_HANDLE wma_handle, coex_cfg_params); } +QDF_STATUS wma_send_ocl_cmd(WMA_HANDLE wma_handle, + struct ocl_cmd_params *ocl_params) +{ + tp_wma_handle wma = (tp_wma_handle)wma_handle; + + if (!wma || !wma->wmi_handle) { + WMA_LOGE("%s: WMA is closed, can not issue coex config command", + __func__); + return QDF_STATUS_E_INVAL; + } + + if (!ocl_params) { + WMA_LOGE("%s: ocl params ptr NULL", __func__); + return QDF_STATUS_E_INVAL; + } + + return wmi_unified_send_ocl_cmd(wma->wmi_handle, ocl_params); +} + /** * wma_get_arp_stats_handler() - handle arp stats data * indicated by FW