Эх сурвалжийг харах

qcacmn: Implement AP start/stop API in mlo mgr

Implement AP start/stop API in mlo manager.

Change-Id: Ib9fcc4a678ebfe1ad57043891b12fc98998cf931
CRs-Fixed: 2970650
Sandeep Puligilla 4 жил өмнө
parent
commit
9c652b4d8b

+ 15 - 0
umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h

@@ -814,6 +814,21 @@ static inline uint8_t wlan_vdev_get_link_id(struct wlan_objmgr_vdev *vdev)
 {
 	return vdev->vdev_mlme.mlo_link_id;
 }
+
+/**
+ * wlan_vdev_set_link_id() - set vdev mlo link id
+ * @vdev: VDEV object
+ * @link_id: link id
+ *
+ * API to set vdev mlo link id
+ *
+ * Return: void
+ */
+static inline void wlan_vdev_set_link_id(struct wlan_objmgr_vdev *vdev,
+					 uint8_t link_id)
+{
+	vdev->vdev_mlme.mlo_link_id = link_id;
+}
 #else
 static inline uint8_t wlan_vdev_get_link_id(struct wlan_objmgr_vdev *vdev)
 {

+ 3 - 0
umac/mlme/vdev_mgr/core/src/vdev_mlme_sm.c

@@ -192,6 +192,7 @@ static bool mlme_vdev_state_init_event(void *ctx, uint16_t event,
 		 */
 		mlme_vdev_notify_down_complete(vdev_mlme, event_data_len,
 					       event_data);
+		mlme_vdev_down_cmpl_notify_mlo_mgr(vdev_mlme);
 		status = true;
 		break;
 
@@ -882,6 +883,8 @@ static bool mlme_vdev_subst_start_conn_progress_event(void *ctx,
 					vdev_mlme,
 					WLAN_VDEV_SM_EV_CONNECTION_FAIL,
 					event_data_len, event_data);
+		else
+			mlme_vdev_start_rsp_notify_mlo_mgr(vdev_mlme);
 		status = true;
 		break;
 

+ 39 - 1
umac/mlme/vdev_mgr/core/src/vdev_mlme_sm.h

@@ -23,6 +23,7 @@
 #ifndef _VDEV_MLME_SM_H_
 #define _VDEV_MLME_SM_H_
 
+#include <wlan_mlo_mgr_ap.h>
 /**
  * mlme_vdev_sm_deliver_event() - Delivers event to VDEV MLME SM
  * @vdev_mlme: MLME VDEV comp object
@@ -631,12 +632,49 @@ static inline QDF_STATUS mlme_vdev_dfs_cac_wait_notify(
  */
 static inline void mlme_vdev_up_notify_mlo_mgr(struct vdev_mlme_obj *vdev_mlme)
 {
-	/* Add call to mlo_handle_link_up(vdev_mlme->vdev) once it is ready */
+	if (wlan_vdev_mlme_is_mlo_ap(vdev_mlme->vdev))
+		mlo_ap_link_sync_wait_notify(vdev_mlme->vdev);
+}
+
+/**
+ * mlme_vdev_start_rsp_notify_mlo_mgr - notify mlo link is started
+ * @vdev_mlme_obj:  VDEV MLME comp object
+ *
+ * Return: VOID.
+ */
+static inline void mlme_vdev_start_rsp_notify_mlo_mgr(
+					struct vdev_mlme_obj *vdev_mlme)
+{
+	if (wlan_vdev_mlme_is_mlo_ap(vdev_mlme->vdev))
+		mlo_ap_link_start_rsp_notify(vdev_mlme->vdev);
+}
+
+/**
+ * mlme_vdev_down_cmpl_notify_mlo_mgr - notify mlo link is down complate
+ * @vdev_mlme_obj:  VDEV MLME comp object
+ *
+ * Return: VOID.
+ */
+static inline void mlme_vdev_down_cmpl_notify_mlo_mgr(
+					struct vdev_mlme_obj *vdev_mlme)
+{
+	if (wlan_vdev_mlme_is_mlo_ap(vdev_mlme->vdev))
+		mlo_ap_link_down_cmpl_notify(vdev_mlme->vdev);
 }
 #else
 static inline void mlme_vdev_up_notify_mlo_mgr(struct vdev_mlme_obj *vdev_mlme)
 {
 }
+
+static inline void mlme_vdev_start_rsp_notify_mlo_mgr(
+					struct vdev_mlme_obj *vdev_mlme)
+{
+}
+
+static inline void mlme_vdev_down_cmpl_notify_mlo_mgr(
+					struct vdev_mlme_obj *vdev_mlme)
+{
+}
 #endif
 
 #ifdef VDEV_SM_LOCK_SUPPORT

+ 50 - 13
umac/mlo_mgr/inc/wlan_mlo_mgr_ap.h

@@ -20,38 +20,75 @@
 #ifndef _WLAN_MLO_MGR_AP_H_
 #define _WLAN_MLO_MGR_AP_H_
 
+#include <wlan_mlo_mgr_cmn.h>
+#include <wlan_mlo_mgr_public_structs.h>
+
 /**
- * mlo_ap_link_start_rsp_notify - Notifies that the link is completed
+ * mlo_is_mld_ap - Check if MLD associated with the vdev is an AP
  *
  * @vdev: pointer to vdev
  *
- * Return: none
+ * Return: true if MLD is an AP, false otherwise
  */
-void mlo_ap_link_start_rsp_notify(struct wlan_objmgr_vdev *vdev);
+bool mlo_is_mld_ap(struct wlan_objmgr_vdev *vdev);
 
 /**
- * mlo_is_ap_vdev_up_allowed - Checks if the AP can be started
+ * mlo_ap_vdev_attach() - update vdev obj and vdev count to
+ *                         wlan_mlo_dev_context
+ * @vdev: vdev pointer
+ * @link_id: link id
+ * @vdev_count: number of vdev in the mlo
  *
- * Return: true if vdev is allowed to come up, false otherwise
+ * Return: true if succeeds
  */
-bool mlo_is_ap_vdev_up_allowed(struct wlan_objmgr_vdev *vdev);
+bool mlo_ap_vdev_attach(struct wlan_objmgr_vdev *vdev,
+			uint8_t link_id,
+			uint16_t vdev_count);
 
 /**
- * mlo_ap_link_down_notify - Currently does nothing
+ * mlo_ap_get_vdev_list() - get mlo vdev list
+ * @vdev: vdev pointer
+ * @vdev_count: vdev count
+ * @wlan_vdev_list: vdev list
  *
- * @vdev: pointer to vdev
+ * Return: None
+ */
+void mlo_ap_get_vdev_list(struct wlan_objmgr_vdev *vdev,
+			  uint16_t *vdev_count,
+			  struct wlan_objmgr_vdev **wlan_vdev_list);
+
+/**
+ * mlo_ap_link_sync_wait_notify() - notify the mlo manager, once vdev
+ *                                  enters WLAN_VDEV_SS_MLO_SYNC_WAIT
+ * @vdev: vdev pointer
  *
- * Return: none
+ * Return: None
  */
-void mlo_ap_link_down_notify(struct wlan_objmgr_vdev *vdev);
+void mlo_ap_link_sync_wait_notify(struct wlan_objmgr_vdev *vdev);
 
 /**
- * mlo_is_mld_ap - Check if MLD associated with the vdev is an AP
+ * mlo_ap_link_start_rsp_notify - Notifies that the link is completed
  *
  * @vdev: pointer to vdev
  *
- * Return: true if MLD is an AP, false otherwise
+ * Return: none
  */
-bool mlo_is_mld_ap(struct wlan_objmgr_vdev *vdev);
+void mlo_ap_link_start_rsp_notify(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * mlo_ap_vdev_detach() - notify the mlo manager to detach given vdev
+ * @vdev: vdev pointer
+ *
+ * Return: None
+ */
+void mlo_ap_vdev_detach(struct wlan_objmgr_vdev *vdev);
 
+/**
+ * mlo_ap_link_down_cmpl_notify() - notify the mlo manager, once vdev
+ *                                  is down completely
+ * @vdev: vdev pointer
+ *
+ * Return: None
+ */
+void mlo_ap_link_down_cmpl_notify(struct wlan_objmgr_vdev *vdev);
 #endif

+ 3 - 3
umac/mlo_mgr/inc/wlan_mlo_mgr_cmn.h

@@ -102,16 +102,16 @@ void mlo_get_link_information(struct qdf_mac_addr *mld_addr,
 void is_mlo_all_links_up(struct wlan_mlo_dev_context *ml_dev);
 
 /**
- * mlo_get_partner_vdev_by_link_id() - get partner vdev by link id
+ * mlo_get_vdev_by_link_id() - get vdev by link id
  * @vdev: vdev pointer
  * @link_id: link id
  *
  * Caller should make sure to release the reference of thus obtained vdev
  * by calling mlo_release_vdev_ref() after usage of vdev.
  *
- * Return: vdev object pointer to partner link
+ * Return: vdev object pointer to link id
  */
-struct wlan_objmgr_vdev *mlo_get_partner_vdev_by_link_id(
+struct wlan_objmgr_vdev *mlo_get_vdev_by_link_id(
 			struct wlan_objmgr_vdev *vdev,
 			uint8_t link_id);
 

+ 175 - 17
umac/mlo_mgr/src/wlan_mlo_mgr_ap.c

@@ -19,35 +19,193 @@
  */
 #include "wlan_objmgr_vdev_obj.h"
 #include "wlan_mlo_mgr_ap.h"
+#include <wlan_mlo_mgr_cmn.h>
+#include <wlan_mlo_mgr_main.h>
 
-void mlo_ap_link_start_rsp_notify(struct wlan_objmgr_vdev *vdev)
+bool mlo_is_mld_ap(struct wlan_objmgr_vdev *vdev)
 {
-	/* This is to notify the link is completed start*/
-	// mlo_is_ap_vdev_up_allowed()
+	return true;
 }
 
-/* Need to take care of DFS CAC WAIT state*/
-bool mlo_is_ap_vdev_up_allowed(struct wlan_objmgr_vdev *vdev)
+bool mlo_ap_vdev_attach(struct wlan_objmgr_vdev *vdev,
+			uint8_t link_id,
+			uint16_t vdev_count)
 {
-// max_links = get the number of links(internal ml dev ctx);
+	struct wlan_mlo_dev_context *dev_ctx;
 
-/* if ( max_links == vdev_list_count)
- *	while ( iterate over vdev object)
- *		check the vdev object status;
- * If ( All sub states are vdev UP WAIT)
- *	Call VDEV MLME to send the VDEV_UP command by sending
- *	WLAN_VDEV_SM_SYNC_COMPLETE on the vdev's which are in UP_WAIT_STATE.
- */
+	if (!vdev || !vdev->mlo_dev_ctx) {
+		mlo_err("Invalid input");
+		return false;
+	}
+
+	dev_ctx = vdev->mlo_dev_ctx;
+	wlan_vdev_set_link_id(vdev, link_id);
+	wlan_vdev_mlme_feat_ext2_cap_set(vdev, WLAN_VDEV_FEXT2_MLO);
+
+	/**
+	 * every link will trigger mlo_ap_vdev_attach,
+	 * and they should provide the same vdev_count.
+	 */
+	mlo_dev_lock_acquire(dev_ctx);
+	dev_ctx->wlan_vdev_count = vdev_count;
+	mlo_dev_lock_release(dev_ctx);
 
 	return true;
 }
 
-void mlo_ap_link_down_notify(struct wlan_objmgr_vdev *vdev)
+void mlo_ap_get_vdev_list(struct wlan_objmgr_vdev *vdev,
+			  uint16_t *vdev_count,
+			  struct wlan_objmgr_vdev **wlan_vdev_list)
 {
-/* No op */
+	struct wlan_mlo_dev_context *dev_ctx;
+	int i;
+	QDF_STATUS status;
+
+	*vdev_count = 0;
+
+	if (!vdev || !vdev->mlo_dev_ctx) {
+		mlo_err("Invalid input");
+		return;
+	}
+
+	dev_ctx = vdev->mlo_dev_ctx;
+
+	mlo_dev_lock_acquire(dev_ctx);
+	*vdev_count = 0;
+	for (i = 0; i < QDF_ARRAY_SIZE(dev_ctx->wlan_vdev_list); i++) {
+		if (dev_ctx->wlan_vdev_list[i] &&
+		    wlan_vdev_mlme_is_mlo_ap(dev_ctx->wlan_vdev_list[i])) {
+			status = wlan_objmgr_vdev_try_get_ref(
+						dev_ctx->wlan_vdev_list[i],
+						WLAN_MLO_MGR_ID);
+			if (QDF_IS_STATUS_ERROR(status))
+				break;
+			wlan_vdev_list[*vdev_count] =
+				dev_ctx->wlan_vdev_list[i];
+			(*vdev_count) += 1;
+		}
+	}
+	mlo_dev_lock_release(dev_ctx);
 }
 
-bool mlo_is_mld_ap(struct wlan_objmgr_vdev *vdev)
+/**
+ * mlo_is_ap_vdev_up_allowed() - Is mlo ap allowed to come up
+ * @vdev: vdev pointer
+ *
+ * Return: true if given ap is allowed to up, false otherwise.
+ */
+static bool mlo_is_ap_vdev_up_allowed(struct wlan_objmgr_vdev *vdev)
 {
-	return true;
+	uint16_t vdev_count = 0;
+	struct wlan_mlo_dev_context *dev_ctx;
+	int i;
+	bool up_allowed = false;
+
+	if (!vdev || !vdev->mlo_dev_ctx) {
+		mlo_err("Invalid input");
+		return up_allowed;
+	}
+
+	dev_ctx = vdev->mlo_dev_ctx;
+
+	mlo_dev_lock_acquire(dev_ctx);
+	for (i = 0; i < QDF_ARRAY_SIZE(dev_ctx->wlan_vdev_list); i++) {
+		if (dev_ctx->wlan_vdev_list[i] &&
+		    wlan_vdev_mlme_is_mlo_ap(dev_ctx->wlan_vdev_list[i]) &&
+		    QDF_IS_STATUS_SUCCESS(
+		    wlan_vdev_chan_config_valid(dev_ctx->wlan_vdev_list[i])))
+			vdev_count++;
+	}
+
+	if (vdev_count == dev_ctx->wlan_vdev_count)
+		up_allowed = true;
+	mlo_dev_lock_release(dev_ctx);
+
+	return up_allowed;
+}
+
+/**
+ * mlo_pre_link_up() - Carry out preparation before bringing up the link
+ * @vdev: vdev pointer
+ *
+ * Return: true if preparation is done successfully
+ */
+static bool mlo_pre_link_up(struct wlan_objmgr_vdev *vdev)
+{
+	if (!vdev) {
+		mlo_err("vdev is NULL");
+		return false;
+	}
+
+	if ((wlan_vdev_mlme_get_state(vdev) == WLAN_VDEV_S_UP) &&
+	    (wlan_vdev_mlme_get_substate(vdev) ==
+	     WLAN_VDEV_SS_MLO_SYNC_WAIT))
+		return true;
+
+	return false;
+}
+
+/**
+ * mlo_handle_link_ready() - Check if mlo ap is allowed to up or not.
+ *                           If it is allowed, for every link in the
+ *                           WLAN_VDEV_SS_MLO_SYNC_WAIT state, deliver
+ *                           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
+ *
+ * @vdev: vdev pointer
+ *
+ * Return: None
+ */
+static void mlo_handle_link_ready(struct wlan_objmgr_vdev *vdev)
+{
+	struct wlan_mlo_dev_context *dev_ctx;
+	int i;
+
+	if (!vdev || !vdev->mlo_dev_ctx) {
+		mlo_err("Invalid input");
+		return;
+	}
+
+	dev_ctx = vdev->mlo_dev_ctx;
+
+	if (!mlo_is_ap_vdev_up_allowed(vdev))
+		return;
+
+	mlo_dev_lock_acquire(dev_ctx);
+	for (i = 0; i < QDF_ARRAY_SIZE(dev_ctx->wlan_vdev_list); i++) {
+		if (dev_ctx->wlan_vdev_list[i] &&
+		    wlan_vdev_mlme_is_mlo_ap(dev_ctx->wlan_vdev_list[i]) &&
+		    mlo_pre_link_up(dev_ctx->wlan_vdev_list[i]))
+			wlan_vdev_mlme_sm_deliver_evt(
+				dev_ctx->wlan_vdev_list[i],
+				WLAN_VDEV_SM_EV_MLO_SYNC_COMPLETE,
+				0, NULL);
+	}
+	mlo_dev_lock_release(dev_ctx);
+}
+
+void mlo_ap_link_sync_wait_notify(struct wlan_objmgr_vdev *vdev)
+{
+	mlo_handle_link_ready(vdev);
+}
+
+void mlo_ap_link_start_rsp_notify(struct wlan_objmgr_vdev *vdev)
+{
+	mlo_handle_link_ready(vdev);
+}
+
+void mlo_ap_vdev_detach(struct wlan_objmgr_vdev *vdev)
+{
+	if (!vdev || !vdev->mlo_dev_ctx) {
+		mlo_err("Invalid input");
+		return;
+	}
+	wlan_vdev_mlme_feat_ext2_cap_clear(vdev, WLAN_VDEV_FEXT2_MLO);
+}
+
+void mlo_ap_link_down_cmpl_notify(struct wlan_objmgr_vdev *vdev)
+{
+	mlo_ap_vdev_detach(vdev);
 }

+ 1 - 1
umac/mlo_mgr/src/wlan_mlo_mgr_cmn.c

@@ -32,7 +32,7 @@ void is_mlo_all_links_up(struct wlan_mlo_dev_context *mldev)
 /* STA: Loop through all the associated vdev status. */
 }
 
-struct wlan_objmgr_vdev *mlo_get_partner_vdev_by_link_id(
+struct wlan_objmgr_vdev *mlo_get_vdev_by_link_id(
 			struct wlan_objmgr_vdev *vdev,
 			uint8_t link_id)
 {