Kaynağa Gözat

qcacmn: Add API to get MLD CAP info from Basic Variant ML element

Add API to get the MLD capabilities from a given Basic variant Multi-Link
element or element fragment  sequence.

Change-Id: I9f0d8069a970523948fd604b4977efd3d41a4d2d
CRs-Fixed: 3177254
Shashikala Prabhu 3 yıl önce
ebeveyn
işleme
1a3a58f4de
2 değiştirilmiş dosya ile 122 ekleme ve 0 silme
  1. 27 0
      umac/mlo_mgr/inc/utils_mlo.h
  2. 95 0
      umac/mlo_mgr/src/utils_mlo.c

+ 27 - 0
umac/mlo_mgr/inc/utils_mlo.h

@@ -194,6 +194,33 @@ QDF_STATUS
 util_get_bvmlie_primary_linkid(uint8_t *mlieseq, qdf_size_t mlieseqlen,
 			       bool *linkidfound, uint8_t *linkid);
 
+/**
+ * util_get_bvmlie_mldcap - Get the MLD capabilities from a given Basic
+ * variant Multi-Link element or element fragment sequence, of the AP that
+ * transmits the Multi-Link element/element fragment sequence or the
+ * nontransmitted BSSID in the same multiple BSSID set as the AP that transmits
+ * the Multi-Link element/element fragment sequence and that is affiliated with
+ * the MLD that is described in the Multi-Link element.
+ *
+ * @mlieseq: Starting address of the Multi-Link element or Multi-Link element
+ * fragment sequence
+ * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element
+ * fragment sequence
+ * @mldcapfound: Pointer to the location where a boolean status should be
+ * updated indicating whether the MLD capabilities was found or not. This should
+ * be ignored by the caller if the function returns error.
+ * @mldcap: Pointer to the location where the value of the MLD capabilities
+ * should be updated. This should be ignored by the caller if the function
+ * returns error, or if the function indicates that the MLD capabilities was not
+ * found.
+ *
+ * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
+ * the reason for error in the case of failure
+ */
+QDF_STATUS
+util_get_bvmlie_mldcap(uint8_t *mlieseq, qdf_size_t mlieseqlen,
+		       bool *mldcapfound, uint16_t *mldcap);
+
 /**
  * util_get_bvmlie_persta_partner_info() - Get per-STA partner link information
  *

+ 95 - 0
umac/mlo_mgr/src/utils_mlo.c

@@ -2302,6 +2302,101 @@ util_get_bvmlie_primary_linkid(uint8_t *mlieseq, qdf_size_t mlieseqlen,
 	return QDF_STATUS_SUCCESS;
 }
 
+QDF_STATUS
+util_get_bvmlie_mldcap(uint8_t *mlieseq, qdf_size_t mlieseqlen,
+		       bool *mldcapfound, uint16_t *mldcap)
+{
+	struct wlan_ie_multilink *mlie_fixed;
+	enum wlan_ml_variant variant;
+	uint16_t mlcontrol;
+	uint16_t presencebitmap;
+	uint8_t *commoninfo;
+	qdf_size_t commoninfolen;
+
+	if (!mlieseq || !mlieseqlen || !mldcapfound || !mldcap)
+		return QDF_STATUS_E_NULL_VALUE;
+
+	*mldcapfound = false;
+	*mldcap = 0;
+
+	if (mlieseqlen < sizeof(struct wlan_ie_multilink))
+		return QDF_STATUS_E_INVAL;
+
+	mlie_fixed = (struct wlan_ie_multilink *)mlieseq;
+
+	if (mlie_fixed->elem_id != WLAN_ELEMID_EXTN_ELEM ||
+	    mlie_fixed->elem_id_ext != WLAN_EXTN_ELEMID_MULTI_LINK)
+		return QDF_STATUS_E_INVAL;
+
+	mlcontrol = qdf_le16_to_cpu(mlie_fixed->mlcontrol);
+
+	variant = QDF_GET_BITS(mlcontrol, WLAN_ML_CTRL_TYPE_IDX,
+			       WLAN_ML_CTRL_TYPE_BITS);
+
+	if (variant != WLAN_ML_VARIANT_BASIC)
+		return QDF_STATUS_E_NOSUPPORT;
+
+	presencebitmap = QDF_GET_BITS(mlcontrol, WLAN_ML_CTRL_PBM_IDX,
+				      WLAN_ML_CTRL_PBM_BITS);
+
+	commoninfo = mlieseq + sizeof(struct wlan_ie_multilink);
+	commoninfolen = 0;
+
+	if (presencebitmap & WLAN_ML_BV_CTRL_PBM_MLDMACADDR_P) {
+		commoninfolen += QDF_MAC_ADDR_SIZE;
+
+		if ((sizeof(struct wlan_ie_multilink) + commoninfolen) >
+				mlieseqlen)
+			return QDF_STATUS_E_PROTO;
+	}
+
+	if (presencebitmap & WLAN_ML_BV_CTRL_PBM_LINKIDINFO_P) {
+		commoninfolen += WLAN_ML_BV_CINFO_LINKIDINFO_SIZE;
+
+		if ((sizeof(struct wlan_ie_multilink) + commoninfolen) >
+				mlieseqlen)
+			return QDF_STATUS_E_PROTO;
+	}
+
+	if (presencebitmap & WLAN_ML_BV_CTRL_PBM_BSSPARAMCHANGECNT_P) {
+		commoninfolen += WLAN_ML_BV_CINFO_BSSPARAMCHNGCNT_SIZE;
+
+		if ((sizeof(struct wlan_ie_multilink) + commoninfolen) >
+				mlieseqlen)
+			return QDF_STATUS_E_PROTO;
+	}
+
+	if (presencebitmap & WLAN_ML_BV_CTRL_PBM_MEDIUMSYNCDELAYINFO_P) {
+		commoninfolen += WLAN_ML_BV_CINFO_MEDMSYNCDELAYINFO_SIZE;
+
+		if ((sizeof(struct wlan_ie_multilink) + commoninfolen) >
+				mlieseqlen)
+			return QDF_STATUS_E_PROTO;
+	}
+
+	if (presencebitmap & WLAN_ML_BV_CTRL_PBM_EMLCAP_P) {
+		commoninfolen += WLAN_ML_BV_CINFO_EMLCAP_SIZE;
+
+		if ((sizeof(struct wlan_ie_multilink) + commoninfolen) >
+				mlieseqlen)
+			return QDF_STATUS_E_PROTO;
+	}
+
+	if (presencebitmap & WLAN_ML_BV_CTRL_PBM_MLDCAP_P) {
+		if ((sizeof(struct wlan_ie_multilink) + commoninfolen +
+					WLAN_ML_BV_CINFO_MLDCAP_SIZE) >
+				mlieseqlen)
+			return QDF_STATUS_E_PROTO;
+
+		*mldcap = *((uint16_t *)(commoninfo + commoninfolen));
+		commoninfolen += WLAN_ML_BV_CINFO_MLDCAP_SIZE;
+
+		*mldcapfound = true;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
 QDF_STATUS
 util_get_bvmlie_persta_partner_info(uint8_t *mlieseq,
 				    qdf_size_t mlieseqlen,