ソースを参照

qcacld-3.0: Send assoc ind to upper layer after assoc rsp tx complete

Do not send assoc indication to hostapd until tx is completed over the
air. This ensures on receiving assoc resp tx status, M1 is triggered
from hostapd.

Otherwise, race condition happens between assoc response and M1 packet.

Change-Id: I1da7d5b2abcc35dc39fd8e3d8b834e1481d369f3
CRs-Fixed: 2507446
bings 5 年 前
コミット
8551233fd6

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

@@ -1107,6 +1107,7 @@ struct assoc_ind {
 	const uint8_t *owe_ie;
 	uint32_t owe_ie_len;
 	uint16_t owe_status;
+	bool need_assoc_rsp_tx_cb;
 };
 
 /**
@@ -1131,6 +1132,7 @@ struct assoc_cnf {
 	enum mac_status_code mac_status_code;
 	uint8_t *owe_ie;
 	uint32_t owe_ie_len;
+	bool need_assoc_rsp_tx_cb;
 };
 
 /* / Enum definition for  Wireless medium status change codes */

+ 2 - 1
core/mac/inc/wni_api.h

@@ -72,8 +72,9 @@ enum eWniMsgTypes {
 	eWNI_SME_DELTS_IND = SIR_SME_MSG_TYPES_BEGIN + 32,
 	/*
 	 * unused SIR_SME_MSG_TYPES_BEGIN + 33 to
-	 * to SIR_SME_MSG_TYPES_BEGIN + 36
+	 * to SIR_SME_MSG_TYPES_BEGIN + 35
 	 */
+	eWNI_SME_ASSOC_IND_UPPER_LAYER = SIR_SME_MSG_TYPES_BEGIN + 36,
 	eWNI_SME_WPS_PBC_PROBE_REQ_IND = SIR_SME_MSG_TYPES_BEGIN + 37,
 	eWNI_SME_UPPER_LAYER_ASSOC_CNF = SIR_SME_MSG_TYPES_BEGIN + 38,
 	eWNI_SME_SESSION_UPDATE_PARAM = SIR_SME_MSG_TYPES_BEGIN + 39,

+ 5 - 3
core/mac/src/pe/lim/lim_assoc_utils.c

@@ -918,9 +918,11 @@ lim_reject_association(struct mac_context *mac_ctx, tSirMacAddr peer_addr,
 	}
 
 	if (delete_sta == false) {
-		lim_send_assoc_rsp_mgmt_frame(mac_ctx,
+		lim_send_assoc_rsp_mgmt_frame(
+				mac_ctx,
 				eSIR_MAC_MAX_ASSOC_STA_REACHED_STATUS,
-				1, peer_addr, sub_type, 0, session_entry);
+				1, peer_addr, sub_type, 0, session_entry,
+				false);
 		pe_warn("received Re/Assoc req when max associated STAs reached from");
 		lim_print_mac_addr(mac_ctx, peer_addr, LOGW);
 		lim_send_sme_max_assoc_exceeded_ntf(mac_ctx, peer_addr,
@@ -950,7 +952,7 @@ lim_reject_association(struct mac_context *mac_ctx, tSirMacAddr peer_addr,
 	 * status code to requesting STA.
 	 */
 	lim_send_assoc_rsp_mgmt_frame(mac_ctx, result_code, 0, peer_addr,
-					 sub_type, 0, session_entry);
+				      sub_type, 0, session_entry, false);
 
 	if (session_entry->parsedAssocReq[sta_ds->assocId]) {
 		uint8_t *assoc_req_frame;

+ 314 - 270
core/mac/src/pe/lim/lim_process_assoc_req_frame.c

@@ -221,7 +221,7 @@ static bool lim_chk_sa_da(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr,
 
 	pe_err("Assoc Req rejected: wlan.sa = wlan.da");
 	lim_send_assoc_rsp_mgmt_frame(mac_ctx, eSIR_MAC_UNSPEC_FAILURE_STATUS,
-				      1, hdr->sa, sub_type, 0, session);
+				      1, hdr->sa, sub_type, 0, session, false);
 	return false;
 }
 
@@ -248,7 +248,7 @@ static bool lim_chk_tkip(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr,
 
 	pe_err("Assoc Req rejected: TKIP counter measure is active");
 	lim_send_assoc_rsp_mgmt_frame(mac_ctx, eSIR_MAC_MIC_FAILURE_REASON, 1,
-				      hdr->sa, sub_type, 0, session);
+				      hdr->sa, sub_type, 0, session, false);
 	return false;
 }
 
@@ -289,7 +289,7 @@ static bool lim_chk_assoc_req_parse_error(struct mac_context *mac_ctx,
 	pe_warn("Assoc Req rejected: frame parsing error. source addr:"
 			QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(hdr->sa));
 	lim_send_assoc_rsp_mgmt_frame(mac_ctx, eSIR_MAC_UNSPEC_FAILURE_STATUS,
-				      1, hdr->sa, sub_type, 0, session);
+				      1, hdr->sa, sub_type, 0, session, false);
 	return false;
 }
 
@@ -331,9 +331,9 @@ static bool lim_chk_capab(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr,
 		 * local capabilities. Respond with 'unsupported capabilities'
 		 * status code.
 		 */
-		lim_send_assoc_rsp_mgmt_frame(mac_ctx,
-			eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
-			1, hdr->sa, sub_type, 0, session);
+		lim_send_assoc_rsp_mgmt_frame(
+			mac_ctx, eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
+			1, hdr->sa, sub_type, 0, session, false);
 		return false;
 	}
 	return true;
@@ -371,7 +371,7 @@ static bool lim_chk_ssid(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr,
 	 * status code.
 	 */
 	lim_send_assoc_rsp_mgmt_frame(mac_ctx, eSIR_MAC_UNSPEC_FAILURE_STATUS,
-				      1, hdr->sa, sub_type, 0, session);
+				      1, hdr->sa, sub_type, 0, session, false);
 	return false;
 }
 
@@ -423,9 +423,9 @@ static bool lim_chk_rates(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr,
 	 * Requesting STA does not support ALL BSS basic rates. Respond with
 	 * 'basic rates not supported' status code.
 	 */
-	lim_send_assoc_rsp_mgmt_frame(mac_ctx,
-				eSIR_MAC_BASIC_RATES_NOT_SUPPORTED_STATUS, 1,
-				hdr->sa, sub_type, 0, session);
+	lim_send_assoc_rsp_mgmt_frame(
+			mac_ctx, eSIR_MAC_BASIC_RATES_NOT_SUPPORTED_STATUS, 1,
+			hdr->sa, sub_type, 0, session, false);
 	return false;
 }
 
@@ -451,9 +451,9 @@ static bool lim_chk_11g_only(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr,
 		pe_err("SOFTAP was in 11G only mode, rejecting legacy STA: "
 				QDF_MAC_ADDR_STR,
 			QDF_MAC_ADDR_ARRAY(hdr->sa));
-		lim_send_assoc_rsp_mgmt_frame(mac_ctx,
-				eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
-				1, hdr->sa, sub_type, 0, session);
+		lim_send_assoc_rsp_mgmt_frame(
+			mac_ctx, eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
+			1, hdr->sa, sub_type, 0, session, false);
 		return false;
 	}
 	return true;
@@ -481,9 +481,9 @@ static bool lim_chk_11n_only(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr,
 		pe_err("SOFTAP was in 11N only mode, rejecting legacy STA: "
 				QDF_MAC_ADDR_STR,
 			QDF_MAC_ADDR_ARRAY(hdr->sa));
-		lim_send_assoc_rsp_mgmt_frame(mac_ctx,
-			eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
-			1, hdr->sa, sub_type, 0, session);
+		lim_send_assoc_rsp_mgmt_frame(
+			mac_ctx, eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
+			1, hdr->sa, sub_type, 0, session, false);
 		return false;
 	}
 	return true;
