Browse Source

qcacld-3.0: Add support to get feature set info

Based on the new requirement, add support to get requested
feature set info from different feature components.

Change-Id: I1bfc097c8ae8c4ab678d4dc07b7932cf3272d851
CRs-Fixed: 3262868
Ashish Kumar Dhanotiya 2 years ago
parent
commit
2490a83a25

+ 9 - 0
components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h

@@ -4511,4 +4511,13 @@ bool policy_mgr_is_ap_ap_mcc_allow(struct wlan_objmgr_psoc *psoc,
 bool policy_mgr_any_other_vdev_on_same_mac_as_freq(
 				struct wlan_objmgr_psoc *psoc,
 				uint32_t freq, uint8_t vdev_id);
+
+/**
+ * policy_mgr_get_sbs_cfg() - Get SBS INI value
+ * @psoc: PSOC object
+ * @sbs: output sbs cfg value
+ *
+ */
+QDF_STATUS policy_mgr_get_sbs_cfg(struct wlan_objmgr_psoc *psoc, bool *sbs);
+
 #endif /* __WLAN_POLICY_MGR_API_H */

+ 14 - 0
components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c

@@ -8714,3 +8714,17 @@ bool policy_mgr_any_other_vdev_on_same_mac_as_freq(
 
 	return same_mac;
 }
+
+QDF_STATUS policy_mgr_get_sbs_cfg(struct wlan_objmgr_psoc *psoc, bool *sbs)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("pm_ctx is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	*sbs = pm_ctx->cfg.sbs_enable;
+
+	return QDF_STATUS_SUCCESS;
+}

+ 13 - 0
components/mlme/dispatcher/inc/wlan_mlme_api.h

@@ -28,6 +28,19 @@
 #include <wlan_cmn.h>
 #include "sme_api.h"
 
+#ifdef FEATURE_SET
+/**
+ * wlan_mlme_get_feature_info() - Get mlme features
+ * @psoc: psoc context
+ * @mlme_feature_set: MLME feature set info structure
+ *
+ * Return: None
+ */
+void wlan_mlme_get_feature_info(
+				struct wlan_objmgr_psoc *psoc,
+				struct wlan_mlme_features *mlme_feature_set);
+#endif
+
 /**
  * wlan_mlme_get_cfg_str() - Copy the uint8_t array for a particular CFG
  * @dst:       pointer to the destination buffer.

+ 43 - 0
components/mlme/dispatcher/inc/wlan_mlme_public_struct.h

@@ -2740,4 +2740,47 @@ struct wlan_change_bi {
 	uint8_t session_id;
 };
 
+#ifdef FEATURE_SET
+/**
+ * struct wlan_mlme_features - Mlme feature set structure
+ * @enable_wifi_optimizer: indicates wifi optimizer is enabled or disabled
+ * @roaming_high_cu_roam_trigger: Roaming high CPU trigger enabled or disabled
+ * @roaming_emergency_trigger: Roaming emergency trigger enabled or disabled
+ * @roaming_btm_trihgger: Roaming btm trigger enabled or disabled
+ * @roaming_idle_trigger: Roaming idle trigger enabled or disabled
+ * @roaming_wtc_trigger: Roaming wtc trigger enabled or disabled
+ * @roaming_btcoex_trigger: Roaming btcoex trigger enabled or disabled
+ * @roaming_btw_wpa_wpa2: Roaming btw wpa wpa2 enabled or disabled
+ * @roaming_manage_chan_list_api: Roaming manage chan list api enabled or
+ * disabled
+ * @roaming_adaptive_11r: Roaming adaptive 11r enabled or disabled
+ * @roaming_ctrl_api_get_set: Roaming ctrl api get set enabled or disabled
+ * @roaming_ctrl_api_reassoc: Roaming ctrl api reassoc enabled or disabled
+ * @roaming_ctrl_get_cu: Roaming ctrl get cu enabled or disabled
+ * @vendor_req_1_version: Vendor requirement version 1
+ * @vendor_req_2_version: Vendor requirement version 2
+ * @sta_dual_p2p_support: STA + dual p2p support enabled or not
+ * @enable2x2: Enable 2x2
+ */
+struct wlan_mlme_features {
+	bool enable_wifi_optimizer;
+	uint8_t sap_max_num_clients;
+	bool roaming_high_cu_roam_trigger;
+	bool roaming_emergency_trigger;
+	bool roaming_btm_trihgger;
+	bool roaming_idle_trigger;
+	bool roaming_wtc_trigger;
+	bool roaming_btcoex_trigger;
+	bool roaming_btw_wpa_wpa2;
+	bool roaming_manage_chan_list_api;
+	bool roaming_adaptive_11r;
+	bool roaming_ctrl_api_get_set;
+	bool roaming_ctrl_api_reassoc;
+	bool roaming_ctrl_get_cu;
+	WMI_HOST_VENDOR1_REQ1_VERSION vendor_req_1_version;
+	WMI_HOST_VENDOR1_REQ2_VERSION vendor_req_2_version;
+	bool sta_dual_p2p_support;
+	bool enable2x2;
+};
+#endif
 #endif

+ 16 - 0
components/mlme/dispatcher/inc/wlan_mlme_twt_public_struct.h

@@ -52,5 +52,21 @@ struct twt_context {
 	uint8_t num_twt_sessions;
 	struct twt_session_info session_info[WLAN_MAX_TWT_SESSIONS_PER_PEER];
 };
+
+#ifdef FEATURE_SET
+/**
+ * struct wlan_twt_features  - TWT features info
+ * @enable_twt: Enable TWT
+ * enable_twt_requester Enable TWT requester
+ * @enable_twt_broadcast: Enable TWT broadcast
+ * @enable_twt_flexible: Enable flexible TWT
+ */
+struct wlan_twt_features {
+	bool enable_twt;
+	bool enable_twt_requester;
+	bool enable_twt_broadcast;
+	bool enable_twt_flexible;
+};
+#endif /* FEATURE_SET */
 #endif /* WLAN_SUPPORT_TWT */
 #endif /* _WLAN_MLME_TWT_PUBLIC_STRUCT_H_ */

+ 114 - 0
components/mlme/dispatcher/src/wlan_mlme_api.c

@@ -6030,3 +6030,117 @@ wlan_mlme_get_peer_ch_width(struct wlan_objmgr_psoc *psoc, uint8_t *mac)
 
 	return wlan_mlme_get_ch_width_from_phymode(phy_mode);
 }
