浏览代码

qcacld-3.0: Add adaptive 11r VSIE changes and akm filter changes

Adaptive 11r feature that enables the AP to support FT-AKM
without configuring the FT-AKM in the network. The AP will
advertise non-FT akm with a vendor specific IE having Adaptive
11r bit set to 1 in the IE data. The AP also advertises the
MDE in beacon/probe response.

The STA should check the adaptive 11r capability if the AP
advertises MDE in beacon/probe and adaptive 11r capability in
vendor specific IE.  If adaptive 11r capability is found,
STA can advertise the FT equivalent of the non-FT AKM and
connect with 11r protocol.

Before sending probe request to the AP, the host driver
intersects the csr_roam_profile akm with the akms advertised
by the AP in the function csr_construct_rsn_ie(). Based on
the intersection, RSN IE is constructed and this RSN IE will
be sent over the association request frame. Add changes to
fill FT-PSK akm selector if AP advertises PSK akm(00:0f:ac,4).
If the AP advertises 802.1X akm, fill FT-802.1x akm(00:0f:ac,3).

If the session is adaptive 11r connection, then copy the
adaptive_11r flag to pe_session while sending join request.

Populate the adaptive 11r vendor specific IE into association
request frame.

Change-Id: Iae6ea37787e96fd7cffca32fc4d9a33eb5772f26
CRs-Fixed: 2441337
Pragaspathi Thilagaraj 6 年之前
父节点
当前提交
54018e049a

+ 11 - 0
core/mac/src/pe/include/lim_session.h

@@ -116,6 +116,14 @@ struct obss_detection_cfg {
 	uint8_t obss_ht_20mhz_detect_mode;
 };
 
