Browse Source

qcacld-3.0: Send roam abort on peer create failure

Sending deauth on one of the links in MLO connection will result
in removing anchor link in FW and driver shall silently remove the
next link without initiating another deauth. For this reason the
status of MLO peer is set to DISCONN_INITIATED on sending first
deauth frame so that subsequent links do not send again.

The MLO peer context holds the list of all object manager peers for
that MLD connection and failure to add to the context shall result
in termination of connection. Currently the failures are not handled
and the object manager peer is not having any MLO peer context and
this results in sending deauth frame on both the links.

Handle the error of peer create and MLO peer attach on roaming
to abort the roam sync.

Change-Id: I4d5a766b673b36edb44d19065237aa35ff7d5f1d
CRs-Fixed: 3837890
Vinod Kumar Pirla 1 năm trước cách đây
mục cha
commit
ab3ca03ac2

+ 8 - 11
components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload_event.c

@@ -564,15 +564,14 @@ QDF_STATUS cm_roam_sync_event_handler_cb(struct wlan_objmgr_vdev *vdev,
 	    !is_multi_link_roam(sync_ind)) {
 		mlme_err("vdev:%d Ignoring RSI as its already in progress on roamed vdev:%d",
 			 vdev_id, sync_ind->roamed_vdev_id);
-		status = QDF_STATUS_E_FAILURE;
-		goto err;
+		return QDF_STATUS_E_FAILURE;
 	}
 
 	status = cm_fw_roam_sync_start_ind(vdev, sync_ind);
 	if (QDF_IS_STATUS_ERROR(status)) {
 		mlme_err("LFR3: vdev:%d CSR Roam synch cb failed", vdev_id);
 		wlan_cm_free_roam_synch_frame_ind(rso_cfg);
-		goto err;
+		return status;
 	}
 
 	/* 24 byte MAC header and 12 byte to ssid IE */
@@ -585,8 +584,7 @@ QDF_STATUS cm_roam_sync_event_handler_cb(struct wlan_objmgr_vdev *vdev,
 		} else {
 			mlme_err("LFR3: MLO: vdev:%d Invalid link Beacon Length",
 				 vdev_id);
-			status = QDF_STATUS_E_FAILURE;
-			goto err;
+			return QDF_STATUS_E_FAILURE;
 		}
 	} else if (sync_ind->beacon_probe_resp_length >
 			(QDF_IEEE80211_3ADDR_HDR_LEN + MAC_B_PR_SSID_OFFSET)) {
@@ -613,18 +611,18 @@ QDF_STATUS cm_roam_sync_event_handler_cb(struct wlan_objmgr_vdev *vdev,
 	} else {
 		mlme_err("LFR3: vdev:%d Invalid Beacon Length:%d", vdev_id,
 			 sync_ind->beacon_probe_resp_length);
-		status = QDF_STATUS_E_FAILURE;
-		goto err;
+		return QDF_STATUS_E_FAILURE;
 	}
 
 	if (QDF_IS_STATUS_ERROR(cm_roam_pe_sync_callback(sync_ind, vdev_id,
 							 ie_len))) {
 		mlme_err("LFR3: vdev:%d PE roam synch cb failed", vdev_id);
-		status = QDF_STATUS_E_BUSY;
-		goto err;
+		return QDF_STATUS_E_BUSY;
 	}
 
-	cm_roam_update_vdev(vdev, sync_ind);
+	status = cm_roam_update_vdev(vdev, sync_ind);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
 
 	/*
 	 * update phy_mode in wma to avoid mismatch in phymode between host and
@@ -640,6 +638,5 @@ QDF_STATUS cm_roam_sync_event_handler_cb(struct wlan_objmgr_vdev *vdev,
 					     vdev_id,
 					     sync_ind);
 
-err:
 	return status;
 }

+ 3 - 3
components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h

@@ -1989,10 +1989,10 @@ cm_roam_vendor_handoff_event_handler(struct wlan_objmgr_psoc *psoc,
  * respect to the self sta and the peer after roaming and completes
  * the roam synch propagation with respect to WMA layer.
  *
- * Return: None
+ * Return: QDF_STATUS
  */
-void cm_roam_update_vdev(struct wlan_objmgr_vdev *vdev,
-			 struct roam_offload_synch_ind *sync_ind);
+QDF_STATUS cm_roam_update_vdev(struct wlan_objmgr_vdev *vdev,
+			       struct roam_offload_synch_ind *sync_ind);
 
 /**
  * cm_roam_pe_sync_callback() - Callback registered at pe, gets invoked when

+ 7 - 8
core/mac/src/pe/include/lim_api.h

@@ -904,12 +904,11 @@ lim_cm_fill_link_session(struct mac_context *mac_ctx,
  *
  * This api will create mlo peer called during mlo roaming scenario
  *
- * Return: none
+ * Return: QDF_STATUS
  */
-void lim_roam_mlo_create_peer(struct mac_context *mac,
-			      struct roam_offload_synch_ind *sync_ind,
-			      uint8_t vdev_id,
-			      uint8_t *peer_mac);
+QDF_STATUS lim_roam_mlo_create_peer(struct mac_context *mac,
+				    struct roam_offload_synch_ind *sync_ind,
+				    uint8_t vdev_id, uint8_t *peer_mac);
 
 /**
  * lim_mlo_roam_delete_link_peer() - Delete mlo link peer
@@ -951,12 +950,12 @@ lim_cm_fill_link_session(struct mac_context *mac_ctx,
 	return QDF_STATUS_E_NOSUPPORT;
 }
 
-static inline void
+static inline QDF_STATUS
 lim_roam_mlo_create_peer(struct mac_context *mac,
 			 struct roam_offload_synch_ind *sync_ind,
-			 uint8_t vdev_id,
-			 uint8_t *peer_mac)
+			 uint8_t vdev_id, uint8_t *peer_mac)
 {
+	return QDF_STATUS_SUCCESS;
 }
 
 static inline void

+ 12 - 11
core/mac/src/pe/lim/lim_api.c

@@ -3700,23 +3700,22 @@ fail:
 	return QDF_STATUS_E_FAILURE;
 }
 
-void lim_roam_mlo_create_peer(struct mac_context *mac,
-			      struct roam_offload_synch_ind *sync_ind,
-			      uint8_t vdev_id,
-			      uint8_t *peer_mac)
+QDF_STATUS lim_roam_mlo_create_peer(struct mac_context *mac,
+				    struct roam_offload_synch_ind *sync_ind,
+				    uint8_t vdev_id, uint8_t *peer_mac)
 {
 	struct wlan_objmgr_vdev *vdev;
 	struct wlan_objmgr_peer *link_peer = NULL;
 	uint8_t link_id;
 	struct mlo_partner_info partner_info;
 	struct qdf_mac_addr link_addr;
-	QDF_STATUS status;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
 
 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc,
 						    vdev_id,
 						    WLAN_LEGACY_MAC_ID);
 	if (!vdev)
-		return;
+		return QDF_STATUS_E_INVAL;
 
 	if (!wlan_vdev_mlme_is_mlo_vdev(vdev))
 		goto end;
@@ -3740,19 +3739,21 @@ void lim_roam_mlo_create_peer(struct mac_context *mac,
 	/* Get the bss peer obj */
 	link_peer = wlan_objmgr_get_peer_by_mac(mac->psoc, peer_mac,
 						WLAN_LEGACY_MAC_ID);
-	if (!link_peer)
+	if (!link_peer) {
+		status = QDF_STATUS_E_INVAL;
 		goto end;
+	}
 
-	status = wlan_mlo_peer_create(vdev, link_peer,
-				      &partner_info, NULL, 0);
-
+	status = wlan_mlo_peer_create(vdev, link_peer, &partner_info, NULL, 0);
 	if (QDF_IS_STATUS_ERROR(status))
-		pe_err("Peer creation failed");
+		pe_err("MLO peer creation failed");
 
 	wlan_objmgr_peer_release_ref(link_peer, WLAN_LEGACY_MAC_ID);
 
 end:
 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
+
+	return status;
 }
 
 void

