Browse Source

qcacmn: Update definitions for MLD capability subfield

Update definition for MLD capabilities subfield present in
the Common Info field of Basic Multi-Link element as per
IEEE802.11be D1.5.

Store parsed MLD capability in node to send these to Target.
Add endianness handling for MLD Capability.

Add a check if the value in the common info length tallies
with the length as determined from the presence bitmap for
MLD capabilities.

CRs-Fixed: 3206837
Change-Id: I3d03afbd60171b2cf5e81c9a8dbb51d7673c9163
Shreedhar Parande 3 years ago
parent
commit
7c2d02ecf3
2 changed files with 31 additions and 17 deletions
  1. 6 1
      umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h
  2. 25 16
      umac/mlo_mgr/src/utils_mlo.c

+ 6 - 1
umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h

@@ -1869,6 +1869,8 @@ struct wlan_ml_probe_req {
  *    Multi-Link element Link Info field.
  * 4. STA Info Length subfield in STA Info field in Per-STA Profile subelement
  *    in Basic variant Multi-Link element Link Info field.
+ * 5. EML Capabilities subfield of Common Info field.
+ * 6. MLD Capabilities subfield of Common Info field.
  */
 
 /* Size in octets of Multi-Link element Control field */
@@ -2098,7 +2100,7 @@ enum wlan_ml_bv_cinfo_emlcap_transtimeout {
 };
 
 /* Size in octets of MLD Capabilities subfield in Basic variant Multi-Link
- * element Common Info field.
+ * element Common Info field as per IEEE P802.11be/D1.5.
  */
 #define WLAN_ML_BV_CINFO_MLDCAP_SIZE                                2
 
@@ -2117,6 +2119,9 @@ enum wlan_ml_bv_cinfo_emlcap_transtimeout {
 /* Frequency Separation For STR */
 #define WLAN_ML_BV_CINFO_MLDCAP_STRFREQSEPARATION_IDX               7
 #define WLAN_ML_BV_CINFO_MLDCAP_STRFREQSEPARATION_BITS              5
+/* AAR Support */
+#define WLAN_ML_BV_CINFO_MLDCAP_AARSUPPORT_IDX                      12
+#define WLAN_ML_BV_CINFO_MLDCAP_AARSUPPORT_BITS                     1
 
 /* Max value in octets of Common Info Length subfield of Common Info field in
  * Basic variant Multi-Link element

+ 25 - 16
umac/mlo_mgr/src/utils_mlo.c

@@ -2701,7 +2701,8 @@ util_get_bvmlie_mldcap(uint8_t *mlieseq, qdf_size_t mlieseqlen,
 	uint16_t mlcontrol;
 	uint16_t presencebitmap;
 	uint8_t *commoninfo;
-	qdf_size_t commoninfolen;
+	uint8_t commoninfo_len;
+	qdf_size_t mldcap_offset;
 
 	if (!mlieseq || !mlieseqlen || !mldcapfound || !mldcap)
 		return QDF_STATUS_E_NULL_VALUE;
@@ -2730,51 +2731,59 @@ util_get_bvmlie_mldcap(uint8_t *mlieseq, qdf_size_t mlieseqlen,
 				      WLAN_ML_CTRL_PBM_BITS);
 
 	commoninfo = mlieseq + sizeof(struct wlan_ie_multilink);
-	commoninfolen = WLAN_ML_BV_CINFO_LENGTH_SIZE;
-
-	commoninfolen += QDF_MAC_ADDR_SIZE;
+	commoninfo_len = *(mlieseq + sizeof(struct wlan_ie_multilink));
+	/* mldcap_offset stores the offset of MLD Capabilities within
+	 * Common Info
+	 */
+	mldcap_offset = WLAN_ML_BV_CINFO_LENGTH_SIZE;
+	mldcap_offset += QDF_MAC_ADDR_SIZE;
 
 	if (presencebitmap & WLAN_ML_BV_CTRL_PBM_LINKIDINFO_P) {
-		commoninfolen += WLAN_ML_BV_CINFO_LINKIDINFO_SIZE;
+		mldcap_offset += WLAN_ML_BV_CINFO_LINKIDINFO_SIZE;
 
-		if ((sizeof(struct wlan_ie_multilink) + commoninfolen) >
+		if ((sizeof(struct wlan_ie_multilink) + mldcap_offset) >
 				mlieseqlen)
 			return QDF_STATUS_E_PROTO;
 	}
 
 	if (presencebitmap & WLAN_ML_BV_CTRL_PBM_BSSPARAMCHANGECNT_P) {
-		commoninfolen += WLAN_ML_BSSPARAMCHNGCNT_SIZE;
+		mldcap_offset += WLAN_ML_BSSPARAMCHNGCNT_SIZE;
 
-		if ((sizeof(struct wlan_ie_multilink) + commoninfolen) >
+		if ((sizeof(struct wlan_ie_multilink) + mldcap_offset) >
 				mlieseqlen)
 			return QDF_STATUS_E_PROTO;
 	}
 
 	if (presencebitmap & WLAN_ML_BV_CTRL_PBM_MEDIUMSYNCDELAYINFO_P) {
-		commoninfolen += WLAN_ML_BV_CINFO_MEDMSYNCDELAYINFO_SIZE;
+		mldcap_offset += WLAN_ML_BV_CINFO_MEDMSYNCDELAYINFO_SIZE;
 
-		if ((sizeof(struct wlan_ie_multilink) + commoninfolen) >
+		if ((sizeof(struct wlan_ie_multilink) + mldcap_offset) >
 				mlieseqlen)
 			return QDF_STATUS_E_PROTO;
 	}
 
 	if (presencebitmap & WLAN_ML_BV_CTRL_PBM_EMLCAP_P) {
-		commoninfolen += WLAN_ML_BV_CINFO_EMLCAP_SIZE;
+		mldcap_offset += WLAN_ML_BV_CINFO_EMLCAP_SIZE;
 
-		if ((sizeof(struct wlan_ie_multilink) + commoninfolen) >
+		if ((sizeof(struct wlan_ie_multilink) + mldcap_offset) >
 				mlieseqlen)
 			return QDF_STATUS_E_PROTO;
 	}
 
 	if (presencebitmap & WLAN_ML_BV_CTRL_PBM_MLDCAP_P) {
-		if ((sizeof(struct wlan_ie_multilink) + commoninfolen +
+		/* Check if the value indicated in the Common Info Length
+		 * subfield is sufficient to access the MLD capabilities.
+		 */
+		if (commoninfo_len < (mldcap_offset +
+				      WLAN_ML_BV_CINFO_MLDCAP_SIZE))
+			return QDF_STATUS_E_PROTO;
+
+		if ((sizeof(struct wlan_ie_multilink) + mldcap_offset +
 					WLAN_ML_BV_CINFO_MLDCAP_SIZE) >
 				mlieseqlen)
 			return QDF_STATUS_E_PROTO;
 
-		*mldcap = *((uint16_t *)(commoninfo + commoninfolen));
-		commoninfolen += WLAN_ML_BV_CINFO_MLDCAP_SIZE;
-
+		*mldcap = qdf_le16_to_cpu(*((uint16_t *)(commoninfo + mldcap_offset)));
 		*mldcapfound = true;
 	}