Browse Source

qcacld-3.0: Add connection manager Logic for connect resp from LIM

Add connection manager Logic for connect resp from LIM.

Change-Id: Ifea77cd839d5f21f50b03f833fd0daa8a1cd8bdd
CRs-Fixed: 2846957
gaurank kathpalia 4 years ago
parent
commit
dc7cca8a80

+ 2 - 7
components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_disconnect.c

@@ -182,12 +182,8 @@ static void cm_copy_peer_disconnect_ies(struct wlan_objmgr_vdev *vdev,
 	if (!discon_ie)
 		return;
 
-	ap_ie->ptr = qdf_mem_malloc(discon_ie->len);
-	if (!ap_ie)
-		return;
-
 	ap_ie->len = discon_ie->len;
-	qdf_mem_copy(ap_ie->ptr, discon_ie->data, discon_ie->len);
+	ap_ie->ptr = discon_ie->data;
 }
 
 QDF_STATUS cm_handle_disconnect_resp(struct scheduler_msg *msg)
@@ -218,9 +214,8 @@ QDF_STATUS cm_handle_disconnect_resp(struct scheduler_msg *msg)
 		cm_copy_peer_disconnect_ies(vdev, &resp.ap_discon_ie);
 
 	status = wlan_cm_disconnect_rsp(vdev, &resp);
+	mlme_free_peer_disconnect_ies(vdev);
 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
-	if (resp.ap_discon_ie.len)
-		qdf_mem_free(resp.ap_discon_ie.ptr);
 
 	qdf_mem_free(ind);
 

+ 0 - 2
core/mac/inc/sir_api.h

@@ -1074,8 +1074,6 @@ struct assoc_ind {
 	bool wmmEnabledSta; /* if present - STA is WMM enabled */
 	bool reassocReq;
 	/* Required for indicating the frames to upper layer */
-	uint32_t beaconLength;
-	uint8_t *beaconPtr;
 	uint32_t assocReqLength;
 	uint8_t *assocReqPtr;
 

+ 25 - 1
core/mac/src/pe/include/lim_process_fils.h

@@ -123,6 +123,22 @@ static inline void lim_increase_fils_sequence_number(struct pe_session *session_
 		session_entry->fils_info->sequence_number++;
 }
 
+#ifdef FEATURE_CM_ENABLE
+/**
+ * populate_fils_connect_params() - Populate FILS connect params to join rsp
+ * @mac_ctx: Mac context
+ * @session: PE session
+ * @connect_rsp: connect join rsp
+ *
+ * This API copies the FILS connect params from PE session to SME join rsp
+ *
+ * Return: None
+ */
+void
+populate_fils_connect_params(struct mac_context *mac_ctx,
+			     struct pe_session *session,
+			     struct wlan_cm_connect_resp *connect_rsp);
+#else
 /**
  * populate_fils_connect_params() - Populate FILS connect params to join rsp
  * @mac_ctx: Mac context
@@ -136,7 +152,7 @@ static inline void lim_increase_fils_sequence_number(struct pe_session *session_
 void populate_fils_connect_params(struct mac_context *mac_ctx,
 				  struct pe_session *session,
 				  struct join_rsp *sme_join_rsp);
-
+#endif
 /**
  * lim_update_fils_hlp_data() - Update the hlp data from association
  * response frame to PE session.
@@ -259,10 +275,18 @@ static inline bool lim_is_fils_connection(struct pe_session *pe_session)
 	return false;
 }
 
+#ifdef FEATURE_CM_ENABLE
+static inline void
+populate_fils_connect_params(struct mac_context *mac_ctx,
+			     struct pe_session *session,
+			     struct wlan_cm_connect_resp *connect_rsp)
+{ }
+#else
 static inline void populate_fils_connect_params(struct mac_context *mac_ctx,
 						struct pe_session *session,
 						struct join_rsp *sme_join_rsp)
 { }
+#endif
 
 static inline
 void lim_update_fils_hlp_data(struct qdf_mac_addr *hlp_frm_src_mac,

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

@@ -2871,8 +2871,6 @@ bool lim_fill_lim_assoc_ind_params(
 	/* Required for indicating the frames to upper layer */
 	assoc_ind->assocReqLength = assoc_req->assocReqFrameLength;
 	assoc_ind->assocReqPtr = assoc_req->assocReqFrame;
-	assoc_ind->beaconPtr = session_entry->beacon;
-	assoc_ind->beaconLength = session_entry->bcnLen;
 
 	assoc_ind->chan_info.mhz = session_entry->curr_op_freq;
 	assoc_ind->chan_info.band_center_freq1 =

+ 3 - 3
core/mac/src/pe/lim/lim_process_beacon_frame.c

@@ -137,15 +137,15 @@ lim_process_beacon_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
 			session->beacon = NULL;
 			session->bcnLen = 0;
 		}