+#define ADAPTIVE_11R_STA_IE_LEN   0x0B
+#define ADAPTIVE_11R_STA_OUI      "\x00\x00\x0f\x22"
+#define ADAPTIVE_11R_OUI_LEN      0x04
+#define ADAPTIVE_11R_OUI_SUBTYPE  0x00
+#define ADAPTIVE_11R_OUI_VERSION  0x01
+#define ADAPTIVE_11R_DATA_LEN      0x04
+#define ADAPTIVE_11R_OUI_DATA     "\x00\x00\x00\x01"
+
 /**
  * struct pe_session - per-vdev PE context
  * @available: true if the entry is available, false if it is in use
@@ -123,6 +131,8 @@ struct obss_detection_cfg {
  * @vdev_id: ID of the vdev for which this entry is applicable
  * @vdev: the actual vdev for which this entry is applicable
  * @connected_akm: AKM of current connection
+ * @is_adaptive_11R_connection: flag to check if we are connecting
+ * to Adaptive 11R network
  */
 struct pe_session {
 	/* To check session table is in use or free */
@@ -312,6 +322,7 @@ struct pe_session {
 	enum QDF_OPMODE pePersona;
 	int8_t txMgmtPower;
 	bool is11Rconnection;
+	bool is_adaptive_11r_connection;
 
 #ifdef FEATURE_WLAN_ESE
 	bool isESEconnection;

+ 2 - 0
core/mac/src/pe/lim/lim_process_sme_req_messages.c

@@ -1506,6 +1506,8 @@ __lim_process_sme_join_req(struct mac_context *mac_ctx, void *msg_buf)
 		 */
 		session->is11Rconnection = sme_join_req->is11Rconnection;
 		session->connected_akm = sme_join_req->akm;
+		session->is_adaptive_11r_connection =
+				sme_join_req->is_adaptive_11r_connection;
 #ifdef FEATURE_WLAN_ESE
 		session->isESEconnection = sme_join_req->isESEconnection;
 #endif

+ 41 - 0
core/mac/src/pe/lim/lim_prop_exts_utils.c

@@ -176,6 +176,44 @@ static void lim_objmgr_update_vdev_nss(struct wlan_objmgr_psoc *psoc,
 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
 }
 
+#ifdef WLAN_ADAPTIVE_11R
+/**
+ * lim_extract_adaptive_11r_cap() - check if the AP has adaptive 11r
+ * IE
+ * @ie: Pointer to the IE
+ * @ie_len: ie Length
+ *
+ * Return: True if adaptive 11r IE is present
+ */
+static bool lim_extract_adaptive_11r_cap(uint8_t *ie, uint16_t ie_len)
+{
+	const uint8_t *adaptive_ie;
+	uint8_t data;
+	bool adaptive_11r;
+
+	adaptive_ie = wlan_get_vendor_ie_ptr_from_oui(LIM_ADAPTIVE_11R_OUI,
+						      LIM_ADAPTIVE_11R_OUI_SIZE,
+						      ie, ie_len);
+	if (!adaptive_ie)
+		return false;
+
+	if ((adaptive_ie[1] < (OUI_LENGTH + 1)) ||
+	    (adaptive_ie[1] > MAX_ADAPTIVE_11R_IE_LEN))
+		return false;
+
+	data = *(adaptive_ie + OUI_LENGTH + 2);
+	adaptive_11r = (data & 0x1) ? true : false;
+
+	return adaptive_11r;
+}
+
+#else
+static inline bool lim_extract_adaptive_11r_cap(uint8_t *ie, uint16_t ie_len)
+{
+	return false;
+}
+#endif
+
 void
 lim_extract_ap_capability(struct mac_context *mac_ctx, uint8_t *p_ie,
 			  uint16_t ie_len, uint8_t *qos_cap, uint8_t *uapsd,
@@ -400,6 +438,9 @@ lim_extract_ap_capability(struct mac_context *mac_ctx, uint8_t *p_ie,
 
 	lim_objmgr_update_vdev_nss(mac_ctx->psoc, session->smeSessionId,
 				   session->nss);
+
+	session->is_adaptive_11r_connection =
+			lim_extract_adaptive_11r_cap(p_ie, ie_len);
 	qdf_mem_free(beacon_struct);
 	return;
 } /****** end lim_extract_ap_capability() ******/

+ 3 - 0
core/mac/src/pe/lim/lim_prop_exts_utils.h

@@ -31,6 +31,9 @@
 #ifndef __LIM_PROP_EXTS_UTILS_H
 #define __LIM_PROP_EXTS_UTILS_H
 
+#define LIM_ADAPTIVE_11R_OUI      "\x00\x40\x96\x2C"
+#define LIM_ADAPTIVE_11R_OUI_SIZE 4
+
 /**
  * lim_extract_ap_capability() - extract AP's HCF/WME/WSM capability
  * @mac_ctx: Pointer to Global MAC structure

+ 99 - 3
core/mac/src/pe/lim/lim_send_management_frames.c

@@ -1553,6 +1553,86 @@ static QDF_STATUS lim_assoc_tx_complete_cnf(void *context,
 	return QDF_STATUS_SUCCESS;
 }
 
+#ifdef WLAN_ADAPTIVE_11R
+/**
+ * lim_fill_adaptive_11r_ie() - Populate the Vendor secific adaptive 11r
+ * IE to association request frame
+ * @pe_session: pointer to PE session
+ * @ie_buf: buffer to which Adaptive 11r IE will be copied
+ * @ie_len: length of the Adaptive 11r Vendor specific IE
+ *
+ * Return QDF_STATUS
+ */
+static QDF_STATUS lim_fill_adaptive_11r_ie(struct pe_session *pe_session,
+					   uint8_t **ie_buf, uint8_t *ie_len)
+{
+	uint8_t *buf = NULL, *adaptive_11r_ie = NULL;
+
+	if (!pe_session->is_adaptive_11r_connection)
+		return QDF_STATUS_SUCCESS;
+
+	/*
+	 * Vendor specific Adaptive 11r IE to be advertised in Assoc
+	 * req:
+	 * Type     0xDD
+	 * Length   0x0B
+	 * OUI      0x00 0x00 0x0F
+	 * Type     0x22
+	 * subtype  0x00
+	 * Version  0x01
+	 * Length   0x04
+	 * Data     0x00 00 00 01(0th bit is 1 means adaptive 11r is
+	 * supported)
+	 */
+	adaptive_11r_ie = qdf_mem_malloc(ADAPTIVE_11R_STA_IE_LEN + 2);
+	if (!adaptive_11r_ie)
+		return QDF_STATUS_E_FAILURE;
+
+	/* Fill the Vendor IE Type (0xDD) */
+	buf = adaptive_11r_ie;
+	*buf = IE_EID_VENDOR;
+	buf++;
+
+	/* Fill the Vendor IE length (0x0B) */
+	*buf = ADAPTIVE_11R_STA_IE_LEN;
+	buf++;
+
+	/*
+	 * Fill the Adaptive 11r Vendor specific OUI(0x00 0x00 0x0F 0x22)
+	 */
+	qdf_mem_copy(buf, ADAPTIVE_11R_STA_OUI, ADAPTIVE_11R_OUI_LEN);
+	buf += ADAPTIVE_11R_OUI_LEN;
+
+	/* Fill Adaptive 11r Vendor specific Subtype (0x00) */
+	*buf = ADAPTIVE_11R_OUI_SUBTYPE;
+	buf++;
+
+	/* Fill Adaptive 11r Version (0x01) */
+	*buf = ADAPTIVE_11R_OUI_VERSION;
+	buf++;
+
+	/* Fill Adaptive 11r IE Data length (0x04) */
+	*buf = ADAPTIVE_11R_DATA_LEN;
+	buf++;
+
+	/* Fill Adaptive 11r IE Data (0x00 0x00 0x00 0x01) */
+	qdf_mem_copy(buf, ADAPTIVE_11R_OUI_DATA, ADAPTIVE_11R_DATA_LEN);
+
+	*ie_len = ADAPTIVE_11R_STA_IE_LEN + 2;
+	*ie_buf = adaptive_11r_ie;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#else
+static inline
+QDF_STATUS lim_fill_adaptive_11r_ie(struct pe_session *pe_session,
+				    uint8_t **ie_buf, uint8_t *ie_len)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
 /**
  * lim_send_assoc_req_mgmt_frame() - Send association request
  * @mac_ctx: Handle to MAC context
@@ -1596,8 +1676,8 @@ lim_send_assoc_req_mgmt_frame(struct mac_context *mac_ctx,
 	uint32_t bcn_ie_len = 0;
 	uint32_t aes_block_size_len = 0;
 	enum rateid min_rid = RATEID_DEFAULT;
-	uint8_t *mbo_ie = NULL;
-	uint8_t mbo_ie_len = 0;
+	uint8_t *mbo_ie = NULL, *adaptive_11r_ie = NULL;
+	uint8_t mbo_ie_len = 0, adaptive_11r_ie_len = 0;
 
 	if (!pe_session) {
 		pe_err("pe_session is NULL");
@@ -1941,6 +2021,13 @@ lim_send_assoc_req_mgmt_frame(struct mac_context *mac_ctx,
 		pe_debug("Stripped MBO IE of length %d", mbo_ie_len);
 	}
 
+	qdf_status = lim_fill_adaptive_11r_ie(pe_session, &adaptive_11r_ie,
+					      &adaptive_11r_ie_len);
+	if (QDF_IS_STATUS_ERROR(qdf_status)) {
+		pe_err("Failed to fill adaptive 11r IE");
+		goto free_mbo_ie;
+	}
+
 	/*
 	 * Do unpack to populate the add_ie buffer to frm structure
 	 * before packing the frm structure. In this way, the IE ordering
@@ -1967,7 +2054,7 @@ lim_send_assoc_req_mgmt_frame(struct mac_context *mac_ctx,
 	}
 
 	bytes = payload + sizeof(tSirMacMgmtHdr) +
-			aes_block_size_len + mbo_ie_len;
+			aes_block_size_len + mbo_ie_len + adaptive_11r_ie_len;
 
 	qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
 				(void **)&packet);
@@ -2012,6 +2099,14 @@ lim_send_assoc_req_mgmt_frame(struct mac_context *mac_ctx,
 		     mbo_ie, mbo_ie_len);
 	payload = payload + mbo_ie_len;
 
+	/*
+	 * Copy the Vendor specific Adaptive 11r IE to end of the
+	 * assoc request frame
+	 */
+	qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
+		     adaptive_11r_ie, adaptive_11r_ie_len);
+	payload = payload + adaptive_11r_ie_len;
+
 	if (pe_session->assocReq) {
 		qdf_mem_free(pe_session->assocReq);
 		pe_session->assocReq = NULL;
@@ -2082,6 +2177,7 @@ free_mbo_ie:
 
 end:
 	/* Free up buffer allocated for mlm_assoc_req */
+	qdf_mem_free(adaptive_11r_ie);
 	qdf_mem_free(mlm_assoc_req);
 	mlm_assoc_req = NULL;
 	qdf_mem_free(frm);

+ 4 - 2
core/sme/src/csr/csr_api_roam.c

@@ -19516,8 +19516,10 @@ static bool
 csr_is_adaptive_11r_roam_supported(struct mac_context *mac_ctx,
 				   struct csr_roam_session *session)
 {
-	return session->is_adaptive_11r_connection &&
-	       mac_ctx->mlme_cfg->lfr.tgt_adaptive_11r_cap;
+	if (session->is_adaptive_11r_connection)
+		return mac_ctx->mlme_cfg->lfr.tgt_adaptive_11r_cap;
+
+	return true;
 }
 #else
 static bool

+ 76 - 16
core/sme/src/csr/csr_util.c

@@ -54,6 +54,9 @@ uint8_t csr_wpa_oui[][CSR_WPA_OUI_SIZE] = {
 #endif /* FEATURE_WLAN_ESE */
 };
 
+#define FT_PSK_IDX   4
+#define FT_8021X_IDX 3
+
 /*
  * PLEASE DO NOT ADD THE #IFDEF IN BELOW TABLE,
  * IF STILL REQUIRE THEN PLEASE ADD NULL ENTRIES
@@ -3273,6 +3276,7 @@ bool csr_is_pmkid_found_for_peer(struct mac_context *mac,
  * @negotiated_mccipher: negotiated multicast cipher
  * @gp_mgmt_cipher: group management cipher
  * @mgmt_encryption_type: group management encryption type
+ * @adaptive_11r: is adaptive 11r connection
  *
  * This routine will get all RSN information
  *
@@ -3288,7 +3292,8 @@ static bool csr_get_rsn_information(struct mac_context *mac_ctx,
 				    eCsrAuthType *negotiated_authtype,
 				    eCsrEncryptionType *negotiated_mccipher,
 				    uint8_t *gp_mgmt_cipher,
-				    tAniEdType *mgmt_encryption_type)
+				    tAniEdType *mgmt_encryption_type,
+				    bool adaptive_11r)
 {
 	bool acceptable_cipher = false;
 	bool group_mgmt_acceptable_cipher = false;
@@ -3415,29 +3420,78 @@ static bool csr_get_rsn_information(struct mac_context *mac_ctx,
 				neg_authtype = eCSR_AUTH_TYPE_CCKM_RSN;
 		}
 #endif
-		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN)
-				&& csr_is_auth_rsn(mac_ctx, authsuites,
-					c_auth_suites, authentication)) {
+		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
+		    csr_is_auth_rsn(mac_ctx, authsuites,
+				    c_auth_suites, authentication)) {
+			/*
+			 * For adaptive 11r connection send FT-802.1X akm in
+			 * association request
+			 */
+			if (adaptive_11r &&
+			    eCSR_AUTH_TYPE_FT_RSN == auth_type->authType[i]) {
+				neg_authtype = eCSR_AUTH_TYPE_FT_RSN;
+				qdf_mem_copy(authentication,
+					     csr_rsn_oui[FT_8021X_IDX],
+					     CSR_WPA_OUI_SIZE);
+			}
+
 			if (eCSR_AUTH_TYPE_RSN == auth_type->authType[i])
 				neg_authtype = eCSR_AUTH_TYPE_RSN;
 		}
-		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN)
-				&& csr_is_auth_rsn_psk(mac_ctx, authsuites,
+		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
+		    csr_is_auth_rsn_psk(mac_ctx, authsuites,
 					c_auth_suites, authentication)) {
+			/*
+			 * For adaptive 11r connection send FT-PSK akm in
+			 * association request
+			 */
+			if (adaptive_11r &&
+			    eCSR_AUTH_TYPE_FT_RSN_PSK == auth_type->authType[i]) {
+				neg_authtype = eCSR_AUTH_TYPE_FT_RSN_PSK;
+				qdf_mem_copy(authentication,
+					     csr_rsn_oui[FT_PSK_IDX],
+					     CSR_WPA_OUI_SIZE);
+			}
+
 			if (eCSR_AUTH_TYPE_RSN_PSK == auth_type->authType[i])
 				neg_authtype = eCSR_AUTH_TYPE_RSN_PSK;
 		}
 #ifdef WLAN_FEATURE_11W
-		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN)
-			&& csr_is_auth_rsn_psk_sha256(mac_ctx, authsuites,
-					c_auth_suites, authentication)) {
+		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
+		    csr_is_auth_rsn_psk_sha256(mac_ctx, authsuites,
+					       c_auth_suites, authentication)) {
+			/*
+			 * For adaptive 11r connection send AP advertises only
+			 * PSK AKM. STA can choose FT-PSK akm in association
+			 * request if FT capable.
+			 */
+			if (adaptive_11r &&
+			    eCSR_AUTH_TYPE_FT_RSN_PSK == auth_type->authType[i]) {
+				neg_authtype = eCSR_AUTH_TYPE_FT_RSN_PSK;
+				qdf_mem_copy(authentication,
+					     csr_rsn_oui[FT_PSK_IDX],
+					     CSR_WPA_OUI_SIZE);
+			}
+
 			if (eCSR_AUTH_TYPE_RSN_PSK_SHA256 ==
 					auth_type->authType[i])
 				neg_authtype = eCSR_AUTH_TYPE_RSN_PSK_SHA256;
 		}
 		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