@@ -518,9 +518,9 @@ static bool lim_chk_11ac_only(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr,
 	if (LIM_IS_AP_ROLE(session) &&
 		(session->dot11mode == MLME_DOT11_MODE_11AC_ONLY) &&
 		((!vht_caps) || ((vht_caps) && (!vht_caps->present)))) {
-		lim_send_assoc_rsp_mgmt_frame(mac_ctx,
-			eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
-			1, hdr->sa, sub_type, 0, session);
+		lim_send_assoc_rsp_mgmt_frame(
+			mac_ctx, eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
+			1, hdr->sa, sub_type, 0, session, false);
 		pe_err("SOFTAP was in 11AC only mode, reject");
 		return false;
 	}
@@ -547,9 +547,9 @@ static bool lim_chk_11ax_only(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr,
 	if (LIM_IS_AP_ROLE(session) &&
 		(session->dot11mode == MLME_DOT11_MODE_11AX_ONLY) &&
 		 !assoc_req->he_cap.present) {
-		lim_send_assoc_rsp_mgmt_frame(mac_ctx,
-			eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
-			1, hdr->sa, sub_type, 0, session);
+		lim_send_assoc_rsp_mgmt_frame(
+			mac_ctx, eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
+			1, hdr->sa, sub_type, 0, session, false);
 		pe_err("SOFTAP was in 11AX only mode, reject");
 		return false;
 	}
@@ -585,9 +585,10 @@ static bool lim_check_11ax_basic_mcs(struct mac_context *mac_ctx,
 		(uint16_t)mac_ctx->mlme_cfg->he_caps.he_ops_basic_mcs_nss;
 		final_mcs = HE_INTERSECT_MCS(sta_mcs, basic_mcs);
 		if (final_mcs != basic_mcs) {
-			lim_send_assoc_rsp_mgmt_frame(mac_ctx,
+			lim_send_assoc_rsp_mgmt_frame(
+				mac_ctx,
 				eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
-				1, hdr->sa, sub_type, 0, session);
+				1, hdr->sa, sub_type, 0, session, false);
 			pe_err("STA did not support basic MCS required by SAP");
 			return false;
 		}
@@ -728,9 +729,9 @@ static bool lim_chk_mcs(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr,
 		 * rates. Spec does not define any status code for this
 		 * scenario.
 		 */
-		lim_send_assoc_rsp_mgmt_frame(mac_ctx,
-					eSIR_MAC_OUTSIDE_SCOPE_OF_SPEC_STATUS,
-					1, hdr->sa, sub_type, 0, session);
+		lim_send_assoc_rsp_mgmt_frame(
+			mac_ctx, eSIR_MAC_OUTSIDE_SCOPE_OF_SPEC_STATUS,
+			1, hdr->sa, sub_type, 0, session, false);
 		return false;
 	}
 	return true;
@@ -765,9 +766,10 @@ static bool lim_chk_is_11b_sta_supported(struct mac_context *mac_ctx,
 			 * only policy option is set. Reject with unspecified
 			 * status code.
 			 */
-			lim_send_assoc_rsp_mgmt_frame(mac_ctx,
+			lim_send_assoc_rsp_mgmt_frame(
+				mac_ctx,
 				eSIR_MAC_BASIC_RATES_NOT_SUPPORTED_STATUS,
-				1, hdr->sa, sub_type, 0, session);
+				1, hdr->sa, sub_type, 0, session, false);
 
 			pe_warn("Rejecting Re/Assoc req from 11b STA:");
 			lim_print_mac_addr(mac_ctx, hdr->sa, LOGW);
@@ -990,9 +992,9 @@ static bool lim_check_wpa_rsn_ie(struct pe_session *session,
 			 * rcvd Assoc req frame with RSN IE but
 			 * length is zero
 			 */
-			lim_send_assoc_rsp_mgmt_frame(mac_ctx,
-				eSIR_MAC_INVALID_IE_STATUS, 1,
-				hdr->sa, sub_type, 0, session);
+			lim_send_assoc_rsp_mgmt_frame(
+				mac_ctx, eSIR_MAC_INVALID_IE_STATUS, 1,
+				hdr->sa, sub_type, 0, session, false);
 			return false;
 		}
 
@@ -1005,7 +1007,7 @@ static bool lim_check_wpa_rsn_ie(struct pe_session *session,
 			pe_err("Invalid RSN IE");
 			lim_send_assoc_rsp_mgmt_frame(
 				mac_ctx, eSIR_MAC_INVALID_IE_STATUS, 1,
-				hdr->sa, sub_type, 0, session);
+				hdr->sa, sub_type, 0, session, false);
 			return false;
 		}
 
@@ -1020,9 +1022,9 @@ static bool lim_check_wpa_rsn_ie(struct pe_session *session,
 					QDF_MAC_ADDR_STR,
 					QDF_MAC_ADDR_ARRAY(hdr->sa));
 
-				lim_send_assoc_rsp_mgmt_frame(mac_ctx, status,
-							 1, hdr->sa, sub_type,
-							 0, session);
+				lim_send_assoc_rsp_mgmt_frame(
+					mac_ctx, status, 1, hdr->sa, sub_type,
+					0, session, false);
 				return false;
 			}
 		} else {
@@ -1032,9 +1034,10 @@ static bool lim_check_wpa_rsn_ie(struct pe_session *session,
 			 * rcvd Assoc req frame with RSN IE but
 			 * IE version is wrong
 			 */
-			lim_send_assoc_rsp_mgmt_frame(mac_ctx,
+			lim_send_assoc_rsp_mgmt_frame(
+				mac_ctx,
 				eSIR_MAC_UNSUPPORTED_RSN_IE_VERSION_STATUS,
-				1, hdr->sa, sub_type, 0, session);
+				1, hdr->sa, sub_type, 0, session, false);
 			return false;
 		}
 		*akm_type = lim_translate_rsn_oui_to_akm_type(
@@ -1048,7 +1051,7 @@ static bool lim_check_wpa_rsn_ie(struct pe_session *session,
 				QDF_MAC_ADDR_ARRAY(hdr->sa));
 			lim_send_assoc_rsp_mgmt_frame(mac_ctx, status,
 						      1, hdr->sa, sub_type,
-						      0, session);
+						      0, session, false);
 			return false;
 		}
 
@@ -1059,9 +1062,9 @@ static bool lim_check_wpa_rsn_ie(struct pe_session *session,
 				QDF_MAC_ADDR_ARRAY(hdr->sa));
 
 			/* rcvd Assoc req frame with invalid WPA IE length */
-			lim_send_assoc_rsp_mgmt_frame(mac_ctx,
-				eSIR_MAC_INVALID_IE_STATUS, 1,
-				hdr->sa, sub_type, 0, session);
+			lim_send_assoc_rsp_mgmt_frame(
+				mac_ctx, eSIR_MAC_INVALID_IE_STATUS, 1,
+				hdr->sa, sub_type, 0, session, false);
 			return false;
 		}
 		/* Unpack the WPA IE */
@@ -1073,7 +1076,7 @@ static bool lim_check_wpa_rsn_ie(struct pe_session *session,
 			pe_err("Invalid WPA IE");
 			lim_send_assoc_rsp_mgmt_frame(
 				mac_ctx, eSIR_MAC_INVALID_IE_STATUS, 1,
-				hdr->sa, sub_type, 0, session);
+				hdr->sa, sub_type, 0, session, false);
 			return false;
 		}
 
