Parcourir la source

qcacld-3.0: Fix LFR2 VDEV SM failure

1. Move the VDEV SM to UP state in lim_process_mlm_reassoc_cnf in
   success cases similar to lim_handle_sme_join_result.

2. Handle LFR2 fail case in lim_process_mlm_reassoc_cnf
1)	Vdev start failure
2)	Reassoc timeout
3)	Reassoc reject

Change-Id: Id34715faa9428fc11f5330a353258542c8ce29e3
CRs-Fixed: 2442470
Jianmin Zhu il y a 6 ans
Parent
commit
d25260775f

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

@@ -76,6 +76,12 @@ typedef struct join_params {
 	tSirResultCodes result_code;
 } join_params;
 
+struct reassoc_params {
+	uint16_t prot_status_code;
+	tSirResultCodes result_code;
+	struct pe_session *session;
+};
+
 #ifdef WLAN_FEATURE_11AX_BSS_COLOR
 #define MAX_BSS_COLOR_VALUE 63
 #define TIME_BEACON_NOT_UPDATED 30000

+ 159 - 0
core/mac/src/pe/lim/lim_process_mlm_host_roam.c

@@ -219,6 +219,164 @@ error:
 		protStatusCode, pe_session, smesessionId);
 }
 
+#ifdef CONFIG_VDEV_SM
+/**
+ * lim_process_mlm_reassoc_cnf() - process mlm reassoc cnf msg
+ *
+ * @mac_ctx:       Pointer to Global MAC structure
+ * @msg_buf:       A pointer to the MLM message buffer
+ *
+ * This function is called to process MLM_REASSOC_CNF message from MLM State
+ * machine.
+ *
+ * @Return: void
+ */
+void lim_process_mlm_reassoc_cnf(struct mac_context *mac_ctx, uint32_t *msg_buf)
+{
+	struct pe_session *session;
+	tLimMlmReassocCnf *lim_mlm_reassoc_cnf;
+	struct reassoc_params param;
+	QDF_STATUS status;
+
+	if (!msg_buf) {
+		pe_err("Buffer is Pointing to NULL");
+		return;
+	}
+	lim_mlm_reassoc_cnf = (tLimMlmReassocCnf *)msg_buf;
+	session = pe_find_session_by_session_id(
+					mac_ctx,
+					lim_mlm_reassoc_cnf->sessionId);
+	if (!session) {
+		pe_err("session Does not exist for given session Id");
+		return;
+	}
+	if (session->limSmeState != eLIM_SME_WT_REASSOC_STATE ||
+	    LIM_IS_AP_ROLE(session)) {
+		/*
+		 * Should not have received Reassocication confirm
+		 * from MLM in other states OR on AP.
+		 */
+		pe_err("Rcv unexpected MLM_REASSOC_CNF role: %d sme 0x%X",
+		       GET_LIM_SYSTEM_ROLE(session), session->limSmeState);
+		return;
+	}
+
+	/*
+	 * Upon Reassoc success or failure, freeup the cached preauth request,
+	 * to ensure that channel switch is now allowed following any change in
+	 * HT params.
+	 */
+	if (session->ftPEContext.pFTPreAuthReq) {
+		pe_debug("Freeing pFTPreAuthReq: %pK",
+			 session->ftPEContext.pFTPreAuthReq);
+		if (session->ftPEContext.pFTPreAuthReq->pbssDescription) {
+			qdf_mem_free(
+			  session->ftPEContext.pFTPreAuthReq->pbssDescription);
+			session->ftPEContext.pFTPreAuthReq->pbssDescription =
+									NULL;
+		}
+		qdf_mem_free(session->ftPEContext.pFTPreAuthReq);
+		session->ftPEContext.pFTPreAuthReq = NULL;
+		session->ftPEContext.ftPreAuthSession = false;
+	}
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	if (session->bRoamSynchInProgress) {
+		pe_debug("LFR3:Re-set the LIM Ctxt Roam Synch In Progress");
+		session->bRoamSynchInProgress = false;
+	}
+#endif
+
+	pe_debug("Rcv MLM_REASSOC_CNF with result code: %d",
+		 lim_mlm_reassoc_cnf->resultCode);
+	if (lim_mlm_reassoc_cnf->resultCode == eSIR_SME_SUCCESS) {
+		/* Successful Reassociation */
+		pe_debug("*** Reassociated with new BSS ***");
+
+		session->limSmeState = eLIM_SME_LINK_EST_STATE;
+		MTRACE(mac_trace(
+			mac_ctx, TRACE_CODE_SME_STATE,
+			session->peSessionId, session->limSmeState));
+
+		wlan_vdev_mlme_sm_deliver_evt(session->vdev,
+					      WLAN_VDEV_SM_EV_START_SUCCESS,
+					      0, NULL);
+
+		/* Need to send Reassoc rsp with Reassoc success to Host. */
+		lim_send_sme_join_reassoc_rsp(
+					mac_ctx, eWNI_SME_REASSOC_RSP,
+					lim_mlm_reassoc_cnf->resultCode,
+					lim_mlm_reassoc_cnf->protStatusCode,
+					session, session->smeSessionId);
+	} else {
+		param.result_code = lim_mlm_reassoc_cnf->resultCode;
+		param.prot_status_code = lim_mlm_reassoc_cnf->protStatusCode;
+		param.session = session;
+
+		mlme_set_connection_fail(session->vdev, true);
+		status = wlan_vdev_mlme_sm_deliver_evt(
+					session->vdev,
+					WLAN_VDEV_SM_EV_CONNECTION_FAIL,
+					sizeof(param), &param);
+	}
+
+	if (session->pLimReAssocReq) {
+		qdf_mem_free(session->pLimReAssocReq);
+		session->pLimReAssocReq = NULL;
+	}
+}
+
+QDF_STATUS lim_sta_reassoc_error_handler(struct reassoc_params *param)
+{
+	struct pe_session *session;
+	struct mac_context *mac_ctx;
+
+	if (!param) {
+		pe_err("param is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
+	if (!mac_ctx) {
+		pe_err("mac_ctx is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	session = param->session;
+	if (param->result_code
+			== eSIR_SME_REASSOC_REFUSED) {
+		/*
+		 * Reassociation failure With the New AP but we still have the
+		 * link with the Older AP
+		 */
+		session->limSmeState = eLIM_SME_LINK_EST_STATE;
+		MTRACE(mac_trace(
+			mac_ctx, TRACE_CODE_SME_STATE,
+			session->peSessionId, session->limSmeState));
+
+		/* Need to send Reassoc rsp with Assoc failure to Host. */
+		lim_send_sme_join_reassoc_rsp(
+					mac_ctx, eWNI_SME_REASSOC_RSP,
+					param->result_code,
+					param->prot_status_code,
+					session, session->smeSessionId);
+	} else {
+		/* Reassociation failure */
+		session->limSmeState = eLIM_SME_JOIN_FAILURE_STATE;
+		MTRACE(mac_trace(
+			mac_ctx, TRACE_CODE_SME_STATE,
+			session->peSessionId, session->limSmeState));
+		/* Need to send Reassoc rsp with Assoc failure to Host. */
+		lim_handle_sme_reaasoc_result(
+					mac_ctx,
+					param->result_code,
+					param->prot_status_code,
+					session);
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+#else
 /**
  * lim_process_mlm_reassoc_cnf() - process mlm reassoc cnf msg
  *
@@ -330,6 +488,7 @@ void lim_process_mlm_reassoc_cnf(struct mac_context *mac_ctx, uint32_t *msg_buf)
 		session->pLimReAssocReq = NULL;
 	}
 }
+#endif
 
 /**
  * lim_process_sta_mlm_add_bss_rsp_ft() - Handle the ADD BSS response

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

@@ -732,6 +732,7 @@ void lim_process_mlm_set_bss_key_rsp(struct mac_context *mac,
 void lim_process_switch_channel_rsp(struct mac_context *mac, void *);
 
 QDF_STATUS lim_sta_send_down_link(join_params *param);
+QDF_STATUS lim_sta_reassoc_error_handler(struct reassoc_params *param);
 
 #ifdef WLAN_FEATURE_11W
 /* 11w send SA query request action frame */

+ 18 - 3
core/mac/src/pe/lim/lim_utils.c

@@ -7923,8 +7923,9 @@ QDF_STATUS lim_sta_mlme_vdev_restart_send(struct vdev_mlme_obj *vdev_mlme,
 QDF_STATUS lim_sta_mlme_vdev_stop_send(struct vdev_mlme_obj *vdev_mlme,
 				       uint16_t data_len, void *data)
 {
-	QDF_STATUS status;
-	bool connection_fail;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	bool connection_fail = false;
+	enum vdev_assoc_type assoc_type;
 
 	if (!vdev_mlme) {
 		pe_err("vdev_mlme is NULL");
@@ -7938,7 +7939,21 @@ QDF_STATUS lim_sta_mlme_vdev_stop_send(struct vdev_mlme_obj *vdev_mlme,
 	connection_fail = mlme_is_connection_fail(vdev_mlme->vdev);
 	pe_info("Send vdev stop, connection_fail %d", connection_fail);
 	if (connection_fail) {
-		status = lim_sta_send_down_link((join_params *)data);
+		assoc_type = mlme_get_assoc_type(vdev_mlme->vdev);
+		switch (assoc_type) {
+		case VDEV_ASSOC:
+			status = lim_sta_send_down_link((join_params *)data);
+			break;
+		case VDEV_REASSOC:
+		case VDEV_FT_REASSOC:
+			status = lim_sta_reassoc_error_handler(
+					(struct reassoc_params *)data);
+			break;
+		default:
+			pe_info("Invalid assoc_type %d", assoc_type);
+			status = QDF_STATUS_E_INVAL;
+			break;
+		}
 		mlme_set_connection_fail(vdev_mlme->vdev, false);
 	} else {
 		status = lim_sta_send_del_bss((struct pe_session *)data);