瀏覽代碼

qcacmn: Add WLAN_VDEV_SS_MLO_SYNC_WAIT and WLAN_VDEV_SS_UP_ACTIVE

For MLO SAP, it can't generate beacon template until all the vdevs
start. To synchronize MLO vdevs start, we add two new substates
WLAN_VDEV_SS_MLO_SYNC_WAIT and WLAN_VDEV_SS_UP_ACTIVE whose parent
state is WLAN_VDEV_S_UP.
Once vdev gets vdev start rsp, notify MLO mgr, who checks whether all
vdevs are active, if so, trigger WLAN_VDEV_SM_EV_MLO_SYNC_COMPLETE for
the vdev which is in WLAN_VDEV_SS_MLO_SYNC_WAIT state.
After vdev translates to WLAN_VDEV_S_UP, MLO SAP will translate to
WLAN_VDEV_SS_MLO_SYNC_WAIT, while the other vdev will translate to
WLAN_VDEV_SS_UP_ACTIVE.
MLO sap will notify MLO mgr once it is in WLAN_VDEV_SS_MLO_SYNC_WAIT.
Then MLO mgr checks whether all the vdevs are active, if so, trigger
WLAN_VDEV_SM_EV_MLO_SYNC_COMPLETE for the vdev which is in
WLAN_VDEV_SS_MLO_SYNC_WAIT state.
If MLO SAP receives WLAN_VDEV_SM_EV_MLO_SYNC_COMPLETE in
WLAN_VDEV_SS_MLO_SYNC_WAIT state, it translates to WLAN_VDEV_SS_UP_ACTIVE

Change-Id: I8be9c02f62719dbdcf4af79d83173c316c64b765
CRs-Fixed: 2866103
bings 4 年之前
父節點
當前提交
4a8bafde55

+ 75 - 1
umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -169,6 +169,10 @@
 	/* Fils discovery on 6G SAP*/
 #define WLAN_VDEV_FEXT_FILS_DISC_6G_SAP     0x80000000
 
+/* Feature more extension flags */
+	/* VDEV is MLO*/
+#define WLAN_VDEV_FEXT2_MLO                 0x00000001
+
 /* VDEV OP flags  */
   /* if the vap destroyed by user */
 #define WLAN_VDEV_OP_DELETE_PROGRESS        0x00000001