@@ -1088,8 +1091,9 @@ static bool lim_check_wpa_rsn_ie(struct pe_session *session,
 			 * rcvd Assoc req frame with WPA IE
 			 * but there is mismatch
 			 */
-			lim_send_assoc_rsp_mgmt_frame(mac_ctx, status, 1,
-					hdr->sa, sub_type, 0, session);
+			lim_send_assoc_rsp_mgmt_frame(
+					mac_ctx, status, 1,
+					hdr->sa, sub_type, 0, session, false);
 			return false;
 		}
 		*akm_type = lim_translate_rsn_oui_to_akm_type(
@@ -1280,9 +1284,9 @@ static bool lim_process_assoc_req_sta_ctx(struct mac_context *mac_ctx,
 			 * query procedure we will end up using the stale value.
 			 */
 			sta_ds->pmfSaQueryRetryCount = 0;
-			lim_send_assoc_rsp_mgmt_frame(mac_ctx,
-					eSIR_MAC_TRY_AGAIN_LATER, 1, hdr->sa,
-					sub_type, sta_ds, session);
+			lim_send_assoc_rsp_mgmt_frame(
+				mac_ctx, eSIR_MAC_TRY_AGAIN_LATER, 1, hdr->sa,
+				sub_type, sta_ds, session, false);
 			lim_send_sa_query_request_frame(mac_ctx,
 				(uint8_t *) &(sta_ds->pmfSaQueryCurrentTransId),
 				hdr->sa, session);
@@ -1303,9 +1307,9 @@ static bool lim_process_assoc_req_sta_ctx(struct mac_context *mac_ctx,
 		 * Request with try again later
 		 */
 		case DPH_SA_QUERY_IN_PROGRESS:
-			lim_send_assoc_rsp_mgmt_frame(mac_ctx,
-						eSIR_MAC_TRY_AGAIN_LATER, 1,
-						hdr->sa, sub_type, 0, session);
+			lim_send_assoc_rsp_mgmt_frame(
+				mac_ctx, eSIR_MAC_TRY_AGAIN_LATER, 1,
+				hdr->sa, sub_type, 0, session, false);
 			return false;
 
 		/*
@@ -1389,9 +1393,11 @@ static bool lim_chk_wmm(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr,
 				0, false, NULL, &tspecIdx, session) !=
 					QDF_STATUS_SUCCESS) {
 				pe_warn("AdmitControl: TSPEC rejected");
-				lim_send_assoc_rsp_mgmt_frame(mac_ctx,
+				lim_send_assoc_rsp_mgmt_frame(
+					mac_ctx,
 					eSIR_MAC_QAP_NO_BANDWIDTH_REASON,
-					1, hdr->sa, sub_type, 0, session);
+					1, hdr->sa, sub_type, 0, session,
+					false);
 #ifdef WLAN_DEBUG
 				mac_ctx->lim.gLimNumAssocReqDropACRejectTS++;
 #endif
@@ -1400,9 +1406,9 @@ static bool lim_chk_wmm(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr,
 		} else if (lim_admit_control_add_sta(mac_ctx, hdr->sa, false)
 				!= QDF_STATUS_SUCCESS) {
 			pe_warn("AdmitControl: Sta rejected");
-			lim_send_assoc_rsp_mgmt_frame(mac_ctx,
-				eSIR_MAC_QAP_NO_BANDWIDTH_REASON, 1,
-				hdr->sa, sub_type, 0, session);
+			lim_send_assoc_rsp_mgmt_frame(
+				mac_ctx, eSIR_MAC_QAP_NO_BANDWIDTH_REASON, 1,
+				hdr->sa, sub_type, 0, session, false);
 #ifdef WLAN_DEBUG
 			mac_ctx->lim.gLimNumAssocReqDropACRejectSta++;
 #endif
@@ -2214,10 +2220,10 @@ void lim_process_assoc_req_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_in
 			 * some STA doesn't like 4way handshake after reassoc
 			 * where some STA does expect 4-way handshake.
 			 */
-			lim_send_assoc_rsp_mgmt_frame(mac_ctx,
-					eSIR_MAC_OUTSIDE_SCOPE_OF_SPEC_STATUS,
-					sta_ds->assocId, sta_ds->staAddr,
-					sub_type, sta_ds, session);
+			lim_send_assoc_rsp_mgmt_frame(
+				mac_ctx, eSIR_MAC_OUTSIDE_SCOPE_OF_SPEC_STATUS,
+				sta_ds->assocId, sta_ds->staAddr,
+				sub_type, sta_ds, session, false);
 			pe_err("Rejecting reassoc req from STA");
 			return;
 		} else if (!sta_ds->rmfEnabled) {
@@ -2226,10 +2232,11 @@ void lim_process_assoc_req_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_in
 			 * STA might have missed the assoc response, so it is
 			 * sending assoc request frame again.
 			 */
-			lim_send_assoc_rsp_mgmt_frame(mac_ctx, QDF_STATUS_SUCCESS,
-					sta_ds->assocId, sta_ds->staAddr,
-					sub_type,
-					sta_ds, session);
+			lim_send_assoc_rsp_mgmt_frame(
+				mac_ctx, QDF_STATUS_SUCCESS,
+				sta_ds->assocId, sta_ds->staAddr,
+				sub_type,
+				sta_ds, session, false);
 			pe_err("DUT already received an assoc request frame and STA is sending another assoc req.So, do not Process sessionid: %d sys sub_type: %d for role: %d from: "
 					QDF_MAC_ADDR_STR,
 				session->peSessionId, sub_type,
@@ -2250,10 +2257,10 @@ void lim_process_assoc_req_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_in
 		 * other vdev.
 		 */
 		lim_send_assoc_rsp_mgmt_frame(
-				mac_ctx,
-				eSIR_MAC_UNSPEC_FAILURE_STATUS,
-				1, hdr->sa,
-				sub_type, 0, session);
+			mac_ctx,
+			eSIR_MAC_UNSPEC_FAILURE_STATUS,
+			1, hdr->sa,
+			sub_type, 0, session, false);
 		return;
 	}
 
@@ -2296,9 +2303,9 @@ void lim_process_assoc_req_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_in
 				 frame_len - LIM_ASSOC_REQ_IE_OFFSET)) {
 			pe_err("Vendor ie not present and access policy is %x, Rejected association",
 				session->access_policy);
-			lim_send_assoc_rsp_mgmt_frame(mac_ctx,
-				eSIR_MAC_UNSPEC_FAILURE_STATUS, 1, hdr->sa,
-				sub_type, 0, session);
+			lim_send_assoc_rsp_mgmt_frame(
+				mac_ctx, eSIR_MAC_UNSPEC_FAILURE_STATUS,
+				1, hdr->sa, sub_type, 0, session, false);
 			return;
 		}
 	}
@@ -2456,6 +2463,13 @@ static void lim_fill_assoc_ind_wapi_info(struct mac_context *mac_ctx,
 	}
 	return;
 }