-				csr_is_auth_rsn8021x_sha256(mac_ctx, authsuites,
-					c_auth_suites, authentication)) {
+		    csr_is_auth_rsn8021x_sha256(mac_ctx,
+						authsuites, c_auth_suites,
+						authentication)) {
+			/*
+			 * For adaptive 11r connection send FT-802.1x akm in
+			 * association request
+			 */
+			if (adaptive_11r &&
+			    eCSR_AUTH_TYPE_FT_RSN == auth_type->authType[i]) {
+				neg_authtype = eCSR_AUTH_TYPE_FT_RSN;
+				qdf_mem_copy(authentication,
+					     csr_rsn_oui[FT_8021X_IDX],
+					     CSR_WPA_OUI_SIZE);
+			}
 			if (eCSR_AUTH_TYPE_RSN_8021X_SHA256 ==
 					auth_type->authType[i])
 				neg_authtype = eCSR_AUTH_TYPE_RSN_8021X_SHA256;
@@ -3622,10 +3676,10 @@ static bool csr_is_rsn_match(struct mac_context *mac_ctx, tCsrAuthList *pAuthTyp
 	 * settings in the profile.
 	 */
 	fRSNMatch = csr_get_rsn_information(mac_ctx, pAuthType, enType,
-					pEnMcType, &pIes->RSN,
-					NULL, NULL, NULL, NULL,
-					pNegotiatedAuthType,
-					pNegotiatedMCCipher, NULL, NULL);
+					    pEnMcType, &pIes->RSN, NULL, NULL,
+					    NULL, NULL, pNegotiatedAuthType,
+					    pNegotiatedMCCipher, NULL, NULL,
+					    false);
 #ifdef WLAN_FEATURE_11W
 	/* If all the filter matches then finally checks for PMF capabilities */
 	if (fRSNMatch)
@@ -3900,6 +3954,11 @@ uint8_t csr_construct_rsn_ie(struct mac_context *mac, uint32_t sessionId,
 						   WLAN_CRYPTO_PARAM_RSN_CAP);
 	wlan_crypto_set_vdev_param(vdev, WLAN_CRYPTO_PARAM_RSN_CAP, rsn_cap);
 	qdf_mem_copy(bssid.bytes, pSirBssDesc->bssId, QDF_MAC_ADDR_SIZE);
+
+	/*
+	 * TODO: Add support for Adaptive 11r connection after
+	 * call to csr_get_rsn_information is added here
+	 */
 	rsn_ie_end = wlan_crypto_build_rsnie(vdev, rsn_ie, &bssid);
 
 	if (rsn_ie_end)
@@ -4000,7 +4059,8 @@ uint8_t csr_construct_rsn_ie(struct mac_context *mac, uint32_t sessionId,
 					MulticastCypher, AuthSuite,
 					&RSNCapabilities, &negAuthType, NULL,
 					gp_mgmt_cipher_suite,
-					&pProfile->mgmt_encryption_type);
+					&pProfile->mgmt_encryption_type,
+					session->is_adaptive_11r_connection);
 		if (!fRSNMatch)
 			break;