@@ -291,6 +295,7 @@ struct wlan_channel {
  * @vdev_caps:          VDEV capabilities
  * @vdev_feat_caps:     VDEV feature caps
  * @vdev_feat_ext_caps: VDEV Extended feature caps
+ * @vdev_feat_ext2_caps: More VDEV Extended feature caps
  * @vdev_op_flags:      Operation flags
  * @mataddr[]:          MAT address
  * @macaddr[]:          VDEV self MAC address
@@ -313,6 +318,7 @@ struct wlan_objmgr_vdev_mlme {
 	uint32_t vdev_caps;
 	uint32_t vdev_feat_caps;
 	uint32_t vdev_feat_ext_caps;
+	uint32_t vdev_feat_ext2_caps;
 	uint32_t vdev_op_flags;
 	uint8_t  mataddr[QDF_MAC_ADDR_SIZE];
 	uint8_t  macaddr[QDF_MAC_ADDR_SIZE];
@@ -979,6 +985,55 @@ static inline uint8_t wlan_vdev_mlme_feat_ext_cap_get(
 	return (vdev->vdev_mlme.vdev_feat_ext_caps & cap) ? 1 : 0;
 }
 
+/**
+ * wlan_vdev_mlme_feat_ext2_cap_set() - set ext2 feature caps
+ * @vdev: VDEV object
+ * @cap: capabilities to be set
+ *
+ * API to set the MLME more extensive feature capabilities
+ *
+ * Return: void
+ */
+static inline void wlan_vdev_mlme_feat_ext2_cap_set(
+				struct wlan_objmgr_vdev *vdev,
+				uint32_t cap)
+{
+	vdev->vdev_mlme.vdev_feat_ext2_caps |= cap;
+}
+
+/**
+ * wlan_vdev_mlme_feat_ext2_cap_clear() - clear ext2 feature caps
+ * @vdev: VDEV object
+ * @cap: capabilities to be cleared
+ *
+ * API to clear the MLME more extensive feature capabilities
+ *
+ * Return: void
+ */
+static inline void wlan_vdev_mlme_feat_ext2_cap_clear(
+				struct wlan_objmgr_vdev *vdev,
+				uint32_t cap)
+{
+	vdev->vdev_mlme.vdev_feat_ext2_caps &= ~cap;
+}
+
+/**
+ * wlan_vdev_mlme_feat_ext2_cap_get() - get feature ext2 caps
+ * @vdev: VDEV object
+ * @cap: capabilities to be checked
+ *
+ * API to know MLME more ext feature capability is set or not
+ *
+ * Return: 1 -- if capabilities set
+ *         0 -- if capabilities clear
+ */
+static inline uint8_t wlan_vdev_mlme_feat_ext2_cap_get(
+				struct wlan_objmgr_vdev *vdev,
+				uint32_t cap)
+{
+	return (vdev->vdev_mlme.vdev_feat_ext2_caps & cap) ? 1 : 0;
+}
+
 /**
  * wlan_vdev_mlme_cap_set() - mlme caps set
  * @vdev: VDEV object
@@ -1185,6 +1240,25 @@ static inline uint16_t wlan_vdev_get_peer_count(struct wlan_objmgr_vdev *vdev)
 	return vdev->vdev_objmgr.wlan_peer_count;
 }
 
+#ifdef WLAN_FEATURE_11BE_MLO
+/**
+ * wlan_vdev_mlme_is_mlo_ap() - whether it is mlo ap or not
+ * @vdev: VDEV object
+ *
+ * Return: True if it is mlo ap, otherwise false.
+ */
+static inline bool wlan_vdev_mlme_is_mlo_ap(struct wlan_objmgr_vdev *vdev)
+{
+	return (wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE) &&
+	       wlan_vdev_mlme_feat_ext2_cap_get(vdev, WLAN_VDEV_FEXT2_MLO);
+}
+#else
+static inline bool wlan_vdev_mlme_is_mlo_ap(struct wlan_objmgr_vdev *vdev)
+{
+	return false;
+}
+#endif
+
 /**
  * DOC: Examples to use VDEV ref count APIs
  *

+ 10 - 2
umac/mlme/mlme_objmgr/dispatcher/inc/wlan_vdev_mlme_main.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -65,6 +65,8 @@ wlan_mlme_get_lmac_tx_ops(struct wlan_objmgr_psoc *psoc)
  * @WLAN_VDEV_SS_STOP_DOWN_PROGRESS:      Stop down progress sub state
  * @WLAN_VDEV_SS_IDLE:                    Idle sub state (used, only if a state
  *                                        does not have substate)
+ * @WLAN_VDEV_SS_MLO_SYNC_WAIT:           Sync wait sub state for MLO SAP
+ * @WLAN_VDEV_SS_UP_ACTIVE:               Up active sub state
  * @WLAN_VDEV_SS_MAX:                     Max substate
  */
 enum wlan_vdev_state {
@@ -86,7 +88,9 @@ enum wlan_vdev_state {
 	WLAN_VDEV_SS_STOP_STOP_PROGRESS = 15,
 	WLAN_VDEV_SS_STOP_DOWN_PROGRESS = 16,
 	WLAN_VDEV_SS_IDLE = 17,
-	WLAN_VDEV_SS_MAX = 18,
+	WLAN_VDEV_SS_MLO_SYNC_WAIT = 18,
+	WLAN_VDEV_SS_UP_ACTIVE = 19,
+	WLAN_VDEV_SS_MAX = 20,
 };
 
 /**
@@ -126,6 +130,9 @@ enum wlan_vdev_state {
  * @WLAN_VDEV_SM_EV_STOP_REQ:            Invoke API to initiate STOP handshake
  * @WLAN_VDEV_SM_EV_CHAN_SWITCH_DISABLED:Test only, CSA completes without
  *					 change in channel
+ * @WLAN_VDEV_SM_EV_MLO_SYNC_COMPLETE:   MLO mgr triggers this event for the mlo
+ *                                       sap in vdev wait up state, if all the
+ *                                       links finish vdev start rsp.
  */
 enum wlan_vdev_sm_evt {
 	WLAN_VDEV_SM_EV_START = 0,
@@ -159,6 +166,7 @@ enum wlan_vdev_sm_evt {
 	WLAN_VDEV_SM_EV_ROAM = 28,
 	WLAN_VDEV_SM_EV_STOP_REQ = 29,
 	WLAN_VDEV_SM_EV_CHAN_SWITCH_DISABLED = 30,
+	WLAN_VDEV_SM_EV_MLO_SYNC_COMPLETE = 31,
 };
 
 /**

+ 253 - 66
umac/mlme/vdev_mgr/core/src/vdev_mlme_sm.c

@@ -441,78 +441,17 @@ static bool mlme_vdev_state_up_event(void *ctx, uint16_t event,
 
 	switch (event) {
 	case WLAN_VDEV_SM_EV_START_SUCCESS:
-		mlme_vdev_update_beacon(vdev_mlme, BEACON_INIT,
-					event_data_len, event_data);
-		if (mlme_vdev_up_send(vdev_mlme, event_data_len,
-				      event_data) != QDF_STATUS_SUCCESS)
-			mlme_vdev_sm_deliver_event(vdev_mlme,
-						   WLAN_VDEV_SM_EV_UP_FAIL,
-						   event_data_len, event_data);
+		if (wlan_vdev_mlme_is_mlo_ap(vdev))
+			mlme_vdev_sm_transition_to(vdev_mlme,
+						   WLAN_VDEV_SS_MLO_SYNC_WAIT);
 		else
-			mlme_vdev_notify_up_complete(vdev_mlme, event_data_len,
-						     event_data);
-
-		status = true;
-		break;
-
-	case WLAN_VDEV_SM_EV_SUSPEND_RESTART:
-	case WLAN_VDEV_SM_EV_HOST_RESTART:
-	case WLAN_VDEV_SM_EV_CSA_RESTART:
-		/* These events are not supported in STA mode */
-		if (mode == QDF_STA_MODE)
-			QDF_BUG(0);
-		/* fallthrough */
-	case WLAN_VDEV_SM_EV_DOWN:
-		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_SUSPEND);
-		mlme_vdev_sm_deliver_event(vdev_mlme, event,
-					   event_data_len, event_data);
-		status = true;
-		break;
-
-	case WLAN_VDEV_SM_EV_RADAR_DETECTED:
-		/* These events are not supported in STA mode */
-		if (mode == QDF_STA_MODE)
-			QDF_BUG(0);
-		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_SUSPEND);
-		mlme_vdev_sm_deliver_event(vdev_mlme,
-					   WLAN_VDEV_SM_EV_CSA_RESTART,
-					   event_data_len, event_data);
-		status = true;
-		break;
-
-	case WLAN_VDEV_SM_EV_UP_HOST_RESTART:
-		/* Reinit beacon, send template to FW(use ping-pong buffer) */
-		mlme_vdev_update_beacon(vdev_mlme, BEACON_UPDATE,
-					event_data_len, event_data);
-		/* fallthrough */
-	case WLAN_VDEV_SM_EV_START:
-		/* notify that UP command is completed */
-		mlme_vdev_notify_up_complete(vdev_mlme,
-					     event_data_len, event_data);
-		status = true;
-		break;
-
-	case WLAN_VDEV_SM_EV_FW_VDEV_RESTART:
-		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_START);
-		mlme_vdev_sm_deliver_event(vdev_mlme,
-					   WLAN_VDEV_SM_EV_RESTART_REQ,
-					   event_data_len, event_data);
-		status = true;
-		break;
-
-	case WLAN_VDEV_SM_EV_UP_FAIL:
-		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_SUSPEND);
+			mlme_vdev_sm_transition_to(vdev_mlme,
+						   WLAN_VDEV_SS_UP_ACTIVE);
 		mlme_vdev_sm_deliver_event(vdev_mlme, event,
 					   event_data_len, event_data);
 		status = true;
 		break;
 
