Pārlūkot izejas kodu

qcacld-3.0: Provide assoc req, rsp IE to kernel in assoc fail case

Currently the driver does not sends the assoc req and assoc
response frame exchanged with the AP if the connection attempt
fails with the peer.
The connection failure can be because of n number of reasons,
OCE assoc reject be one of them.
The supplicant requires these IEs to reject the connection
attempt with the AP with which the connect attempt failed
for t number of seconds, which is mentioned by the AP.

Fix is to send the assoc req, and assoc response IEs to
the driver.

Change-Id: I9c1f7063105912a8005f9e8399640d028b15eec7
CRs-Fixed: 2445709
gaurank kathpalia 6 gadi atpakaļ
vecāks
revīzija
efb20a8901

+ 22 - 2
core/hdd/src/wlan_hdd_assoc.c

@@ -3372,7 +3372,21 @@ hdd_association_completion_handler(struct hdd_adapter *adapter,
 		 */
 		 */
 		if (eCSR_ROAM_ASSOCIATION_FAILURE == roam_status
 		if (eCSR_ROAM_ASSOCIATION_FAILURE == roam_status
 		    && !hddDisconInProgress) {
 		    && !hddDisconInProgress) {
+			u8 *assoc_rsp = NULL;
+			u8 *assoc_req = NULL;
+
 			if (roam_info) {
 			if (roam_info) {
+				if (roam_info->pbFrames) {
+				/* Association Request */
+					assoc_req =
+						(u8 *)(roam_info->pbFrames +
+						      roam_info->nBeaconLength);
+					/* Association Response */
+					assoc_rsp =
+						(u8 *)(roam_info->pbFrames +
+						      roam_info->nBeaconLength +
+						    roam_info->nAssocReqLength);
+				}
 				hdd_err("send connect failure to nl80211: for bssid "
 				hdd_err("send connect failure to nl80211: for bssid "
 					QDF_MAC_ADDR_STR
 					QDF_MAC_ADDR_STR
 					" result: %d and Status: %d reasoncode: %d",
 					" result: %d and Status: %d reasoncode: %d",
@@ -3397,7 +3411,10 @@ hdd_association_completion_handler(struct hdd_adapter *adapter,
 				if (roam_info)
 				if (roam_info)
 					hdd_connect_result(dev,
 					hdd_connect_result(dev,
 						roam_info->bssid.bytes,
 						roam_info->bssid.bytes,
-						roam_info, NULL, 0, NULL, 0,
+						roam_info, assoc_req,
+						roam_info->nAssocReqLength,
+						assoc_rsp,
+						roam_info->nAssocRspLength,
 						WLAN_STATUS_ASSOC_DENIED_UNSPEC,
 						WLAN_STATUS_ASSOC_DENIED_UNSPEC,
 						GFP_KERNEL,
 						GFP_KERNEL,
 						connect_timeout,
 						connect_timeout,
@@ -3414,7 +3431,10 @@ hdd_association_completion_handler(struct hdd_adapter *adapter,
 				if (roam_info)
 				if (roam_info)
 					hdd_connect_result(dev,
 					hdd_connect_result(dev,
 						roam_info->bssid.bytes,
 						roam_info->bssid.bytes,
-						roam_info, NULL, 0, NULL, 0,
+						roam_info, assoc_req,
+						roam_info->nAssocReqLength,
+						assoc_rsp,
+						roam_info->nAssocRspLength,
 						roam_info->reasonCode ?
 						roam_info->reasonCode ?
 						roam_info->reasonCode :
 						roam_info->reasonCode :
 						WLAN_STATUS_UNSPECIFIED_FAILURE,
 						WLAN_STATUS_UNSPECIFIED_FAILURE,

+ 40 - 38
core/mac/src/pe/lim/lim_send_sme_rsp_messages.c

@@ -191,43 +191,47 @@ static void lim_handle_join_rsp_status(struct mac_context *mac_ctx,
 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
 	struct ht_profile *ht_profile;
 	struct ht_profile *ht_profile;
 #endif
 #endif
+	if (session_entry->beacon) {
+		sme_join_rsp->beaconLength = session_entry->bcnLen;
+		qdf_mem_copy(sme_join_rsp->frames,
+			     session_entry->beacon,
+			     sme_join_rsp->beaconLength);
+		qdf_mem_free(session_entry->beacon);
+		session_entry->beacon = NULL;
+		session_entry->bcnLen = 0;
+		pe_debug("Beacon: %d",
+			sme_join_rsp->beaconLength);
+	}
+
+	if (session_entry->assocReq) {
+		sme_join_rsp->assocReqLength =
+			session_entry->assocReqLen;
+		qdf_mem_copy(sme_join_rsp->frames +
+			     sme_join_rsp->beaconLength,
+			     session_entry->assocReq,
+			     sme_join_rsp->assocReqLength);
+		qdf_mem_free(session_entry->assocReq);
+		session_entry->assocReq = NULL;
+		session_entry->assocReqLen = 0;
+		pe_debug("AssocReq: %d",
+			sme_join_rsp->assocReqLength);
+	}
+	if (session_entry->assocRsp) {
+		sme_join_rsp->assocRspLength =
+			session_entry->assocRspLen;
+		qdf_mem_copy(sme_join_rsp->frames +
+			     sme_join_rsp->beaconLength +
+			     sme_join_rsp->assocReqLength,
+			     session_entry->assocRsp,
+			     sme_join_rsp->assocRspLength);
+		qdf_mem_free(session_entry->assocRsp);
+		session_entry->assocRsp = NULL;
+		session_entry->assocRspLen = 0;
+		pe_debug("AssocRsp: %d",
+			sme_join_rsp->assocRspLength);
+	}
+
 	if (result_code == eSIR_SME_SUCCESS) {
 	if (result_code == eSIR_SME_SUCCESS) {
-		if (session_entry->beacon) {
-			sme_join_rsp->beaconLength = session_entry->bcnLen;
-			qdf_mem_copy(sme_join_rsp->frames,
-				session_entry->beacon,
-				sme_join_rsp->beaconLength);
-			qdf_mem_free(session_entry->beacon);
-			session_entry->beacon = NULL;
-			session_entry->bcnLen = 0;
-			pe_debug("Beacon: %d",
-				sme_join_rsp->beaconLength);
-		}
-		if (session_entry->assocReq) {
-			sme_join_rsp->assocReqLength =
-				session_entry->assocReqLen;
-			qdf_mem_copy(sme_join_rsp->frames +
-				sme_join_rsp->beaconLength,
-				session_entry->assocReq,
-				sme_join_rsp->assocReqLength);
-			qdf_mem_free(session_entry->assocReq);
-			session_entry->assocReq = NULL;
-			session_entry->assocReqLen = 0;
-			pe_debug("AssocReq: %d",
-				sme_join_rsp->assocReqLength);
-		}
-		if (session_entry->assocRsp) {
-			sme_join_rsp->assocRspLength =
-				session_entry->assocRspLen;
-			qdf_mem_copy(sme_join_rsp->frames +
-				sme_join_rsp->beaconLength +
-				sme_join_rsp->assocReqLength,
-				session_entry->assocRsp,
-				sme_join_rsp->assocRspLength);
-			qdf_mem_free(session_entry->assocRsp);
-			session_entry->assocRsp = NULL;
-			session_entry->assocRspLen = 0;
-		}
 		if (session_entry->ricData) {
 		if (session_entry->ricData) {
 			sme_join_rsp->parsedRicRspLen =
 			sme_join_rsp->parsedRicRspLen =
 				session_entry->RICDataLen;
 				session_entry->RICDataLen;
@@ -262,8 +266,6 @@ static void lim_handle_join_rsp_status(struct mac_context *mac_ctx,
 		}
 		}
 #endif
 #endif
 		sme_join_rsp->aid = session_entry->limAID;
 		sme_join_rsp->aid = session_entry->limAID;
-		pe_debug("AssocRsp: %d",
-			sme_join_rsp->assocRspLength);
 		sme_join_rsp->vht_channel_width =
 		sme_join_rsp->vht_channel_width =
 			session_entry->ch_width;
 			session_entry->ch_width;
 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH

+ 1 - 0
core/sme/inc/csr_internal.h

@@ -583,6 +583,7 @@ struct csr_roam_session {
 	struct rsn_caps rsn_caps;
 	struct rsn_caps rsn_caps;
 	tCsrRoamConnectedProfile connectedProfile;
 	tCsrRoamConnectedProfile connectedProfile;
 	struct csr_roam_connectedinfo connectedInfo;
 	struct csr_roam_connectedinfo connectedInfo;
+	struct csr_roam_connectedinfo prev_assoc_ap_info;
 	struct csr_roam_profile *pCurRoamProfile;
 	struct csr_roam_profile *pCurRoamProfile;
 	tSirBssDescription *pConnectBssDesc;
 	tSirBssDescription *pConnectBssDesc;
 	uint16_t NumPmkidCache; /* valid number of pmkid in the cache*/
 	uint16_t NumPmkidCache; /* valid number of pmkid in the cache*/

+ 42 - 3
core/sme/src/csr/csr_api_roam.c

@@ -6299,6 +6299,7 @@ static void csr_roam_process_results_default(struct mac_context *mac_ctx,
 	struct csr_roam_session *session;
 	struct csr_roam_session *session;
 	struct csr_roam_info *roam_info;
 	struct csr_roam_info *roam_info;
 	QDF_STATUS status;
 	QDF_STATUS status;
+	struct csr_roam_connectedinfo *prev_connect_info = NULL;
 
 
 	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
 	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
 		sme_err("Invalid session id %d", session_id);
 		sme_err("Invalid session id %d", session_id);
@@ -6309,6 +6310,8 @@ static void csr_roam_process_results_default(struct mac_context *mac_ctx,
 		return;
 		return;
 	session = CSR_GET_SESSION(mac_ctx, session_id);
 	session = CSR_GET_SESSION(mac_ctx, session_id);
 
 
+	prev_connect_info = &session->prev_assoc_ap_info;
+
 	sme_debug("receives no association indication; FILS %d",
 	sme_debug("receives no association indication; FILS %d",
 		  session->is_fils_connection);
 		  session->is_fils_connection);
 	sme_debug("Assoc ref count: %d", session->bRefAssocStartCnt);
 	sme_debug("Assoc ref count: %d", session->bRefAssocStartCnt);
@@ -6360,7 +6363,15 @@ static void csr_roam_process_results_default(struct mac_context *mac_ctx,
 		qdf_mem_copy(&roam_info->bssid,
 		qdf_mem_copy(&roam_info->bssid,
 			     &session->joinFailStatusCode.bssId,
 			     &session->joinFailStatusCode.bssId,
 			     sizeof(struct qdf_mac_addr));
 			     sizeof(struct qdf_mac_addr));
-
+		if (prev_connect_info->pbFrames) {
+			roam_info->nAssocReqLength =
+					prev_connect_info->nAssocReqLength;
+			roam_info->nAssocRspLength =
+					prev_connect_info->nAssocRspLength;
+			roam_info->nBeaconLength =
+				prev_connect_info->nBeaconLength;
+			roam_info->pbFrames = prev_connect_info->pbFrames;
+		}
 		/*
 		/*
 		 * If Join fails while Handoff is in progress, indicate
 		 * If Join fails while Handoff is in progress, indicate
 		 * disassociated event to supplicant to reconnect
 		 * disassociated event to supplicant to reconnect
@@ -8732,6 +8743,8 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac,
 	tListElem *pEntry = NULL;
 	tListElem *pEntry = NULL;
 	tSmeCmd *pCommand = NULL;
 	tSmeCmd *pCommand = NULL;
 	struct csr_roam_session *session_ptr;
 	struct csr_roam_session *session_ptr;
+	struct csr_roam_connectedinfo *prev_connect_info;
+	uint32_t len = 0;
 
 
 	if (pSmeJoinRsp) {
 	if (pSmeJoinRsp) {
 		session_ptr = CSR_GET_SESSION(mac, pSmeJoinRsp->sessionId);
 		session_ptr = CSR_GET_SESSION(mac, pSmeJoinRsp->sessionId);
@@ -8745,6 +8758,8 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac,
 			("session %d not found"), pSmeJoinRsp->sessionId);
 			("session %d not found"), pSmeJoinRsp->sessionId);
 		return;
 		return;
 	}
 	}
+
+	prev_connect_info = &session_ptr->prev_assoc_ap_info;
 	/* The head of the active list is the request we sent */
 	/* The head of the active list is the request we sent */
 	pEntry = csr_nonscan_active_ll_peek_head(mac, LL_ACCESS_LOCK);
 	pEntry = csr_nonscan_active_ll_peek_head(mac, LL_ACCESS_LOCK);
 	if (pEntry)
 	if (pEntry)
@@ -8809,6 +8824,25 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac,
 							 pSmeJoinRsp->sessionId,
 							 pSmeJoinRsp->sessionId,
 							 QDF_STATUS_E_FAILURE);
 							 QDF_STATUS_E_FAILURE);
 		}
 		}
+
+		len = pSmeJoinRsp->assocReqLength +
+		      pSmeJoinRsp->assocRspLength + pSmeJoinRsp->beaconLength;
+		if (prev_connect_info->pbFrames)
+			csr_roam_free_connected_info(mac, prev_connect_info);
+
+		prev_connect_info->pbFrames = qdf_mem_malloc(len);
+		if (!prev_connect_info->pbFrames)
+			sme_err("memory allocation failed for previous assoc profile");
+		else {
+			qdf_mem_copy(prev_connect_info->pbFrames,
+				     pSmeJoinRsp->frames, len);
+			prev_connect_info->nAssocReqLength =
+						pSmeJoinRsp->assocReqLength;
+			prev_connect_info->nAssocRspLength =
+						pSmeJoinRsp->assocRspLength;
+			prev_connect_info->nBeaconLength =
+						pSmeJoinRsp->beaconLength;
+		}
 		/*
 		/*
 		 * if userspace has issued disconnection,
 		 * if userspace has issued disconnection,
 		 * driver should not continue connecting
 		 * driver should not continue connecting
@@ -8816,9 +8850,9 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac,
 		is_dis_pending = is_disconnect_pending(mac,
 		is_dis_pending = is_disconnect_pending(mac,
 							session_ptr->sessionId);
 							session_ptr->sessionId);
 		if (pCommand && (session_ptr->join_bssid_count <
 		if (pCommand && (session_ptr->join_bssid_count <
-				CSR_MAX_BSSID_COUNT) && !is_dis_pending)
+				CSR_MAX_BSSID_COUNT) && !is_dis_pending) {
 			csr_roam(mac, pCommand);
 			csr_roam(mac, pCommand);
-		else {
+		} else {
 			/*
 			/*
 			 * When the upper layers issue a connect command, there
 			 * When the upper layers issue a connect command, there
 			 * is a roam command with reason eCsrHddIssued that
 			 * is a roam command with reason eCsrHddIssued that
@@ -8854,6 +8888,7 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac,
 			csr_roam_complete(mac, eCsrNothingToJoin, NULL,
 			csr_roam_complete(mac, eCsrNothingToJoin, NULL,
 					pSmeJoinRsp->sessionId);
 					pSmeJoinRsp->sessionId);
 		}
 		}
+		csr_roam_free_connected_info(mac, prev_connect_info);
 	} /*else: ( eSIR_SME_SUCCESS == pSmeJoinRsp->statusCode ) */
 	} /*else: ( eSIR_SME_SUCCESS == pSmeJoinRsp->statusCode ) */
 }
 }
 
 
@@ -17183,6 +17218,8 @@ void csr_cleanup_session(struct mac_context *mac, uint32_t sessionId)
 		csr_reset_cfg_privacy(mac);
 		csr_reset_cfg_privacy(mac);
 		csr_roam_free_connect_profile(&pSession->connectedProfile);
 		csr_roam_free_connect_profile(&pSession->connectedProfile);
 		csr_roam_free_connected_info(mac, &pSession->connectedInfo);
 		csr_roam_free_connected_info(mac, &pSession->connectedInfo);
+		csr_roam_free_connected_info(mac,
+					     &pSession->prev_assoc_ap_info);
 		qdf_mc_timer_destroy(&pSession->hTimerRoaming);
 		qdf_mc_timer_destroy(&pSession->hTimerRoaming);
 		qdf_mc_timer_destroy(&pSession->roaming_offload_timer);
 		qdf_mc_timer_destroy(&pSession->roaming_offload_timer);
 		csr_purge_vdev_pending_ser_cmd_list(mac, sessionId);
 		csr_purge_vdev_pending_ser_cmd_list(mac, sessionId);
@@ -17249,6 +17286,8 @@ static void csr_init_session(struct mac_context *mac, uint32_t sessionId)
 	csr_free_roam_profile(mac, sessionId);
 	csr_free_roam_profile(mac, sessionId);
 	csr_roam_free_connect_profile(&pSession->connectedProfile);
 	csr_roam_free_connect_profile(&pSession->connectedProfile);
 	csr_roam_free_connected_info(mac, &pSession->connectedInfo);
 	csr_roam_free_connected_info(mac, &pSession->connectedInfo);
+	csr_roam_free_connected_info(mac,
+				     &pSession->prev_assoc_ap_info);
 	csr_free_connect_bss_desc(mac, sessionId);
 	csr_free_connect_bss_desc(mac, sessionId);
 	qdf_mem_zero(&pSession->selfMacAddr, sizeof(struct qdf_mac_addr));
 	qdf_mem_zero(&pSession->selfMacAddr, sizeof(struct qdf_mac_addr));
 	if (pSession->pWpaRsnReqIE) {
 	if (pSession->pWpaRsnReqIE) {