+#else
+static void lim_fill_assoc_ind_wapi_info(
+	struct mac_context *mac_ctx,
+	tpSirAssocReq assoc_req, tpLimMlmAssocInd assoc_ind,
+	const uint8_t *wpsie)
+{
+}
 #endif
 
 /**
@@ -2591,6 +2605,224 @@ static void fill_mlm_assoc_ind_vht(tpSirAssocReq assocreq,
 	}
 }
 
+bool lim_fill_lim_assoc_ind_params(
+		tpLimMlmAssocInd assoc_ind,
+		struct mac_context *mac_ctx,
+		tpDphHashNode sta_ds,
+		struct pe_session *session_entry)
+{
+	tpSirAssocReq assoc_req;
+	uint16_t rsn_len;
+	uint32_t phy_mode;
+	const uint8_t *wpsie = NULL;
+	uint8_t maxidx, i;
+	bool wme_enable;
+
+	if (!session_entry->parsedAssocReq) {
+		pe_err(" Parsed Assoc req is NULL");
+		return false;
+	}
+
+	/* Get a copy of the already parsed Assoc Request */
+	assoc_req =
+		(tpSirAssocReq)session_entry->parsedAssocReq[sta_ds->assocId];
+
+	if (!assoc_req) {
+		pe_err("assoc req for assoc_id:%d is NULL", sta_ds->assocId);
+		return false;
+	}
+
+	/* Get the phy_mode */
+	lim_get_phy_mode(mac_ctx, &phy_mode, session_entry);
+
+	qdf_mem_copy((uint8_t *)assoc_ind->peerMacAddr,
+		     (uint8_t *)sta_ds->staAddr, sizeof(tSirMacAddr));
+	assoc_ind->aid = sta_ds->assocId;
+	qdf_mem_copy((uint8_t *)&assoc_ind->ssId,
+		     (uint8_t *)&assoc_req->ssId,
+		     assoc_req->ssId.length + 1);
+	assoc_ind->sessionId = session_entry->peSessionId;
+	assoc_ind->authType = sta_ds->mlmStaContext.authType;
+	assoc_ind->akm_type = sta_ds->mlmStaContext.akm_type;
+	assoc_ind->capabilityInfo = assoc_req->capabilityInfo;
+
+	/* Fill in RSN IE information */
+	assoc_ind->rsnIE.length = 0;
+	/* if WPS IE is present, ignore RSN IE */
+	if (assoc_req->addIEPresent && assoc_req->addIE.length) {
+		wpsie = limGetWscIEPtr(
+			mac_ctx,
+			assoc_req->addIE.addIEdata,
+			assoc_req->addIE.length);
+	}
+	if (assoc_req->rsnPresent && !wpsie) {
+		pe_debug("Assoc Req RSN IE len: %d",
+			 assoc_req->rsn.length);
+		assoc_ind->rsnIE.length = 2 + assoc_req->rsn.length;
+		assoc_ind->rsnIE.rsnIEdata[0] = WLAN_ELEMID_RSN;
+		assoc_ind->rsnIE.rsnIEdata[1] =
+			assoc_req->rsn.length;
+		qdf_mem_copy(
+			&assoc_ind->rsnIE.rsnIEdata[2],
+			assoc_req->rsn.info,
+			assoc_req->rsn.length);
+	}
+	/* Fill in 802.11h related info */
+	if (assoc_req->powerCapabilityPresent &&
+	    assoc_req->supportedChannelsPresent) {
+		assoc_ind->spectrumMgtIndicator = true;
+		assoc_ind->powerCap.minTxPower =
+			assoc_req->powerCapability.minTxPower;
+		assoc_ind->powerCap.maxTxPower =
+			assoc_req->powerCapability.maxTxPower;
+		lim_convert_supported_channels(
+			mac_ctx, assoc_ind,
+			assoc_req);
+	} else {
+		assoc_ind->spectrumMgtIndicator = false;
+	}
+
+	/* This check is to avoid extra Sec IEs present incase of WPS */
+	if (assoc_req->wpaPresent && !wpsie) {
+		rsn_len = assoc_ind->rsnIE.length;
+		if ((rsn_len + assoc_req->wpa.length)
+		    >= WLAN_MAX_IE_LEN) {
+			pe_err("rsnIEdata index out of bounds: %d",
+			       rsn_len);
+			return false;
+		}
+		assoc_ind->rsnIE.rsnIEdata[rsn_len] =
+			SIR_MAC_WPA_EID;
+		assoc_ind->rsnIE.rsnIEdata[rsn_len + 1]
+			= assoc_req->wpa.length;
+		qdf_mem_copy(
+			&assoc_ind->rsnIE.rsnIEdata[rsn_len + 2],
+			assoc_req->wpa.info, assoc_req->wpa.length);
+		assoc_ind->rsnIE.length += 2 + assoc_req->wpa.length;
+	}
+	lim_fill_assoc_ind_wapi_info(mac_ctx, assoc_req, assoc_ind, wpsie);
+
+	assoc_ind->addIE.length = 0;
+	if (assoc_req->addIEPresent) {
+		qdf_mem_copy(
+			&assoc_ind->addIE.addIEdata,
+			assoc_req->addIE.addIEdata,
+			assoc_req->addIE.length);
+		assoc_ind->addIE.length = assoc_req->addIE.length;
+	}
+	/*
+	 * Add HT Capabilities into addIE for OBSS
+	 * processing in hostapd
+	 */
+	if (assoc_req->HTCaps.present) {
+		qdf_mem_copy(&assoc_ind->ht_caps, &assoc_req->HTCaps,
+			     sizeof(tDot11fIEHTCaps));
+		rsn_len = assoc_ind->addIE.length;
+		if (assoc_ind->addIE.length + DOT11F_IE_HTCAPS_MIN_LEN
+		    + 2 < WLAN_MAX_IE_LEN) {
+			assoc_ind->addIE.addIEdata[rsn_len] =
+				WLAN_ELEMID_HTCAP_ANA;
+			assoc_ind->addIE.addIEdata[rsn_len + 1] =
+				DOT11F_IE_HTCAPS_MIN_LEN;
+			qdf_mem_copy(
+				&assoc_ind->addIE.addIEdata[rsn_len + 2],
+				((uint8_t *)&assoc_req->HTCaps) + 1,
+				DOT11F_IE_HTCAPS_MIN_LEN);
+			assoc_ind->addIE.length +=
+				2 + DOT11F_IE_HTCAPS_MIN_LEN;
+		} else {
+			pe_err("Fail:HT capabilities IE to addIE");
+		}
+	}
+
+	if (assoc_req->wmeInfoPresent) {
+		/* Set whether AP is enabled with WMM or not */
+		wme_enable = mac_ctx->mlme_cfg->wmm_params.wme_enabled;
+		assoc_ind->WmmStaInfoPresent = wme_enable;
+		/*
+		 * Note: we are not rejecting association here
+		 * because IOT will fail
+		 */
+	}
+	/* 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 =
+		session_entry->curr_op_freq;
+	assoc_ind->chan_info.band_center_freq2 = 0;
+	assoc_ind->chan_info.reg_info_1 =
+		(session_entry->maxTxPower << 16);
+	assoc_ind->chan_info.reg_info_2 =
+		(session_entry->maxTxPower << 8);
+	assoc_ind->chan_info.nss = sta_ds->nss;
+	assoc_ind->chan_info.rate_flags =
+		lim_get_max_rate_flags(mac_ctx, sta_ds);
+	assoc_ind->ampdu = false;
+	assoc_ind->sgi_enable = false;
+	assoc_ind->tx_stbc = false;
+	assoc_ind->rx_stbc = false;
+	assoc_ind->ch_width = eHT_CHANNEL_WIDTH_20MHZ;
+	assoc_ind->mode = SIR_SME_PHY_MODE_LEGACY;
+	assoc_ind->max_supp_idx = 0xff;
+	assoc_ind->max_ext_idx = 0xff;
+	assoc_ind->max_mcs_idx = 0xff;
+	assoc_ind->rx_mcs_map = 0xff;
+	assoc_ind->tx_mcs_map = 0xff;
+
+	if (assoc_req->supportedRates.numRates)
+		assoc_ind->max_supp_idx =
+			lim_get_max_rate_idx(&assoc_req->supportedRates);
+	if (assoc_req->extendedRates.numRates)
+		assoc_ind->max_ext_idx =
+			lim_get_max_rate_idx(&assoc_req->extendedRates);
+
+	if (sta_ds->mlmStaContext.htCapability) {
+		/* ampdu */
+		assoc_ind->ampdu = true;
+
+		/* sgi */
+		if (sta_ds->htShortGI20Mhz || sta_ds->htShortGI40Mhz)
+			assoc_ind->sgi_enable = true;
+
+		/* stbc */
+		assoc_ind->tx_stbc = assoc_req->HTCaps.txSTBC;
+		assoc_ind->rx_stbc = assoc_req->HTCaps.rxSTBC;
+
+		/* ch width */
+		assoc_ind->ch_width =
+			sta_ds->htSupportedChannelWidthSet ?
+			eHT_CHANNEL_WIDTH_40MHZ :
+			eHT_CHANNEL_WIDTH_20MHZ;
+		/* mode */
+		assoc_ind->mode = SIR_SME_PHY_MODE_HT;
+		maxidx = 0;
+		for (i = 0; i < 8; i++) {
+			if (assoc_req->HTCaps.supportedMCSSet[0] &
+			    (1 << i))
+				maxidx = i;
+		}
+		assoc_ind->max_mcs_idx = maxidx;
+	}
+	fill_mlm_assoc_ind_vht(assoc_req, sta_ds, assoc_ind);
+	if (assoc_req->ExtCap.present)
+		assoc_ind->ecsa_capable =
+		((struct s_ext_cap *)assoc_req->ExtCap.bytes)->ext_chan_switch;
+	/* updates VHT information in assoc indication */
+	 qdf_mem_copy(&assoc_ind->vht_caps, &assoc_req->VHTCaps,
+		      sizeof(tDot11fIEVHTCaps));
+	lim_fill_assoc_ind_vht_info(mac_ctx, session_entry, assoc_req,
+				    assoc_ind, sta_ds);
+	assoc_ind->he_caps_present = assoc_req->he_cap.present;
+	assoc_ind->is_sae_authenticated =
+				assoc_req->is_sae_authenticated;
+
+	return true;
+}
+
 /**
  * lim_send_mlm_assoc_ind() - Sends assoc indication to SME
  * @mac_ctx: Global Mac context
@@ -2605,14 +2837,11 @@ static void fill_mlm_assoc_ind_vht(tpSirAssocReq assocreq,
 void lim_send_mlm_assoc_ind(struct mac_context *mac_ctx,
 	tpDphHashNode sta_ds, struct pe_session *session_entry)
 {
-	tpLimMlmAssocInd assoc_ind = NULL;
+	tpLimMlmAssocInd assoc_ind;
 	tpSirAssocReq assoc_req;
-	uint16_t temp, rsn_len;
+	uint16_t temp;
 	uint32_t phy_mode;
 	uint8_t sub_type;
-	const uint8_t *wpsie = NULL;
-	uint8_t maxidx, i;
-	bool wme_enable;
 
 	if (!session_entry->parsedAssocReq) {
 		pe_err(" Parsed Assoc req is NULL");
@@ -2639,8 +2868,8 @@ void lim_send_mlm_assoc_ind(struct mac_context *mac_ctx,
 
 	pe_debug("Sessionid: %d ssid: %s sub_type: %d Associd: %d staAddr: "
 		 QDF_MAC_ADDR_STR, session_entry->peSessionId,
-		assoc_req->ssId.ssId, sub_type, sta_ds->assocId,
-		QDF_MAC_ADDR_ARRAY(sta_ds->staAddr));
+		 assoc_req->ssId.ssId, sub_type, sta_ds->assocId,
+		 QDF_MAC_ADDR_ARRAY(sta_ds->staAddr));
 
 	if (sub_type == LIM_ASSOC || sub_type == LIM_REASSOC) {
 		temp = sizeof(tLimMlmAssocInd);
@@ -2648,203 +2877,18 @@ void lim_send_mlm_assoc_ind(struct mac_context *mac_ctx,
 		assoc_ind = qdf_mem_malloc(temp);
 		if (!assoc_ind) {
 			lim_release_peer_idx(mac_ctx, sta_ds->assocId,
-				session_entry);
+					     session_entry);
 			return;
 		}
-		qdf_mem_copy((uint8_t *) assoc_ind->peerMacAddr,
-			(uint8_t *) sta_ds->staAddr, sizeof(tSirMacAddr));
-		assoc_ind->aid = sta_ds->assocId;
-		qdf_mem_copy((uint8_t *) &assoc_ind->ssId,
-			(uint8_t *) &(assoc_req->ssId),
-			assoc_req->ssId.length + 1);
-		assoc_ind->sessionId = session_entry->peSessionId;
-		assoc_ind->authType = sta_ds->mlmStaContext.authType;
-		assoc_ind->akm_type = sta_ds->mlmStaContext.akm_type;
-		assoc_ind->capabilityInfo = assoc_req->capabilityInfo;
-
-		/* Fill in RSN IE information */
-		assoc_ind->rsnIE.length = 0;
-		/* if WPS IE is present, ignore RSN IE */
-		if (assoc_req->addIEPresent && assoc_req->addIE.length) {
-			wpsie = limGetWscIEPtr(mac_ctx,
-				assoc_req->addIE.addIEdata,
-				assoc_req->addIE.length);
-		}
-		if (assoc_req->rsnPresent && (!wpsie)) {
-			pe_debug("Assoc Req RSN IE len: %d",
-				assoc_req->rsn.length);
-			assoc_ind->rsnIE.length = 2 + assoc_req->rsn.length;
-			assoc_ind->rsnIE.rsnIEdata[0] = WLAN_ELEMID_RSN;
-			assoc_ind->rsnIE.rsnIEdata[1] =
-				assoc_req->rsn.length;
-			qdf_mem_copy(&assoc_ind->rsnIE.rsnIEdata[2],
-				assoc_req->rsn.info,
-				assoc_req->rsn.length);
-		}
-		/* Fill in 802.11h related info */
-		if (assoc_req->powerCapabilityPresent
-			&& assoc_req->supportedChannelsPresent) {
-			assoc_ind->spectrumMgtIndicator = true;
-			assoc_ind->powerCap.minTxPower =
-				assoc_req->powerCapability.minTxPower;
-			assoc_ind->powerCap.maxTxPower =
-				assoc_req->powerCapability.maxTxPower;
-			lim_convert_supported_channels(mac_ctx, assoc_ind,
-				 assoc_req);
-		} else {
-			assoc_ind->spectrumMgtIndicator = false;
-		}
-
-		/* This check is to avoid extra Sec IEs present incase of WPS */
-		if (assoc_req->wpaPresent && (!wpsie)) {
-			rsn_len = assoc_ind->rsnIE.length;
-			if ((rsn_len + assoc_req->wpa.length)
-				>= WLAN_MAX_IE_LEN) {
-				pe_err("rsnIEdata index out of bounds: %d",
-					rsn_len);
-				qdf_mem_free(assoc_ind);
-				return;
-			}
-			assoc_ind->rsnIE.rsnIEdata[rsn_len] =
-				SIR_MAC_WPA_EID;
-			assoc_ind->rsnIE.rsnIEdata[rsn_len + 1]
-				= assoc_req->wpa.length;
-			qdf_mem_copy(
-				&assoc_ind->rsnIE.rsnIEdata[rsn_len + 2],
-				assoc_req->wpa.info, assoc_req->wpa.length);
-			assoc_ind->rsnIE.length += 2 + assoc_req->wpa.length;
-		}
-#ifdef FEATURE_WLAN_WAPI
-		lim_fill_assoc_ind_wapi_info(mac_ctx, assoc_req, assoc_ind,
-			wpsie);
-#endif
-
-		assoc_ind->addIE.length = 0;
-		if (assoc_req->addIEPresent) {
-			qdf_mem_copy(&assoc_ind->addIE.addIEdata,
-				assoc_req->addIE.addIEdata,
-				assoc_req->addIE.length);
-			assoc_ind->addIE.length = assoc_req->addIE.length;
-		}
-		/*
-		 * Add HT Capabilities into addIE for OBSS
-		 * processing in hostapd
-		 */
-		if (assoc_req->HTCaps.present) {
-			qdf_mem_copy(&assoc_ind->ht_caps, &assoc_req->HTCaps,
-				     sizeof(tDot11fIEHTCaps));
-
-			rsn_len = assoc_ind->addIE.length;
-			if (assoc_ind->addIE.length + DOT11F_IE_HTCAPS_MIN_LEN
-				+ 2 < WLAN_MAX_IE_LEN) {
-				assoc_ind->addIE.addIEdata[rsn_len] =
-					WLAN_ELEMID_HTCAP_ANA;
-				assoc_ind->addIE.addIEdata[rsn_len + 1] =
-					DOT11F_IE_HTCAPS_MIN_LEN;
-				qdf_mem_copy(
-					&assoc_ind->addIE.addIEdata[rsn_len+2],
-					((uint8_t *)&assoc_req->HTCaps) + 1,
-					DOT11F_IE_HTCAPS_MIN_LEN);
-				assoc_ind->addIE.length +=
-					2 + DOT11F_IE_HTCAPS_MIN_LEN;
-			} else {
-				pe_err("Fail:HT capabilities IE to addIE");
-			}
-		}
-
-		if (assoc_req->wmeInfoPresent) {
-			/* Set whether AP is enabled with WMM or not */
-			wme_enable = mac_ctx->mlme_cfg->wmm_params.wme_enabled;
-			assoc_ind->WmmStaInfoPresent = wme_enable;
-			/*
-			 * Note: we are not rejecting association here
-			 * because IOT will fail
-			 */
-		}
-		/* 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 =
-			session_entry->curr_op_freq;
-		assoc_ind->chan_info.band_center_freq2 = 0;
-		assoc_ind->chan_info.reg_info_1 =
-			(session_entry->maxTxPower << 16);
-		assoc_ind->chan_info.reg_info_2 =
-			(session_entry->maxTxPower << 8);
-		assoc_ind->chan_info.nss = sta_ds->nss;
-		assoc_ind->chan_info.rate_flags =
-			lim_get_max_rate_flags(mac_ctx, sta_ds);
-		assoc_ind->ampdu = false;
-		assoc_ind->sgi_enable = false;
-		assoc_ind->tx_stbc = false;
-		assoc_ind->rx_stbc = false;
-		assoc_ind->ch_width = eHT_CHANNEL_WIDTH_20MHZ;
-		assoc_ind->mode = SIR_SME_PHY_MODE_LEGACY;
-		assoc_ind->max_supp_idx = 0xff;
-		assoc_ind->max_ext_idx = 0xff;
-		assoc_ind->max_mcs_idx = 0xff;
-		assoc_ind->rx_mcs_map = 0xff;
-		assoc_ind->tx_mcs_map = 0xff;
-
-		if (assoc_req->supportedRates.numRates)
-			assoc_ind->max_supp_idx =
-				lim_get_max_rate_idx(
-					&assoc_req->supportedRates);
-		if (assoc_req->extendedRates.numRates)
-			assoc_ind->max_ext_idx =
-				lim_get_max_rate_idx(
-					&assoc_req->extendedRates);
-
-		if (sta_ds->mlmStaContext.htCapability) {
-			/* ampdu */
-			assoc_ind->ampdu = true;
-
-			/* sgi */
-			if (sta_ds->htShortGI20Mhz || sta_ds->htShortGI40Mhz)
-				assoc_ind->sgi_enable = true;
-
-			/* stbc */
-			assoc_ind->tx_stbc = assoc_req->HTCaps.txSTBC;
-			assoc_ind->rx_stbc = assoc_req->HTCaps.rxSTBC;
-
-			/* ch width */
-			assoc_ind->ch_width =
-				sta_ds->htSupportedChannelWidthSet ?
-				eHT_CHANNEL_WIDTH_40MHZ :
-				eHT_CHANNEL_WIDTH_20MHZ;
-
-			/* mode */
-			assoc_ind->mode = SIR_SME_PHY_MODE_HT;
-			maxidx = 0;
-			for (i = 0; i < 8; i++) {
-				if (assoc_req->HTCaps.supportedMCSSet[0] &
-					(1 << i))
-					maxidx = i;
-			}
-			assoc_ind->max_mcs_idx = maxidx;
+		if (!lim_fill_lim_assoc_ind_params(assoc_ind, mac_ctx,
+						   sta_ds, session_entry)) {
+			qdf_mem_free(assoc_ind);
+			return;
 		}
