Эх сурвалжийг харах

qcacld-3.0: Add support for MESH_BSTEERING_GET_DATARATE_INFO

Add support for MESH_BSTEERING_GET_DATARATE_INFO
and PDEV_GET_CAPABILITY

Change-Id: I8857c795adc71f6b28343501fe389717b5cbd4a0
CRs-Fixed: 3086477
anikkuma 3 жил өмнө
parent
commit
da23350e06

+ 52 - 0
components/son/dispatcher/inc/son_api.h

@@ -397,6 +397,38 @@ int wlan_son_anqp_frame(struct wlan_objmgr_vdev *vdev, int subtype,
 			uint8_t *frame, uint16_t frame_len, void *action_hdr,
 			uint8_t *macaddr);
 
+/**
+ * wlan_son_get_node_tx_power() - Gets the max transmit power for peer
+ * @assoc_req_ies: assoc req ies
+ *
+ * Return: Returns the max tx power
+ */
+uint8_t wlan_son_get_node_tx_power(struct element_info assoc_req_ies);
+
+/**
+ * wlan_son_get_max_mcs() - calculate the max mcs supported by the node
+ * @mode: current phymode
+ * @supp_idx: max supported idx
+ * @ext_idx: max extended idx
+ * @ht_mcs_idx: max mcs index for HT
+ * @vht_mcs_map: mcs map for VHT
+ *
+ * return: max_mcs for the node
+ */
+uint8_t wlan_son_get_max_mcs(uint8_t mode, uint8_t supp_idx, uint8_t ext_idx,
+			     uint8_t ht_mcs_idx, uint8_t vht_mcs_map);
+
+/**
+ * wlan_son_get_peer_rrm_info() - Get RRM info for peer
+ * @assoc_req_ies: assoc req ies
+ * @rrmcaps: rrm capabilities
+ * @is_beacon_meas_supported: if beacon meas is supported
+ *
+ * Return: Returns QDF_STATUS_SUCCESS if succeed
+ */
+QDF_STATUS wlan_son_get_peer_rrm_info(struct element_info assoc_req_ies,
+				      uint8_t *rrmcaps,
+				      bool *is_beacon_meas_supported);
 #else
 
 static inline bool wlan_son_peer_is_kickout_allow(struct wlan_objmgr_vdev *vdev,
@@ -468,5 +500,25 @@ int wlan_son_anqp_frame(struct wlan_objmgr_vdev *vdev, int subtype,
 	return -EINVAL;
 }
 
+static inline
+uint8_t wlan_son_get_node_tx_power(struct element_info assoc_req_ies)
+{
+	return 0;
+}
+
+static inline
+uint8_t wlan_son_get_max_mcs(uint8_t mode, uint8_t supp_idx, uint8_t ext_idx,
+			     uint8_t ht_mcs_idx, uint8_t vht_mcs_map)
+{
+	return 0;
+}
+
+static inline
+QDF_STATUS wlan_son_get_peer_rrm_info(struct element_info assoc_req_ies,
+				      uint8_t *rrmcaps,
+				      bool *is_beacon_meas_supported)
+{
+	return QDF_STATUS_E_INVAL;
+}
 #endif /*WLAN_FEATURE_SON*/
 #endif

+ 33 - 0
components/son/dispatcher/inc/son_ucfg_api.h

@@ -170,6 +170,39 @@ int ucfg_son_set_cbs_wait_time(struct wlan_objmgr_vdev *vdev,
 int ucfg_son_set_cbs_dwell_split_time(struct wlan_objmgr_vdev *vdev,
 				      uint32_t val);
 
+/**
+ * ucfg_son_get_max_tx_power() - Gets the max transmit power for peer
+ * @assoc_req_ies: assoc req ies
+ *
+ * Return: Returns the max tx power
+ */
+uint8_t ucfg_son_get_tx_power(struct element_info assoc_req_ies);
+
+/**
+ * ucfg_get_max_mcs() - calculate the max mcs supported by the node
+ * @mode: current phy mode
+ * @supp_idx: max supported idx
+ * @ext_idx: max extended idx
+ * @ht_mcs_idx: max mcs index for HT
+ * @vht_mcs_map: mcs map for VHT
+ *
+ * Return: max_mcs for the node
+ */
+uint8_t ucfg_son_get_max_mcs(uint8_t mode, uint8_t supp_idx, uint8_t ext_idx,
+			     uint8_t ht_mcs_idx, uint8_t vht_mcs_map);
+
+/**
+ * ucfg_son_get_peer_rrm_info() - Get RRM info for peer
+ * @assoc_req_ies: assoc req ies
+ * @rrmcaps: rrm capabiities
+ * @is_beacon_meas_supported: if beacon meas is supported
+ *
+ * Return: Returns QDF_STATUS_SUCCESS if succeed
+ */
+QDF_STATUS ucfg_son_get_peer_rrm_info(struct element_info assoc_req_ies,
+				      uint8_t *rrmcaps,
+				      bool *is_beacon_meas_supported);
+
 #ifdef WLAN_FEATURE_SON
 /* ucfg_son_disable_cbs() - son cbs disable
  * @vdev: vdev pointer

+ 57 - 0
components/son/dispatcher/src/son_api.c

@@ -1263,3 +1263,60 @@ int wlan_son_set_cbs_dwell_split_time(struct wlan_objmgr_vdev *vdev,
 
 	return 0;
 }
+
+uint8_t wlan_son_get_node_tx_power(struct element_info assoc_req_ies)
+{
+	const uint8_t *power_cap_ie_data;
+
+	power_cap_ie_data = wlan_get_ie_ptr_from_eid(WLAN_ELEMID_PWRCAP,
+						     assoc_req_ies.ptr,
+						     assoc_req_ies.len);
+	if (power_cap_ie_data)
+		return *(power_cap_ie_data + 3);
+	else
+		return 0;
+}
+
+uint8_t wlan_son_get_max_mcs(uint8_t mode, uint8_t supp_idx, uint8_t ext_idx,
+			     uint8_t ht_mcs_idx, uint8_t vht_mcs_map)
+{
+	uint8_t maxidx = MAX_HE_MCS_IDX;
+
+	/* check supported rates */
+	if (supp_idx != 0xff && maxidx < supp_idx)
+		maxidx = supp_idx;
+
+	/* check extended rates */
+	if (ext_idx != 0xff && maxidx < ext_idx)
+		maxidx = ext_idx;
+
+	/* check for HT Mode */
+	if (mode == SIR_SME_PHY_MODE_HT)
+		maxidx = ht_mcs_idx;
+
+	if (mode == SIR_SME_PHY_MODE_VHT)
+		maxidx = (vht_mcs_map & DATA_RATE_11AC_MCS_MASK);
+
+	return maxidx;
+}
+
+QDF_STATUS wlan_son_get_peer_rrm_info(struct element_info assoc_req_ies,
+				      uint8_t *rrmcaps,
+				      bool *is_beacon_meas_supported)
+{
+	const uint8_t *eid;
+
+	eid = wlan_get_ie_ptr_from_eid(WLAN_ELEMID_RRM,
+				       assoc_req_ies.ptr,
+				       assoc_req_ies.len);
+	if (eid) {
+		qdf_mem_copy(rrmcaps, &eid[2], eid[1]);
+		if ((rrmcaps[0] &
+		    IEEE80211_RRM_CAPS_BEACON_REPORT_PASSIVE) ||
+		    (rrmcaps[0] &
+		    IEEE80211_RRM_CAPS_BEACON_REPORT_ACTIVE))
+			*is_beacon_meas_supported = true;
+		return QDF_STATUS_SUCCESS;
+	}
+	return QDF_STATUS_E_RESOURCES;
+}

+ 20 - 0
components/son/dispatcher/src/son_ucfg_api.c

@@ -124,3 +124,23 @@ int ucfg_son_disable_cbs(struct wlan_objmgr_vdev *vdev)
 {
 	return wlan_son_cbs_disable(vdev);
 }
+
+uint8_t ucfg_son_get_tx_power(struct element_info assoc_req_ies)
+{
+	return wlan_son_get_node_tx_power(assoc_req_ies);
+}
+
+uint8_t ucfg_son_get_max_mcs(uint8_t mode, uint8_t supp_idx, uint8_t ext_idx,
+			     uint8_t ht_mcs_idx, uint8_t vht_mcs_map)
+{
+	return wlan_son_get_max_mcs(mode, supp_idx, ext_idx, ht_mcs_idx,
+				    vht_mcs_map);
+}
+
+QDF_STATUS ucfg_son_get_peer_rrm_info(struct element_info assoc_req_ies,
+				      uint8_t *rrmcaps,
+				      bool *is_beacon_meas_supported)
+{
+	return wlan_son_get_peer_rrm_info(assoc_req_ies, rrmcaps,
+					  is_beacon_meas_supported);
+}

+ 159 - 0
core/hdd/src/wlan_hdd_son.c

@@ -31,6 +31,8 @@
 #include <son_ucfg_api.h>
 #include <wlan_hdd_son.h>
 #include <wlan_hdd_object_manager.h>
+#include <wlan_hdd_stats.h>
+
 
 /**
  * hdd_son_is_acs_in_progress() - whether acs is in progress or not
@@ -2215,6 +2217,161 @@ end:
 	return ret;
 }
 
+static const uint8_t wlanphymode2ieeephymode[WLAN_PHYMODE_MAX] = {
+	[WLAN_PHYMODE_AUTO] = IEEE80211_MODE_AUTO,
+	[WLAN_PHYMODE_11A] = IEEE80211_MODE_11A,
+	[WLAN_PHYMODE_11B] = IEEE80211_MODE_11B,
+	[WLAN_PHYMODE_11G] = IEEE80211_MODE_11G,
+	[WLAN_PHYMODE_11G_ONLY] = 0,
+	[WLAN_PHYMODE_11NA_HT20] = IEEE80211_MODE_11NA_HT20,
+	[WLAN_PHYMODE_11NG_HT20] = IEEE80211_MODE_11NG_HT20,
+	[WLAN_PHYMODE_11NA_HT40] = IEEE80211_MODE_11NA_HT40,
+	[WLAN_PHYMODE_11NG_HT40PLUS] = IEEE80211_MODE_11NG_HT40PLUS,
+	[WLAN_PHYMODE_11NG_HT40MINUS] = IEEE80211_MODE_11NG_HT40MINUS,
+	[WLAN_PHYMODE_11NG_HT40] = IEEE80211_MODE_11NG_HT40,
+	[WLAN_PHYMODE_11AC_VHT20] = IEEE80211_MODE_11AC_VHT20,
+	[WLAN_PHYMODE_11AC_VHT20_2G] = 0,
+	[WLAN_PHYMODE_11AC_VHT40] = IEEE80211_MODE_11AC_VHT40,
+	[WLAN_PHYMODE_11AC_VHT40PLUS_2G] = IEEE80211_MODE_11AC_VHT40PLUS,
+	[WLAN_PHYMODE_11AC_VHT40MINUS_2G] = IEEE80211_MODE_11AC_VHT40MINUS,
+	[WLAN_PHYMODE_11AC_VHT40_2G] = 0,
+	[WLAN_PHYMODE_11AC_VHT80] = IEEE80211_MODE_11AC_VHT80,
+	[WLAN_PHYMODE_11AC_VHT80_2G] = 0,
+	[WLAN_PHYMODE_11AC_VHT160] = IEEE80211_MODE_11AC_VHT160,
+	[WLAN_PHYMODE_11AC_VHT80_80] = IEEE80211_MODE_11AC_VHT80_80,
+	[WLAN_PHYMODE_11AXA_HE20] = IEEE80211_MODE_11AXA_HE20,
+	[WLAN_PHYMODE_11AXG_HE20] = IEEE80211_MODE_11AXG_HE20,
+	[WLAN_PHYMODE_11AXA_HE40MINUS] = IEEE80211_MODE_11AXA_HE40,
+	[WLAN_PHYMODE_11AXG_HE40PLUS] = IEEE80211_MODE_11AXG_HE40PLUS,
+	[WLAN_PHYMODE_11AXG_HE40MINUS] = IEEE80211_MODE_11AXG_HE40MINUS,
+	[WLAN_PHYMODE_11AXG_HE40] = IEEE80211_MODE_11AXG_HE40,
+	[WLAN_PHYMODE_11AXA_HE80] = IEEE80211_MODE_11AXA_HE80,
+	[WLAN_PHYMODE_11AXA_HE80] = 0,
+	[WLAN_PHYMODE_11AXA_HE160] = IEEE80211_MODE_11AXA_HE160,
+	[WLAN_PHYMODE_11AXA_HE80_80] = IEEE80211_MODE_11AXA_HE80_80,
+#ifdef WLAN_FEATURE_11BE
+	[WLAN_PHYMODE_11BEA_EHT20] = IEEE80211_MODE_11BEA_EHT20,
+	[WLAN_PHYMODE_11BEG_EHT20] = IEEE80211_MODE_11BEG_EHT20,
+	[WLAN_PHYMODE_11BEA_EHT40MINUS] = IEEE80211_MODE_11BEA_EHT40,
+	[WLAN_PHYMODE_11BEG_EHT40PLUS] = IEEE80211_MODE_11BEG_EHT40PLUS,
+	[WLAN_PHYMODE_11BEG_EHT40MINUS] = IEEE80211_MODE_11BEG_EHT40MINUS,
+	[WLAN_PHYMODE_11BEG_EHT40] = IEEE80211_MODE_11BEG_EHT40,
+	[WLAN_PHYMODE_11BEA_EHT80] = IEEE80211_MODE_11BEA_EHT80,
+	[WLAN_PHYMODE_11BEG_EHT80] = 0,
+	[WLAN_PHYMODE_11BEA_EHT160] = IEEE80211_MODE_11BEA_EHT160,
+	[WLAN_PHYMODE_11BEA_EHT320] = IEEE80211_MODE_11BEA_EHT320,
+#endif /* WLAN_FEATURE_11BE */
+};
+
+static enum ieee80211_phymode
+wlan_hdd_son_get_ieee_phymode(enum wlan_phymode wlan_phymode)
+{
+	if (wlan_phymode >= WLAN_PHYMODE_MAX)
+		return IEEE80211_MODE_AUTO;
+
+	return wlanphymode2ieeephymode[wlan_phymode];
+}
+
+static QDF_STATUS hdd_son_get_node_info(struct wlan_objmgr_vdev *vdev,
+					uint8_t *mac_addr,
+					wlan_node_info *node_info)
+{
+	struct hdd_adapter *adapter = wlan_hdd_get_adapter_from_objmgr(vdev);
+	struct hdd_station_info *sta_info;
+	enum wlan_phymode peer_phymode;
+	struct wlan_objmgr_psoc *psoc;
+
+	sta_info = hdd_get_sta_info_by_mac(&adapter->sta_info_list, mac_addr,
+					   STA_INFO_SON_GET_DATRATE_INFO);
+	if (!sta_info) {
+		hdd_err("Sta info is null");
+		return QDF_STATUS_E_FAILURE;
+	}
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc) {
+		hdd_err("null psoc");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	node_info->max_chwidth =
+			hdd_chan_width_to_son_chwidth(sta_info->ch_width);
+	node_info->num_streams = (sta_info->max_mcs_idx >= 8) ? 2 : 1;
+	ucfg_mlme_get_peer_phymode(psoc, mac_addr, &peer_phymode);
+	node_info->phymode = wlan_hdd_son_get_ieee_phymode(peer_phymode);
+	node_info->max_txpower = ucfg_son_get_tx_power(sta_info->assoc_req_ies);
+	node_info->max_MCS = ucfg_son_get_max_mcs(sta_info->mode,
+						  sta_info->max_supp_idx,
+						  sta_info->max_ext_idx,
+						  sta_info->max_mcs_idx,
+						  sta_info->rx_mcs_map);
+	if (sta_info->vht_present)
+		node_info->is_mu_mimo_supported =
+				sta_info->vht_caps.vht_cap_info
+				& IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
+	if (sta_info->ht_present)
+		node_info->is_static_smps = ((sta_info->ht_caps.cap_info
+				& IEEE80211_HTCAP_C_SM_MASK) ==
+				IEEE80211_HTCAP_C_SMPOWERSAVE_STATIC);
+	hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true,
+			     STA_INFO_SON_GET_DATRATE_INFO);
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS hdd_son_get_peer_capability(struct wlan_objmgr_vdev *vdev,
+					      struct wlan_objmgr_peer *peer,
+					      wlan_peer_cap *peer_cap)
+{
+	struct hdd_station_info *sta_info;
+	struct hdd_adapter *adapter;
+	bool b_meas_supported;
+	QDF_STATUS status;
+
+	adapter = wlan_hdd_get_adapter_from_objmgr(vdev);
+	if (!adapter) {
+		hdd_err("null adapter");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	sta_info = hdd_get_sta_info_by_mac(&adapter->sta_info_list,
+					   peer->macaddr,
+					   STA_INFO_SOFTAP_GET_STA_INFO);
+	if (!sta_info) {
+		hdd_err("sta_info NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	hdd_info("Getting peer capability from sta_info");
+	qdf_mem_copy(peer_cap->bssid, vdev->vdev_mlme.macaddr,
+		     QDF_MAC_ADDR_SIZE);
+	peer_cap->is_BTM_Supported = !!(sta_info->ext_cap &
+				   BIT(19/*BSS_TRANSITION*/));
+	peer_cap->is_RRM_Supported = !!(sta_info->capability &
+				   WLAN_CAPABILITY_RADIO_MEASURE);
+
+	peer_cap->band_cap = sta_info->supported_band;
+	if (sta_info->assoc_req_ies.len) {
+		status = ucfg_son_get_peer_rrm_info(sta_info->assoc_req_ies,
+						    peer_cap->rrmcaps,
+						    &(b_meas_supported));
+		if (status == QDF_STATUS_SUCCESS)
+			peer_cap->is_beacon_meas_supported = b_meas_supported;
+	}
+	if (sta_info->ht_present)
+		peer_cap->htcap = sta_info->ht_caps.cap_info;
+	if (sta_info->vht_present)
+		peer_cap->vhtcap = sta_info->vht_caps.vht_cap_info;
+
+	qdf_mem_zero(&peer_cap->hecap, sizeof(wlan_client_he_capabilities));
+
+	os_if_son_get_node_datarate_info(vdev, peer->macaddr,
+					 &peer_cap->info);
+
+	hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true,
+			     STA_INFO_SOFTAP_GET_STA_INFO);
+
+	return QDF_STATUS_SUCCESS;
+}
+
 void hdd_son_register_callbacks(struct hdd_context *hdd_ctx)
 {
 	struct son_callbacks cb_obj = {0};
@@ -2250,6 +2407,8 @@ void hdd_son_register_callbacks(struct hdd_context *hdd_ctx)
 	cb_obj.os_if_start_acs = hdd_son_start_acs;
 	cb_obj.os_if_set_acs_channels = hdd_son_set_acs_channels;
 	cb_obj.os_if_get_acs_report = hdd_son_get_acs_report;
+	cb_obj.os_if_get_node_info = hdd_son_get_node_info;
+	cb_obj.os_if_get_peer_capability = hdd_son_get_peer_capability;
 
 	os_if_son_register_hdd_callbacks(hdd_ctx->psoc, &cb_obj);
 

+ 2 - 1
core/hdd/src/wlan_hdd_sta_info.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-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
@@ -64,6 +64,7 @@ char *sta_info_string_from_dbgid(wlan_sta_info_dbgid id)
 				"STA_INFO_SHOW",
 				"STA_INFO_SOFTAP_IPA_RX_PKT_CALLBACK",
 				"STA_INFO_WLAN_HDD_CFG80211_DUMP_STATION",
+				"STA_INFO_SON_GET_DATRATE_INFO",
 				"STA_INFO_ID_MAX"};
 	int32_t num_dbg_strings = QDF_ARRAY_SIZE(strings);
 

+ 3 - 2
core/hdd/src/wlan_hdd_sta_info.h

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-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
@@ -111,6 +111,7 @@ enum dhcp_nego_status {
  * @STA_INFO_SOFTAP_IPA_RX_PKT_CALLBACK: Update rx mcbc stats for IPA case
  * @STA_INFO_WLAN_HDD_CFG80211_DUMP_STATION: NL80211_CMD_GET_STATION dumpit
  *                                           handler for SoftAP
+ * @STA_INFO_SON_GET_DATRATE_INFO: gets datarate info for a SON node
  *
  */
 /*
@@ -150,7 +151,7 @@ typedef enum {
 	STA_INFO_SHOW = 29,
 	STA_INFO_SOFTAP_IPA_RX_PKT_CALLBACK = 30,
 	STA_INFO_WLAN_HDD_CFG80211_DUMP_STATION = 31,
-
+	STA_INFO_SON_GET_DATRATE_INFO = 32,
 	STA_INFO_ID_MAX,
 } wlan_sta_info_dbgid;
 

+ 19 - 0
os_if/son/inc/os_if_son.h

@@ -66,6 +66,8 @@
  * @os_if_start_acs: Trigger ACS
  * @os_if_set_acs_channels: Set channel list for ACS
  * @os_if_get_acs_report: Gets the ACS report
+ * @os_if_get_node_info: Gets the datarate info for node
+ * @os_if_get_peer_capability: Gets peer capability
  */
 struct son_callbacks {
 	uint32_t (*os_if_is_acs_in_progress)(struct wlan_objmgr_vdev *vdev);
@@ -125,6 +127,12 @@ struct son_callbacks {
 				      struct ieee80211req_athdbg *req);
 	int (*os_if_get_acs_report)(struct wlan_objmgr_vdev *vdev,
 				    struct ieee80211_acs_dbg *acs_r);
+	QDF_STATUS (*os_if_get_node_info)(struct wlan_objmgr_vdev *vdev,
+					  uint8_t *mac_addr,
+					  wlan_node_info *nodeinfo);
+	QDF_STATUS (*os_if_get_peer_capability)(struct wlan_objmgr_vdev *vdev,
+						struct wlan_objmgr_peer *peer,
+						wlan_peer_cap *cap);
 };
 
 /**
@@ -745,4 +753,15 @@ int os_if_son_parse_generic_nl_cmd(struct wiphy *wiphy,
 				   struct nlattr **tb,
 				   enum os_if_son_vendor_cmd_type type);
 
+/**
+ * os_if_son_get_node_datarate_info() - Get datarate info about given mac
+ * @vdev: vdev_obj
+ * @mac_addr: mac_address to get datarate information
+ * @node_info: object to store datarate information
+ *
+ * Return: void
+ */
+QDF_STATUS os_if_son_get_node_datarate_info(struct wlan_objmgr_vdev *vdev,
+					    uint8_t *mac_addr,
+					    wlan_node_info *node_info);
 #endif

+ 122 - 0
os_if/son/src/os_if_son.c

@@ -884,11 +884,88 @@ QDF_STATUS os_if_son_vdev_ops(struct wlan_objmgr_vdev *vdev,
 			      enum wlan_mlme_vdev_param type,
 			      void *data, void *ret)
 {
+	union wlan_mlme_vdev_data *in = (union wlan_mlme_vdev_data *)data;
+	union wlan_mlme_vdev_data *out = (union wlan_mlme_vdev_data *)ret;
+
+	if (!vdev)
+		return QDF_STATUS_E_INVAL;
+	switch (type) {
+	case VDEV_SET_IE:
+		break;
+	case VDEV_CLR_IE:
+		break;
+	case VDEV_SET_ACL:
+		break;
+	case VDEV_CLR_ACL:
+		break;
+	case VDEV_SET_ACL_TIMER:
+		break;
+	case VDEV_SET_PEER_ACT_STATS:
+		break;
+	case VDEV_SET_SEC_STA_WDS:
+		break;
+	case VDEV_SET_MEC:
+		break;
+	case VDEV_SET_MBO_IE_BSTM:
+		break;
+	case VDEV_SET_WPS_ACL_ENABLE:
+		break;
+	case VDEV_SET_WNM_BSS_PREF:
+		break;
+	case VDEV_GET_NSS:
+		break;
+	case VDEV_GET_CHAN:
+		if (!out)
+			return QDF_STATUS_E_INVAL;
+		qdf_mem_copy(&out->chan,
+			     wlan_vdev_get_active_channel(vdev),
+			     sizeof(out->chan));
+		break;
+	case VDEV_GET_CHAN_WIDTH:
+		break;
+	case VDEV_GET_CHAN_UTIL:
+		if (!out)
+			return QDF_STATUS_E_INVAL;
+		out->chan_util = os_if_son_get_chan_uti(vdev, NULL);
+		break;
+	case VDEV_GET_APCAP:
+		break;
+	case VDEV_GET_CONNECT_N_TX:
+		break;
+	case VDEV_GET_SSID:
+		break;
+	case VDEV_GET_MAX_PHYRATE:
+		break;
+	case VDEV_GET_ACL:
+		break;
+	case VDEV_GET_ACL_RSSI_THRESHOLDS:
+		break;
+	case VDEV_GET_NODE_CAP:
+		if (!out || !in)
+			return QDF_STATUS_E_INVAL;
+		os_if_son_get_node_datarate_info(vdev, in->mac, &out->nodeinfo);
+		break;
+	case VDEV_GET_WDS:
+		break;
+	default:
+		return QDF_STATUS_E_INVAL;
+	}
+
 	return QDF_STATUS_SUCCESS;
 }
 
 qdf_export_symbol(os_if_son_vdev_ops);
 
+static QDF_STATUS os_if_son_get_peer_capability(struct wlan_objmgr_vdev *vdev,
+						struct wlan_objmgr_peer *peer,
+						wlan_peer_cap *peer_cap)
+{
+	if (g_son_os_if_cb.os_if_get_peer_capability)
+		return g_son_os_if_cb.os_if_get_peer_capability(vdev, peer,
+								peer_cap);
+	return QDF_STATUS_E_INVAL;
+}
+
 QDF_STATUS os_if_son_peer_ops(struct wlan_objmgr_peer *peer,
 			      enum wlan_mlme_peer_param type,
 			      union wlan_mlme_peer_data *in,
@@ -931,6 +1008,12 @@ QDF_STATUS os_if_son_peer_ops(struct wlan_objmgr_peer *peer,
 		status = ucfg_son_set_peer_kickout_allow(vdev, peer,
 							 in->enable);
 		break;
+	case PEER_GET_CAPABILITY:
+		if (!out)
+			return QDF_STATUS_E_INVAL;
+		status = os_if_son_get_peer_capability(vdev, peer,
+						       &out->peercap);
+		break;
 	default:
 		osif_err("invalid type: %d", type);
 		status = QDF_STATUS_E_INVAL;
@@ -1522,3 +1605,42 @@ int os_if_son_parse_generic_nl_cmd(struct wiphy *wiphy,
 
 	return rx_ops->parse_generic_nl_cmd(wiphy, wdev, &param, type);
 }
+
+QDF_STATUS os_if_son_get_node_datarate_info(struct wlan_objmgr_vdev *vdev,
+					    uint8_t *mac_addr,
+					    wlan_node_info *node_info)
+{
+	int8_t max_tx_power;
+	int8_t min_tx_power;
+	struct wlan_objmgr_psoc *psoc;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc) {
+		osif_err("null posc");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (WLAN_ADDR_EQ(wlan_vdev_mlme_get_macaddr(vdev), mac_addr) ==
+							   QDF_STATUS_SUCCESS) {
+		node_info->max_chwidth = os_if_son_get_chwidth(vdev);
+		node_info->phymode = os_if_son_get_phymode(vdev);
+		node_info->num_streams = os_if_son_get_rx_streams(vdev);
+		ucfg_son_get_min_and_max_power(psoc, &max_tx_power,
+					       &min_tx_power);
+		node_info->max_txpower = max_tx_power;
+		node_info->max_MCS = MAX_HE_MCS_IDX;
+		osif_debug("node info: max_chwidth: %u, phymode: %u, num_streams: %d, max_mcs: %d, max_txpower: %d",
+			   node_info->max_chwidth, node_info->phymode,
+			   node_info->num_streams, node_info->max_MCS,
+			   node_info->max_txpower);
+	} else {
+		if (!g_son_os_if_cb.os_if_get_node_info) {
+			osif_err("Callback not registered");
+			return QDF_STATUS_E_INVAL;
+		}
+		status = g_son_os_if_cb.os_if_get_node_info(vdev, mac_addr,
+							    node_info);
+	}
+	return status;
+}