-	case WLAN_VDEV_SM_EV_ROAM:
-		mlme_vdev_notify_roam_start(vdev_mlme, event_data_len,
-					    event_data);
-		status = true;
-		break;
-
 	default:
 		status = false;
 		break;
@@ -1643,6 +1582,233 @@ static bool mlme_vdev_subst_stop_down_progress_event(void *ctx,
 	return status;
 }
 
+/**
+ * mlme_vdev_subst_mlo_sync_wait_entry() - Entry API for mlo sync wait sub state
+ * @ctx: VDEV MLME object
+ *
+ * API to perform operations on moving to MLO-SYNC-WAIT substate
+ *
+ * Return: void
+ */
+static void mlme_vdev_subst_mlo_sync_wait_entry(void *ctx)
+{
+	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
+	struct wlan_objmgr_vdev *vdev;
+
+	vdev = vdev_mlme->vdev;
+
+	if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_UP)
+		QDF_BUG(0);
+
+	mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_MLO_SYNC_WAIT);
+}
+
+/**
+ * mlme_vdev_subst_mlo_sync_wait_exit() - Exit API for mlo sync wait sub state
+ * @ctx: VDEV MLME object
+ *
+ * API to perform operations on moving out of MLO-SYNC-WAIT substate
+ *
+ * Return: void
+ */
+static void mlme_vdev_subst_mlo_sync_wait_exit(void *ctx)
+{
+	/* NONE */
+}
+
+/**
+ * mlme_vdev_subst_mlo_sync_wait_event() - Event handler API for mlo sync wait
+ *                                         substate
+ * @ctx: VDEV MLME object
+ *
+ * API to handle events in MLO-SYNC-WAIT substate
+ *
+ * Return: SUCCESS: on handling event
+ *         FAILURE: on ignoring the event
+ */
+static bool mlme_vdev_subst_mlo_sync_wait_event(void *ctx, uint16_t event,
+						uint16_t event_data_len,
+						void *event_data)
+{
+	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
+	bool status;
+
+	switch (event) {
+	case WLAN_VDEV_SM_EV_START_SUCCESS:
+		mlme_vdev_up_notify_mlo_mgr(vdev_mlme);
+		status = true;
+		break;
+
+	case WLAN_VDEV_SM_EV_MLO_SYNC_COMPLETE:
+		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_SS_UP_ACTIVE);
+		mlme_vdev_sm_deliver_event(vdev_mlme, event,
+					   event_data_len, event_data);
+		status = true;
+		break;
+
+	case WLAN_VDEV_SM_EV_DOWN:
+		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_STOP);
+		mlme_vdev_sm_deliver_event(vdev_mlme, WLAN_VDEV_SM_EV_STOP_REQ,
+					   event_data_len, event_data);
+		status = true;
+		break;
+
+	case WLAN_VDEV_SM_EV_RADAR_DETECTED:
+		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_START);
+		mlme_vdev_sm_deliver_event(vdev_mlme,
+					   WLAN_VDEV_SM_EV_RESTART_REQ,
+					   event_data_len, event_data);
+		status = true;
+		break;
+
+	default:
+		status = false;
+		break;
+	}
+
+	return status;
+}
+
+/**
+ * mlme_vdev_subst_up_active_entry() - Entry API for up active sub state
+ * @ctx: VDEV MLME object
+ *
+ * API to perform operations on moving to UP-ACTIVE substate
+ *
+ * Return: void
+ */
+static void mlme_vdev_subst_up_active_entry(void *ctx)
+{
+	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
+	struct wlan_objmgr_vdev *vdev;
+
+	vdev = vdev_mlme->vdev;
+
+	if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_UP)
+		QDF_BUG(0);
+
+	mlme_vdev_set_substate(vdev, WLAN_VDEV_SS_UP_ACTIVE);
+}
+
+/**
+ * mlme_vdev_subst_up_active_exit() - Exit API for up active sub state
+ * @ctx: VDEV MLME object
+ *
+ * API to perform operations on moving out of UP-ACTIVE substate
+ *
+ * Return: void
+ */
+static void mlme_vdev_subst_up_active_exit(void *ctx)
+{
+	/* NONE */
+}
+
+/**
+ * mlme_vdev_subst_up_active_event() - Event handler API for up active substate
+ * @ctx: VDEV MLME object
+ *
+ * API to handle events in UP-ACTIVE substate
+ *
+ * Return: SUCCESS: on handling event
+ *         FAILURE: on ignoring the event
+ */
+static bool mlme_vdev_subst_up_active_event(void *ctx, uint16_t event,
+					    uint16_t event_data_len,
+					    void *event_data)
+{
+	struct vdev_mlme_obj *vdev_mlme = (struct vdev_mlme_obj *)ctx;
+	enum QDF_OPMODE mode;
+	struct wlan_objmgr_vdev *vdev;
+	bool status;
+
+	vdev = vdev_mlme->vdev;
+	mode = wlan_vdev_mlme_get_opmode(vdev);
+
+	switch (event) {
+	case WLAN_VDEV_SM_EV_START_SUCCESS:
+		if (wlan_vdev_mlme_is_mlo_ap(vdev))
+			QDF_BUG(0);
+		/* fallthrough */
+	case WLAN_VDEV_SM_EV_MLO_SYNC_COMPLETE:
+		mlme_vdev_update_beacon(vdev_mlme, BEACON_INIT,
+					event_data_len, event_data);
+		if (mlme_vdev_up_send(vdev_mlme, event_data_len,
+				      event_data) != QDF_STATUS_SUCCESS)
+			mlme_vdev_sm_deliver_event(vdev_mlme,
+						   WLAN_VDEV_SM_EV_UP_FAIL,
+						   event_data_len, event_data);
+		else
+			mlme_vdev_notify_up_complete(vdev_mlme, event_data_len,
+						     event_data);
+		status = true;
+		break;
+
+	case WLAN_VDEV_SM_EV_SUSPEND_RESTART:
+	case WLAN_VDEV_SM_EV_HOST_RESTART:
+	case WLAN_VDEV_SM_EV_CSA_RESTART:
+		/* These events are not supported in STA mode */
+		if (mode == QDF_STA_MODE)
+			QDF_BUG(0);
+		/* fallthrough */
+	case WLAN_VDEV_SM_EV_DOWN:
+		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_SUSPEND);
+		mlme_vdev_sm_deliver_event(vdev_mlme, event,
+					   event_data_len, event_data);
+		status = true;
+		break;
+
+	case WLAN_VDEV_SM_EV_RADAR_DETECTED:
+		/* These events are not supported in STA mode */
+		if (mode == QDF_STA_MODE)
+			QDF_BUG(0);
+		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_SUSPEND);
+		mlme_vdev_sm_deliver_event(vdev_mlme,
+					   WLAN_VDEV_SM_EV_CSA_RESTART,
+					   event_data_len, event_data);
+		status = true;
+		break;
+
+	case WLAN_VDEV_SM_EV_UP_HOST_RESTART:
+		/* Reinit beacon, send template to FW(use ping-pong buffer) */
+		mlme_vdev_update_beacon(vdev_mlme, BEACON_UPDATE,
+					event_data_len, event_data);
+		/* fallthrough */
+	case WLAN_VDEV_SM_EV_START:
+		/* notify that UP command is completed */
+		mlme_vdev_notify_up_complete(vdev_mlme,
+					     event_data_len, event_data);
+		status = true;
+		break;
+
+	case WLAN_VDEV_SM_EV_FW_VDEV_RESTART:
+		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_START);
+		mlme_vdev_sm_deliver_event(vdev_mlme,
+					   WLAN_VDEV_SM_EV_RESTART_REQ,
+					   event_data_len, event_data);
+		status = true;
+		break;
+
+	case WLAN_VDEV_SM_EV_UP_FAIL:
+		mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_SUSPEND);
+		mlme_vdev_sm_deliver_event(vdev_mlme, event,
+					   event_data_len, event_data);
+		status = true;
+		break;
+
+	case WLAN_VDEV_SM_EV_ROAM:
+		mlme_vdev_notify_roam_start(vdev_mlme, event_data_len,
+					    event_data);
+		status = true;
+		break;
+
+	default:
+		status = false;
+		break;
+	}
+
+	return status;
+}
+
 
 static const char *vdev_sm_event_names[] = {
 	"EV_START",
@@ -1676,6 +1842,7 @@ static const char *vdev_sm_event_names[] = {
 	"EV_ROAM",
 	"EV_STOP_REQ",
 	"EV_CHAN_SWITCH_DISABLED",
+	"EV_MLO_SYNC_COMPLETE",
 };
 
 struct wlan_sm_state_info sm_info[] = {
@@ -1859,6 +2026,26 @@ struct wlan_sm_state_info sm_info[] = {
 		NULL,
 		NULL,
 	},
+	{
+		(uint8_t)WLAN_VDEV_SS_MLO_SYNC_WAIT,
+		(uint8_t)WLAN_VDEV_S_UP,
+		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
+		false,
+		"UP-MLO-SYNC-WAIT",
+		mlme_vdev_subst_mlo_sync_wait_entry,
+		mlme_vdev_subst_mlo_sync_wait_exit,
+		mlme_vdev_subst_mlo_sync_wait_event
+	},
+	{
+		(uint8_t)WLAN_VDEV_SS_UP_ACTIVE,
+		(uint8_t)WLAN_VDEV_S_UP,
+		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,
+		false,
+		"UP-UP-ACTIVE",
+		mlme_vdev_subst_up_active_entry,
+		mlme_vdev_subst_up_active_exit,
+		mlme_vdev_subst_up_active_event
+	},
 	{
 		(uint8_t)WLAN_VDEV_SS_MAX,
 		(uint8_t)WLAN_SM_ENGINE_STATE_NONE,

+ 17 - 0
umac/mlme/vdev_mgr/core/src/vdev_mlme_sm.h

@@ -622,6 +622,23 @@ static inline QDF_STATUS mlme_vdev_dfs_cac_wait_notify(
 	return ret;
 }
 
+#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
+ *
+ * Return: VOID.
+ */
+static inline void mlme_vdev_up_notify_mlo_mgr(struct vdev_mlme_obj *vdev_mlme)
+{
+	mlo_handle_link_up(vdev_mlme->vdev);
+}
+#else
+static inline void mlme_vdev_up_notify_mlo_mgr(struct vdev_mlme_obj *vdev_mlme)
+{
+}
+#endif
+
 #ifdef VDEV_SM_LOCK_SUPPORT
 /**
  * mlme_vdev_sm_spinlock_create - Create VDEV MLME spinlock

+ 6 - 3
umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mlme_api.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2019, 2021 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -158,7 +158,7 @@ QDF_STATUS wlan_vdev_allow_connect_n_tx(struct wlan_objmgr_vdev *vdev)
 
 	state = wlan_vdev_mlme_get_state(vdev);
 	substate = wlan_vdev_mlme_get_substate(vdev);
-	if ((state == WLAN_VDEV_S_UP) ||
+	if ((state == WLAN_VDEV_S_UP && substate == WLAN_VDEV_SS_UP_ACTIVE) ||
 	    ((state == WLAN_VDEV_S_SUSPEND) &&
 	     (substate == WLAN_VDEV_SS_SUSPEND_CSA_RESTART)))
 		return QDF_STATUS_SUCCESS;
@@ -275,9 +275,12 @@ void wlan_vdev_mlme_cmd_unlock(struct wlan_objmgr_vdev *vdev)
 QDF_STATUS wlan_vdev_mlme_is_scan_allowed(struct wlan_objmgr_vdev *vdev)
 {
 	enum wlan_vdev_state state;
+	enum wlan_vdev_state substate;
 
 	state = wlan_vdev_mlme_get_state(vdev);
-	if ((state == WLAN_VDEV_S_INIT) ||  (state == WLAN_VDEV_S_UP) ||
+	substate = wlan_vdev_mlme_get_substate(vdev);
+	if ((state == WLAN_VDEV_S_INIT) ||
+	    (state == WLAN_VDEV_S_UP && substate == WLAN_VDEV_SS_UP_ACTIVE) ||
 	    (state == WLAN_VDEV_S_STOP))
 		return QDF_STATUS_SUCCESS;