+ 45 - 29
core/wma/src/wma_scan_roam.c

@@ -689,9 +689,9 @@ wma_delete_all_peers(tp_wma_handle wma,
  * respect to the self sta and the peer after roaming and completes
  * the roam synch propagation with respect to WMA layer.
  *
- * Return: None
+ * Return: QDF_STATUS
  */
-static void
+static QDF_STATUS
 wma_roam_update_vdev(tp_wma_handle wma,
 		     struct roam_offload_synch_ind *roam_synch_ind_ptr,
 		     uint8_t roamed_vdev_id)
@@ -707,8 +707,7 @@ wma_roam_update_vdev(tp_wma_handle wma,
 	wma->interfaces[vdev_id].nss = roam_synch_ind_ptr->nss;
 
 	/* update channel width */
-	wma->interfaces[vdev_id].chan_width =
-		roam_synch_ind_ptr->chan_width;
+	wma->interfaces[vdev_id].chan_width = roam_synch_ind_ptr->chan_width;
 	/* Fill link freq from roam_synch_ind */
 	if (is_multi_link_roam(roam_synch_ind_ptr))
 		wma->interfaces[vdev_id].ch_freq =
@@ -718,9 +717,8 @@ wma_roam_update_vdev(tp_wma_handle wma,
 			roam_synch_ind_ptr->chan_freq;
 
 	add_sta_params = qdf_mem_malloc(sizeof(*add_sta_params));
-	if (!add_sta_params) {
-		return;
-	}
+	if (!add_sta_params)
+		return QDF_STATUS_E_INVAL;
 
 	if (is_multi_link_roam(roam_synch_ind_ptr))
 		mlo_get_sta_link_mac_addr(vdev_id, roam_synch_ind_ptr,
@@ -745,35 +743,45 @@ wma_roam_update_vdev(tp_wma_handle wma,
 
 	add_sta_params->staType = STA_ENTRY_SELF;
 	add_sta_params->smesessionId = vdev_id;
-	qdf_mem_copy(&add_sta_params->bssId, &mac_addr,
-			 QDF_MAC_ADDR_SIZE);
+	qdf_mem_copy(&add_sta_params->bssId, &mac_addr, QDF_MAC_ADDR_SIZE);
 	add_sta_params->assocId = roam_synch_ind_ptr->aid;
 
 	bssid = wma_get_vdev_bssid(wma->interfaces[vdev_id].vdev);
 	if (!bssid) {
 		wma_err("Failed to get bssid for vdev_%d", vdev_id);
-		return;
+		return QDF_STATUS_E_INVAL;
 	}
 
 	is_assoc_peer = wlan_vdev_mlme_get_is_mlo_vdev(wma->psoc, vdev_id);
 	if (is_multi_link_roam(roam_synch_ind_ptr)) {
-		wma_create_peer(wma, mac_addr.bytes,
-				WMI_PEER_TYPE_DEFAULT, vdev_id,
-				roam_synch_ind_ptr->bssid.bytes,
-				is_assoc_peer);
+		status = wma_create_peer(wma, mac_addr.bytes,
+					 WMI_PEER_TYPE_DEFAULT, vdev_id,
+					 roam_synch_ind_ptr->bssid.bytes,
+					 is_assoc_peer);
 	} else {
-		wma_create_peer(wma, mac_addr.bytes,
-				WMI_PEER_TYPE_DEFAULT,
-				vdev_id,
-				NULL,
-				is_assoc_peer);
+		status = wma_create_peer(wma, mac_addr.bytes,
+					 WMI_PEER_TYPE_DEFAULT, vdev_id, NULL,
+					 is_assoc_peer);
 	}
 
-	if (is_multi_link_roam(roam_synch_ind_ptr))
-		lim_roam_mlo_create_peer(wma->mac_context,
-					 roam_synch_ind_ptr,
-					 vdev_id,
-					 mac_addr.bytes);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		wma_err("Failed to create peer " QDF_MAC_ADDR_FMT,
+			QDF_MAC_ADDR_REF(mac_addr.bytes));
+		goto end;
+	}
+
+	if (is_multi_link_roam(roam_synch_ind_ptr)) {
+		status = lim_roam_mlo_create_peer(wma->mac_context,
+						  roam_synch_ind_ptr, vdev_id,
+						  mac_addr.bytes);
+
+		/* The created peer will be destroyed on HO failure cleanup */
+		if (QDF_IS_STATUS_ERROR(status)) {
+			wma_err("Failed to attach MLO peer " QDF_MAC_ADDR_FMT,
+				QDF_MAC_ADDR_REF(mac_addr.bytes));
+			goto end;
+		}
+	}
 
 	if (wlan_vdev_mlme_get_opmode(wma->interfaces[vdev_id].vdev) ==
 								QDF_STA_MODE)
@@ -796,6 +804,7 @@ wma_roam_update_vdev(tp_wma_handle wma,
 				      roam_synch_ind_ptr);
 end:
 	qdf_mem_free(add_sta_params);
+	return status;
 }
 
 static void wma_update_phymode_on_roam(tp_wma_handle wma,
@@ -3148,19 +3157,24 @@ QDF_STATUS wma_send_ht40_obss_scanind(tp_wma_handle wma,
 }
 
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
-void cm_roam_update_vdev(struct wlan_objmgr_vdev *vdev,
-			 struct roam_offload_synch_ind *sync_ind)
+QDF_STATUS cm_roam_update_vdev(struct wlan_objmgr_vdev *vdev,
+			       struct roam_offload_synch_ind *sync_ind)
 {
+	QDF_STATUS status;
 	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
 	struct qdf_mac_addr *self_mac_addr;
 	uint8_t vdev_id;
 
 	if (!wma)
-		return;
+		return QDF_STATUS_E_INVAL;
 
 	vdev_id = wlan_vdev_get_id(vdev);
 
-	wma_roam_update_vdev(wma, sync_ind, vdev_id);
+	status = wma_roam_update_vdev(wma, sync_ind, vdev_id);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		wma_debug("VDEV update failed for roam on %d", vdev_id);
+		return status;
+	}
 
 	if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) {
 		self_mac_addr =
@@ -3170,13 +3184,15 @@ void cm_roam_update_vdev(struct wlan_objmgr_vdev *vdev,
 
 	if (wlan_vdev_mlme_is_mlo_vdev(vdev) &&
 	    wlan_vdev_mlme_is_mlo_link_vdev(vdev))
-		return;
+		return QDF_STATUS_SUCCESS;
 
 	self_mac_addr = (struct qdf_mac_addr *)wlan_vdev_mlme_get_mldaddr(vdev);
 
 update_deflink:
 	/* Set the assoc vdev as DP deflink after roaming */
 	wlan_dp_update_def_link(wma->psoc, self_mac_addr, vdev);
+
+	return QDF_STATUS_SUCCESS;
 }
 
 QDF_STATUS