Kaynağa Gözat

qcacmn: Update crypto params based on IEs for connect request

Currently connection manager does not update crypto params
of connect request based on RSN/WPA/WAPI IEs.

Add logic to update the connect params based on IEs.

Change-Id: I74aba3c061ed5fc203be7270dcc244f14718c781
CRs-Fixed: 2777574
Ashish Kumar Dhanotiya 4 yıl önce
ebeveyn
işleme
7232e077f7

+ 5 - 2
os_if/linux/mlme/src/osif_cm_req.c

@@ -30,10 +30,14 @@
 static void osif_cm_free_wep_key_params(struct wlan_cm_connect_req *connect_req)
 {
 	if (connect_req->crypto.wep_keys.key) {
+		qdf_mem_zero(connect_req->crypto.wep_keys.key,
+			     connect_req->crypto.wep_keys.key_len);
 		qdf_mem_free(connect_req->crypto.wep_keys.key);
 		connect_req->crypto.wep_keys.key = NULL;
 	}
 	if (connect_req->crypto.wep_keys.seq) {
+		qdf_mem_zero(connect_req->crypto.wep_keys.seq,
+			     connect_req->crypto.wep_keys.seq_len);
 		qdf_mem_free(connect_req->crypto.wep_keys.seq);
 		connect_req->crypto.wep_keys.seq = NULL;
 	}
@@ -63,8 +67,7 @@ static QDF_STATUS osif_cm_set_wep_key_params(
 		connect_req->crypto.wep_keys.seq =
 			qdf_mem_malloc(connect_req->crypto.wep_keys.seq_len);
 		if (!connect_req->crypto.wep_keys.seq) {
-			qdf_mem_free(connect_req->crypto.wep_keys.key);
-			connect_req->crypto.wep_keys.key = NULL;
+			osif_cm_free_wep_key_params(connect_req);
 			return QDF_STATUS_E_NOMEM;
 		}
 		qdf_mem_copy(connect_req->crypto.wep_keys.seq,

+ 69 - 9
umac/cmn_services/crypto/inc/wlan_crypto_global_api.h

@@ -289,27 +289,29 @@ bool wlan_crypto_is_mmie_valid(struct wlan_objmgr_vdev *vdev,
 
 /**
  * wlan_crypto_wpaie_check - called by mlme to check the wpaie
- * @crypto params: crypto params
- * @iebuf: ie buffer
+ * @crypto_params: crypto params
+ * @frm: ie buffer
  *
  * This function gets called by mlme to check the contents of wpa is
  * matching with given crypto params
  *
  * Return: QDF_STATUS_SUCCESS - in case of success
  */
-QDF_STATUS wlan_crypto_wpaie_check(struct wlan_crypto_params *, uint8_t *frm);
+QDF_STATUS wlan_crypto_wpaie_check(struct wlan_crypto_params *crypto_params,
+				   const uint8_t *frm);
 
 /**
  * wlan_crypto_rsnie_check - called by mlme to check the rsnie
- * @crypto params: crypto params
- * @iebuf: ie buffer
+ * @crypto_params: crypto params
+ * @frm: ie buffer
  *
  * This function gets called by mlme to check the contents of rsn is
  * matching with given crypto params
  *
  * Return: QDF_STATUS_SUCCESS - in case of success
  */
-QDF_STATUS wlan_crypto_rsnie_check(struct wlan_crypto_params *, uint8_t *frm);
+QDF_STATUS wlan_crypto_rsnie_check(struct wlan_crypto_params *crypto_params,
+				   const uint8_t *frm);
 /**
  * wlan_crypto_build_wpaie - called by mlme to build wpaie
  * @vdev: vdev
@@ -352,8 +354,8 @@ uint8_t *wlan_crypto_build_rsnie(struct wlan_objmgr_vdev *vdev,
 
 /**
  * wlan_crypto_wapiie_check - called by mlme to check the wapiie
- * @crypto params: crypto params
- * @iebuf: ie buffer
+ * @crypto_params: crypto params
+ * @frm: ie buffer
  *
  * This function gets called by mlme to check the contents of wapi is
  * matching with given crypto params
@@ -361,7 +363,7 @@ uint8_t *wlan_crypto_build_rsnie(struct wlan_objmgr_vdev *vdev,
  * Return: QDF_STATUS_SUCCESS - in case of success
  */
 QDF_STATUS wlan_crypto_wapiie_check(struct wlan_crypto_params *crypto_params,
-					uint8_t *frm);
+				    const uint8_t *frm);
 
 /**
  * wlan_crypto_build_wapiie - called by mlme to build wapi ie
@@ -722,6 +724,64 @@ bool wlan_crypto_check_wpa_match(struct wlan_objmgr_psoc *psoc,
 uint8_t *
 wlan_crypto_parse_rsnxe_ie(uint8_t *rsnxe_ie, uint8_t *cap_len);
 
+/**
+ * wlan_get_crypto_params_from_wapi_ie - Function to get crypto params
+ * from wapi ie
+ * @crypto_params: return crypto parameters
+ * @ie_ptr: pointer to IEs
+ * @ie_len: IE length
+ *
+ * This function is used to get the crypto parameters from wapi ie
+ *
+ * Context: Any context.
+ * Return: QDF_STATUS
+ */
+#ifdef FEATURE_WLAN_WAPI
+QDF_STATUS
+wlan_get_crypto_params_from_wapi_ie(struct wlan_crypto_params *crypto_params,
+				    const uint8_t *ie_ptr, uint16_t ie_len);
+
+#else
+static inline QDF_STATUS
+wlan_get_crypto_params_from_wapi_ie(struct wlan_crypto_params *crypto_params,
+				    const uint8_t *ie_ptr, uint16_t ie_len)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+#endif
+
+/**
+ * wlan_get_crypto_params_from_wpa_ie - Function to get crypto params
+ * from wpa ie
+ * @crypto_params: return crypto parameters
+ * @ie_ptr: pointer to IEs
+ * @ie_len: IE length
+ *
+ * This function is used to get the crypto parameters from wpa ie
+ *
+ * Context: Any context.
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+wlan_get_crypto_params_from_wpa_ie(struct wlan_crypto_params *crypto_params,
+				   const uint8_t *ie_ptr, uint16_t ie_len);
+
+/**
+ * wlan_get_crypto_params_from_rsn_ie - Function to get crypto params
+ * from rsn ie
+ * @crypto_params: return crypto parameters
+ * @ie_ptr: pointer to IEs
+ * @ie_len: IE length
+ *
+ * This function is used to get the crypto parameters from rsn ie
+ *
+ * Context: Any context.
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+wlan_get_crypto_params_from_rsn_ie(struct wlan_crypto_params *crypto_params,
+				   const uint8_t *ie_ptr, uint16_t ie_len);
+
 /**
  * wlan_set_vdev_crypto_prarams_from_ie - Sets vdev crypto params from IE info
  * @vdev: vdev pointer

+ 44 - 45
umac/cmn_services/crypto/src/wlan_crypto_global_api.c

@@ -2408,7 +2408,7 @@ wlan_crypto_wpa_keymgmt_to_suite(uint32_t keymgmt)
  * cipher algorithm.  Where appropriate we also
  * record any key length.
  */
-static int32_t wlan_crypto_wpa_suite_to_cipher(uint8_t *sel)
+static int32_t wlan_crypto_wpa_suite_to_cipher(const uint8_t *sel)
 {
 	uint32_t w = LE_READ_4(sel);
 	int32_t status = -1;
@@ -2429,7 +2429,7 @@ static int32_t wlan_crypto_wpa_suite_to_cipher(uint8_t *sel)
  * Convert a WPA key management/authentication algorithm
  * to an internal code.
  */
-static int32_t wlan_crypto_wpa_suite_to_keymgmt(uint8_t *sel)
+static int32_t wlan_crypto_wpa_suite_to_keymgmt(const uint8_t *sel)
 {
 	uint32_t w = LE_READ_4(sel);
 	int32_t status = -1;
@@ -2452,7 +2452,7 @@ static int32_t wlan_crypto_wpa_suite_to_keymgmt(uint8_t *sel)
  * cipher algorithm.  Where appropriate we also
  * record any key length.
  */
-static int32_t wlan_crypto_rsn_suite_to_cipher(uint8_t *sel)
+static int32_t wlan_crypto_rsn_suite_to_cipher(const uint8_t *sel)
 {
 	uint32_t w = LE_READ_4(sel);
 	int32_t status = -1;
@@ -2486,7 +2486,7 @@ static int32_t wlan_crypto_rsn_suite_to_cipher(uint8_t *sel)
  * Convert an RSN key management/authentication algorithm
  * to an internal code.
  */
-static int32_t wlan_crypto_rsn_suite_to_keymgmt(uint8_t *sel)
+static int32_t wlan_crypto_rsn_suite_to_keymgmt(const uint8_t *sel)
 {
 	uint32_t w = LE_READ_4(sel);
 	int32_t status = -1;
@@ -2535,18 +2535,9 @@ static int32_t wlan_crypto_rsn_suite_to_keymgmt(uint8_t *sel)
 	return status;
 }
 
-/**
- * wlan_crypto_wpaie_check - called by mlme to check the wpaie
- * @crypto params: crypto params
- * @iebuf: ie buffer
- *
- * This function gets called by mlme to check the contents of wpa is
- * matching with given crypto params
- *
- * Return: QDF_STATUS_SUCCESS - in case of success
- */
 QDF_STATUS wlan_crypto_wpaie_check(struct wlan_crypto_params *crypto_params,
-					uint8_t *frm){
+				   const uint8_t *frm)
+{
 	uint8_t len = frm[1];
 	int32_t w;
 	int n;
@@ -2617,18 +2608,9 @@ QDF_STATUS wlan_crypto_wpaie_check(struct wlan_crypto_params *crypto_params,
 	return QDF_STATUS_SUCCESS;
 }
 
-/**
- * wlan_crypto_rsnie_check - called by mlme to check the rsnie
- * @crypto params: crypto params
- * @iebuf: ie buffer
- *
- * This function gets called by mlme to check the contents of wpa is
- * matching with given crypto params
- *
- * Return: QDF_STATUS_SUCCESS - in case of success
- */
 QDF_STATUS wlan_crypto_rsnie_check(struct wlan_crypto_params *crypto_params,
-					uint8_t *frm){
+				   const uint8_t *frm)
+{
 	uint8_t len = frm[1];
 	int32_t w;
 	int n;
@@ -3118,7 +3100,7 @@ bool wlan_crypto_rsn_info(struct wlan_objmgr_vdev *vdev,
 /*
  * Convert an WAPI CIPHER suite to to an internal code.
  */
-static int32_t wlan_crypto_wapi_suite_to_cipher(uint8_t *sel)
+static int32_t wlan_crypto_wapi_suite_to_cipher(const uint8_t *sel)
 {
 	uint32_t w = LE_READ_4(sel);
 	int32_t status = -1;
@@ -3135,7 +3117,7 @@ static int32_t wlan_crypto_wapi_suite_to_cipher(uint8_t *sel)
  * Convert an WAPI key management/authentication algorithm
  * to an internal code.
  */
-static int32_t wlan_crypto_wapi_keymgmt(u_int8_t *sel)
+static int32_t wlan_crypto_wapi_keymgmt(const u_int8_t *sel)
 {
 	uint32_t w = LE_READ_4(sel);
 	int32_t status = -1;
@@ -3149,18 +3131,9 @@ static int32_t wlan_crypto_wapi_keymgmt(u_int8_t *sel)
 
 	return status;
 }
-/**
- * wlan_crypto_wapiie_check - called by mlme to check the wapiie
- * @crypto params: crypto params
- * @iebuf: ie buffer
- *
- * This function gets called by mlme to check the contents of wapi is
- * matching with given crypto params
- *
- * Return: QDF_STATUS_SUCCESS - in case of success
- */
+
 QDF_STATUS wlan_crypto_wapiie_check(struct wlan_crypto_params *crypto_params,
-					uint8_t *frm)
+				    const uint8_t *frm)
 {
 	uint8_t len = frm[1];
 	int32_t w;
@@ -4095,9 +4068,9 @@ send_res:
 	return match;
 }
 
-static QDF_STATUS
+QDF_STATUS
 wlan_get_crypto_params_from_rsn_ie(struct wlan_crypto_params *crypto_params,
-				   uint8_t *ie_ptr, uint16_t ie_len)
+				   const uint8_t *ie_ptr, uint16_t ie_len)
 {
 	const uint8_t *rsn_ie = NULL;
 	QDF_STATUS status;
@@ -4109,7 +4082,7 @@ wlan_get_crypto_params_from_rsn_ie(struct wlan_crypto_params *crypto_params,
 		return QDF_STATUS_E_INVAL;
 	}
 
-	status = wlan_crypto_rsnie_check(crypto_params, (uint8_t *)rsn_ie);
+	status = wlan_crypto_rsnie_check(crypto_params, rsn_ie);
 	if (QDF_STATUS_SUCCESS != status) {
 		crypto_err("RSN IE check failed");
 		return status;
@@ -4118,9 +4091,9 @@ wlan_get_crypto_params_from_rsn_ie(struct wlan_crypto_params *crypto_params,
 	return QDF_STATUS_SUCCESS;
 }
 
-static QDF_STATUS
+QDF_STATUS
 wlan_get_crypto_params_from_wpa_ie(struct wlan_crypto_params *crypto_params,
-				   uint8_t *ie_ptr, uint16_t ie_len)
+				   const uint8_t *ie_ptr, uint16_t ie_len)
 {
 	const uint8_t *wpa_ie = NULL;
 	uint32_t wpa_oui;
@@ -4136,7 +4109,7 @@ wlan_get_crypto_params_from_wpa_ie(struct wlan_crypto_params *crypto_params,
 		return QDF_STATUS_E_INVAL;
 	}
 
-	status = wlan_crypto_wpaie_check(crypto_params, (uint8_t *)wpa_ie);
+	status = wlan_crypto_wpaie_check(crypto_params, wpa_ie);
 	if (QDF_STATUS_SUCCESS != status) {
 		crypto_err("WPA IE check failed");
 		return status;
@@ -4144,6 +4117,32 @@ wlan_get_crypto_params_from_wpa_ie(struct wlan_crypto_params *crypto_params,
 
 	return QDF_STATUS_SUCCESS;
 }
+
+#ifdef FEATURE_WLAN_WAPI
+QDF_STATUS
+wlan_get_crypto_params_from_wapi_ie(struct wlan_crypto_params *crypto_params,
+				    const uint8_t *ie_ptr, uint16_t ie_len)
+{
+	const uint8_t *wapi_ie;
+	QDF_STATUS status;
+
+	qdf_mem_zero(crypto_params, sizeof(*crypto_params));
+	wapi_ie = wlan_get_ie_ptr_from_eid(WLAN_ELEMID_WAPI, ie_ptr, ie_len);
+	if (!wapi_ie) {
+		crypto_debug("WAPI ie not present");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wlan_crypto_wapiie_check(crypto_params, wapi_ie);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		crypto_err("WAPI IE check failed");
+		return status;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
 /**
  * wlan_crypto_check_rsn_match - called by ucfg to check for RSN match
  * @psoc: psoc pointer

+ 123 - 12
umac/mlme/connection_mgr/core/src/wlan_cm_connect.c

@@ -26,6 +26,7 @@
 #include "wlan_policy_mgr_api.h"
 #endif
 #include <wlan_serialization_api.h>
+#include "wlan_crypto_global_api.h"
 #ifdef CONN_MGR_ADV_FEATURE
 #include "wlan_blm_api.h"
 #endif
@@ -376,17 +377,16 @@ void cm_calculate_scores(struct wlan_objmgr_pdev *pdev,
 }
 #endif
 
-#ifdef WLAN_FEATURE_11W
 static inline void
 cm_set_pmf_caps(struct cm_connect_req *cm_req, struct scan_filter *filter)
 {
-	filter->pmf_cap = cm_req->req.crypto.pmf_cap;
+	if (cm_req->req.crypto.rsn_caps & WLAN_CRYPTO_RSN_CAP_MFP_REQUIRED)
+		filter->pmf_cap = WLAN_PMF_REQUIRED;
+	else if (cm_req->req.crypto.rsn_caps & WLAN_CRYPTO_RSN_CAP_MFP_ENABLED)
+		filter->pmf_cap = WLAN_PMF_CAPABLE;
+	else
+		filter->pmf_cap = WLAN_PMF_DISABLED;
 }
-#else
-static inline void
-cm_set_pmf_caps(struct cm_connect_req *cm_req, struct scan_filter *filter)
-{}
-#endif
 
 static void cm_connect_prepare_scan_fliter(struct cnx_mgr *cm_ctx,
 					   struct cm_connect_req *cm_req,
@@ -972,6 +972,110 @@ post_err:
 	return qdf_status;
 }
 
+static void
+cm_copy_crypto_prarams(struct wlan_cm_connect_crypto_info *dst_params,
+		       struct wlan_crypto_params  *src_params)
+{
+	dst_params->akm_suites = src_params->key_mgmt;
+	dst_params->auth_type = src_params->authmodeset;
+	dst_params->ciphers_pairwise = src_params->ucastcipherset;
+	dst_params->group_cipher = src_params->mcastcipherset;
+	dst_params->mgmt_ciphers = src_params->mgmtcipherset;
+	dst_params->rsn_caps = src_params->rsn_caps;
+}
+
+static void
+cm_set_crypto_params_from_ie(struct wlan_cm_connect_req *req)
+{
+	struct wlan_crypto_params crypto_params;
+	QDF_STATUS status;
+
+	if (!req->assoc_ie.ptr)
+		return;
+
+	status = wlan_get_crypto_params_from_rsn_ie(&crypto_params,
+						    req->assoc_ie.ptr,
+						    req->assoc_ie.len);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		cm_copy_crypto_prarams(&req->crypto, &crypto_params);
+		return;
+	}
+
+	status = wlan_get_crypto_params_from_wpa_ie(&crypto_params,
+						    req->assoc_ie.ptr,
+						    req->assoc_ie.len);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		cm_copy_crypto_prarams(&req->crypto, &crypto_params);
+		return;
+	}
+
+	status = wlan_get_crypto_params_from_wapi_ie(&crypto_params,
+						     req->assoc_ie.ptr,
+						     req->assoc_ie.len);
+	if (QDF_IS_STATUS_SUCCESS(status))
+		cm_copy_crypto_prarams(&req->crypto, &crypto_params);
+}
+
+static QDF_STATUS
+cm_allocate_and_copy_assoc_wep_ie(struct wlan_cm_connect_req *target,
+				  struct wlan_cm_connect_req *source)
+{
+	if (source->assoc_ie.ptr) {
+		target->assoc_ie.ptr = qdf_mem_malloc(source->assoc_ie.len);
+		if (!target->assoc_ie.ptr)
+			return QDF_STATUS_E_NOMEM;
+
+		target->assoc_ie.len = source->assoc_ie.len;
+		qdf_mem_copy(target->assoc_ie.ptr, source->assoc_ie.ptr,
+			     source->assoc_ie.len);
+	}
+
+	if (source->crypto.wep_keys.key) {
+		target->crypto.wep_keys.key =
+			qdf_mem_malloc(source->crypto.wep_keys.key_len);
+		if (!target->crypto.wep_keys.key)
+			goto wep_key_alloc_fail;
+
+		target->crypto.wep_keys.key_len =
+				source->crypto.wep_keys.key_len;
+		qdf_mem_copy(target->crypto.wep_keys.key,
+			     source->crypto.wep_keys.key,
+			     source->crypto.wep_keys.key_len);
+	}
+
+	if (source->crypto.wep_keys.seq) {
+		target->crypto.wep_keys.seq =
+			qdf_mem_malloc(source->crypto.wep_keys.seq_len);
+		if (!target->crypto.wep_keys.seq)
+			goto wep_seq_alloc_fail;
+
+		target->crypto.wep_keys.seq_len =
+					source->crypto.wep_keys.seq_len;
+		qdf_mem_copy(target->crypto.wep_keys.seq,
+			     source->crypto.wep_keys.seq,
+			     source->crypto.wep_keys.seq_len);
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+wep_seq_alloc_fail:
+	if (target->crypto.wep_keys.key) {
+		qdf_mem_zero(target->crypto.wep_keys.key,
+			     target->crypto.wep_keys.key_len);
+		qdf_mem_free(target->crypto.wep_keys.key);
+		target->crypto.wep_keys.key = NULL;
+	}
+
+wep_key_alloc_fail:
+	if (target->assoc_ie.ptr) {
+		qdf_mem_zero(target->assoc_ie.ptr, target->assoc_ie.len);
+		qdf_mem_free(target->assoc_ie.ptr);
+		target->assoc_ie.ptr = NULL;
+	}
+
+	return QDF_STATUS_E_NOMEM;
+}
+
 QDF_STATUS cm_connect_start_req(struct wlan_objmgr_vdev *vdev,
 				struct wlan_cm_connect_req *req)
 {
@@ -987,6 +1091,8 @@ QDF_STATUS cm_connect_start_req(struct wlan_objmgr_vdev *vdev,
 		return QDF_STATUS_E_INVAL;
 	}
 
+	cm_vdev_scan_cancel(wlan_vdev_get_pdev(cm_ctx->vdev), cm_ctx->vdev);
+
 	/*
 	 * This would be freed as part of removal from cm req list if adding
 	 * to list is success after posting WLAN_CM_SM_EV_CONNECT_REQ.
@@ -995,19 +1101,24 @@ QDF_STATUS cm_connect_start_req(struct wlan_objmgr_vdev *vdev,
 	if (!cm_req)
 		return QDF_STATUS_E_NOMEM;
 
-	/*
-	 * Get WAPI/WPA/RSN IE and refill crypto params of req.
-	 */
-
 	connect_req = &cm_req->connect_req;
 	connect_req->req = *req;
 
+	status = cm_allocate_and_copy_assoc_wep_ie(&connect_req->req, req);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		qdf_mem_free(cm_req);
+		return status;
+	}
+	cm_set_crypto_params_from_ie(&connect_req->req);
+
 	status = cm_sm_deliver_event(vdev, WLAN_CM_SM_EV_CONNECT_REQ,
 				     sizeof(*connect_req), connect_req);
 
 	/* free the req if connect is not handled */
-	if (QDF_IS_STATUS_ERROR(status))
+	if (QDF_IS_STATUS_ERROR(status)) {
+		cm_free_connect_req_mem(connect_req);
 		qdf_mem_free(cm_req);
+	}
 
 	return status;
 }

+ 19 - 0
umac/mlme/connection_mgr/core/src/wlan_cm_main_api.h

@@ -332,6 +332,15 @@ bool cm_check_cmid_match_list_head(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id);
 bool cm_check_scanid_match_list_head(struct cnx_mgr *cm_ctx,
 				     wlan_scan_id *scan_id);
 
+/**
+ * cm_free_connect_req_mem() - free connect req internal memory, to be called
+ * before cm_req is freed
+ * @connect_req: connect req
+ *
+ * Return: void
+ */
+void cm_free_connect_req_mem(struct cm_connect_req *connect_req);
+
 /**
  * cm_delete_req_from_list() - Delete the request matching cm id
  * @cm_ctx: connection manager context
@@ -380,4 +389,14 @@ QDF_STATUS cm_add_req_to_list_and_indicate_osif(struct cnx_mgr *cm_ctx,
  */
 struct cm_req *cm_get_req_by_cm_id(struct cnx_mgr *cm_ctx, wlan_cm_id cm_id);
 
+/**
+ * cm_vdev_scan_cancel() - cancel all scans for vdev
+ * @pdev: pdev pointer
+ * @vdev: vdev for which scan to be canceled
+ *
+ * Return: void
+ */
+void cm_vdev_scan_cancel(struct wlan_objmgr_pdev *pdev,
+			 struct wlan_objmgr_vdev *vdev);
+
 #endif /* __WLAN_CM_MAIN_API_H__ */

+ 50 - 1
umac/mlme/connection_mgr/core/src/wlan_cm_util.c

@@ -223,6 +223,33 @@ QDF_STATUS cm_add_req_to_list_and_indicate_osif(struct cnx_mgr *cm_ctx,
 	return QDF_STATUS_SUCCESS;
 }
 
+void cm_free_connect_req_mem(struct cm_connect_req *connect_req)
+{
+	if (connect_req->candidate_list)
+		wlan_scan_purge_results(connect_req->candidate_list);
+
+	if (connect_req->req.assoc_ie.ptr) {
+		qdf_mem_zero(connect_req->req.assoc_ie.ptr,
+			     connect_req->req.assoc_ie.len);
+		qdf_mem_free(connect_req->req.assoc_ie.ptr);
+		connect_req->req.assoc_ie.ptr = NULL;
+	}
+
+	if (connect_req->req.crypto.wep_keys.key) {
+		qdf_mem_zero(connect_req->req.crypto.wep_keys.key,
+			     connect_req->req.crypto.wep_keys.key_len);
+		qdf_mem_free(connect_req->req.crypto.wep_keys.key);
+		connect_req->req.crypto.wep_keys.key = NULL;
+	}
+
+	if (connect_req->req.crypto.wep_keys.seq) {
+		qdf_mem_zero(connect_req->req.crypto.wep_keys.seq,
+			     connect_req->req.crypto.wep_keys.seq_len);
+		qdf_mem_free(connect_req->req.crypto.wep_keys.seq);
+		connect_req->req.crypto.wep_keys.seq = NULL;
+	}
+}
+
 QDF_STATUS
 cm_delete_req_from_list(struct cnx_mgr *cm_ctx, wlan_cm_id cm_id)
 {
@@ -253,7 +280,7 @@ cm_delete_req_from_list(struct cnx_mgr *cm_ctx, wlan_cm_id cm_id)
 	qdf_list_remove_node(&cm_ctx->req_list, &cm_req->node);
 	if (prefix == CONNECT_REQ_PREFIX) {
 		cm_ctx->connect_count--;
-		wlan_scan_purge_results(cm_req->connect_req.candidate_list);
+		cm_free_connect_req_mem(&cm_req->connect_req);
 	} else {
 		cm_ctx->disconnect_count--;
 	}
@@ -300,3 +327,25 @@ void cm_remove_cmd(struct cnx_mgr *cm_ctx, wlan_cm_id cm_id)
 		wlan_serialization_cancel_request(&cmd_info);
 	}
 }
+
+void cm_vdev_scan_cancel(struct wlan_objmgr_pdev *pdev,
+			 struct wlan_objmgr_vdev *vdev)
+{
+	struct scan_cancel_request *req;
+	QDF_STATUS status;
+
+	req = qdf_mem_malloc(sizeof(*req));
+	if (!req)
+		return;
+
+	req->vdev = vdev;
+	req->cancel_req.scan_id = INVAL_SCAN_ID;
+	req->cancel_req.vdev_id = wlan_vdev_get_id(vdev);
+	req->cancel_req.pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
+	req->cancel_req.req_type = WLAN_SCAN_CANCEL_VDEV_ALL;
+
+	status = wlan_scan_cancel(req);
+	/* In success/failure case wlan_scan_cancel free the req memory */
+	if (QDF_IS_STATUS_ERROR(status))
+		mlme_err("Cancel scan request failed");
+}

+ 2 - 2
umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_public_struct.h

@@ -57,7 +57,7 @@ struct wlan_cm_wep_key_params {
  * @akm_suites: AKM suites bitmask
  * @wep_keys: static WEP keys, if not NULL points to an array of
  *	MAX_WEP_KEYS WEP keys
- * @pmf_cap: Pmf capability
+ * @rsn_caps: rsn caps
  * @mgmt_ciphers: mgmt cipher bitmask
  */
 struct wlan_cm_connect_crypto_info {
@@ -67,7 +67,7 @@ struct wlan_cm_connect_crypto_info {
 	uint32_t ciphers_pairwise;
 	uint32_t akm_suites;
 	struct wlan_cm_wep_key_params wep_keys;
-	enum wlan_pmf_cap pmf_cap;
+	uint16_t rsn_caps;
 	uint32_t mgmt_ciphers;
 };