Parcourir la source

qcacld-3.0: Fix RSO state machine issues

For MLO connection, when disconnect is started as part of
link switch, host will send RSO STOP to FW.
Post disconnect complete host tries to enable RSO again on
the other connected STA. This is protected by link switch in
progress check to avoid sending RSO start on link vdev during
link switch. But when NB or SB disconnect is queued during link
switch, then link switch in progress flag is reset and RSO start
might go on the assoc vdev.

Do not enable RSO if disconnect is ongoing on same MLD.
Also while processing RSO stop response fw might send RSO stop
response on link vdev. Add handling to process RSO stop response
on other vdev belonging to same MLD

During roam sync if assoc rsp is received from unexpected peer
then abort roaming and send rso stop to FW,HO fail will clean
host CM state machine.

Change-Id: Ibd1f424c3dea80e50e70ebdf112ee2cf44868ebe
CRs-Fixed: 3626015
Amruta Kulkarni il y a 1 an
Parent
commit
06c7860fe1

+ 4 - 4
components/cmn_services/interface_mgr/src/wlan_if_mgr_roam.c

@@ -168,7 +168,10 @@ if_mgr_enable_roaming_on_connected_sta(struct wlan_objmgr_pdev *pdev,
 				       struct wlan_objmgr_vdev *vdev)
 {
 	struct wlan_objmgr_psoc *psoc;
-	uint8_t vdev_id;
+	uint8_t vdev_id = wlan_vdev_get_id(vdev);
+
+	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE)
+		return QDF_STATUS_E_FAILURE;
 
 	/*
 	 * When link switch is in progress, don't send RSO Enable before vdev
@@ -183,10 +186,7 @@ if_mgr_enable_roaming_on_connected_sta(struct wlan_objmgr_pdev *pdev,
 		return QDF_STATUS_E_FAILURE;
 
 	if (policy_mgr_is_sta_active_connection_exists(psoc) &&
-	    wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE &&
 	    mlo_is_enable_roaming_on_connected_sta_allowed(vdev)) {
-		vdev_id = wlan_vdev_get_id(vdev);
-		ifmgr_debug("Enable roaming on connected sta for vdev_id %d", vdev_id);
 		wlan_cm_enable_roaming_on_connected_sta(pdev, vdev_id);
 		policy_mgr_set_pcl_for_connected_vdev(psoc, vdev_id, true);
 	}

+ 130 - 26
components/target_if/connection_mgr/src/target_if_cm_roam_offload.c

@@ -1621,21 +1621,123 @@ target_if_start_rso_stop_timer(struct wlan_objmgr_vdev *vdev)
 						  RSO_STOP_RESPONSE_BIT);
 }
 
+static bool
+target_if_is_vdev_rsp_valid(struct wlan_objmgr_psoc *psoc,
+			    struct vdev_response_timer **vdev_rsp,
+			    struct wlan_lmac_if_mlme_rx_ops *rx_ops,
+			    uint8_t vdev_id)
+{
+	*vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id);
+	if (!*vdev_rsp) {
+		mlme_err("MLO_ROAM: vdev rsp not found for vdev:%d", vdev_id);
+		return false;
+	}
+
+	if (qdf_atomic_test_bit(RSO_STOP_RESPONSE_BIT,
+				&((*vdev_rsp)->rsp_status))) {
+		mlme_debug("MLO_ROAM: RSO bit set on vdev id %d",
+			   (*vdev_rsp)->vdev_id);
+		return true;
+	}
+
+	/* Failure case vdev_rsp is set to NULL */
+	*vdev_rsp = NULL;
+
+	return false;
+}
+
+/**
+ * target_if_find_active_rso_stop_rsp() - Iterate through ml vdevs to find
+ * the vdev rsp for which RSO_STOP_RESPONSE_BIT is set.
+ * @roam_event: Roam event data
+ *
+ * This is needed when for e.g.: host sends rso stop on vdev id 0, fw response
+ * is received on vdev 1.
+ * Since the timer is vdev specific, this function will iterate through ml vdevs
+ * to find the vdev_rsp on which RSO_STOP_RESPONSE_BIT is set.
+ *
+ * Return: struct vdev_response_timer for success, NULL for failure
+ */
+static struct vdev_response_timer *
+target_if_find_active_rso_stop_rsp(struct roam_offload_roam_event *roam_event)
+{
+	struct vdev_response_timer *vdev_rsp = NULL;
+	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
+	struct wlan_objmgr_vdev *vdev;
+	struct wlan_mlo_dev_context *mlo_dev_ctx;
+	uint8_t i;
+	QDF_STATUS status;
+
+	rx_ops = target_if_vdev_mgr_get_rx_ops(roam_event->psoc);
+	if (!rx_ops || !rx_ops->psoc_get_vdev_response_timer_info) {
+		mlme_err("No Rx Ops");
+		return NULL;
+	}
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(roam_event->psoc,
+						    roam_event->vdev_id,
+						    WLAN_MLME_SB_ID);
+	if (!vdev)
+		return NULL;
+
+	/* For legacy case use the incoming vdev */
+	if (target_if_is_vdev_rsp_valid(roam_event->psoc, &vdev_rsp,
+					rx_ops, roam_event->vdev_id))
+		goto end;
+
+	mlo_dev_ctx = vdev->mlo_dev_ctx;
+	if (!mlo_dev_ctx)
+		goto end;
+
+	/*
+	 * if vdev_rsp with RSO_STOP_RESPONSE bit is not set then check for
+	 * the same on other ML vdevs
+	 */
+	for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
+		if (!mlo_dev_ctx->wlan_vdev_list[i])
+			continue;
+
+		status = wlan_objmgr_vdev_try_get_ref(mlo_dev_ctx->wlan_vdev_list[i],
+						      WLAN_MLO_MGR_ID);
+		if (QDF_IS_STATUS_ERROR(status))
+			continue;
+
+		if (target_if_is_vdev_rsp_valid(roam_event->psoc, &vdev_rsp,
+						rx_ops,
+						wlan_vdev_get_id(mlo_dev_ctx->wlan_vdev_list[i]))) {
+			mlo_release_vdev_ref(mlo_dev_ctx->wlan_vdev_list[i]);
+			goto end;
+		}
+
+		mlo_release_vdev_ref(mlo_dev_ctx->wlan_vdev_list[i]);
+	}
+
+	if (i == WLAN_UMAC_MLO_MAX_VDEVS) {
+		mlme_err("RSO bit not set on any mlo vdev");
+		goto end;
+	}
+
+end:
+	if (vdev)
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_SB_ID);
+
+	return vdev_rsp;
+}
+
 QDF_STATUS
 target_if_stop_rso_stop_timer(struct roam_offload_roam_event *roam_event)
 {
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 	struct vdev_response_timer *vdev_rsp;
-	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
 
 	roam_event->rso_timer_stopped = false;
-	rx_ops = target_if_vdev_mgr_get_rx_ops(roam_event->psoc);
-	if (!rx_ops || !rx_ops->vdev_mgr_start_response) {
-		mlme_err("No Rx Ops");
-		return QDF_STATUS_E_INVAL;
+	if (roam_event->reason == ROAM_REASON_RSO_STATUS &&
+	    roam_event->notif == CM_ROAM_NOTIF_HO_FAIL) {
+		mlme_debug("HO_FAIL happened, wait for HO_FAIL event vdev_id: %u",
+			   roam_event->vdev_id);
 	}
-	vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(roam_event->psoc,
-							roam_event->vdev_id);
+
+	vdev_rsp = target_if_find_active_rso_stop_rsp(roam_event);
 	if (!vdev_rsp) {
 		mlme_err("vdev response timer is null VDEV_%d PSOC_%d",
 			 roam_event->vdev_id,
@@ -1643,33 +1745,35 @@ target_if_stop_rso_stop_timer(struct roam_offload_roam_event *roam_event)
 		return QDF_STATUS_E_INVAL;
 	}
 
-	if (!qdf_atomic_test_bit(RSO_STOP_RESPONSE_BIT,
-				 &vdev_rsp->rsp_status)) {
-		mlme_debug("rso stop timer is not started");
-		return QDF_STATUS_SUCCESS;
-	}
+	switch (roam_event->reason) {
+	case ROAM_REASON_RSO_STATUS:
+		if (roam_event->notif != CM_ROAM_NOTIF_SCAN_MODE_SUCCESS &&
+		    roam_event->notif != CM_ROAM_NOTIF_SCAN_MODE_FAIL)
+			break;
 
-	if ((roam_event->reason == ROAM_REASON_RSO_STATUS &&
-	     (roam_event->notif == CM_ROAM_NOTIF_SCAN_MODE_SUCCESS ||
-	      roam_event->notif == CM_ROAM_NOTIF_SCAN_MODE_FAIL)) ||
-	    roam_event->reason == ROAM_REASON_HO_FAILED) {
+		/*
+		 * fallthrough if notif == CM_ROAM_NOTIF_SCAN_MODE_SUCCESS or
+		 * notif == CM_ROAM_NOTIF_SCAN_MODE_FAIL
+		 */
+		fallthrough;
+	case ROAM_REASON_HO_FAILED:
 		status = target_if_vdev_mgr_rsp_timer_stop(roam_event->psoc,
-					vdev_rsp, RSO_STOP_RESPONSE_BIT);
-		if (QDF_IS_STATUS_SUCCESS(status))
-			roam_event->rso_timer_stopped = true;
-		else
-			mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed",
+							   vdev_rsp,
+							   RSO_STOP_RESPONSE_BIT);
+		roam_event->rso_timer_stopped = true;
+		if (QDF_IS_STATUS_ERROR(status)) {
+			roam_event->rso_timer_stopped = false;
+			mlme_err("PSOC_%d VDEV_%d: VDEV MGR RSO Stop RSP Timer stop failed",
 				 roam_event->psoc->soc_objmgr.psoc_id,
 				 roam_event->vdev_id);
-	} else if (roam_event->reason == ROAM_REASON_RSO_STATUS &&
-		   roam_event->notif == CM_ROAM_NOTIF_HO_FAIL) {
-		mlme_debug("HO_FAIL happened, wait for HO_FAIL event vdev_id: %u",
-			   roam_event->vdev_id);
+		}
+		break;
+	default:
+		return status;
 	}
 
 	return status;
 }
-
 #else
 static inline QDF_STATUS
 target_if_start_rso_stop_timer(struct wlan_objmgr_vdev *vdev)

+ 17 - 16
components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c

@@ -3986,7 +3986,6 @@ cm_roam_switch_to_rso_stop(struct wlan_objmgr_pdev *pdev,
 	 * nothing to do here
 	 */
 	default:
-
 		return QDF_STATUS_SUCCESS;
 	}
 	mlme_set_roam_state(psoc, vdev_id, WLAN_ROAM_RSO_STOPPED);
@@ -4308,7 +4307,9 @@ cm_roam_switch_to_rso_enable(struct wlan_objmgr_pdev *pdev,
 	control_bitmap = mlme_get_operations_bitmap(psoc, vdev_id);
 
 	cur_state = mlme_get_roam_state(psoc, vdev_id);
-	mlme_debug("CM_RSO: vdev%d: cur_state : %d", vdev_id, cur_state);
+	mlme_debug("CM_RSO: vdev%d: cur_state : %d reason:%d control_bmap:0x%x sup_disabled_roam:%d",
+		   vdev_id, cur_state, reason, control_bitmap,
+		   sup_disabled_roaming);
 
 	switch (cur_state) {
 	case WLAN_ROAM_INIT:
@@ -4382,7 +4383,7 @@ cm_roam_switch_to_rso_enable(struct wlan_objmgr_pdev *pdev,
 
 	status = cm_roam_send_rso_cmd(psoc, vdev_id, rso_command, reason);
 	if (QDF_IS_STATUS_ERROR(status)) {
-		mlme_debug("ROAM: RSO start failed");
+		mlme_err("ROAM: vdev:%d RSO start failed", vdev_id);
 		return status;
 	}
 	mlme_set_roam_state(psoc, vdev_id, WLAN_ROAM_RSO_ENABLED);
@@ -4696,8 +4697,7 @@ cm_record_state_change(struct wlan_objmgr_pdev *pdev,
  */
 static QDF_STATUS
 cm_mlo_roam_switch_for_link(struct wlan_objmgr_pdev *pdev,
-			    uint8_t vdev_id,
-			    uint8_t reason)
+			    uint8_t vdev_id, uint8_t reason)
 {
 	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
 	enum roam_offload_state cur_state = mlme_get_roam_state(psoc, vdev_id);
@@ -4738,6 +4738,7 @@ cm_mlo_roam_switch_for_link(struct wlan_objmgr_pdev *pdev,
 
 QDF_STATUS
 cm_handle_mlo_rso_state_change(struct wlan_objmgr_pdev *pdev, uint8_t *vdev_id,
+			       enum roam_offload_state requested_state,
 			       uint8_t reason, bool *is_rso_skip)
 {
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
@@ -4757,8 +4758,8 @@ cm_handle_mlo_rso_state_change(struct wlan_objmgr_pdev *pdev, uint8_t *vdev_id,
 	 */
 	if (wlan_vdev_mlme_get_is_mlo_vdev(psoc, *vdev_id) &&
 	    mlo_mgr_is_link_switch_in_progress(vdev)) {
-		mlme_debug("MLO ROAM: Link switch in prog! skip RSO cmd on vdev %d",
-			   *vdev_id);
+		mlme_debug("MLO ROAM: Link switch in prog! skip RSO cmd:%d on vdev %d",
+			   requested_state, *vdev_id);
 		*is_rso_skip = true;
 		goto end;
 	}
@@ -4774,12 +4775,12 @@ cm_handle_mlo_rso_state_change(struct wlan_objmgr_pdev *pdev, uint8_t *vdev_id,
 		 */
 		if (!wlan_vdev_mlme_get_is_mlo_link(psoc, *vdev_id) &&
 		    wlan_is_roaming_enabled(pdev, *vdev_id)) {
-			mlme_debug("MLO ROAM: Process RSO stop on assoc vdev : %d",
-				   *vdev_id);
+			mlme_debug("MLO ROAM: Process RSO cmd:%d on assoc vdev : %d",
+				   requested_state, *vdev_id);
 			*is_rso_skip = false;
 		} else {
-			mlme_debug("MLO ROAM: skip RSO cmd on assoc vdev %d",
-				   *vdev_id);
+			mlme_debug("MLO ROAM: skip RSO cmd:%d on assoc vdev %d",
+				   requested_state, *vdev_id);
 			*is_rso_skip = true;
 		}
 	}
@@ -4846,14 +4847,13 @@ cm_roam_state_change(struct wlan_objmgr_pdev *pdev,
 		is_up = QDF_IS_STATUS_SUCCESS(wlan_vdev_is_up(vdev));
 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
 
-	cur_state = mlme_get_roam_state(psoc, vdev_id);
-
 	if (requested_state != WLAN_ROAM_DEINIT && !is_up) {
-		mlme_debug("ROAM: roam state change requested in non-connected state");
+		mlme_debug("ROAM: roam state(%d) change requested in non-connected state",
+			   requested_state);
 		goto end;
 	}
 
-	status = cm_handle_mlo_rso_state_change(pdev, &vdev_id,
+	status = cm_handle_mlo_rso_state_change(pdev, &vdev_id, requested_state,
 						reason, &is_rso_skip);
 	if (is_rso_skip)
 		return status;
@@ -4861,7 +4861,7 @@ cm_roam_state_change(struct wlan_objmgr_pdev *pdev,
 	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id,
 						    WLAN_MLME_CM_ID);
 	if (!vdev) {
-		mlme_err("Invalid vdev");
+		mlme_err("Invalid vdev:%d", vdev_id);
 		goto end;
 	}
 
@@ -4901,6 +4901,7 @@ cm_roam_state_change(struct wlan_objmgr_pdev *pdev,
 release_ref:
 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
 end:
+	cur_state = mlme_get_roam_state(psoc, vdev_id);
 	cm_record_state_change(pdev, vdev_id, cur_state, requested_state,
 			       reason, is_up, status);
 

+ 6 - 8
components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.h

@@ -555,16 +555,14 @@ void cm_update_owe_info(struct wlan_objmgr_vdev *vdev,
 
 #ifdef WLAN_FEATURE_11BE_MLO
 QDF_STATUS
-cm_handle_mlo_rso_state_change(struct wlan_objmgr_pdev *pdev,
-			       uint8_t *vdev_id,
-			       uint8_t reason,
-			       bool *is_rso_skip);
+cm_handle_mlo_rso_state_change(struct wlan_objmgr_pdev *pdev, uint8_t *vdev_id,
+			       enum roam_offload_state requested_state,
+			       uint8_t reason, bool *is_rso_skip);
 #else
 static inline QDF_STATUS
-cm_handle_mlo_rso_state_change(struct wlan_objmgr_pdev *pdev,
-			       uint8_t *vdev_id,
-			       uint8_t reason,
-			       bool *is_rso_skip)
+cm_handle_mlo_rso_state_change(struct wlan_objmgr_pdev *pdev, uint8_t *vdev_id,
+			       enum roam_offload_state requested_state,
+			       uint8_t reason, bool *is_rso_skip)
 {
 	return QDF_STATUS_E_NOSUPPORT;
 }

+ 8 - 3
components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c

@@ -50,8 +50,7 @@ wlan_cm_enable_roaming_on_connected_sta(struct wlan_objmgr_pdev *pdev,
 	uint32_t op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
 	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
 	uint32_t sta_vdev_id = WLAN_INVALID_VDEV_ID;
-	uint32_t count;
-	uint32_t idx;
+	uint32_t count, idx;
 	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
 
 	sta_vdev_id = policy_mgr_get_roam_enabled_sta_session_id(psoc, vdev_id);
@@ -62,7 +61,6 @@ wlan_cm_enable_roaming_on_connected_sta(struct wlan_objmgr_pdev *pdev,
 						       op_ch_freq_list,
 						       vdev_id_list,
 						       PM_STA_MODE);
-
 	if (!count)
 		return QDF_STATUS_E_FAILURE;
 
@@ -82,6 +80,13 @@ wlan_cm_enable_roaming_on_connected_sta(struct wlan_objmgr_pdev *pdev,
 	if (sta_vdev_id == WLAN_INVALID_VDEV_ID)
 		return QDF_STATUS_E_FAILURE;
 
+	if (mlo_check_is_given_vdevs_on_same_mld(psoc, sta_vdev_id, vdev_id)) {
+		mlme_debug("RSO_CFG: vdev:%d , vdev:%d are on same MLD skip RSO enable",
+			   sta_vdev_id, vdev_id);
+
+		return QDF_STATUS_E_FAILURE;
+	}
+
 	mlme_debug("ROAM: Enabling roaming on vdev[%d]", sta_vdev_id);
 
 	return cm_roam_state_change(pdev,

+ 24 - 3
components/umac/mlme/mlo_mgr/inc/wlan_mlo_mgr_roam.h

@@ -453,14 +453,27 @@ mlo_add_all_link_probe_rsp_to_scan_db(struct wlan_objmgr_psoc *psoc,
 
 /**
  * mlo_is_enable_roaming_on_connected_sta_allowed() - whether connected STA is
- *                                                    allowed to enable roaming
- *                                                    if link vdev disconnects
+ * allowed to enable roaming if link vdev disconnects
  * @vdev: vdev object
  *
- * Return true if connected STA is allowed to enable roaming, false otherwise.
+ * Return: true if connected STA is allowed to enable roaming, false otherwise.
  */
 bool
 mlo_is_enable_roaming_on_connected_sta_allowed(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * mlo_check_is_given_vdevs_on_same_mld() - check if the 2 given vdev's are on
+ * same MLD
+ * @psoc: PSOC object
+ * @vdev_id_1: Current connected station vdev id on which roaming is to be
+ * enabled
+ * @vdev_id_2: vdev id on which disconnection is happening
+ *
+ * Return: true if both vdev ids are on same MLD, false otherwise.
+ */
+bool
+mlo_check_is_given_vdevs_on_same_mld(struct wlan_objmgr_psoc *psoc,
+				     uint8_t vdev_id_1, uint8_t vdev_id_2);
 #else /* WLAN_FEATURE_11BE_MLO */
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
 static inline
@@ -657,5 +670,13 @@ mlo_is_enable_roaming_on_connected_sta_allowed(struct wlan_objmgr_vdev *vdev)
 {
 	return true;
 }
+
+static inline bool
+mlo_check_is_given_vdevs_on_same_mld(struct wlan_objmgr_psoc *psoc,
+				     uint8_t vdev_id_1, uint8_t vdev_id_2)
+{
+	return false;
+}
+
 #endif /* WLAN_FEATURE_11BE_MLO */
 #endif

+ 37 - 0
components/umac/mlme/mlo_mgr/src/wlan_mlo_mgr_roam.c

@@ -1593,3 +1593,40 @@ mlo_is_enable_roaming_on_connected_sta_allowed(struct wlan_objmgr_vdev *vdev)
 	/* Roamed to MLO AP, do nothing if link vdev is disconnected */
 	return false;
 }
+
+bool
+mlo_check_is_given_vdevs_on_same_mld(struct wlan_objmgr_psoc *psoc,
+				     uint8_t vdev_id_1, uint8_t vdev_id_2)
+{
+	struct wlan_objmgr_vdev *vdev1;
+	struct wlan_mlo_dev_context *ml_dev_ctx1;
+	struct wlan_objmgr_vdev **vdev_list;
+	bool is_same_mld = false;
+	uint8_t i;
+
+	vdev1 = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id_1,
+						     WLAN_MLME_CM_ID);
+	if (!vdev1)
+		return false;
+
+	ml_dev_ctx1 = vdev1->mlo_dev_ctx;
+	if (!ml_dev_ctx1)
+		goto end;
+
+	vdev_list = ml_dev_ctx1->wlan_vdev_list;
+	for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
+		if (!vdev_list[i])
+			continue;
+
+		if (wlan_vdev_get_id(vdev_list[i]) == vdev_id_2) {
+			is_same_mld = true;
+			goto end;
+		}
+	}
+
+end:
+	if (vdev1)
+		wlan_objmgr_vdev_release_ref(vdev1, WLAN_MLME_CM_ID);
+
+	return is_same_mld;
+}

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

@@ -677,6 +677,7 @@ struct wlan_mlo_ie_info {
  * @mlo_ie:
  * @user_edca_set:
  * @is_oui_auth_assoc_6mbps_2ghz_enable: send auth/assoc req with 6 Mbps rate
+ * @is_unexpected_peer_error: true if unexpected peer error
  * on 2.4 GHz
  */
 struct pe_session {
@@ -1006,6 +1007,7 @@ struct pe_session {
 #endif /* WLAN_FEATURE_11BE */
 	uint8_t user_edca_set;
 	bool is_oui_auth_assoc_6mbps_2ghz_enable;
+	bool is_unexpected_peer_error;
 };
 
 /*-------------------------------------------------------------------------

+ 9 - 2
core/mac/src/pe/lim/lim_api.c

@@ -3049,13 +3049,20 @@ pe_roam_synch_callback(struct mac_context *mac_ctx,
 						ft_session_ptr,
 						reassoc_resp,
 						roam_sync_ind_ptr->reassoc_resp_length);
+		if (ft_session_ptr->is_unexpected_peer_error)
+			status = QDF_STATUS_E_FAILURE;
+
 		if (QDF_IS_STATUS_ERROR(status))
 			goto roam_sync_fail;
-	}
-	else
+	} else {
 		lim_process_assoc_rsp_frame(mac_ctx, reassoc_resp,
 					    roam_sync_ind_ptr->reassoc_resp_length - SIR_MAC_HDR_LEN_3A,
 					    LIM_REASSOC, ft_session_ptr);
+		if (ft_session_ptr->is_unexpected_peer_error) {
+			status = QDF_STATUS_E_FAILURE;
+			goto roam_sync_fail;
+		}
+	}
 
 	lim_check_ft_initial_im_association(roam_sync_ind_ptr, ft_session_ptr);
 

+ 13 - 0
core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c

@@ -1188,6 +1188,12 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
 			 */
 			pe_warn("received AssocRsp from unexpected peer "QDF_MAC_ADDR_FMT,
 				QDF_MAC_ADDR_REF(hdr->sa));
+
+			if (lim_is_roam_synch_in_progress(mac_ctx->psoc, session_entry)) {
+				session_entry->is_unexpected_peer_error = true;
+				qdf_mem_free(beacon);
+				return;
+			}
 			/*
 			 * Send Assoc failure to avoid connection in
 			 * progress state for link vdev.
@@ -1208,6 +1214,13 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
 			 */
 			pe_warn("received ReassocRsp from unexpected peer "QDF_MAC_ADDR_FMT,
 				QDF_MAC_ADDR_REF(hdr->sa));
+
+			if (lim_is_roam_synch_in_progress(mac_ctx->psoc, session_entry)) {
+				session_entry->is_unexpected_peer_error = true;
+				qdf_mem_free(beacon);
+				return;
+			}
+
 			/*
 			 * Send Reassoc failure to avoid connection in
 			 * progress state for link vdev.