Ver código fonte

qcacmn: Dispatch mlo_sync_complete in async context

In scenario where the last ML-AP vdev of the MLD receives start response,
then in the same context mlo_sync_complete is dispatched to all the
partner ML AP vdevs.

But for the partner vdevs, VDEV SM event should be dispatched in
non-sync mode with lock held. If not it can lead to event being
dispatched when the VDEV is in intermediate transition state.

For partner vdevs dispatch event as part of callback and based on return
value, dispatch event in sync context for self vdev.
This is to avoid usage of mlme vdev sm sync event dispatch outside VDEV SM

Change-Id: Ib9220c04377985b700138127695a02a5e29952c2
CRs-Fixed: 3317097
Santosh Anbu 2 anos atrás
pai
commit
2bdc874104

+ 5 - 1
umac/mlme/vdev_mgr/core/src/vdev_mlme_sm.c

@@ -1693,7 +1693,11 @@ static bool mlme_vdev_subst_mlo_sync_wait_event(void *ctx, uint16_t event,
 
 	switch (event) {
 	case WLAN_VDEV_SM_EV_START_SUCCESS:
-		mlme_vdev_up_notify_mlo_mgr(vdev_mlme);
+		if (mlme_vdev_up_notify_mlo_mgr(vdev_mlme))
+			mlme_vdev_sm_deliver_event(
+					vdev_mlme,
+					WLAN_VDEV_SM_EV_MLO_SYNC_COMPLETE,
+					event_data_len, event_data);
 		status = true;
 		break;
 

+ 8 - 5
umac/mlme/vdev_mgr/core/src/vdev_mlme_sm.h

@@ -644,14 +644,16 @@ static inline QDF_STATUS mlme_vdev_chan_switch_disable_notify_dfs(
 #ifdef WLAN_FEATURE_11BE_MLO
 /**
  * mlme_vdev_up_notify_mlo_mgr - notify mlo link is ready to up
- * @vdev_mlme_obj:  VDEV MLME comp object
+ * @vdev_mlme:  VDEV MLME comp object
  *
- * Return: VOID.
+ * Return: true if MLO_SYNC_COMPLETE is posted, else false
  */
-static inline void mlme_vdev_up_notify_mlo_mgr(struct vdev_mlme_obj *vdev_mlme)
+static inline bool mlme_vdev_up_notify_mlo_mgr(struct vdev_mlme_obj *vdev_mlme)
 {
 	if (wlan_vdev_mlme_is_mlo_ap(vdev_mlme->vdev))
-		mlo_ap_link_sync_wait_notify(vdev_mlme->vdev);
+		return mlo_ap_link_sync_wait_notify(vdev_mlme->vdev);
+
+	return true;
 }
 
 /**
@@ -713,8 +715,9 @@ static inline QDF_STATUS mlme_vdev_notify_mlo_sync_wait_entry(
 	return ret;
 }
 #else
-static inline void mlme_vdev_up_notify_mlo_mgr(struct vdev_mlme_obj *vdev_mlme)
+static inline bool mlme_vdev_up_notify_mlo_mgr(struct vdev_mlme_obj *vdev_mlme)
 {
+	return true;
 }
 
 static inline void mlme_vdev_start_rsp_notify_mlo_mgr(

+ 2 - 2
umac/mlo_mgr/inc/wlan_mlo_mgr_ap.h

@@ -85,9 +85,9 @@ void mlo_ap_get_partner_vdev_list_from_mld(
  *                                  enters WLAN_VDEV_SS_MLO_SYNC_WAIT
  * @vdev: vdev pointer
  *
- * Return: None
+ * Return: true if MLO_SYNC_COMPLETE is posted, else false
  */
-void mlo_ap_link_sync_wait_notify(struct wlan_objmgr_vdev *vdev);
+bool mlo_ap_link_sync_wait_notify(struct wlan_objmgr_vdev *vdev);
 
 /**
  * mlo_ap_link_start_rsp_notify - Notify that the link start is completed

+ 13 - 10
umac/mlo_mgr/src/wlan_mlo_mgr_ap.c

@@ -261,13 +261,13 @@ static bool mlo_pre_link_up(struct wlan_objmgr_vdev *vdev)
  *                           event WLAN_VDEV_SM_EV_MLO_SYNC_COMPLETE.
  *
  * This function is triggered once a link gets start response or enters
- * LAN_VDEV_SS_MLO_SYNC_WAIT state
+ * WLAN_VDEV_SS_MLO_SYNC_WAIT state
  *
  * @vdev: vdev pointer
  *
- * Return: None
+ * Return: true if MLO_SYNC_COMPLETE is posted, else false
  */
-static void mlo_handle_link_ready(struct wlan_objmgr_vdev *vdev)
+static bool mlo_handle_link_ready(struct wlan_objmgr_vdev *vdev)
 {
 	struct wlan_objmgr_vdev *vdev_list[WLAN_UMAC_MLO_MAX_VDEVS] = {NULL};
 	uint16_t num_links = 0;
@@ -275,32 +275,35 @@ static void mlo_handle_link_ready(struct wlan_objmgr_vdev *vdev)
 
 	if (!vdev || !vdev->mlo_dev_ctx) {
 		mlo_err("Invalid input");
-		return;
+		return false;
 	}
 
 	if (!mlo_is_ap_vdev_up_allowed(vdev))
-		return;
+		return false;
 
 	mlo_ap_get_vdev_list(vdev, &num_links, vdev_list);
 	if (!num_links || (num_links > QDF_ARRAY_SIZE(vdev_list))) {
 		mlo_err("Invalid number of VDEVs under AP-MLD");
-		return;
+		return false;
 	}
 
 	for (i = 0; i < num_links; i++) {
-		if (mlo_pre_link_up(vdev_list[i]))
-			wlan_vdev_mlme_sm_deliver_evt_sync(
+		if (mlo_pre_link_up(vdev_list[i])) {
+			if (vdev_list[i] != vdev)
+				wlan_vdev_mlme_sm_deliver_evt(
 					vdev_list[i],
 					WLAN_VDEV_SM_EV_MLO_SYNC_COMPLETE,
 					0, NULL);
+		}
 		/* Release ref taken as part of mlo_ap_get_vdev_list */
 		mlo_release_vdev_ref(vdev_list[i]);
 	}
+	return true;
 }
 
-void mlo_ap_link_sync_wait_notify(struct wlan_objmgr_vdev *vdev)
+bool mlo_ap_link_sync_wait_notify(struct wlan_objmgr_vdev *vdev)
 {
-	mlo_handle_link_ready(vdev);
+	return mlo_handle_link_ready(vdev);
 }
 
 void mlo_ap_link_start_rsp_notify(struct wlan_objmgr_vdev *vdev)