+
+#ifdef FEATURE_SET
+
+/**
+ * wlan_mlme_get_latency_enable() - get wlm latency cfg value
+ * @psoc: psoc context
+ * @value: Pointer in which wlam latency cfg value needs to be filled
+ *
+ * Return: QDF_STATUS_SUCCESS on success or QDF_STATUS_E_INVAL on failure
+ */
+static QDF_STATUS
+wlan_mlme_get_latency_enable(struct wlan_objmgr_psoc *psoc, bool *value)
+{
+	struct wlan_mlme_psoc_ext_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_ext_obj(psoc);
+	if (!mlme_obj) {
+		mlme_legacy_err("mlme obj null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	*value = mlme_obj->cfg.wlm_config.latency_enable;
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef WLAN_ADAPTIVE_11R
+/**
+ * wlan_mlme_get_adaptive11r_enabled() - get adaptive 11r cfg value
+ * @psoc: psoc context
+ * @val: Pointer in which adaptive 11r cfg value needs to be filled
+ *
+ * Return: QDF_STATUS_SUCCESS on success or QDF_STATUS_E_INVAL on failure
+ */
+static QDF_STATUS
+wlan_mlme_get_adaptive11r_enabled(struct wlan_objmgr_psoc *psoc, bool *val)
+{
+	struct wlan_mlme_psoc_ext_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_ext_obj(psoc);
+	if (!mlme_obj) {
+		*val = cfg_default(CFG_ADAPTIVE_11R);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	*val = mlme_obj->cfg.lfr.enable_adaptive_11r;
+
+	return QDF_STATUS_SUCCESS;
+}
+#else
+static inline QDF_STATUS
+wlan_mlme_get_adaptive11r_enabled(struct wlan_objmgr_psoc *psoc, bool *val)
+{
+	*val = false;
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+#ifdef WLAN_FEATURE_P2P_P2P_STA
+static bool
+wlan_mlme_get_p2p_p2p_host_conc_support(void)
+{
+	return true;
+}
+#else
+static bool
+wlan_mlme_get_p2p_p2p_host_conc_support(void)
+{
+	return false;
+}
+#endif
+
+void wlan_mlme_get_feature_info(struct wlan_objmgr_psoc *psoc,
+				struct wlan_mlme_features *mlme_feature_set)
+{
+	uint32_t roam_triggers;
+	int sap_max_num_clients;
+
+	wlan_mlme_get_latency_enable(psoc,
+				     &mlme_feature_set->enable_wifi_optimizer);
+	wlan_mlme_get_sap_max_peers(psoc, &sap_max_num_clients);
+	mlme_feature_set->sap_max_num_clients = sap_max_num_clients;
+	mlme_feature_set->vendor_req_1_version =
+					WMI_HOST_VENDOR1_REQ1_VERSION_3_20;
+	roam_triggers = wlan_mlme_get_roaming_triggers(psoc);
+
+	mlme_feature_set->roaming_high_cu_roam_trigger =
+			roam_triggers & BIT(ROAM_TRIGGER_REASON_BSS_LOAD);
+	mlme_feature_set->roaming_emergency_trigger =
+			roam_triggers & BIT(ROAM_TRIGGER_REASON_FORCED);
+	mlme_feature_set->roaming_btm_trihgger =
+			roam_triggers & BIT(ROAM_TRIGGER_REASON_BTM);
+	mlme_feature_set->roaming_idle_trigger =
+			roam_triggers & BIT(ROAM_TRIGGER_REASON_IDLE);
+	mlme_feature_set->roaming_wtc_trigger =
+			roam_triggers & BIT(ROAM_TRIGGER_REASON_WTC_BTM);
+	mlme_feature_set->roaming_btcoex_trigger =
+			roam_triggers & BIT(ROAM_TRIGGER_REASON_BTC);
+	mlme_feature_set->roaming_btw_wpa_wpa2 = true;
+	mlme_feature_set->roaming_manage_chan_list_api = true;
+
+	wlan_mlme_get_adaptive11r_enabled(
+				psoc,
+				&mlme_feature_set->roaming_adaptive_11r);
+	mlme_feature_set->roaming_ctrl_api_get_set = true;
+	mlme_feature_set->roaming_ctrl_api_reassoc = true;
+	mlme_feature_set->roaming_ctrl_get_cu = true;
+
+	mlme_feature_set->vendor_req_2_version =
+					WMI_HOST_VENDOR1_REQ2_VERSION_3_20;
+	mlme_feature_set->sta_dual_p2p_support =
+				wlan_mlme_get_p2p_p2p_host_conc_support();
+	wlan_mlme_get_vht_enable2x2(psoc, &mlme_feature_set->enable2x2);
+}
+#endif

+ 15 - 0
components/tdls/dispatcher/inc/wlan_tdls_api.h

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 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 above
@@ -25,6 +26,20 @@
 #include "wlan_objmgr_vdev_obj.h"
 
 #ifdef FEATURE_WLAN_TDLS
+
+#ifdef FEATURE_SET
+/**
+ * wlan_tdls_get_features_info() - Get tdls features info
+ * @psoc: psoc context
+ * @tdls_feature_set: TDLS feature set info structure
+ *
+ * Return: None
+ */
+
+void wlan_tdls_get_features_info(struct wlan_objmgr_psoc *psoc,
+				 struct wlan_tdls_features *tdls_feature_set);
+#endif
+
 /**
  * wlan_tdls_teardown_links() - notify TDLS module to teardown all TDLS links
  * @psoc: psoc object

+ 15 - 0
components/tdls/dispatcher/inc/wlan_tdls_public_structs.h

@@ -1400,4 +1400,19 @@ struct tdls_link_teardown {
 	struct wlan_objmgr_psoc *psoc;
 };
 
+#ifdef FEATURE_SET
+/**
+ * struct wlan_tdls_features - TDLS feature set struct
+ * @enable_tdls: enable/disable tdls
+ * @enable_tdls_offchannel: enable/disable tdls offchannel
+ * @max_tdls_peers: Max tdls Peers
+ * @enable_tdls_capability_enhance: enable tdls capability enhance
+ */
+struct wlan_tdls_features {
+	bool enable_tdls;
+	bool enable_tdls_offchannel;
+	bool max_tdls_peers;
+	bool enable_tdls_capability_enhance;
+};
+#endif
 #endif

+ 17 - 0
components/tdls/dispatcher/src/wlan_tdls_api.c

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 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 above
@@ -27,6 +28,7 @@
 #include "../../core/src/wlan_tdls_mgmt.h"
 #include <wlan_objmgr_global_obj.h>
 #include <wlan_objmgr_cmn.h>
+#include "wlan_tdls_cfg_api.h"
 
 static QDF_STATUS tdls_teardown_flush_cb(struct scheduler_msg *msg)
 {
@@ -251,3 +253,18 @@ wlan_tdls_notify_sta_connect(uint8_t session_id,
 	tdls_notify_connect(&notify_info);
 }
 
+#ifdef FEATURE_SET
+void wlan_tdls_get_features_info(struct wlan_objmgr_psoc *psoc,
+				 struct wlan_tdls_features *tdls_feature_set)
+{
+	cfg_tdls_get_support_enable(psoc, &tdls_feature_set->enable_tdls);
+	if (tdls_feature_set->enable_tdls) {
+		cfg_tdls_get_off_channel_enable(
+				psoc,
+				&tdls_feature_set->enable_tdls_offchannel);
+		tdls_feature_set->max_tdls_peers =
+					cfg_tdls_get_max_peer_count(psoc);
+		tdls_feature_set->enable_tdls_capability_enhance = true;
+	}
+}
+#endif

+ 15 - 0
components/umac/twt/dispatcher/inc/wlan_twt_cfg_ext_api.h

@@ -22,6 +22,8 @@
 #if defined(WLAN_SUPPORT_TWT) && defined(WLAN_TWT_CONV_SUPPORTED)
 #include <wlan_objmgr_psoc_obj.h>
 #include <wlan_twt_public_structs.h>
+#include <wlan_mlme_twt_public_struct.h>
+
 /**
  * wlan_twt_cfg_get_req_flag() - Get TWT requestor flag
  * @psoc: Pointer to global psoc object
@@ -63,6 +65,19 @@ wlan_twt_cfg_get_support_in_11n(struct wlan_objmgr_psoc *psoc,
 QDF_STATUS
 wlan_twt_cfg_get_support_requestor(struct wlan_objmgr_psoc *psoc,
 				   bool *val);
+
+#ifdef FEATURE_SET
+/**
+ * wlan_twt_get_feature_info() - Get TWT feature set information
+ * @psoc: Pointer to global psoc object
+ * @twt_feature_set: pointer to output twt feature set structure
+ *
+ * Return: None
+ */
+void wlan_twt_get_feature_info(struct wlan_objmgr_psoc *psoc,
+			       struct wlan_twt_features *twt_feature_set);
+#endif
+
 #else
 static inline QDF_STATUS
 wlan_twt_cfg_get_res_flag(struct wlan_objmgr_psoc *psoc, bool *val)

+ 20 - 0
components/umac/twt/dispatcher/src/wlan_twt_cfg_ext_api.c

@@ -17,6 +17,8 @@
  */
 #include <wlan_twt_cfg_ext_api.h>
 #include "twt/core/src/wlan_twt_cfg.h"
+#include "wlan_mlme_api.h"
+#include "wlan_mlme_twt_api.h"
 
 QDF_STATUS
 wlan_twt_cfg_get_req_flag(struct wlan_objmgr_psoc *psoc, bool *val)
@@ -41,3 +43,21 @@ wlan_twt_cfg_get_support_requestor(struct wlan_objmgr_psoc *psoc, bool *val)
 {
 	return wlan_twt_cfg_get_requestor(psoc, val);
 }
+
+#ifdef FEATURE_SET
+void wlan_twt_get_feature_info(struct wlan_objmgr_psoc *psoc,
+			       struct wlan_twt_features *twt_feature_set)
+{
+	twt_feature_set->enable_twt = mlme_is_twt_enabled(psoc);
+	if (twt_feature_set->enable_twt) {
+		wlan_twt_cfg_get_bcast_requestor(
+					psoc,
+					&twt_feature_set->enable_twt_broadcast);
+		wlan_twt_cfg_get_requestor(
+					psoc,
+					&twt_feature_set->enable_twt_requester);
+		twt_feature_set->enable_twt_flexible =
+					mlme_is_flexible_twt_enabled(psoc);
+	}
+}
+#endif

+ 19 - 0
core/cds/inc/cds_config.h

@@ -34,6 +34,7 @@
 #include "wlan_cmn_ieee80211.h"
 #include "wlan_pmo_common_public_struct.h"
 #include "qca_vendor.h"
+#include "wmi_unified_param.h"
 
 /**
  * enum cfg_sub_20_channel_width: ini values for su 20 mhz channel width
@@ -46,6 +47,20 @@ enum cfg_sub_20_channel_width {
 	WLAN_SUB_20_CH_WIDTH_10 = 2,
 };
 
+#ifdef FEATURE_SET
+/**
+ * struct wlan_cds_feature_set - CDS feature set struct
+ * @wifi_standard: Supported wifi standard
+ * @sap_5g_supported: 5GHz SAP supported or not
+ * @sap_6g_supported: 6GHz SAP supported or no
+ */
+struct wlan_cds_feature_set {
+	WMI_HOST_WIFI_STANDARD wifi_standard;
+	bool sap_5g_supported;
+	bool sap_6g_supported;
+};
+#endif
+
 /**
  * struct cds_config_info - Place Holder for cds configuration
  * @max_station: Max station supported
@@ -76,6 +91,7 @@ enum cfg_sub_20_channel_width {
  * @rps_enabled: RPS enabled in SAP mode
  * Structure for holding cds ini parameters.
  * @num_vdevs: Configured max number of VDEVs can be supported in the stack.
+ * @cds_feature_set: CDS feature set structure.
  */
 
 struct cds_config_info {
@@ -108,5 +124,8 @@ struct cds_config_info {
 	bool rps_enabled;
 	uint32_t num_vdevs;
 	bool enable_tx_compl_tsf64;
+#ifdef FEATURE_SET
+	struct wlan_cds_feature_set cds_feature_set;
+#endif
 };
 #endif /* !defined( __CDS_CONFIG_H ) */

+ 92 - 0
core/hdd/src/wlan_hdd_main.c

@@ -12955,6 +12955,97 @@ static inline void hdd_txrx_populate_cds_config(struct cds_config_info
 }
 #endif
 
+#ifdef FEATURE_SET
+#ifdef WLAN_FEATURE_11BE
+/**
+ * hdd_is_cfg_dot11_mode_11be() - Check if dot11 mode is 11 be
+ * @dot11_mode: Input dot11_mode which needs to be checked
+ *
+ * Return: True, ifinput dot11_mode is 11be dot11 mode else return false
+ */
+static bool hdd_is_cfg_dot11_mode_11be(enum hdd_dot11_mode dot11_mode)
+{
+	return (dot11_mode == eHDD_DOT11_MODE_11be ||
+		dot11_mode == eHDD_DOT11_MODE_11be_ONLY);
+}
+#else
+static bool hdd_is_cfg_dot11_mode_11be(enum hdd_dot11_mode dot11_mode)
+{
+	return false;
+}
+#endif
+
+/**
+ * hdd_get_wifi_standard() - Get wifi standard
+ * @hdd_ctx: hdd context pointer
+ *
+ * Return: WMI_HOST_WIFI_STANDARD
+ */
+static WMI_HOST_WIFI_STANDARD hdd_get_wifi_standard(struct hdd_context *hdd_ctx)
+{
+	WMI_HOST_WIFI_STANDARD wifi_standard = WMI_HOST_WIFI_STANDARD_4;
+
+	if (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_AUTO ||
+	    hdd_is_cfg_dot11_mode_11be(hdd_ctx->config->dot11Mode))
+		wifi_standard = WMI_HOST_WIFI_STANDARD_7;
+
+	if (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11ax ||
+	    (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY)) {
+		if (wlan_reg_is_6ghz_supported(hdd_ctx->psoc))
+			wifi_standard =  WMI_HOST_WIFI_STANDARD_6E;
+		else
+			wifi_standard = WMI_HOST_WIFI_STANDARD_6;
+	}
+
+	if ((hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11ac) ||
+	    (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY))
+		wifi_standard = WMI_HOST_WIFI_STANDARD_5;
+
+	return wifi_standard;
+}
+
+/**
+ * hdd_populate_feature_set_cds_config() - Populate cds feature set config
+ * @cds_cfg: cds config where feature set info needs to be updated
+ * @hdd_ctx: hdd context pointer
+ *
+ * Return: None
+ */
+static void hdd_populate_feature_set_cds_config(struct cds_config_info *cds_cfg,
+						struct hdd_context *hdd_ctx)
+{
+	struct wlan_objmgr_psoc *psoc;
+	uint32_t band_capability;
+	QDF_STATUS status;
+
+	if (!hdd_ctx)
+		return;
+
+	psoc = hdd_ctx->psoc;
+
+	cds_cfg->cds_feature_set.wifi_standard = hdd_get_wifi_standard(hdd_ctx);
+
+	status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("Failed to get MLME band capability");
+
+	band_capability =
+		hdd_update_band_cap_from_dot11mode(hdd_ctx, band_capability);
+
+	cds_cfg->cds_feature_set.sap_5g_supported =
+					band_capability & BIT(REG_BAND_5G);
+
+	cds_cfg->cds_feature_set.sap_6g_supported =
+					band_capability & BIT(REG_BAND_6G);
+}
+#else
+static inline void
+hdd_populate_feature_set_cds_config(struct cds_config_info *cds_cfg,
+				    struct hdd_context *hdd_ctx)
+{
+}
+#endif
+
 /**
  * hdd_update_cds_config() - API to update cds configuration parameters
  * @hdd_ctx: HDD Context
@@ -13046,6 +13137,7 @@ static int hdd_update_cds_config(struct hdd_context *hdd_ctx)
 		hdd_tsf_is_tsf64_tx_set(hdd_ctx);
 	hdd_txrx_populate_cds_config(cds_cfg, hdd_ctx);
 	hdd_lpass_populate_cds_config(cds_cfg, hdd_ctx);
+	hdd_populate_feature_set_cds_config(cds_cfg, hdd_ctx);
 	cds_init_ini_config(cds_cfg);
 	return 0;
 

+ 226 - 0
core/wma/src/wma_main.c

@@ -118,6 +118,8 @@
 #include "wlan_pkt_capture_ucfg_api.h"
 #include "target_if_cm_roam_event.h"
 #include "wlan_fwol_ucfg_api.h"
+#include "wlan_tdls_api.h"
+#include "wlan_twt_cfg_ext_api.h"
 
 #define WMA_LOG_COMPLETION_TIMER 500 /* 500 msecs */
 #define WMI_TLV_HEADROOM 128
@@ -299,6 +301,227 @@ static void wma_set_peer_map_unmap_v2_config(struct wlan_objmgr_psoc *psoc,
 }
 #endif
 
+#ifdef FEATURE_SET
+/**
+ * wma_get_concurrency_support() - Get concurrency support
+ * @psoc: Object manager psoc
+ *
+ * Return: WMI_HOST_BAND_CONCURRENCY
+ */
+static WMI_HOST_BAND_CONCURRENCY
+wma_get_concurrency_support(struct wlan_objmgr_psoc *psoc)
+{
+	bool is_sbs_enabled = false;
+
+	if (policy_mgr_is_dual_mac_disabled_in_ini(psoc))
+		return WMI_HOST_BAND_CONCURRENCY_NONE;
+
+	policy_mgr_get_sbs_cfg(psoc, &is_sbs_enabled);
+
+	if (is_sbs_enabled)
+		return WMI_HOST_BAND_CONCURRENCY_DBS_SBS;
+	else
+		return WMI_HOST_BAND_CONCURRENCY_DBS;
+}
+
+/**
+ * wma_set_feature_set_info() - Set feature set info
+ * @wma_handle: WMA handle
+ * @feature_set: Feature set structure which needs to be filled
+ *
+ * Return: WMI_HOST_BAND_CONCURRENCY
+ */
+static void wma_set_feature_set_info(tp_wma_handle wma_handle,
+				     struct target_feature_set *feature_set)
+{
+	struct cds_context *cds_ctx =
+		(struct cds_context *)(wma_handle->cds_context);
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_scan_features scan_feature_set;
+	struct wlan_twt_features twt_feature_set;
+	struct wlan_mlme_features mlme_feature_set;
+	struct wlan_tdls_features tdls_feature_set;
+
+	psoc = wma_handle->psoc;
+	if (!psoc) {
+		wma_err("Invalid psoc");
+		return;
+	}
+
+	if (!cds_ctx) {
+		wma_err("Invalid cds context");
+		return;
+	}
+
+	if (!cds_ctx->cds_cfg) {
+		wma_err("Invalid cds config");
+		return;
+	}
+
+	feature_set->wifi_standard =
+			cds_ctx->cds_cfg->cds_feature_set.wifi_standard;
+	feature_set->sap_5g_supported =
+			cds_ctx->cds_cfg->cds_feature_set.sap_5g_supported;
+	feature_set->sap_6g_supported =
+			cds_ctx->cds_cfg->cds_feature_set.sap_6g_supported;
+
+	feature_set->concurrency_support = wma_get_concurrency_support(psoc);
+
+	wlan_scan_get_feature_info(psoc, &scan_feature_set);
+	feature_set->pno_in_unassoc_state =
+					scan_feature_set.pno_in_unassoc_state;
+	if (feature_set->pno_in_unassoc_state)
+		feature_set->pno_in_assoc_state =
+					scan_feature_set.pno_in_assoc_state;
+
+	wlan_twt_get_feature_info(psoc, &twt_feature_set);
+	feature_set->enable_twt = twt_feature_set.enable_twt;
+	if (feature_set->enable_twt) {
+		feature_set->enable_twt_requester =
+					twt_feature_set.enable_twt_requester;
+		feature_set->enable_twt_broadcast =
+					twt_feature_set.enable_twt_broadcast;
+		feature_set->enable_twt_flexible =
+					twt_feature_set.enable_twt_flexible;
+	}
+
+	feature_set->enable_rfc835 = true;
+
+	wlan_mlme_get_feature_info(psoc, &mlme_feature_set);
+
+	feature_set->enable_wifi_optimizer =
+				mlme_feature_set.enable_wifi_optimizer;
+	feature_set->sap_max_num_clients =
+				mlme_feature_set.sap_max_num_clients;
+
+	feature_set->vendor_req_1_version =
+				mlme_feature_set.vendor_req_1_version;
+	feature_set->roaming_high_cu_roam_trigger =
+				mlme_feature_set.roaming_high_cu_roam_trigger;
+	feature_set->roaming_emergency_trigger =
+				mlme_feature_set.roaming_emergency_trigger;
+	feature_set->roaming_btm_trihgger =
+					mlme_feature_set.roaming_btm_trihgger;
+	feature_set->roaming_idle_trigger =
+					mlme_feature_set.roaming_idle_trigger;
+	feature_set->roaming_wtc_trigger =
+				mlme_feature_set.roaming_wtc_trigger;
+	feature_set->roaming_btcoex_trigger =
+				mlme_feature_set.roaming_btcoex_trigger;
+	feature_set->roaming_btw_wpa_wpa2 =
+					mlme_feature_set.roaming_btw_wpa_wpa2;
+	feature_set->roaming_manage_chan_list_api =
+				mlme_feature_set.roaming_manage_chan_list_api;
+
+	feature_set->roaming_adaptive_11r =
+					mlme_feature_set.roaming_adaptive_11r;
+	feature_set->roaming_ctrl_api_get_set =
+				mlme_feature_set.roaming_ctrl_api_get_set;
+	feature_set->roaming_ctrl_api_reassoc =
+				mlme_feature_set.roaming_ctrl_api_reassoc;
+	feature_set->roaming_ctrl_get_cu =
+					mlme_feature_set.roaming_ctrl_get_cu;
+	feature_set->vendor_req_2_version =
+			mlme_feature_set.vendor_req_2_version;
+	feature_set->sta_dual_p2p_support =
+					mlme_feature_set.sta_dual_p2p_support;
+	if (mlme_feature_set.enable2x2)
+		feature_set->num_antennas = WMI_HOST_MIMO_2X2;
+	else
+		feature_set->num_antennas = WMI_HOST_SISO;
+
+	feature_set->set_country_code_hal_supported = true;
+	feature_set->get_valid_channel_supported = true;
+	feature_set->supported_dot11mode = feature_set->wifi_standard;
+	feature_set->sap_wpa3_support = true;
+	feature_set->assurance_disconnect_reason_api = true;
+	feature_set->frame_pcap_log_mgmt = true;
+	feature_set->frame_pcap_log_ctrl = true;
+	feature_set->frame_pcap_log_data = true;
+
+	/*
+	 * This information is hardcoded based on hdd_sta_akm_suites,
+	 *wlan_crypto_key_mgmt and wlan_crypto_rsnx_cap
+	 */
+
+	/* WLAN_CRYPTO_RSNX_CAP_SAE_H2E support*/
+	feature_set->security_wpa3_sae_h2e = true;
+	feature_set->security_wpa3_sae_ft = true;
+	feature_set->security_wpa3_enterp_suitb = true;
+	feature_set->security_wpa3_enterp_suitb_192bit = true;
+	feature_set->security_fills_sha_256 = true;
+	feature_set->security_fills_sha_384 = true;
+	feature_set->security_fills_sha_256_FT = true;
+	feature_set->security_fills_sha_384_FT = true;
+	/* This is OWE security support */
+	feature_set->security_enhanced_open = true;
+
+	feature_set->enable_nan = cfg_nan_get_enable(psoc);
+
+	wlan_tdls_get_features_info(psoc, &tdls_feature_set);
+	feature_set->enable_tdls = tdls_feature_set.enable_tdls;
+	if (feature_set->enable_tdls) {
+		feature_set->enable_tdls_offchannel =
+				tdls_feature_set.enable_tdls_offchannel;
+		feature_set->max_tdls_peers = tdls_feature_set.max_tdls_peers;
+		feature_set->enable_tdls_capability_enhance =
+			tdls_feature_set.enable_tdls_capability_enhance;
+	}
+
+	feature_set->enable_p2p_6e = policy_mgr_is_6ghz_conc_mode_supported(
+							psoc,
+							PM_P2P_CLIENT_MODE);
+
+	feature_set->peer_bigdata_getbssinfo_support = true;
+	feature_set->peer_bigdata_assocreject_info_support = true;
+	feature_set->peer_getstainfo_support = true;
+	feature_set->feature_set_version = 1;
+}
+
+/**
+ * wma_send_feature_set_cmd() - Send feature set command to FW
+ * @wma_handle: WMA handle
+ *
+ * Return: None
+ */
+static void wma_send_feature_set_cmd(tp_wma_handle wma_handle)
+{
+	struct target_feature_set feature_set;
+
+	if (!wma_handle) {
+		wma_err("Invalid wma_handle");
+		return;
+	}
+
+	wma_set_feature_set_info(wma_handle, &feature_set);
+
+	wmi_feature_set_cmd_send(wma_handle->wmi_handle,
+				 &feature_set);
+}
+
+/**
+ * wma_is_feature_set_supported() - Check if feaure set is supported or not
+ * @wma_handle: WMA handle
+ *
+ * Return: True, if feature set is supporte lese return false
+ */
+static bool wma_is_feature_set_supported(tp_wma_handle wma_handle)
+{
+	return wmi_service_enabled(wma_handle->wmi_handle,
+				   wmi_service_feature_set_event_support);
+}
+#else
+static inline void wma_send_feature_set_cmd(tp_wma_handle wma_handle)
+{
+}
+
+static bool wma_is_feature_set_supported(tp_wma_handle wma_handle)
+{
+	return false;
+}
+
+#endif
+
 /**
  * wma_set_default_tgt_config() - set default tgt config
  * @wma_handle: wma handle
@@ -7037,6 +7260,9 @@ int wma_rx_ready_event(void *handle, uint8_t *cmd_param_info,
 
 	wma_debug("WMA <-- WMI_READY_EVENTID");
 
+	if (wma_is_feature_set_supported(wma_handle))
+		wma_send_feature_set_cmd(wma_handle);
+
 	ev = param_buf->fixed_param;
 	/* Indicate to the waiting thread that the ready
 	 * event was received