-		fill_mlm_assoc_ind_vht(assoc_req, sta_ds, assoc_ind);
-		if (assoc_req->ExtCap.present)
-			assoc_ind->ecsa_capable =
-			((struct s_ext_cap *)assoc_req->ExtCap.bytes)->
-			ext_chan_switch;
-
-		/* updates VHT information in assoc indication */
-		 qdf_mem_copy(&assoc_ind->vht_caps, &assoc_req->VHTCaps,
-			      sizeof(tDot11fIEVHTCaps));
-		lim_fill_assoc_ind_vht_info(mac_ctx, session_entry, assoc_req,
-					    assoc_ind, sta_ds);
-		assoc_ind->he_caps_present = assoc_req->he_cap.present;
-		assoc_ind->is_sae_authenticated =
-					assoc_req->is_sae_authenticated;
 		lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_IND,
-			 (uint32_t *) assoc_ind);
+				     (uint32_t *)assoc_ind);
 		qdf_mem_free(assoc_ind);
 	}
+
 	return;
 }

+ 6 - 18
core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c

@@ -640,21 +640,9 @@ void lim_process_mlm_assoc_cnf(struct mac_context *mac_ctx,
 	}
 }
 
-/**
- * lim_fill_assoc_ind_params() - Initialize association indication
- * mac_ctx: Pointer to Global MAC structure
- * assoc_ind: PE association indication structure
- * sme_assoc_ind: SME association indication
- * session_entry: PE session entry
- *
- * This function is called to initialzie the association
- * indication strucutre to process association indication.
- *
- * Return: None
- */
-
-static void
-lim_fill_assoc_ind_params(struct mac_context *mac_ctx,
+void
+lim_fill_sme_assoc_ind_params(
+	struct mac_context *mac_ctx,
 	tpLimMlmAssocInd assoc_ind, struct assoc_ind *sme_assoc_ind,
 	struct pe_session *session_entry)
 {
@@ -775,9 +763,9 @@ void lim_process_mlm_assoc_ind(struct mac_context *mac, uint32_t *msg_buf)
 	}
 
 	pSirSmeAssocInd->messageType = eWNI_SME_ASSOC_IND;
-	lim_fill_assoc_ind_params(mac, (tpLimMlmAssocInd) msg_buf,
-				  pSirSmeAssocInd,
-				  pe_session);
+	lim_fill_sme_assoc_ind_params(mac, (tpLimMlmAssocInd)msg_buf,
+				      pSirSmeAssocInd,
+				      pe_session);
 	msg.type = eWNI_SME_ASSOC_IND;
 	msg.bodyptr = pSirSmeAssocInd;
 	msg.bodyval = 0;

+ 8 - 5
core/mac/src/pe/lim/lim_process_sme_req_messages.c

@@ -3118,12 +3118,14 @@ void __lim_process_sme_assoc_cnf_new(struct mac_context *mac_ctx, uint32_t msg_t
 			eLIM_MLM_LINK_ESTABLISHED_STATE;
 		sta_ds->mlmStaContext.owe_ie = assoc_cnf.owe_ie;
 		sta_ds->mlmStaContext.owe_ie_len = assoc_cnf.owe_ie_len;
-		pe_debug("sending Assoc Rsp frame to STA (assoc id=%d)",
-			sta_ds->assocId);
-		lim_send_assoc_rsp_mgmt_frame(mac_ctx, QDF_STATUS_SUCCESS,
+		pe_debug("sending Assoc Rsp frame to STA assoc id=%d, tx cb %d",
+			 sta_ds->assocId, assoc_cnf.need_assoc_rsp_tx_cb);
+		lim_send_assoc_rsp_mgmt_frame(
+					mac_ctx, QDF_STATUS_SUCCESS,
 					sta_ds->assocId, sta_ds->staAddr,
 					sta_ds->mlmStaContext.subType, sta_ds,
-					session_entry);
+					session_entry,
+					assoc_cnf.need_assoc_rsp_tx_cb);
 		sta_ds->mlmStaContext.owe_ie = NULL;
 		sta_ds->mlmStaContext.owe_ie_len = 0;
 		goto end;
@@ -3160,7 +3162,8 @@ void __lim_process_sme_assoc_cnf_new(struct mac_context *mac_ctx, uint32_t msg_t
 	}
 end:
 	if (((session_entry) && (sta_ds)) &&
-		(session_entry->parsedAssocReq[sta_ds->assocId])) {
+		(session_entry->parsedAssocReq[sta_ds->assocId]) &&
+		!assoc_cnf.need_assoc_rsp_tx_cb) {
 		assoc_req = (tpSirAssocReq)
 			session_entry->parsedAssocReq[sta_ds->assocId];
 		if (assoc_req->assocReqFrame) {

+ 135 - 14
core/mac/src/pe/lim/lim_send_management_frames.c

@@ -1011,24 +1011,135 @@ lim_send_addts_req_action_frame(struct mac_context *mac,
 } /* End lim_send_addts_req_action_frame. */
 
 /**
- * lim_send_assoc_rsp_mgmt_frame() - Send assoc response
- * @mac_ctx: Handle for mac context
- * @status_code: Status code for assoc response frame
- * @aid: Association ID
- * @peer_addr: Mac address of requesting peer
- * @subtype: Assoc/Reassoc
- * @sta: Pointer to station node
- * @pe_session: PE session id.
- *
- * Builds and sends association response frame to the requesting peer.
+ * lim_assoc_rsp_tx_complete() - Confirmation for assoc rsp OTA
+ * @context: pointer to global mac
+ * @buf: buffer which is nothing but entire assoc rsp frame
+ * @tx_complete : Sent status
+ * @params; tx completion params
  *
- * Return: void
+ * Return: This returns QDF_STATUS
  */
+static QDF_STATUS lim_assoc_rsp_tx_complete(
+					void *context,
+					qdf_nbuf_t buf,
+					uint32_t tx_complete,
+					void *params)
+{
+	struct mac_context *mac_ctx = (struct mac_context *)context;
+	tSirMacMgmtHdr *mac_hdr;
+	struct pe_session *session_entry;
+	uint8_t session_id;
+	tpLimMlmAssocInd lim_assoc_ind;
+	tpDphHashNode sta_ds;
+	uint16_t aid;
+	uint8_t *data;
+	struct assoc_ind *sme_assoc_ind;
+	struct scheduler_msg msg;
+	tpSirAssocReq assoc_req;
+
+	if (!buf) {
+		pe_err("Assoc rsp frame buffer is NULL");
+		goto null_buf;
+	}
+
+	data = qdf_nbuf_data(buf);
+
+	if (!data) {
+		pe_err("Assoc rsp frame is NULL");
+		goto end;
+	}
+
+	mac_hdr = (tSirMacMgmtHdr *)data;
+
+	session_entry = pe_find_session_by_bssid(
+				mac_ctx, mac_hdr->sa,
+				&session_id);
+	if (!session_entry) {
+		pe_err("session entry is NULL");
+		goto end;
+	}
+
+	sta_ds = dph_lookup_hash_entry(mac_ctx,
+				       (uint8_t *)mac_hdr->da, &aid,
+				       &session_entry->dph.dphHashTable);
+	if (!sta_ds) {
+		pe_err("sta_ds is NULL");
+		goto end;
+	}
+
+	/* Get a copy of the already parsed Assoc Request */
+	assoc_req =
+		(tpSirAssocReq)session_entry->parsedAssocReq[sta_ds->assocId];
+
+	if (!assoc_req) {
+		pe_err("assoc req for assoc_id:%d is NULL", sta_ds->assocId);
+		goto end;
+	}
+
+	lim_assoc_ind = qdf_mem_malloc(sizeof(tLimMlmAssocInd));
+	if (!lim_assoc_ind) {
+		pe_err("lim assoc ind is NULL");
+		goto free_assoc_req;
+	}
+	if (!lim_fill_lim_assoc_ind_params(lim_assoc_ind, mac_ctx,
+					   sta_ds, session_entry)) {
+		pe_err("lim assoc ind fill error");
+		goto lim_assoc_ind;
+	}
+
+	sme_assoc_ind = qdf_mem_malloc(sizeof(struct assoc_ind));
+	if (!sme_assoc_ind) {
+		pe_err("sme assoc ind is NULL");
+		goto lim_assoc_ind;
+	}
+	sme_assoc_ind->messageType = eWNI_SME_ASSOC_IND_UPPER_LAYER;
+	lim_fill_sme_assoc_ind_params(
+				mac_ctx, lim_assoc_ind,
+				sme_assoc_ind,
+				session_entry);
+
+	qdf_mem_zero(&msg, sizeof(struct scheduler_msg));
+	msg.type = eWNI_SME_ASSOC_IND_UPPER_LAYER;
+	msg.bodyptr = sme_assoc_ind;
+	msg.bodyval = 0;
+	sme_assoc_ind->staId = sta_ds->staIndex;
+	sme_assoc_ind->reassocReq = sta_ds->mlmStaContext.subType;
+	sme_assoc_ind->timingMeasCap = sta_ds->timingMeasCap;
+
+	mac_ctx->lim.sme_msg_callback(mac_ctx, &msg);
+
+	qdf_mem_free(lim_assoc_ind);
+	if (assoc_req->assocReqFrame) {
+		qdf_mem_free(assoc_req->assocReqFrame);
+		assoc_req->assocReqFrame = NULL;
+	}
+	qdf_mem_free(session_entry->parsedAssocReq[sta_ds->assocId]);
+	session_entry->parsedAssocReq[sta_ds->assocId] = NULL;
+	qdf_nbuf_free(buf);
+
+	return QDF_STATUS_SUCCESS;
+
+lim_assoc_ind:
+	qdf_mem_free(lim_assoc_ind);
+free_assoc_req:
+	if (assoc_req->assocReqFrame) {
+		qdf_mem_free(assoc_req->assocReqFrame);
+		assoc_req->assocReqFrame = NULL;
+	}
+	qdf_mem_free(session_entry->parsedAssocReq[sta_ds->assocId]);
+	session_entry->parsedAssocReq[sta_ds->assocId] = NULL;
+end:
+	qdf_nbuf_free(buf);
+null_buf:
+	return QDF_STATUS_E_FAILURE;
+}
 
 void
-lim_send_assoc_rsp_mgmt_frame(struct mac_context *mac_ctx,
+lim_send_assoc_rsp_mgmt_frame(
+	struct mac_context *mac_ctx,
 	uint16_t status_code, uint16_t aid, tSirMacAddr peer_addr,
-	uint8_t subtype, tpDphHashNode sta, struct pe_session *pe_session)
+	uint8_t subtype, tpDphHashNode sta, struct pe_session *pe_session,
+	bool tx_complete)
 {
 	static tDot11fAssocResponse frm;
 	uint8_t *frame;
@@ -1371,7 +1482,17 @@ lim_send_assoc_rsp_mgmt_frame(struct mac_context *mac_ctx,
 	lim_diag_mgmt_tx_event_report(mac_ctx, mac_hdr,
 				      pe_session, QDF_STATUS_SUCCESS, status_code);
 	/* Queue Association Response frame in high priority WQ */
-	qdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) bytes,
+	if (tx_complete)
+		qdf_status = wma_tx_frameWithTxComplete(
+				mac_ctx, packet, (uint16_t)bytes,
+				TXRX_FRM_802_11_MGMT,
+				ANI_TXDIR_TODS,
+				7, lim_tx_complete, frame,
+				lim_assoc_rsp_tx_complete, tx_flag,
+				sme_session, false, 0, RATEID_DEFAULT);
+	else
+		qdf_status = wma_tx_frame(
+				mac_ctx, packet, (uint16_t)bytes,
 				TXRX_FRM_802_11_MGMT,
 				ANI_TXDIR_TODS,
 				7, lim_tx_complete, frame, tx_flag,

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

@@ -404,6 +404,36 @@ QDF_STATUS lim_process_auth_frame_no_session(struct mac_context *mac,
 					     uint8_t *bd, void *body);
 
 void lim_process_assoc_req_frame(struct mac_context *, uint8_t *, uint8_t, struct pe_session *);
+
+/**
+ * lim_fill_lim_assoc_ind_params() - Initialize lim association indication
+ * @assoc_ind: PE association indication structure
+ * @mac_ctx: Pointer to Global MAC structure
+ * @sta_ds: station dph entry
+ * @session_entry: PE session entry
+ *
+ * Return: true if lim assoc ind filled successfully
+ */
+bool lim_fill_lim_assoc_ind_params(
+		tpLimMlmAssocInd assoc_ind,
+		struct mac_context *mac_ctx,
+		tpDphHashNode sta_ds,
+		struct pe_session *session_entry);
+
+/**
+ * lim_fill_sme_assoc_ind_params() - Initialize association indication
+ * @mac_ctx: Pointer to Global MAC structure
+ * @assoc_ind: PE association indication structure
+ * @sme_assoc_ind: SME association indication
+ * @session_entry: PE session entry
+ *
+ * Return: None
+ */
+void
+lim_fill_sme_assoc_ind_params(
+	struct mac_context *mac_ctx,
+	tpLimMlmAssocInd assoc_ind, struct assoc_ind *sme_assoc_ind,
+	struct pe_session *session_entry);
 void lim_send_mlm_assoc_ind(struct mac_context *mac, tpDphHashNode sta,
 			    struct pe_session *pe_session);
 
@@ -565,8 +595,27 @@ void lim_send_delts_req_action_frame(struct mac_context *mac, tSirMacAddr peer,
 void lim_send_addts_req_action_frame(struct mac_context *mac, tSirMacAddr peerMacAddr,
 				     tSirAddtsReqInfo *addts, struct pe_session *);
 
-void lim_send_assoc_rsp_mgmt_frame(struct mac_context *, uint16_t, uint16_t, tSirMacAddr,
-				   uint8_t, tpDphHashNode pSta, struct pe_session *);
+/**
+ * lim_send_assoc_rsp_mgmt_frame() - Send assoc response
+ * @mac_ctx: Handle for mac context
+ * @status_code: Status code for assoc response frame
+ * @aid: Association ID
+ * @peer_addr: Mac address of requesting peer
+ * @subtype: Assoc/Reassoc
+ * @sta: Pointer to station node
+ * @pe_session: PE session id.
+ * @tx_complete: Need tx complete callback or not
+ *
+ * Builds and sends association response frame to the requesting peer.
+ *
+ * Return: void
+ */
+void
+lim_send_assoc_rsp_mgmt_frame(
+	struct mac_context *mac_ctx,
+	uint16_t status_code, uint16_t aid, tSirMacAddr peer_addr,
+	uint8_t subtype, tpDphHashNode sta, struct pe_session *pe_session,
+	bool tx_complete);
 
 void lim_send_disassoc_mgmt_frame(struct mac_context *, uint16_t, tSirMacAddr,
 				  struct pe_session *, bool waitForAck);

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

@@ -302,6 +302,8 @@ char *lim_msg_str(uint32_t msgType)
 		return "eWNI_SME_START_BSS_RSP";
 	case eWNI_SME_ASSOC_IND:
 		return "eWNI_SME_ASSOC_IND";
+	case eWNI_SME_ASSOC_IND_UPPER_LAYER:
+		return "eWNI_SME_ASSOC_IND_UPPER_LAYER";
 	case eWNI_SME_ASSOC_CNF:
 		return "eWNI_SME_ASSOC_CNF";
 	case eWNI_SME_SWITCH_CHL_IND:

+ 1 - 0
core/mac/src/sys/legacy/src/utils/src/mac_trace.c

@@ -245,6 +245,7 @@ uint8_t *mac_trace_get_sme_msg_string(uint16_t sme_msg)
 		CASE_RETURN_STRING(eWNI_SME_DELTS_REQ);
 		CASE_RETURN_STRING(eWNI_SME_DELTS_RSP);
 		CASE_RETURN_STRING(eWNI_SME_DELTS_IND);
+		CASE_RETURN_STRING(eWNI_SME_ASSOC_IND_UPPER_LAYER);
 		CASE_RETURN_STRING(eWNI_SME_WPS_PBC_PROBE_REQ_IND);
 		CASE_RETURN_STRING(eWNI_SME_UPPER_LAYER_ASSOC_CNF);
 		CASE_RETURN_STRING(eWNI_SME_SESSION_UPDATE_PARAM);

+ 27 - 10
core/sme/src/csr/csr_api_roam.c

@@ -11619,6 +11619,26 @@ csr_send_assoc_ind_to_upper_layer_cnf_msg(struct mac_context *mac,
 	return QDF_STATUS_SUCCESS;
 }
 
+static void
+csr_roam_chk_lnk_assoc_ind_upper_layer(
+		struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
+{
+	uint32_t session_id = WLAN_UMAC_VDEV_ID_MAX;
+	struct assoc_ind *assoc_ind;
+	QDF_STATUS status;
+
+	assoc_ind = (struct assoc_ind *)msg_ptr;
+	status = csr_roam_get_session_id_from_bssid(
+			mac_ctx, (struct qdf_mac_addr *)assoc_ind->bssId,
+			&session_id);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		sme_debug("Couldn't find session_id for given BSSID");
+		return;
+	}
+	csr_send_assoc_ind_to_upper_layer_cnf_msg(
+					mac_ctx, assoc_ind, status, session_id);
+}
+
 static void
 csr_roam_chk_lnk_assoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
 {
@@ -11743,19 +11763,12 @@ csr_roam_chk_lnk_assoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
 	}
 
 	if (csr_akm_type != eCSR_AUTH_TYPE_OWE) {
+		if (CSR_IS_INFRA_AP(roam_info->u.pConnectedProfile) &&
+		    roam_info->status_code != eSIR_SME_ASSOC_REFUSED)
+			pAssocInd->need_assoc_rsp_tx_cb = true;
 		/* Send Association completion message to PE */
 		status = csr_send_assoc_cnf_msg(mac_ctx, pAssocInd, status,
 						mac_status_code);
-		/*
-		 * send a message to CSR itself just to avoid the EAPOL frames
-		 * going OTA before association response
-		 */
-		if (CSR_IS_INFRA_AP(roam_info->u.pConnectedProfile) &&
-		    roam_info->status_code != eSIR_SME_ASSOC_REFUSED) {
-			roam_info->fReassocReq = pAssocInd->reassocReq;
-			status = csr_send_assoc_ind_to_upper_layer_cnf_msg(
-					mac_ctx, pAssocInd, status, sessionId);
-		}
 	}
 
 	qdf_mem_free(roam_info);
@@ -12557,6 +12570,9 @@ void csr_roam_check_for_link_status_change(struct mac_context *mac,
 	case eWNI_SME_ASSOC_IND:
 		csr_roam_chk_lnk_assoc_ind(mac, pSirMsg);
 		break;
+	case eWNI_SME_ASSOC_IND_UPPER_LAYER:
+		csr_roam_chk_lnk_assoc_ind_upper_layer(mac, pSirMsg);
+		break;
 	case eWNI_SME_DISASSOC_IND:
 		csr_roam_chk_lnk_disassoc_ind(mac, pSirMsg);
 		break;
@@ -16567,6 +16583,7 @@ QDF_STATUS csr_send_assoc_cnf_msg(struct mac_context *mac,
 				     pAssocInd->owe_ie_len);
 			pMsg->owe_ie_len = pAssocInd->owe_ie_len;
 		}
+		pMsg->need_assoc_rsp_tx_cb = pAssocInd->need_assoc_rsp_tx_cb;
 
 		msg.type = pMsg->messageType;
 		msg.bodyval = 0;