Browse Source

qcacmn: Update ML IE handling as per D1.4 new definitions

Update multi link IE definition as per 11BE draft 1.4 spec.

Change-Id: I560d63019d10e22672dc95e9426fa6e8aca5a105
CRs-Fixed: 3156980
Deeksha Gupta 3 years ago
parent
commit
598c7f9c07

+ 51 - 55
umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h

@@ -1849,6 +1849,13 @@ struct wlan_ml_probe_req {
  * variants.
  */
 
+/* Below fields and subfields have been transitioned to D1.4, and rest will
+ * be checked and transitioned to D1.4 separately.
+ * 1. Presence bitmap subfield.
+ * 2. Common info length subfield of common info field.
+ * 3. STA info length subfield in STA Info field.
+ */
+
 /* Size in octets of Multi-Link element Control field */
 #define WLAN_ML_CTRL_SIZE                                          2
 
@@ -1886,21 +1893,25 @@ enum wlan_ml_variant {
 /* Definitions for bits in the Presence Bitmap subfield in Basic variant
  * Multi-Link element Control field. Any unused bits are reserved.
  */
-/* MLD MAC Address Present */
-#define WLAN_ML_BV_CTRL_PBM_MLDMACADDR_P               ((uint16_t)BIT(0))
 /* Link ID Info Present */
-#define WLAN_ML_BV_CTRL_PBM_LINKIDINFO_P               ((uint16_t)BIT(1))
+#define WLAN_ML_BV_CTRL_PBM_LINKIDINFO_P               ((uint16_t)BIT(0))
 /* BSS Parameters Change Count Present */
-#define WLAN_ML_BV_CTRL_PBM_BSSPARAMCHANGECNT_P        ((uint16_t)BIT(2))
+#define WLAN_ML_BV_CTRL_PBM_BSSPARAMCHANGECNT_P        ((uint16_t)BIT(1))
 /* Medium Synchronization Delay Information Present */
-#define WLAN_ML_BV_CTRL_PBM_MEDIUMSYNCDELAYINFO_P      ((uint16_t)BIT(3))
+#define WLAN_ML_BV_CTRL_PBM_MEDIUMSYNCDELAYINFO_P      ((uint16_t)BIT(2))
 /* EML Capabilities Present */
-#define WLAN_ML_BV_CTRL_PBM_EMLCAP_P                   ((uint16_t)BIT(4))
+#define WLAN_ML_BV_CTRL_PBM_EMLCAP_P                   ((uint16_t)BIT(3))
 /* MLD Capabilities */
-#define WLAN_ML_BV_CTRL_PBM_MLDCAP_P                   ((uint16_t)BIT(5))
+#define WLAN_ML_BV_CTRL_PBM_MLDCAP_P                   ((uint16_t)BIT(4))
 
 /* Definitions related to Basic variant Multi-Link element Common Info field */
 
+/* Size in octets of Common Info Length subfield of Common Info field in
+ * Basic variant Multi-Link element.
+ */
+/* Common Info Length  */
+#define WLAN_ML_BV_CINFO_LENGTH_SIZE                               1
+
 /* Size in octets of Link ID Info subfield in Basic variant Multi-Link element
  * Common Info field.
  */
@@ -2071,6 +2082,18 @@ enum wlan_ml_bv_cinfo_emlcap_transtimeout {
 #define WLAN_ML_BV_CINFO_MLDCAP_STRFREQSEPARATION_IDX               7
 #define WLAN_ML_BV_CINFO_MLDCAP_STRFREQSEPARATION_BITS              5
 
+/* Max value in octets of Common Info Length subfield of Common Info field in
+ * Basic variant Multi-Link element
+ */
+#define WLAN_ML_BV_CINFO_LENGTH_MAX \
+	(WLAN_ML_BV_CINFO_LENGTH_SIZE + \
+	 QDF_MAC_ADDR_SIZE + \
+	 WLAN_ML_BV_CINFO_LINKIDINFO_SIZE + \
+	 WLAN_ML_BV_CINFO_BSSPARAMCHNGCNT_SIZE + \
+	 WLAN_ML_BV_CINFO_MEDMSYNCDELAYINFO_SIZE + \
+	 WLAN_ML_BV_CINFO_EMLCAP_SIZE + \
+	 WLAN_ML_BV_CINFO_MLDCAP_SIZE)
+
 /* End of definitions related to Basic variant Multi-Link element Common Info
  * field.
  */
@@ -2143,6 +2166,12 @@ struct wlan_ml_bv_linfo_perstaprof {
 #define WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_NSTRBMSZ_IDX            9
 #define WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_NSTRBMSZ_BITS           1
 
+/* Definitions for subfields in STA Info field of Per-STA Profile subelement
+ * in Basic variant Multi-Link element Link Info field.
+ */
+/* STA Info Length */
+#define WLAN_ML_BV_LINFO_PERSTAPROF_STAINFO_LENGTH_SIZE             1
+
 /**
  * wlan_ml_bv_linfo_perstaprof_stactrl_nstrbmsz - Encoding for NSTR Bitmap Size
  * in STA Control field of Per-STA Profile subelement in Basic variant
@@ -2162,6 +2191,11 @@ enum wlan_ml_bv_linfo_perstaprof_stactrl_nstrbmsz {
 	WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_NSTRBMSZ_INVALIDSTART,
 };
 
+/* Max size in octets of the NSTR Bitmap in STA Control field of Per-STA Profile
+ * subelement in Basic variant Multi-Link element Link Info field.
+ */
+#define WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_NSTRBMSZ_MAX 2
+
 /**
  * struct wlan_ml_bv_linfo_perstaprof_stainfo_dtiminfo - DTIM info in STA info
  * in Per-STA Profile subelement in Basic variant Multi-Link element Link Info
@@ -2174,6 +2208,16 @@ struct wlan_ml_bv_linfo_perstaprof_stainfo_dtiminfo {
 	uint8_t dtimperiod;
 } qdf_packed;
 
+/* Max value in octets of STA Info Length in STA Info field of Per-STA Profile
+ * subelement in Basic variant Multi-Link element Link Info field.
+ */
+#define WLAN_ML_BV_LINFO_PERSTAPROF_STAINFO_LENGTH_MAX \
+	(WLAN_ML_BV_LINFO_PERSTAPROF_STAINFO_LENGTH_SIZE + \
+	 QDF_MAC_ADDR_SIZE + \
+	 WLAN_BEACONINTERVAL_LEN + \
+	 sizeof(struct wlan_ml_bv_linfo_perstaprof_stainfo_dtiminfo) + \
+	 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_NSTRBMSZ_MAX)
+
 /* End of definitions related to Basic variant Multi-Link element Link Info
  * field.
  */
@@ -2751,54 +2795,6 @@ struct wlan_eht_cap_info {
 #endif
 } qdf_packed;
 
-/**
- * struct wlan_mlo_ie_info - struct for mlo IE information
- * mld_mac_addr: MLD MAC address
- * reserved_1: reserved bits
- * mld_capab_present: MLD capability present
- * eml_capab_present: EML capability present
- * medium_sync_delay_info_present: Medium sync delay information present
- * bss_param_change_cnt_present: BSS parameter change count present
- * link_id_info_present: Link ID information present
- * mld_mac_addr_present: MLD MAC address present
- * reserved: reserved bit
- * type: Type bits
- */
-
-struct wlan_mlo_ie_info {
-#ifndef ANI_LITTLE_BIT_ENDIAN
-	union {
-		struct {
-			uint8_t mld_mac_addr[6];
-		} info; /* mld_mac_addr_present = 1 */
-	} mld_mac_addr;
-	uint16_t reserved_1:6;
-	uint16_t mld_capab_present:1;
-	uint16_t eml_capab_present:1;
-	uint16_t medium_sync_delay_info_present:1;
-	uint16_t bss_param_change_cnt_present:1;
-	uint16_t link_id_info_present:1;
-	uint16_t mld_mac_addr_present:1;
-	uint16_t reserved:1;
-	uint16_t type:3;
-#else
-	uint16_t type:3;
-	uint16_t reserved:1;
-	uint16_t mld_mac_addr_present:1;
-	uint16_t link_id_info_present:1;
-	uint16_t bss_param_change_cnt_present:1;
-	uint16_t medium_sync_delay_info_present:1;
-	uint16_t eml_capab_present:1;
-	uint16_t mld_capab_present:1;
-	uint16_t reserved_1:6;
-	union {
-		struct {
-			uint8_t mld_mac_addr[6];
-		} info; /* mld_mac_addr_present = 1 */
-	} mld_mac_addr;
-#endif
-} qdf_packed;
-
 /**
  * wlan_eht_cap_info_network_endian - struct for eht capabilities information
  * epcs_pri_access: EPCS priority access support

+ 1 - 6
umac/mlo_mgr/inc/utils_mlo.h

@@ -152,19 +152,14 @@ util_get_mlie_variant(uint8_t *mlieseq, qdf_size_t mlieseqlen,
  * fragment sequence
  * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element
  * fragment sequence
- * @mldmacaddrfound: Pointer to the location where a boolean status should be
- * updated indicating whether the MLD MAC address was found or not. This should
- * be ignored by the caller if the function returns error.
  * @linkid: Pointer to the location where the MLD MAC address should be updated.
- * This should be ignored by the caller if the function returns error, or if the
- * function indicates that the MLD MAC address was not found.
+ * This should be ignored by the caller if the function returns error.
  *
  * 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_mldmacaddr(uint8_t *mlieseq, qdf_size_t mlieseqlen,
-			   bool *mldmacaddrfound,
 			   struct qdf_mac_addr *mldmacaddr);
 
 /**

+ 79 - 54
umac/mlo_mgr/src/utils_mlo.c

@@ -73,7 +73,9 @@ util_parse_multi_link_ctrl(uint8_t *mlieseqpayload,
 {
 	qdf_size_t parsed_payload_len;
 	uint16_t mlcontrol;
-	uint16_t presencebm;
+	uint16_t presence_bm;
+	uint16_t cinfo_len = 0;
+	uint16_t exp_cinfo_len = 0;
 
 	/* This helper returns the location(s) and length(s) of (sub)field(s)
 	 * inferable after parsing the Multi Link element Control field. These
@@ -110,25 +112,34 @@ util_parse_multi_link_ctrl(uint8_t *mlieseqpayload,
 	mlcontrol = qdf_le16_to_cpu(mlcontrol);
 	parsed_payload_len += WLAN_ML_CTRL_SIZE;
 
-	presencebm = QDF_GET_BITS(mlcontrol, WLAN_ML_CTRL_PBM_IDX,
-				  WLAN_ML_CTRL_PBM_BITS);
+	presence_bm = QDF_GET_BITS(mlcontrol, WLAN_ML_CTRL_PBM_IDX,
+				   WLAN_ML_CTRL_PBM_BITS);
 
-	/* Check if MLD MAC address is present */
-	if (presencebm & WLAN_ML_BV_CTRL_PBM_MLDMACADDR_P) {
-		if (mlieseqpayloadlen <
-				(parsed_payload_len + QDF_MAC_ADDR_SIZE)) {
-			mlo_err_rl("ML seq payload len %zu insufficient for MAC address size %u after parsed payload len %zu.",
-				   mlieseqpayloadlen,
-				   QDF_MAC_ADDR_SIZE,
-				   parsed_payload_len);
-			return QDF_STATUS_E_PROTO;
-		}
+	if (mlieseqpayloadlen <
+			(parsed_payload_len + WLAN_ML_BV_CINFO_LENGTH_SIZE)) {
+		mlo_err_rl("ML seq payload len %zu insufficient for common info length size %u after parsed payload len %zu.",
+			   mlieseqpayloadlen,
+			   WLAN_ML_BV_CINFO_LENGTH_SIZE,
+			   parsed_payload_len);
+		return QDF_STATUS_E_PROTO;
+	}
 
-		parsed_payload_len += QDF_MAC_ADDR_SIZE;
+	cinfo_len = *(mlieseqpayload + parsed_payload_len);
+	parsed_payload_len += WLAN_ML_BV_CINFO_LENGTH_SIZE;
+
+	if (mlieseqpayloadlen <
+			(parsed_payload_len + QDF_MAC_ADDR_SIZE)) {
+		mlo_err_rl("ML seq payload len %zu insufficient for MAC address size %u after parsed payload len %zu.",
+			   mlieseqpayloadlen,
+			   QDF_MAC_ADDR_SIZE,
+			   parsed_payload_len);
+		return QDF_STATUS_E_PROTO;
 	}
 
+	parsed_payload_len += QDF_MAC_ADDR_SIZE;
+
 	/* Check if Link ID info is present */
-	if (presencebm & WLAN_ML_BV_CTRL_PBM_LINKIDINFO_P) {
+	if (presence_bm & WLAN_ML_BV_CTRL_PBM_LINKIDINFO_P) {
 		if (mlieseqpayloadlen <
 				(parsed_payload_len +
 				 WLAN_ML_BV_CINFO_LINKIDINFO_SIZE)) {
@@ -143,7 +154,7 @@ util_parse_multi_link_ctrl(uint8_t *mlieseqpayload,
 	}
 
 	/* Check if BSS parameter change count is present */
-	if (presencebm & WLAN_ML_BV_CTRL_PBM_BSSPARAMCHANGECNT_P) {
+	if (presence_bm & WLAN_ML_BV_CTRL_PBM_BSSPARAMCHANGECNT_P) {
 		if (mlieseqpayloadlen <
 				(parsed_payload_len +
 				 WLAN_ML_BV_CINFO_BSSPARAMCHNGCNT_SIZE)) {
@@ -158,7 +169,7 @@ util_parse_multi_link_ctrl(uint8_t *mlieseqpayload,
 	}
 
 	/* Check if Medium Sync Delay Info is present */
-	if (presencebm & WLAN_ML_BV_CTRL_PBM_MEDIUMSYNCDELAYINFO_P) {
+	if (presence_bm & WLAN_ML_BV_CTRL_PBM_MEDIUMSYNCDELAYINFO_P) {
 		if (mlieseqpayloadlen <
 				(parsed_payload_len +
 				 WLAN_ML_BV_CINFO_MEDMSYNCDELAYINFO_SIZE)) {
@@ -173,7 +184,7 @@ util_parse_multi_link_ctrl(uint8_t *mlieseqpayload,
 	}
 
 	/* Check if EML cap is present */
-	if (presencebm & WLAN_ML_BV_CTRL_PBM_EMLCAP_P) {
+	if (presence_bm & WLAN_ML_BV_CTRL_PBM_EMLCAP_P) {
 		if (mlieseqpayloadlen <
 				(parsed_payload_len +
 				 WLAN_ML_BV_CINFO_EMLCAP_SIZE)) {
@@ -188,7 +199,7 @@ util_parse_multi_link_ctrl(uint8_t *mlieseqpayload,
 	}
 
 	/* Check if MLD cap is present */
-	if (presencebm & WLAN_ML_BV_CTRL_PBM_MLDCAP_P) {
+	if (presence_bm & WLAN_ML_BV_CTRL_PBM_MLDCAP_P) {
 		if (mlieseqpayloadlen <
 				(parsed_payload_len +
 				 WLAN_ML_BV_CINFO_MLDCAP_SIZE)) {
@@ -202,6 +213,13 @@ util_parse_multi_link_ctrl(uint8_t *mlieseqpayload,
 		parsed_payload_len += WLAN_ML_BV_CINFO_MLDCAP_SIZE;
 	}
 
+	exp_cinfo_len = parsed_payload_len - WLAN_ML_CTRL_SIZE;
+	if (cinfo_len != exp_cinfo_len) {
+		mlo_err_rl("ML seq common info len %u doesn't match with expected common info len %u",
+			   cinfo_len, exp_cinfo_len);
+		return QDF_STATUS_E_PROTO;
+	}
+
 	if (link_info_len) {
 		*link_info_len = mlieseqpayloadlen - parsed_payload_len;
 		mlo_debug("link_info_len:%zu, parsed_payload_len:%zu",
@@ -286,6 +304,18 @@ util_parse_bvmlie_perstaprofile_stactrl(uint8_t *subelempayload,
 				       WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_CMPLTPROF_IDX,
 				       WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_CMPLTPROF_BITS);
 
+	/* Check STA Info Length */
+	if (subelempayloadlen <
+		parsed_payload_len + WLAN_ML_BV_LINFO_PERSTAPROF_STAINFO_LENGTH_SIZE) {
+		mlo_err_rl("Length of subelement payload %zu octets not sufficient to contain STA Info Length of size %u octets after parsed payload length of %zu octets.",
+			   subelempayloadlen,
+			   WLAN_ML_BV_LINFO_PERSTAPROF_STAINFO_LENGTH_SIZE,
+			   parsed_payload_len);
+		return QDF_STATUS_E_PROTO;
+	}
+
+	parsed_payload_len += WLAN_ML_BV_LINFO_PERSTAPROF_STAINFO_LENGTH_SIZE;
+
 	if (is_macaddr_valid)
 		*is_macaddr_valid = false;
 
@@ -2184,18 +2214,16 @@ util_get_mlie_variant(uint8_t *mlieseq, qdf_size_t mlieseqlen,
 
 QDF_STATUS
 util_get_bvmlie_mldmacaddr(uint8_t *mlieseq, qdf_size_t mlieseqlen,
-			   bool *mldmacaddrfound,
 			   struct qdf_mac_addr *mldmacaddr)
 {
 	struct wlan_ie_multilink *mlie_fixed;
 	enum wlan_ml_variant variant;
 	uint16_t mlcontrol;
-	uint16_t presencebitmap;
+	uint8_t commoninfo_len;
 
-	if (!mlieseq || !mlieseqlen || !mldmacaddrfound || !mldmacaddr)
+	if (!mlieseq || !mlieseqlen || !mldmacaddr)
 		return QDF_STATUS_E_NULL_VALUE;
 
-	*mldmacaddrfound = false;
 	qdf_mem_zero(mldmacaddr, sizeof(*mldmacaddr));
 
 	if (mlieseqlen < sizeof(struct wlan_ie_multilink))
@@ -2207,7 +2235,7 @@ util_get_bvmlie_mldmacaddr(uint8_t *mlieseq, qdf_size_t mlieseqlen,
 	    (mlie_fixed->elem_id_ext != WLAN_EXTN_ELEMID_MULTI_LINK))
 		return QDF_STATUS_E_INVAL;
 
-	mlcontrol = le16toh(mlie_fixed->mlcontrol);
+	mlcontrol = qdf_le16_to_cpu(mlie_fixed->mlcontrol);
 
 	variant = QDF_GET_BITS(mlcontrol, WLAN_ML_CTRL_TYPE_IDX,
 			       WLAN_ML_CTRL_TYPE_BITS);
@@ -2215,23 +2243,25 @@ util_get_bvmlie_mldmacaddr(uint8_t *mlieseq, qdf_size_t mlieseqlen,
 	if (variant != WLAN_ML_VARIANT_BASIC)
 		return QDF_STATUS_E_INVAL;
 
-	presencebitmap = QDF_GET_BITS(mlcontrol, WLAN_ML_CTRL_PBM_IDX,
-				      WLAN_ML_CTRL_PBM_BITS);
+	/* Common Info starts at mlieseq + sizeof(struct wlan_ie_multilink).
+	 * Check if there is sufficient space in the buffer for the Common Info
+	 * Length and MLD MAC address.
+	 */
+	if ((sizeof(struct wlan_ie_multilink) + WLAN_ML_BV_CINFO_LENGTH_SIZE +
+	    QDF_MAC_ADDR_SIZE) > mlieseqlen)
+		return QDF_STATUS_E_PROTO;
 
-	if (presencebitmap & WLAN_ML_BV_CTRL_PBM_MLDMACADDR_P) {
-		/* Common Info starts at mlieseq + sizeof(struct
-		 * wlan_ie_multilink). Check if there is sufficient space in
-		 * Common Info for the MLD MAC address.
-		 */
-		if ((sizeof(struct wlan_ie_multilink) + QDF_MAC_ADDR_SIZE) >
-				mlieseqlen)
-			return QDF_STATUS_E_PROTO;
+	/* Check if the value indicated in the Common Info Length subfield is
+	 * sufficient to access the MLD MAC address.
+	 */
+	commoninfo_len = *(mlieseq + sizeof(struct wlan_ie_multilink));
+	if (commoninfo_len < (WLAN_ML_BV_CINFO_LENGTH_SIZE + QDF_MAC_ADDR_SIZE))
+		return QDF_STATUS_E_PROTO;
 
-		*mldmacaddrfound = true;
-		qdf_mem_copy(mldmacaddr->bytes,
-			     mlieseq + sizeof(struct wlan_ie_multilink),
-			     QDF_MAC_ADDR_SIZE);
-	}
+	qdf_mem_copy(mldmacaddr->bytes,
+		     mlieseq + sizeof(struct wlan_ie_multilink) +
+		     WLAN_ML_BV_CINFO_LENGTH_SIZE,
+		     QDF_MAC_ADDR_SIZE);
 
 	return QDF_STATUS_SUCCESS;
 }
@@ -2276,14 +2306,15 @@ util_get_bvmlie_primary_linkid(uint8_t *mlieseq, qdf_size_t mlieseqlen,
 
 	commoninfo = mlieseq + sizeof(struct wlan_ie_multilink);
 	commoninfolen = 0;
+	commoninfolen += WLAN_ML_BV_CINFO_LENGTH_SIZE;
+	if ((sizeof(struct wlan_ie_multilink) + commoninfolen) >
+			mlieseqlen)
+		return QDF_STATUS_E_PROTO;
 
-	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;
-	}
+	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) {
 		linkidinfo = commoninfo + commoninfolen;
@@ -2340,15 +2371,9 @@ util_get_bvmlie_mldcap(uint8_t *mlieseq, qdf_size_t mlieseqlen,
 				      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;
+	commoninfolen = WLAN_ML_BV_CINFO_LENGTH_SIZE;
 
-		if ((sizeof(struct wlan_ie_multilink) + commoninfolen) >
-				mlieseqlen)
-			return QDF_STATUS_E_PROTO;
-	}
+	commoninfolen += QDF_MAC_ADDR_SIZE;
 
 	if (presencebitmap & WLAN_ML_BV_CTRL_PBM_LINKIDINFO_P) {
 		commoninfolen += WLAN_ML_BV_CINFO_LINKIDINFO_SIZE;

+ 13 - 11
umac/scan/dispatcher/src/wlan_scan_utils_api.c

@@ -1792,8 +1792,7 @@ static void util_scan_set_security(struct scan_cache_entry *scan_params)
 #define ML_CONTROL_OFFSET 3
 #define ML_CMN_INFO_OFFSET ML_CONTROL_OFFSET + 2
 
-#define CMN_INFO_MLD_ADDR_PRESENT_BIT     BIT(4)
-#define CMN_INFO_LINK_ID_PRESENT_BIT      BIT(5)
+#define CMN_INFO_LINK_ID_PRESENT_BIT      BIT(4)
 #define LINK_INFO_MAC_ADDR_PRESENT_BIT    BIT(5)
 
 /* This function is implemented as per IEEE802.11be D1.0, there is no difference
@@ -1833,9 +1832,8 @@ static uint8_t util_get_link_info_offset(uint8_t *ml_ie)
 
 	parsed_ie_len += sizeof(*mlie_fixed);
 
-	/* Check if MLD MAC address is present */
-	if (presencebm & WLAN_ML_BV_CTRL_PBM_MLDMACADDR_P)
-		parsed_ie_len += QDF_MAC_ADDR_SIZE;
+	parsed_ie_len += WLAN_ML_BV_CINFO_LENGTH_SIZE;
+	parsed_ie_len += QDF_MAC_ADDR_SIZE;
 
 	/* Check if Link ID info is present */
 	if (presencebm & WLAN_ML_BV_CTRL_PBM_LINKIDINFO_P)
@@ -1914,6 +1912,9 @@ static void util_get_partner_link_info(struct scan_cache_entry *scan_entry)
 		/* Skip STA control field */
 		offset += 2;
 
+		 /* Skip STA Info Length field */
+		 offset += WLAN_ML_BV_LINFO_PERSTAPROF_STAINFO_LENGTH_SIZE;
+
 		scan_entry->ml_info.link_info[0].link_id = sta_ctrl & 0xF;
 		if (sta_ctrl & LINK_INFO_MAC_ADDR_PRESENT_BIT) {
 			qdf_mem_copy(
@@ -1957,12 +1958,13 @@ static void util_scan_update_ml_info(struct scan_cache_entry *scan_entry)
 
 	multi_link_ctrl = *(uint16_t *)(ml_ie + ML_CONTROL_OFFSET);
 	offset = ML_CMN_INFO_OFFSET;
-	/* TODO: Add proper parsing based on presense bitmap */
-	if (multi_link_ctrl & CMN_INFO_MLD_ADDR_PRESENT_BIT) {
-		qdf_mem_copy(&scan_entry->ml_info.mld_mac_addr,
-			     ml_ie + offset, 6);
-		offset += 6;
-	}
+
+	/* Increment the offset to account for the Common Info Length */
+	offset += WLAN_ML_BV_CINFO_LENGTH_SIZE;
+
+	qdf_mem_copy(&scan_entry->ml_info.mld_mac_addr,
+		     ml_ie + offset, 6);
+	offset += 6;
 
 	/* TODO: Decode it from ML IE */
 	scan_entry->ml_info.num_links = 0;