-		session->bcnLen = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+		session->bcnLen = WMA_GET_RX_MPDU_LEN(rx_pkt_info);
 		session->beacon = qdf_mem_malloc(session->bcnLen);
 		if (session->beacon)
 			/*
-			 * Store the Beacon/ProbeRsp. This is sent to
+			 * Store the whole Beacon frame. This is sent to
 			 * csr/hdd in join cnf response.
 			 */
 			qdf_mem_copy(session->beacon,
-				WMA_GET_RX_MPDU_DATA(rx_pkt_info),
+				WMA_GET_RX_MAC_HEADER(rx_pkt_info),
 				session->bcnLen);
 
 		lim_check_and_announce_join_success(mac_ctx, bcn_ptr,

+ 60 - 0
core/mac/src/pe/lim/lim_process_fils.c

@@ -1574,6 +1574,65 @@ QDF_STATUS lim_create_fils_auth_data(struct mac_context *mac_ctx,
 	return QDF_STATUS_SUCCESS;
 }
 
+#ifdef FEATURE_CM_ENABLE
+void populate_fils_connect_params(struct mac_context *mac_ctx,
+				  struct pe_session *session,
+				  struct wlan_cm_connect_resp *connect_rsp)
+{
+	struct pe_fils_session *fils_info = session->fils_info;
+	struct fils_connect_rsp_params *fils_ie;
+
+	if (!lim_is_fils_connection(session))
+		return;
+
+	if (!fils_info->fils_pmk_len ||
+	    !fils_info->tk_len || !fils_info->gtk_len ||
+	    !fils_info->fils_pmk || !fils_info->kek_len) {
+		pe_err("Invalid FILS info pmk len %d kek len %d tk len %d gtk len %d",
+		       fils_info->fils_pmk_len, fils_info->kek_len,
+		       fils_info->tk_len, fils_info->gtk_len);
+		return;
+	}
+
+	connect_rsp->connect_ies.fils_ie = qdf_mem_malloc(sizeof(*fils_ie));
+	if (!connect_rsp->connect_ies.fils_ie) {
+		pe_delete_fils_info(session);
+		return;
+	}
+
+	fils_ie = connect_rsp->connect_ies.fils_ie;
+	fils_ie->fils_pmk = qdf_mem_malloc(fils_info->fils_pmk_len);
+	if (!fils_ie->fils_pmk) {
+		qdf_mem_free(fils_ie);
+		connect_rsp->connect_ies.fils_ie = NULL;
+		pe_delete_fils_info(session);
+		return;
+	}
+	fils_ie->fils_seq_num = fils_info->sequence_number;
+	fils_ie->fils_pmk_len = fils_info->fils_pmk_len;
+	qdf_mem_copy(fils_ie->fils_pmk, fils_info->fils_pmk,
+		     fils_info->fils_pmk_len);
+
+	qdf_mem_copy(fils_ie->fils_pmkid, fils_info->fils_pmkid, PMKID_LEN);
+
+	fils_ie->kek_len = fils_info->kek_len;
+	qdf_mem_copy(fils_ie->kek, fils_info->kek, fils_info->kek_len);
+
+	fils_ie->tk_len = fils_info->tk_len;
+	qdf_mem_copy(fils_ie->tk, fils_info->tk, fils_info->tk_len);
+
+	fils_ie->gtk_len = fils_info->gtk_len;
+	qdf_mem_copy(fils_ie->gtk, fils_info->gtk, fils_info->gtk_len);
+
+	cds_copy_hlp_info(&fils_info->dst_mac, &fils_info->src_mac,
+			  fils_info->hlp_data_len, fils_info->hlp_data,
+			  &fils_ie->dst_mac, &fils_ie->src_mac,
+			  &fils_ie->hlp_data_len,
+			  fils_ie->hlp_data);
+
+	pe_debug("FILS connect params copied lim");
+}
+#else
 void populate_fils_connect_params(struct mac_context *mac_ctx,
 				  struct pe_session *session,
 				  struct join_rsp *sme_join_rsp)
@@ -1633,6 +1692,7 @@ void populate_fils_connect_params(struct mac_context *mac_ctx,
 
 	pe_debug("FILS connect params copied lim");
 }
+#endif
 
 /**
  * lim_parse_kde_elements() - Parse Key Delivery Elements

+ 0 - 3
core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c

@@ -710,9 +710,6 @@ lim_fill_sme_assoc_ind_params(
 		sme_assoc_ind->assocReqPtr = assoc_ind->assocReqPtr;
 	}
 
-	sme_assoc_ind->beaconPtr = session_entry->beacon;
-	sme_assoc_ind->beaconLength = session_entry->bcnLen;
-
 	/* Fill in peerMacAddr */
 	qdf_mem_copy(sme_assoc_ind->peerMacAddr, assoc_ind->peerMacAddr,
 		sizeof(tSirMacAddr));

+ 3 - 3
core/mac/src/pe/lim/lim_process_probe_rsp_frame.c

@@ -166,18 +166,18 @@ lim_process_probe_rsp_frame(struct mac_context *mac_ctx, uint8_t *rx_Packet_info
 			session_entry->bcnLen = 0;
 		}
 		session_entry->bcnLen =
-			WMA_GET_RX_PAYLOAD_LEN(rx_Packet_info);
+			WMA_GET_RX_MPDU_LEN(rx_Packet_info);
 			session_entry->beacon =
 			qdf_mem_malloc(session_entry->bcnLen);
 		if (!session_entry->beacon) {
 			pe_err("No Memory to store beacon");
 		} else {
 			/*
-			 * Store the Beacon/ProbeRsp.
+			 * Store the whole ProbeRsp frame.
 			 * This is sent to csr/hdd in join cnf response.
 			 */
 			qdf_mem_copy(session_entry->beacon,
-				     WMA_GET_RX_MPDU_DATA
+				     WMA_GET_RX_MAC_HEADER
 					     (rx_Packet_info),
 				     session_entry->bcnLen);
 		}

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

@@ -1272,138 +1272,6 @@ lim_get_vdev_rmf_capable(struct mac_context *mac, struct pe_session *session)
 #endif
 
 #ifdef FEATURE_CM_ENABLE
-static QDF_STATUS
-lim_cm_prepare_join_rsp_from_pe_session(struct pe_session *pe_session,
-				        struct cm_vdev_join_rsp *rsp,
-				        enum wlan_cm_connect_fail_reason reason,
-				        QDF_STATUS connect_status,
-				        enum wlan_status_code status_code)
-{
-	struct wlan_cm_connect_resp *connect_rsp = &rsp->connect_rsp;
-	struct wlan_connect_rsp_ies *connect_ie = &rsp->connect_rsp.connect_ies;
-
-	connect_rsp->cm_id = pe_session->cm_id;
-	connect_rsp->vdev_id = pe_session->vdev_id;
-	qdf_mem_copy(connect_rsp->bssid.bytes, pe_session->bssId,
-		     QDF_MAC_ADDR_SIZE);
-
-	connect_rsp->freq = pe_session->curr_op_freq;
-	connect_rsp->connect_status = connect_status;
-	connect_rsp->reason = reason;
-	connect_rsp->status_code = status_code;
-	connect_rsp->ssid.length =
-			QDF_MIN(WLAN_SSID_MAX_LEN, pe_session->ssId.length);
-	qdf_mem_copy(connect_rsp->ssid.ssid, pe_session->ssId.ssId,
-		     connect_rsp->ssid.length);
-	connect_rsp->aid = pe_session->limAID;
-
-	if (pe_session->assoc_req) {
-		connect_ie->assoc_req.len = pe_session->assocReqLen;
-		connect_ie->assoc_req.ptr =
-			qdf_mem_malloc(sizeof(connect_ie->assoc_req.len));
-		if (!connect_ie->assoc_req.ptr)
-			return QDF_STATUS_E_NOMEM;
-
-		qdf_mem_copy(connect_ie->assoc_req.ptr, pe_session->assoc_req,
-			     connect_ie->assoc_req.len);
-	}
-
-	if (pe_session->assocRsp) {
-		connect_ie->assoc_rsp.len = pe_session->assocRspLen;
-		connect_ie->assoc_rsp.ptr =
-			qdf_mem_malloc(sizeof(connect_ie->assoc_rsp.len));
-		if (!connect_ie->assoc_rsp.ptr)
-			return QDF_STATUS_E_NOMEM;
-
-		qdf_mem_copy(connect_ie->assoc_rsp.ptr, pe_session->assocRsp,
-			     connect_ie->assoc_rsp.len);
-	}
-
-	return QDF_STATUS_SUCCESS;
-}
-
-static void
-lim_cm_fill_join_rsp_from_connect_req(struct cm_vdev_join_req *req,
-				      struct cm_vdev_join_rsp *rsp,
-				      enum wlan_cm_connect_fail_reason reason)
-{
-	struct wlan_cm_connect_resp *connect_rsp = &rsp->connect_rsp;
-
-	connect_rsp->cm_id = req->cm_id;
-	connect_rsp->vdev_id = req->vdev_id;
-	qdf_copy_macaddr(&connect_rsp->bssid, &req->entry->bssid);
-	connect_rsp->freq = req->entry->channel.chan_freq;
-	connect_rsp->connect_status = QDF_STATUS_E_FAILURE;
-	connect_rsp->reason = reason;
-	connect_rsp->ssid = req->entry->ssid;
-}
-
-static QDF_STATUS lim_cm_flush_connect_rsp(struct scheduler_msg *msg)
-{
-	struct cm_vdev_join_rsp *rsp;
-
-	if (!msg || !msg->bodyptr)
-		return QDF_STATUS_E_INVAL;
-
-	rsp = msg->bodyptr;
-	wlan_cm_free_connect_rsp(rsp);
-
-	return QDF_STATUS_SUCCESS;
-}
-
-static void
-lim_cm_send_connect_rsp(struct mac_context *mac_ctx,
-		        struct pe_session *pe_session,
-		        struct cm_vdev_join_req *req,
-		        enum wlan_cm_connect_fail_reason reason,
-		        QDF_STATUS connect_status,
-		        enum wlan_status_code status_code)
-{
-	struct cm_vdev_join_rsp *rsp;
-	QDF_STATUS status;
-	struct scheduler_msg msg;
-
-	if (!pe_session && !req)
-		return;
-
-	rsp = qdf_mem_malloc(sizeof(*rsp));
-	if (!rsp)
-		return;
-
-	rsp->psoc = mac_ctx->psoc;
-
-	if (!pe_session) {
-		lim_cm_fill_join_rsp_from_connect_req(req, rsp, reason);
-	} else {
-		status =
-			lim_cm_prepare_join_rsp_from_pe_session(pe_session,
-								rsp,
-								reason,
-								connect_status,
-								status_code);
-		if (QDF_IS_STATUS_ERROR(status)) {
-			wlan_cm_free_connect_rsp(rsp);
-			return;
-		}
-	}
-
-	qdf_mem_zero(&msg, sizeof(msg));
-
-	msg.bodyptr = rsp;
-	msg.callback = wlan_cm_send_connect_rsp;
-	msg.flush_callback = lim_cm_flush_connect_rsp;
-
-	status = scheduler_post_message(QDF_MODULE_ID_PE,
-					QDF_MODULE_ID_SME,
-					QDF_MODULE_ID_SME, &msg);
-
-	if (QDF_IS_STATUS_ERROR(status)) {
-		pe_err("vdev_id: %d cm_id 0x%x : msg post fails",
-			rsp->connect_rsp.vdev_id, rsp->connect_rsp.cm_id);
-		wlan_cm_free_connect_rsp(rsp);
-	}
-}
-
 static struct pe_session *
 lim_cm_create_session(struct mac_context *mac_ctx, struct cm_vdev_join_req *req)
 {

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

@@ -2333,9 +2333,12 @@ lim_send_assoc_req_mgmt_frame(struct mac_context *mac_ctx,
 				DOT11F_FF_CAPABILITIES_LEN;
 
 		qdf_mem_zero((uint8_t *)&bcn_ext_cap, sizeof(tDot11fIEExtCap));
-		if (pe_session->beacon && pe_session->bcnLen > ie_offset) {
-			bcn_ie = pe_session->beacon + ie_offset;
-			bcn_ie_len = pe_session->bcnLen - ie_offset;
+		if (pe_session->beacon && (pe_session->bcnLen >
+		    (ie_offset + sizeof(struct wlan_frame_hdr)))) {
+			bcn_ie = pe_session->beacon + ie_offset +
+						sizeof(struct wlan_frame_hdr);
+			bcn_ie_len = pe_session->bcnLen - ie_offset -
+						sizeof(struct wlan_frame_hdr);
 			p_ext_cap = (uint8_t *)wlan_get_ie_ptr_from_eid(
 							DOT11F_EID_EXTCAP,
 							bcn_ie, bcn_ie_len);

+ 365 - 4
core/mac/src/pe/lim/lim_send_sme_rsp_messages.c

@@ -139,6 +139,358 @@ uint32_t lim_get_max_rate_flags(struct mac_context *mac_ctx, tpDphHashNode sta_d
 	return rate_flags;
 }
 
+#ifdef FEATURE_CM_ENABLE
+static void lim_send_smps_intolerent(struct mac_context *mac_ctx,
+				     struct pe_session *pe_session,
+				     uint32_t bcn_len, uint8_t *bcn_ptr)
+{
+	const uint8_t *vendor_ap_1;
+	uint32_t bcn_ie_len;
+	uint8_t *bcn_ie_ptr;
+
+	if (!bcn_ptr || (bcn_len <= (sizeof(struct wlan_frame_hdr) +
+			  offsetof(struct wlan_bcn_frame, ie))))
+		return;
+
+	bcn_ie_len = bcn_len - sizeof(struct wlan_frame_hdr) -
+			offsetof(struct wlan_bcn_frame, ie);
+	bcn_ie_ptr = bcn_ptr + sizeof(struct wlan_frame_hdr) +
+			offsetof(struct wlan_bcn_frame, ie);
+
+	vendor_ap_1 =
+		wlan_get_vendor_ie_ptr_from_oui(SIR_MAC_VENDOR_AP_1_OUI,
+						SIR_MAC_VENDOR_AP_1_OUI_LEN,
+						bcn_ie_ptr, bcn_ie_len);
+	if (mac_ctx->roam.configParam.is_force_1x1 &&
+	    vendor_ap_1 && (pe_session->nss == 2) &&
+	    (!mac_ctx->mlme_cfg->gen.as_enabled ||
+	     wlan_reg_is_5ghz_ch_freq(pe_session->curr_op_freq))) {
+		/* SET vdev param */
+		pe_debug("sending SMPS intolrent vdev_param");
+		wma_cli_set_command(pe_session->vdev_id,
+				    (int)WMI_VDEV_PARAM_SMPS_INTOLERANT,
+				    1, VDEV_CMD);
+	}
+}
+
+#ifdef WLAN_FEATURE_FILS_SK
+static void lim_set_fils_connection(struct wlan_cm_connect_resp *connect_rsp,
+				    struct pe_session *session_entry)
+{
+	if (lim_is_fils_connection(session_entry))
+		connect_rsp->is_fils_connection = true;
+}
+#else
+static inline
+void lim_set_fils_connection(struct wlan_cm_connect_resp *connect_rsp,
+			     struct pe_session *session_entry)
+{}
+#endif
+
+static QDF_STATUS
+lim_cm_prepare_join_rsp_from_pe_session(struct mac_context *mac_ctx,
+					struct pe_session *pe_session,
+					struct cm_vdev_join_rsp *rsp,
+					enum wlan_cm_connect_fail_reason reason,
+					QDF_STATUS connect_status,
+					enum wlan_status_code status_code)
+{
+	struct wlan_cm_connect_resp *connect_rsp = &rsp->connect_rsp;
+	struct wlan_connect_rsp_ies *connect_ie = &rsp->connect_rsp.connect_ies;
+	uint32_t bcn_len;
+	uint8_t *bcn_ptr;
+
+	connect_rsp->cm_id = pe_session->cm_id;
+	connect_rsp->vdev_id = pe_session->vdev_id;
+	qdf_mem_copy(connect_rsp->bssid.bytes, pe_session->bssId,
+		     QDF_MAC_ADDR_SIZE);
+
+	connect_rsp->freq = pe_session->curr_op_freq;
+	connect_rsp->connect_status = connect_status;
+	connect_rsp->reason = reason;
+	connect_rsp->status_code = status_code;
+	connect_rsp->ssid.length =
+			QDF_MIN(WLAN_SSID_MAX_LEN, pe_session->ssId.length);
+	qdf_mem_copy(connect_rsp->ssid.ssid, pe_session->ssId.ssId,
+		     connect_rsp->ssid.length);
+
+	lim_set_fils_connection(connect_rsp, pe_session);
+	if (pe_session->beacon) {
+		connect_ie->bcn_probe_rsp.len = pe_session->bcnLen;
+		connect_ie->bcn_probe_rsp.ptr =
+			qdf_mem_malloc(sizeof(connect_ie->bcn_probe_rsp.len));
+		if (!connect_ie->bcn_probe_rsp.ptr)
+			return QDF_STATUS_E_NOMEM;
+
+		qdf_mem_copy(connect_ie->bcn_probe_rsp.ptr, pe_session->beacon,
+			     connect_ie->bcn_probe_rsp.len);
+	}
+	bcn_len = connect_ie->bcn_probe_rsp.len;
+	bcn_ptr = connect_ie->bcn_probe_rsp.ptr;
+
+	if (pe_session->assoc_req) {
+		connect_ie->assoc_req.len = pe_session->assocReqLen;
+		connect_ie->assoc_req.ptr =
+			qdf_mem_malloc(sizeof(connect_ie->assoc_req.len));
+		if (!connect_ie->assoc_req.ptr)
+			return QDF_STATUS_E_NOMEM;
+
+		qdf_mem_copy(connect_ie->assoc_req.ptr, pe_session->assoc_req,
+			     connect_ie->assoc_req.len);
+	}
+
+	if (pe_session->assocRsp) {
+		connect_ie->assoc_rsp.len = pe_session->assocRspLen;
+		connect_ie->assoc_rsp.ptr =
+			qdf_mem_malloc(sizeof(connect_ie->assoc_rsp.len));
+		if (!connect_ie->assoc_rsp.ptr)
+			return QDF_STATUS_E_NOMEM;
+
+		qdf_mem_copy(connect_ie->assoc_rsp.ptr, pe_session->assocRsp,
+			     connect_ie->assoc_rsp.len);
+	}
+
+	if (QDF_IS_STATUS_SUCCESS(connect_status)) {
+		populate_fils_connect_params(mac_ctx, pe_session, connect_rsp);
+		connect_rsp->aid = pe_session->limAID;
+
+		/* move ric date to cm_vdev_join_rsp to fill in csr session */
+		if (pe_session->ricData) {
+			connect_ie->ric_resp_ie.len = pe_session->RICDataLen;
+			connect_ie->ric_resp_ie.ptr =
+			    qdf_mem_malloc(sizeof(connect_ie->ric_resp_ie.len));
+			if (!connect_ie->ric_resp_ie.ptr)
+				return QDF_STATUS_E_NOMEM;
+
+			qdf_mem_copy(connect_ie->ric_resp_ie.ptr,
+				     pe_session->ricData,
+				     connect_ie->ric_resp_ie.len);
+		}
+
+		/* copy tspec ie to fil lin csr */
+
+		lim_send_smps_intolerent(mac_ctx, pe_session, bcn_len, bcn_ptr);
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static void
+lim_cm_fill_join_rsp_from_connect_req(struct cm_vdev_join_req *req,
+				      struct cm_vdev_join_rsp *rsp,
+				      enum wlan_cm_connect_fail_reason reason)
+{
+	struct wlan_cm_connect_resp *connect_rsp = &rsp->connect_rsp;
+
+	connect_rsp->cm_id = req->cm_id;
+	connect_rsp->vdev_id = req->vdev_id;
+	qdf_copy_macaddr(&connect_rsp->bssid, &req->entry->bssid);
+	connect_rsp->freq = req->entry->channel.chan_freq;
+	connect_rsp->connect_status = QDF_STATUS_E_FAILURE;
+	connect_rsp->reason = reason;
+	connect_rsp->ssid = req->entry->ssid;
+}
+
+static QDF_STATUS lim_cm_flush_connect_rsp(struct scheduler_msg *msg)
+{
+	struct cm_vdev_join_rsp *rsp;
+
+	if (!msg || !msg->bodyptr)
+		return QDF_STATUS_E_INVAL;
+
+	rsp = msg->bodyptr;
+	wlan_cm_free_connect_rsp(rsp);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef FEATURE_WLAN_ESE
+static void lim_free_tspec_ie(struct pe_session *pe_session)
+{
+	if (pe_session->tspecIes) {
+		qdf_mem_free(pe_session->tspecIes);
+		pe_session->tspecIes = NULL;
+		pe_session->tspecLen = 0;
+	}
+}
+#else
+static inline void lim_free_tspec_ie(struct pe_session *pe_session)
+{}
+#endif
+
+static void lim_free_pession_ies(struct pe_session *pe_session)
+{
+	if (pe_session->beacon) {
+		qdf_mem_free(pe_session->beacon);
+		pe_session->beacon = NULL;
+		pe_session->bcnLen = 0;
+	}
+	if (pe_session->assoc_req) {
+		qdf_mem_free(pe_session->assoc_req);
+		pe_session->assoc_req = NULL;
+		pe_session->assocReqLen = 0;
+	}
+	if (pe_session->assocRsp) {
+		qdf_mem_free(pe_session->assocRsp);
+		pe_session->assocRsp = NULL;
+		pe_session->assocRspLen = 0;
+	}
+	if (pe_session->ricData) {
+		qdf_mem_free(pe_session->ricData);
+		pe_session->ricData = NULL;
+		pe_session->RICDataLen = 0;
+	}
+	lim_free_tspec_ie(pe_session);
+}
+
+void lim_cm_send_connect_rsp(struct mac_context *mac_ctx,
+			     struct pe_session *pe_session,
+			     struct cm_vdev_join_req *req,
+			     enum wlan_cm_connect_fail_reason reason,
+			     QDF_STATUS connect_status,
+			     enum wlan_status_code status_code)
+{
+	struct cm_vdev_join_rsp *rsp;
+	QDF_STATUS status;
+	struct scheduler_msg msg;
+
+	if (!pe_session && !req)
+		return;
+
+	rsp = qdf_mem_malloc(sizeof(*rsp));
+	if (!rsp)
+		return;
+
+	rsp->psoc = mac_ctx->psoc;
+
+	if (!pe_session) {
+		lim_cm_fill_join_rsp_from_connect_req(req, rsp, reason);
+	} else {
+		status =
+			lim_cm_prepare_join_rsp_from_pe_session(mac_ctx,
+								pe_session,
+								rsp,
+								reason,
+								connect_status,
+								status_code);
+		lim_free_pession_ies(pe_session);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			pe_err("vdev_id: %d cm_id 0x%x : fail to prepare rsp",
+			       rsp->connect_rsp.vdev_id,
+			       rsp->connect_rsp.cm_id);
+			wlan_cm_free_connect_rsp(rsp);
+			return;
+		}
+	}
+
+	qdf_mem_zero(&msg, sizeof(msg));
+
+	msg.bodyptr = rsp;
+	msg.callback = wlan_cm_send_connect_rsp;
+	msg.flush_callback = lim_cm_flush_connect_rsp;
+
+	status = scheduler_post_message(QDF_MODULE_ID_PE,
+					QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_SME, &msg);
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		pe_err("vdev_id: %d cm_id 0x%x : msg post fails",
+		       rsp->connect_rsp.vdev_id, rsp->connect_rsp.cm_id);
+		wlan_cm_free_connect_rsp(rsp);
+	}
+}
+
+static enum wlan_cm_connect_fail_reason
+lim_cm_get_fail_reason_from_result_code(tSirResultCodes result_code)
+{
+	enum wlan_cm_connect_fail_reason fail_reason;
+
+	switch (result_code) {
+	case eSIR_SME_JOIN_TIMEOUT_RESULT_CODE:
+		fail_reason = CM_JOIN_TIMEOUT;
+		break;
+	case eSIR_SME_AUTH_TIMEOUT_RESULT_CODE:
+		fail_reason = CM_AUTH_TIMEOUT;
+		break;
+	case eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE:
+	case eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE:
+	case eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE:
+		fail_reason = CM_ASSOC_TIMEOUT;
+		break;
+	case eSIR_SME_AUTH_REFUSED:
+	case eSIR_SME_INVALID_WEP_DEFAULT_KEY:
+		fail_reason = CM_AUTH_FAILED;
+		break;
+	case eSIR_SME_ASSOC_REFUSED:
+	case eSIR_SME_REASSOC_REFUSED:
+	case eSIR_SME_FT_REASSOC_FAILURE:
+	case eSIR_SME_INVALID_ASSOC_RSP_RXED:
+	case eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA:
+		fail_reason = CM_ASSOC_FAILED;
+		break;
+	default:
+		fail_reason = CM_JOIN_FAILED;
+		break;
+	}
+
+	return fail_reason;
+}
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
+static
+void lim_send_assoc_rsp_diag_event(struct mac_context *mac_ctx,
+				   struct pe_session *session_entry,
+				   uint16_t msg_type, uint16_t result_code)
+{
+	if (msg_type == eWNI_SME_REASSOC_RSP)
+		lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_REASSOC_RSP_EVENT,
+				      session_entry, result_code, 0);
+	else
+		lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_JOIN_RSP_EVENT,
+				      session_entry, result_code, 0);
+}
+#else
+static inline
+void lim_send_assoc_rsp_diag_event(struct mac_context *mac_ctx,
+				   struct pe_session *session_entry,
+				   uint16_t msg_type, uint16_t result_code)
+{}
+#endif
+
+void lim_send_sme_join_reassoc_rsp(struct mac_context *mac_ctx,
+				   uint16_t msg_type,
+				   tSirResultCodes result_code,
+				   uint16_t prot_status_code,
+				   struct pe_session *session_entry,
+				   uint8_t vdev_id)
+{
+	QDF_STATUS connect_status;
+	enum wlan_cm_connect_fail_reason fail_reason = 0;
+
+	lim_send_assoc_rsp_diag_event(mac_ctx, session_entry, msg_type,
+				      result_code);
+
+	pe_debug("Sending message: %s with reasonCode: %s",
+		 lim_msg_str(msg_type), lim_result_code_str(result_code));
+
+	if (result_code == eSIR_SME_SUCCESS) {
+		connect_status = QDF_STATUS_SUCCESS;
+	} else {
+		connect_status = QDF_STATUS_E_FAILURE;
+		fail_reason =
+			lim_cm_get_fail_reason_from_result_code(result_code);
+	}
+
+	if (msg_type == eWNI_SME_JOIN_RSP)
+		return lim_cm_send_connect_rsp(mac_ctx, session_entry, NULL,
+					       fail_reason, connect_status,
+					       prot_status_code);
+
+	/* add reassoc resp API */
+}
+
+#else
+
 /**
  * lim_send_sme_join_reassoc_rsp_after_resume() - Send Response to SME
  * @mac_ctx:      Pointer to Global MAC structure
@@ -190,10 +542,13 @@ static void lim_handle_join_rsp_status(struct mac_context *mac_ctx,
 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
 	struct ht_profile *ht_profile;
 #endif
-	if (session_entry->beacon) {
-		sme_join_rsp->beaconLength = session_entry->bcnLen;
+	if (session_entry->beacon &&
+	    session_entry->bcnLen > sizeof(struct wlan_frame_hdr)) {
+		sme_join_rsp->beaconLength = session_entry->bcnLen -
+						sizeof(struct wlan_frame_hdr);
 		qdf_mem_copy(sme_join_rsp->frames,
-			     session_entry->beacon,
+			     session_entry->beacon +
+			     sizeof(struct wlan_frame_hdr),
 			     sme_join_rsp->beaconLength);
 		qdf_mem_free(session_entry->beacon);
 		session_entry->beacon = NULL;
@@ -409,6 +764,8 @@ void lim_send_sme_join_reassoc_rsp(struct mac_context *mac_ctx,
 	struct join_rsp *sme_join_rsp;
 	uint32_t rsp_len;
 	tpDphHashNode sta_ds = NULL;
+	uint32_t bcn_data_len = 0;
+
 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
 	if (msg_type == eWNI_SME_REASSOC_RSP)
 		lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_REASSOC_RSP_EVENT,
@@ -431,8 +788,11 @@ void lim_send_sme_join_reassoc_rsp(struct mac_context *mac_ctx,
 		sme_join_rsp->assocReqLength = 0;
 		sme_join_rsp->assocRspLength = 0;
 	} else {
+		if (session_entry->bcnLen > sizeof(struct wlan_frame_hdr))
+			bcn_data_len = session_entry->bcnLen -
+						sizeof(struct wlan_frame_hdr);
 		rsp_len = session_entry->assocReqLen +
-			session_entry->assocRspLen + session_entry->bcnLen +
+			session_entry->assocRspLen + bcn_data_len +
 			session_entry->RICDataLen +
 #ifdef FEATURE_WLAN_ESE
 			session_entry->tspecLen +
@@ -503,6 +863,7 @@ void lim_send_sme_join_reassoc_rsp(struct mac_context *mac_ctx,
 	lim_send_sme_join_reassoc_rsp_after_resume(mac_ctx, QDF_STATUS_SUCCESS,
 						   sme_join_rsp);
 }
+#endif
 
 void lim_send_sme_start_bss_rsp(struct mac_context *mac,
 				uint16_t msgType,

+ 21 - 0
core/mac/src/pe/lim/lim_send_sme_rsp_messages.h

@@ -33,6 +33,7 @@
 #include "sir_common.h"
 #include "sir_api.h"
 #include "sir_mac_prot_def.h"
+#include <../../core/src/wlan_cm_vdev_api.h>
 
 /* Functions for sending responses up the stack */
 
@@ -93,6 +94,26 @@ void lim_send_sme_join_reassoc_rsp(struct mac_context *mac_ctx,
 				   struct pe_session *session_entry,
 				   uint8_t vdev_id);
 
+#ifdef FEATURE_CM_ENABLE
+/**
+ * lim_cm_send_connect_rsp() - Send Response to Upper Layers
+ * @mac_ctx: Pointer to Global MAC structure
+ * @pe_session: PE Session Info
+ * @req: connect req if pe session is NULL
+ * @reason: reason of failure, valid only if status is failure
+ * @connect_status: Indicates the staus of the req
+ * @status_code: Protocol Status Code
+ *
+ * Return: None
+ */
+void lim_cm_send_connect_rsp(struct mac_context *mac_ctx,
+			     struct pe_session *pe_session,
+			     struct cm_vdev_join_req *req,
+			     enum wlan_cm_connect_fail_reason reason,
+			     QDF_STATUS connect_status,
+			     enum wlan_status_code status_code);
+#endif
+
 /**
  * lim_prepare_disconnect_done_ind() - Prepares the disconnect done ind message
  * @mac_ctx: Global mac_ctx

+ 0 - 2
core/mac/src/pe/lim/lim_types.h

@@ -223,8 +223,6 @@ typedef struct sLimMlmAssocInd {
 	bool WmmStaInfoPresent;
 
 	/* Required for indicating the frames to upper layer */
-	uint32_t beaconLength;
-	uint8_t *beaconPtr;
 	uint32_t assocReqLength;
 	uint8_t *assocReqPtr;
 	struct oem_channel_info chan_info;

+ 0 - 16
core/mac/src/pe/sch/sch_api.c

@@ -115,22 +115,6 @@ QDF_STATUS sch_send_beacon_req(struct mac_context *mac, uint8_t *beaconPayload,
 	msgQ.bodyptr = beaconParams;
 	msgQ.bodyval = 0;
 
-	/* Keep a copy of recent beacon frame sent */
-
-	/* free previous copy of the beacon */
-	if (pe_session->beacon) {
-		qdf_mem_free(pe_session->beacon);
-	}
-
-	pe_session->bcnLen = 0;
-	pe_session->beacon = NULL;
-
-	pe_session->beacon = qdf_mem_malloc(size);
-	if (pe_session->beacon) {
-		qdf_mem_copy(pe_session->beacon, beaconPayload, size);
-		pe_session->bcnLen = size;
-	}
-
 	MTRACE(mac_trace_msg_tx(mac, pe_session->peSessionId, msgQ.type));
 	retCode = wma_post_ctrl_msg(mac, &msgQ);
 	if (QDF_STATUS_SUCCESS != retCode)

+ 0 - 2
core/sap/inc/sap_api.h

@@ -246,8 +246,6 @@ typedef struct sap_StationAssocIndication_s {
 	uint8_t staId;
 	uint8_t status;
 	/* Required for indicating the frames to upper layer */
-	uint32_t beaconLength;
-	uint8_t *beaconPtr;
 	uint32_t assocReqLength;
 	uint8_t *assocReqPtr;
 	bool fWmmEnabled;

+ 0 - 2
core/sap/src/sap_fsm.c

@@ -1397,8 +1397,6 @@ QDF_STATUS sap_signal_hdd_event(struct sap_context *sap_ctx,
 		assoc_ind->staId = csr_roaminfo->staId;
 		assoc_ind->status = 0;
 		/* Required for indicating the frames to upper layer */
-		assoc_ind->beaconLength = csr_roaminfo->beaconLength;
-		assoc_ind->beaconPtr = csr_roaminfo->beaconPtr;
 		assoc_ind->assocReqLength = csr_roaminfo->assocReqLength;
 		assoc_ind->assocReqPtr = csr_roaminfo->assocReqPtr;
 		assoc_ind->fWmmEnabled = csr_roaminfo->wmmEnabledSta;

+ 0 - 2
core/sme/inc/csr_api.h

@@ -989,8 +989,6 @@ struct csr_roam_info {
 	bool tdls_chan_swit_prohibited; /* per ExtCap in Assoc/Reassoc resp */
 #endif
 	/* Required for indicating the frames to upper layer */
-	uint32_t beaconLength;
-	uint8_t *beaconPtr;
 	uint32_t assocReqLength;
 	uint8_t *assocReqPtr;
 	int8_t rxRssi;

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

@@ -11344,8 +11344,6 @@ csr_roam_chk_lnk_assoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
 	/* Required for indicating the frames to upper layer */
 	roam_info->assocReqLength = pAssocInd->assocReqLength;
 	roam_info->assocReqPtr = pAssocInd->assocReqPtr;
-	roam_info->beaconPtr = pAssocInd->beaconPtr;
-	roam_info->beaconLength = pAssocInd->beaconLength;
 	roam_info->status_code = eSIR_SME_SUCCESS;
 	roam_info->u.pConnectedProfile = &session->connectedProfile;
 	roam_info->staId = (uint8_t)pAssocInd->staId;