diff --git a/components/mlme/core/inc/wlan_mlme_main.h b/components/mlme/core/inc/wlan_mlme_main.h index d485dca15a..399c9726f0 100644 --- a/components/mlme/core/inc/wlan_mlme_main.h +++ b/components/mlme/core/inc/wlan_mlme_main.h @@ -75,6 +75,7 @@ enum vdev_assoc_type { * @assoc_type: vdev associate/reassociate type * @dynamic_cfg: current configuration of nss, chains for vdev. * @ini_cfg: Max configuration of nss, chains supported for vdev. + * @sta_dynamic_oce_value: Dyanmic oce flags value for sta */ struct mlme_legacy_priv { bool chan_switch_in_progress; @@ -84,18 +85,20 @@ struct mlme_legacy_priv { enum vdev_assoc_type assoc_type; struct wlan_mlme_nss_chains dynamic_cfg; struct wlan_mlme_nss_chains ini_cfg; + uint8_t sta_dynamic_oce_value; }; #else - /** * struct vdev_mlme_obj - VDEV MLME component object * @dynamic_cfg: current configuration of nss, chains for vdev. * @ini_cfg: Max configuration of nss, chains supported for vdev. + * @sta_dynamic_oce_value: Dyanmic oce flags value for sta */ struct vdev_mlme_priv_obj { struct wlan_mlme_nss_chains dynamic_cfg; struct wlan_mlme_nss_chains ini_cfg; + uint8_t sta_dynamic_oce_value; }; /** @@ -211,6 +214,16 @@ QDF_STATUS mlme_peer_object_destroyed_notification(struct wlan_objmgr_peer *peer, void *arg); +/** + * mlme_get_dynamic_oce_flags(): mlme get dynamic oce flags + * @vdev: pointer to vdev object + * + * This api is used to get the dynamic oce flags pointer + * + * Return: QDF_STATUS status in case of success else return error + */ +uint8_t *mlme_get_dynamic_oce_flags(struct wlan_objmgr_vdev *vdev); + /** * mlme_get_dynamic_vdev_config() - get the vdev dynamic config params * @vdev: vdev pointer diff --git a/components/mlme/core/src/wlan_mlme_main.c b/components/mlme/core/src/wlan_mlme_main.c index 61a64f5e6a..b8628bc0c2 100644 --- a/components/mlme/core/src/wlan_mlme_main.c +++ b/components/mlme/core/src/wlan_mlme_main.c @@ -79,6 +79,22 @@ struct wlan_mlme_nss_chains *mlme_get_ini_vdev_config( return &mlme_priv->ini_cfg; } +uint8_t *mlme_get_dynamic_oce_flags(struct wlan_objmgr_vdev *vdev) +{ + struct vdev_mlme_obj *vdev_mlme; + struct mlme_legacy_priv *mlme_priv; + + vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); + if (!vdev_mlme) { + mlme_err("vdev component object is NULL"); + return NULL; + } + + mlme_priv = vdev_mlme->ext_vdev_ptr; + + return &mlme_priv->sta_dynamic_oce_value; +} + #else static struct vdev_mlme_priv_obj * @@ -101,6 +117,19 @@ wlan_vdev_mlme_get_priv_obj(struct wlan_objmgr_vdev *vdev) return vdev_mlme; } +uint8_t *mlme_get_dynamic_oce_flags(struct wlan_objmgr_vdev *vdev) +{ + struct vdev_mlme_priv_obj *vdev_mlme; + + vdev_mlme = wlan_vdev_mlme_get_priv_obj(vdev); + if (!vdev_mlme) { + mlme_err("vdev component object is NULL"); + return NULL; + } + + return &vdev_mlme->sta_dynamic_oce_value; +} + struct wlan_mlme_nss_chains *mlme_get_dynamic_vdev_config( struct wlan_objmgr_vdev *vdev) { diff --git a/components/mlme/dispatcher/inc/wlan_mlme_api.h b/components/mlme/dispatcher/inc/wlan_mlme_api.h index 666947333d..3847c0f4b0 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_api.h @@ -782,6 +782,14 @@ QDF_STATUS wlan_mlme_get_oce_sta_enabled_info(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_oce_sap_enabled_info(struct wlan_objmgr_psoc *psoc, bool *value); +/** + * wlan_mlme_update_oce_flags() - Update the oce flags to FW + * @pdev: pointer to pdev object + * + * Return: void + */ +void wlan_mlme_update_oce_flags(struct wlan_objmgr_pdev *pdev); + #ifdef WLAN_FEATURE_11AX /** * wlan_mlme_cfg_get_he_ul_mumimo() - Get the HE Ul Mumio diff --git a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h index fa62cfb5e7..0d1f527ed8 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h @@ -1807,6 +1807,22 @@ QDF_STATUS ucfg_mlme_get_oce_sap_enabled_info(struct wlan_objmgr_psoc *psoc, return wlan_mlme_get_oce_sap_enabled_info(psoc, value); } +/** + * ucfg_mlme_update_oce_flags: Update the OCE flags + * + * @pdev: pointer to pdev object + * + * Inline UCFG API to be used by HDD/OSIF callers to update the + * OCE feature flags + * + * Return: void + */ +static inline +void ucfg_mlme_update_oce_flags(struct wlan_objmgr_pdev *pdev) +{ + wlan_mlme_update_oce_flags(pdev); +} + /** * ucfg_mlme_is_ap_prot_enabled() - Check if sap is enabled * @psoc: pointer to psoc object diff --git a/components/mlme/dispatcher/src/wlan_mlme_api.c b/components/mlme/dispatcher/src/wlan_mlme_api.c index b9345ed5b5..d8976931d0 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_api.c +++ b/components/mlme/dispatcher/src/wlan_mlme_api.c @@ -27,6 +27,7 @@ #include "wma.h" #include "wma_internal.h" #include "wlan_crypto_global_api.h" +#include "wlan_utility.h" QDF_STATUS wlan_mlme_get_cfg_str(uint8_t *dst, struct mlme_cfg_str *cfg_str, qdf_size_t *len) @@ -1935,6 +1936,73 @@ QDF_STATUS wlan_mlme_get_oce_sap_enabled_info(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +/** + * wlan_mlme_send_oce_flags_fw() - Send the oce flags to FW + * @pdev: pointer to pdev object + * @object: vdev object + * @arg: Arguments to the handler + * + * Return: void + */ +static void wlan_mlme_send_oce_flags_fw(struct wlan_objmgr_pdev *pdev, + void *object, void *arg) +{ + struct wlan_objmgr_vdev *vdev = object; + uint8_t *updated_fw_value = arg; + uint8_t *dynamic_fw_value = 0; + uint8_t vdev_id; + + if (wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE) { + dynamic_fw_value = mlme_get_dynamic_oce_flags(vdev); + if (*updated_fw_value == *dynamic_fw_value) { + mlme_debug("Current FW flags matches with updated value."); + return; + } + *dynamic_fw_value = *updated_fw_value; + vdev_id = wlan_vdev_get_id(vdev); + if (wma_cli_set_command(vdev_id, + WMI_VDEV_PARAM_ENABLE_DISABLE_OCE_FEATURES, + *updated_fw_value, VDEV_CMD)) + mlme_err("Failed to send OCE update to FW"); + } +} + +void wlan_mlme_update_oce_flags(struct wlan_objmgr_pdev *pdev) +{ + uint16_t sap_connected_peer, go_connected_peer; + struct wlan_objmgr_psoc *psoc = NULL; + struct wlan_mlme_psoc_obj *mlme_obj; + uint8_t updated_fw_value = 0; + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) + return; + + sap_connected_peer = + wlan_util_get_peer_count_for_mode(pdev, QDF_SAP_MODE); + go_connected_peer = + wlan_util_get_peer_count_for_mode(pdev, QDF_P2P_GO_MODE); + mlme_obj = mlme_get_psoc_obj(psoc); + + if (sap_connected_peer || go_connected_peer) { + updated_fw_value = mlme_obj->cfg.oce.feature_bitmap; + updated_fw_value &= + ~(WMI_VDEV_OCE_PROBE_REQUEST_RATE_FEATURE_BITMAP); + updated_fw_value &= + ~(WMI_VDEV_OCE_PROBE_REQUEST_DEFERRAL_FEATURE_BITMAP); + mlme_debug("Disable STA OCE probe req rate and defferal updated_fw_value :%d", + updated_fw_value); + } else { + updated_fw_value = mlme_obj->cfg.oce.feature_bitmap; + mlme_debug("Update the STA OCE flags to default INI updated_fw_value :%d", + updated_fw_value); + } + + wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP, + wlan_mlme_send_oce_flags_fw, + &updated_fw_value, 0, WLAN_MLME_NB_ID); +} + bool wlan_mlme_is_ap_prot_enabled(struct wlan_objmgr_psoc *psoc) { struct wlan_mlme_psoc_obj *mlme_obj; diff --git a/core/hdd/src/wlan_hdd_softap_tx_rx.c b/core/hdd/src/wlan_hdd_softap_tx_rx.c index 8b1339802e..a0d857db0a 100644 --- a/core/hdd/src/wlan_hdd_softap_tx_rx.c +++ b/core/hdd/src/wlan_hdd_softap_tx_rx.c @@ -996,6 +996,7 @@ QDF_STATUS hdd_softap_deregister_sta(struct hdd_adapter *adapter, } hdd_ctx->sta_to_adapter[sta_id] = NULL; + ucfg_mlme_update_oce_flags(hdd_ctx->pdev); return qdf_status; } @@ -1111,7 +1112,7 @@ QDF_STATUS hdd_softap_register_sta(struct hdd_adapter *adapter, wlan_hdd_netif_queue_control(adapter, WLAN_START_ALL_NETIF_QUEUE_N_CARRIER, WLAN_CONTROL_PATH); - + ucfg_mlme_update_oce_flags(hdd_ctx->pdev); return qdf_status; } diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 66c937d713..2f978154ad 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -16742,6 +16742,33 @@ static QDF_STATUS csr_roam_session_opened(struct mac_context *mac, return status; } +/** + * csr_store_oce_cfg_flags_in_vdev() - fill OCE flags from ini + * @mac: mac_context. + * @vdev: Pointer to pdev obj + * @vdev_id: vdev_id + * + * This API will store the oce flags in vdev mlme priv object + * + * Return: none + */ +static void csr_store_oce_cfg_flags_in_vdev(struct mac_context *mac, + struct wlan_objmgr_pdev *pdev, + uint8_t vdev_id) +{ + uint8_t *vdev_dynamic_oce; + struct wlan_objmgr_vdev *vdev = + wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id, WLAN_LEGACY_MAC_ID); + + if (!vdev) + return; + + vdev_dynamic_oce = mlme_get_dynamic_oce_flags(vdev); + + *vdev_dynamic_oce = mac->mlme_cfg->oce.feature_bitmap; + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); +} + QDF_STATUS csr_process_add_sta_session_rsp(struct mac_context *mac, uint8_t *pMsg) { struct add_sta_self_params *rsp; @@ -16775,6 +16802,12 @@ QDF_STATUS csr_process_add_sta_session_rsp(struct mac_context *mac, uint8_t *pMs csr_roam_session_opened(mac, rsp->status, rsp->session_id); + if (QDF_IS_STATUS_SUCCESS(rsp->status) && + rsp->type == WMI_VDEV_TYPE_STA) { + csr_store_oce_cfg_flags_in_vdev(mac, mac->pdev, + rsp->session_id); + wlan_mlme_update_oce_flags(mac->pdev); + } if (QDF_IS_STATUS_ERROR(rsp->status)) csr_cleanup_session(mac, rsp->session_id);