Browse Source

qcacld-3.0: Reject back to back TWT commands

Don't allow TWT commands back to back till response for
existing command is not received.
Reject the new command till the existing command completion
event is received from firmware. Allow TWT teardown when
any other command is in progress after TWT setup is complete.

Change-Id: I9282230c7cb24691b44ddfd273972272fd80f44b
CRs-Fixed: 2853515
Pragaspathi Thilagaraj 4 years ago
parent
commit
fa947de7a3

+ 28 - 0
components/mlme/core/inc/wlan_mlme_twt_api.h

@@ -178,6 +178,34 @@ bool mlme_is_flexible_twt_enabled(struct wlan_objmgr_psoc *psoc);
  * Return: True if tgt cap is advertised.
  */
 bool mlme_get_twt_bcast_requestor_tgt_cap(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * mlme_set_twt_command_in_progress() - Set TWT command is in progress.
+ * @psoc: Pointer to psoc object
+ * @peer_mac: Pointer to peer mac address
+ * @dialog_id: Dialog id
+ * @cmd: TWT command
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS mlme_set_twt_command_in_progress(struct wlan_objmgr_psoc *psoc,
+					    struct qdf_mac_addr *peer_mac,
+					    uint8_t dialog_id,
+					    enum wlan_twt_commands cmd);
+
+/**
+ * mlme_twt_is_command_in_progress() - Get TWT command in progress.
+ * @psoc: Pointer to psoc object
+ * @peer_mac: Pointer to peer mac address
+ * @dialog_id: Dialog id
+ * @cmd: TWT command
+ *
+ * Return: True if given command is in progress.
+ */
+bool mlme_twt_is_command_in_progress(struct wlan_objmgr_psoc *psoc,
+				     struct qdf_mac_addr *peer_mac,
+				     uint8_t dialog_id,
+				     enum wlan_twt_commands cmd);
 #else
 static inline
 void mlme_set_twt_peer_capabilities(struct wlan_objmgr_psoc *psoc,

+ 1 - 1
components/mlme/core/src/wlan_mlme_main.c

@@ -66,8 +66,8 @@ uint32_t mlme_get_vdev_he_ops(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
 
 	mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev);
 	if (!mlme_obj) {
-		mlme_legacy_err("Failed to get vdev MLME Obj");
 		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
+		mlme_legacy_err("Failed to get vdev MLME Obj");
 		return he_ops;
 	}
 

+ 88 - 1
components/mlme/core/src/wlan_mlme_twt_api.c

@@ -45,8 +45,8 @@ bool mlme_is_twt_setup_in_progress(struct wlan_objmgr_psoc *psoc,
 	peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer,
 							  WLAN_UMAC_COMP_MLME);
 	if (!peer_priv) {
-		mlme_legacy_err("peer mlme component object is NULL");
 		wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
+		mlme_legacy_err("peer mlme component object is NULL");
 		return false;
 	}
 
@@ -164,6 +164,10 @@ QDF_STATUS mlme_init_twt_context(struct wlan_objmgr_psoc *psoc,
 			peer_priv->twt_ctx.session_info[i].setup_done = false;
 			peer_priv->twt_ctx.session_info[i].dialog_id =
 					WLAN_ALL_SESSIONS_DIALOG_ID;
+			mlme_set_twt_command_in_progress(
+				psoc, peer_mac,
+				peer_priv->twt_ctx.session_info[i].dialog_id,
+				WLAN_TWT_NONE);
 		}
 	}
 
@@ -411,3 +415,86 @@ bool mlme_get_twt_bcast_requestor_tgt_cap(struct wlan_objmgr_psoc *psoc)
 
 	return mlme_obj->cfg.twt_cfg.bcast_requestor_tgt_cap;
 }
+
+QDF_STATUS mlme_set_twt_command_in_progress(struct wlan_objmgr_psoc *psoc,
+					    struct qdf_mac_addr *peer_mac,
+					    uint8_t dialog_id,
+					    enum wlan_twt_commands cmd)
+{
+	struct wlan_objmgr_peer *peer;
+	struct peer_mlme_priv_obj *peer_priv;
+	uint8_t i = 0;
+
+	peer = wlan_objmgr_get_peer_by_mac(psoc, peer_mac->bytes,
+					   WLAN_MLME_NB_ID);
+	if (!peer) {
+		mlme_legacy_err("Peer object not found");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer,
+							  WLAN_UMAC_COMP_MLME);
+	if (!peer_priv) {
+		wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
+		mlme_legacy_err(" peer mlme component object is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	for (i = 0; i < peer_priv->twt_ctx.num_twt_sessions; i++) {
+		if (peer_priv->twt_ctx.session_info[i].dialog_id == dialog_id ||
+		    dialog_id == WLAN_ALL_SESSIONS_DIALOG_ID) {
+			peer_priv->twt_ctx.session_info[i].active_cmd = cmd;
+			if (dialog_id != WLAN_ALL_SESSIONS_DIALOG_ID)
+				break;
+		}
+	}
+
+	wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+bool mlme_twt_is_command_in_progress(struct wlan_objmgr_psoc *psoc,
+				     struct qdf_mac_addr *peer_mac,
+				     uint8_t dialog_id,
+				     enum wlan_twt_commands cmd)
+{
+	struct wlan_objmgr_peer *peer;
+	struct peer_mlme_priv_obj *peer_priv;
+	enum wlan_twt_commands active_cmd;
+	uint8_t i = 0;
+	bool is_command_in_progress = false;
+
+	peer = wlan_objmgr_get_peer_by_mac(psoc, peer_mac->bytes,
+					   WLAN_MLME_NB_ID);
+	if (!peer) {
+		mlme_legacy_err("Peer object not found");
+		return false;
+	}
+
+	peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer,
+							  WLAN_UMAC_COMP_MLME);
+	if (!peer_priv) {
+		wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
+		mlme_legacy_err(" peer mlme component object is NULL");
+		return false;
+	}
+
+	for (i = 0; i < peer_priv->twt_ctx.num_twt_sessions; i++) {
+		active_cmd = peer_priv->twt_ctx.session_info[i].active_cmd;
+		if (peer_priv->twt_ctx.session_info[i].dialog_id == dialog_id) {
+			if (cmd == WLAN_TWT_ANY) {
+				is_command_in_progress =
+					(active_cmd != WLAN_TWT_NONE);
+				break;
+			} else {
+				is_command_in_progress = (active_cmd == cmd);
+				break;
+			}
+		}
+	}
+
+	wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
+
+	return is_command_in_progress;
+}

+ 23 - 0
components/mlme/dispatcher/inc/wlan_mlme_twt_public_struct.h

@@ -21,6 +21,26 @@
 #ifndef _WLAN_MLME_TWT_STRUCT_H_
 #define _WLAN_MLME_TWT_STRUCT_H_
 
+/**
+ * enum wlan_twt_commands  - TWT commands
+ * @WLAN_TWT_NONE: Indicates none of the TWT commands are active.
+ * @WLAN_TWT_SETUP: TWT setup
+ * @WLAN_TWT_TERMINATE: TWT terminate
+ * @WLAN_TWT_SUSPEND: TWT suspend
+ * @WLAN_TWT_RESUME: TWT resume
+ * @WLAN_TWT_NUDGE: TWT nudge
+ * @WLAN_TWT_ANY: Indicates one of the commands is in progress.
+ */
+enum wlan_twt_commands {
+	WLAN_TWT_NONE       = 0,
+	WLAN_TWT_SETUP      = BIT(0),
+	WLAN_TWT_TERMINATE  = BIT(1),
+	WLAN_TWT_SUSPEND    = BIT(2),
+	WLAN_TWT_RESUME     = BIT(3),
+	WLAN_TWT_NUDGE      = BIT(4),
+	WLAN_TWT_ANY        = 0xFF,
+};
+
 /**
  * enum wlan_twt_capabilities  - Represents the Bitmap of TWT capabilities
  * supported by device and peer.
@@ -64,11 +84,14 @@ enum wlan_twt_session_state {
  * @dialog_id: TWT session dialog id
  * @state: TWT session state
  * @setup_done: TWT session setup is complete
+ * @active_cmd: bitmap to indicate which command is
+ * in progress. Bits are provided by enum wlan_twt_commands.
  */
 struct twt_session_info {
 	uint8_t dialog_id;
 	uint8_t state;
 	bool setup_done;
+	enum wlan_twt_commands active_cmd;
 };
 
 /**

+ 0 - 21
components/mlme/dispatcher/inc/wlan_mlme_twt_ucfg_api.h

@@ -223,22 +223,6 @@ QDF_STATUS
 ucfg_mlme_set_twt_bcast_responder_tgt_cap(struct wlan_objmgr_psoc *psoc,
 					  bool val);
 
-/**
- * ucfg_mlme_add_twt_session()  - Add the entry for the given dialog id in TWT
- * context once TWT setup command is received
- * @psoc: pointer to psoc object
- * @peer_mac: Pointer to peer mac
- * @dialog_id: TWT session dialog id
- *
- * Return: None
- */
-static inline
-void ucfg_mlme_add_twt_session(struct wlan_objmgr_psoc *psoc,
-			       struct qdf_mac_addr *peer_mac, uint8_t dialog_id)
-{
-	mlme_add_twt_session(psoc, peer_mac, dialog_id);
-}
-
 /**
  * ucfg_mlme_is_twt_setup_in_progress() - Get TWT setup in progress for
  * given dialog id
@@ -404,11 +388,6 @@ ucfg_mlme_set_enable_twt(struct wlan_objmgr_psoc *psoc,
 	return QDF_STATUS_E_NOSUPPORT;
 }
 
-static inline
-void ucfg_mlme_add_twt_session(struct wlan_objmgr_psoc *psoc,
-			       struct qdf_mac_addr *peer_mac, uint8_t dialog_id)
-{}
-
 static inline bool
 ucfg_mlme_is_twt_setup_done(struct wlan_objmgr_psoc *psoc,
 			    struct qdf_mac_addr *peer_mac, uint8_t dialog_id)

+ 2 - 10
core/hdd/src/wlan_hdd_twt.c

@@ -898,9 +898,9 @@ int wmi_twt_del_status_to_vendor_twt_status(enum WMI_HOST_DEL_TWT_STATUS status)
 		return QCA_WLAN_VENDOR_TWT_STATUS_NO_ACK;
 	case WMI_HOST_DEL_TWT_STATUS_UNKNOWN_ERROR:
 		return QCA_WLAN_VENDOR_TWT_STATUS_UNKNOWN_ERROR;
-	case WMI_DEL_TWT_STATUS_PEER_INIT_TEARDOWN:
+	case WMI_HOST_DEL_TWT_STATUS_PEER_INIT_TEARDOWN:
 		return QCA_WLAN_VENDOR_TWT_STATUS_PEER_INITIATED_TERMINATE;
-	case WMI_DEL_TWT_STATUS_ROAMING:
+	case WMI_HOST_DEL_TWT_STATUS_ROAMING:
 		return QCA_WLAN_VENDOR_TWT_STATUS_ROAM_INITIATED_TERMINATE;
 	default:
 		return QCA_WLAN_VENDOR_TWT_STATUS_UNKNOWN_ERROR;
@@ -1286,14 +1286,6 @@ static int hdd_twt_setup_session(struct hdd_adapter *adapter,
 	if (ret < 0)
 		return ret;
 
-	/*
-	 * Add the dialog id to TWT context to drop back to back
-	 * commands
-	 */
-	ucfg_mlme_add_twt_session(adapter->hdd_ctx->psoc,
-				  &hdd_sta_ctx->conn_info.bssid,
-				  params.dialog_id);
-
 	return ret;
 }
 

+ 166 - 4
core/sme/src/common/sme_api.c

@@ -68,6 +68,8 @@
 #include "wlan_cm_roam_api.h"
 #include "wlan_cm_tgt_if_tx_api.h"
 #include "wlan_cm_api.h"
+#include "wlan_mlme_twt_public_struct.h"
+#include "wlan_mlme_twt_api.h"
 #include "parser_api.h"
 #include <../../core/src/wlan_cm_vdev_api.h>
 
@@ -2107,10 +2109,24 @@ sme_process_twt_add_dialog_event(struct mac_context *mac,
 				 struct twt_add_dialog_complete_event *add_dialog_event)
 {
 	twt_add_dialog_cb callback;
+	bool is_evt_allowed;
+
+	is_evt_allowed = mlme_twt_is_command_in_progress(
+		mac->psoc,
+		(struct qdf_mac_addr *)add_dialog_event->params.peer_macaddr,
+		add_dialog_event->params.dialog_id, WLAN_TWT_SETUP);
+	if (!is_evt_allowed)
+		return;
 
 	callback = mac->sme.twt_add_dialog_cb;
 	if (callback)
 		callback(mac->psoc, add_dialog_event);
+
+	/* Reset the active TWT command to none */
+	mlme_set_twt_command_in_progress(
+		mac->psoc,
+		(struct qdf_mac_addr *)add_dialog_event->params.peer_macaddr,
+		add_dialog_event->params.dialog_id, WLAN_TWT_NONE);
 }
 
 /**
@@ -2126,10 +2142,30 @@ sme_process_twt_del_dialog_event(struct mac_context *mac,
 				 struct wmi_twt_del_dialog_complete_event_param *param)
 {
 	twt_del_dialog_cb callback;
+	bool is_evt_allowed;
+
+	is_evt_allowed = mlme_twt_is_command_in_progress(
+		mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr,
+		param->dialog_id, WLAN_TWT_TERMINATE);
+	if (!is_evt_allowed &&
+	    (param->status != WMI_HOST_DEL_TWT_STATUS_ROAMING ||
+	     param->status != WMI_HOST_DEL_TWT_STATUS_PEER_INIT_TEARDOWN))
+		return;
 
 	callback = mac->sme.twt_del_dialog_cb;
 	if (callback)
 		callback(mac->psoc, param);
+
+	if (param->status == WMI_HOST_DEL_TWT_STATUS_ROAMING ||
+	    param->status == WMI_HOST_DEL_TWT_STATUS_PEER_INIT_TEARDOWN)
+		mlme_twt_set_wait_for_notify(
+			mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr,
+			true);
+
+	/* Reset the active TWT command to none */
+	mlme_set_twt_command_in_progress(
+			mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr,
+			param->dialog_id, WLAN_TWT_NONE);
 }
 
 /**
@@ -2145,10 +2181,22 @@ sme_process_twt_pause_dialog_event(struct mac_context *mac,
 				   struct wmi_twt_pause_dialog_complete_event_param *param)
 {
 	twt_pause_dialog_cb callback;
+	bool is_evt_allowed;
+
+	is_evt_allowed = mlme_twt_is_command_in_progress(
+		mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr,
+		param->dialog_id, WLAN_TWT_SUSPEND);
+	if (!is_evt_allowed)
+		return;
 
 	callback = mac->sme.twt_pause_dialog_cb;
 	if (callback)
 		callback(mac->psoc, param);
+
+	/* Reset the active TWT command to none */
+	mlme_set_twt_command_in_progress(
+		mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr,
+		param->dialog_id, WLAN_TWT_NONE);
 }
 
 /**
@@ -2165,12 +2213,24 @@ sme_process_twt_nudge_dialog_event(struct mac_context *mac,
 {
 	twt_nudge_dialog_cb callback;
 	void *context;
+	bool is_evt_allowed;
+
+	is_evt_allowed = mlme_twt_is_command_in_progress(
+		mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr,
+		param->dialog_id, WLAN_TWT_NUDGE);
+	if (!is_evt_allowed)
+		return;
 
 	callback = mac->sme.twt_nudge_dialog_cb;
 	context = mac->sme.twt_nudge_dialog_context;
 	mac->sme.twt_nudge_dialog_cb = NULL;
 	if (callback)
 		callback(context, param);
+
+	/* Reset the active TWT command to none */
+	mlme_set_twt_command_in_progress(
+			mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr,
+			param->dialog_id, WLAN_TWT_NONE);
 }
 
 /**
@@ -2186,13 +2246,24 @@ sme_process_twt_resume_dialog_event(struct mac_context *mac,
 				    struct wmi_twt_resume_dialog_complete_event_param *param)
 {
 	twt_resume_dialog_cb callback;
+	bool is_evt_allowed;
+
+	is_evt_allowed = mlme_twt_is_command_in_progress(
+		mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr,
+		param->dialog_id, WLAN_TWT_RESUME);
+	if (!is_evt_allowed)
+		return;
 
 	callback = mac->sme.twt_resume_dialog_cb;
 	if (callback)
 		callback(mac->psoc, param);
+
+	/* Reset the active TWT command to none */
+	mlme_set_twt_command_in_progress(
+			mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr,
+			param->dialog_id, WLAN_TWT_NONE);
 }
 #else
-
 static void
 sme_process_twt_add_dialog_event(struct mac_context *mac,
 				 struct twt_add_dialog_complete_event *add_dialog_event)
@@ -13918,11 +13989,22 @@ QDF_STATUS sme_add_dialog_cmd(mac_handle_t mac_handle,
 {
 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
 	struct scheduler_msg twt_msg = {0};
+	bool is_twt_cmd_in_progress;
 	QDF_STATUS status;
 	void *wma_handle;
 	struct wmi_twt_add_dialog_param *cmd_params;
 
 	SME_ENTER();
+
+	is_twt_cmd_in_progress = mlme_twt_is_command_in_progress(
+			mac->psoc,
+			(struct qdf_mac_addr *)twt_params->peer_macaddr,
+			twt_params->dialog_id, WLAN_TWT_ANY);
+	if (is_twt_cmd_in_progress) {
+		sme_debug("Already TWT command is in progress");
+		return QDF_STATUS_E_AGAIN;
+	}
+
 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
 	if (!wma_handle)
 		return QDF_STATUS_E_FAILURE;
@@ -13955,6 +14037,20 @@ QDF_STATUS sme_add_dialog_cmd(mac_handle_t mac_handle,
 		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
 			  FL("Post twt add dialog msg fail"));
 		qdf_mem_free(cmd_params);
+	} else {
+		/*
+		 * Add the dialog id to TWT context to drop back to back
+		 * commands
+		 */
+		mlme_add_twt_session(
+			mac->psoc,
+			(struct qdf_mac_addr *)twt_params->peer_macaddr,
+			twt_params->dialog_id);
+
+		mlme_set_twt_command_in_progress(
+				mac->psoc,
+				(struct qdf_mac_addr *)twt_params->peer_macaddr,
+				twt_params->dialog_id, WLAN_TWT_SETUP);
 	}
 
 	SME_EXIT();
@@ -13967,11 +14063,27 @@ QDF_STATUS sme_del_dialog_cmd(mac_handle_t mac_handle,
 {
 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
 	struct scheduler_msg twt_msg = {0};
+	bool is_twt_cmd_in_progress;
 	QDF_STATUS status;
 	void *wma_handle;
 	struct wmi_twt_del_dialog_param *cmd_params;
 
 	SME_ENTER();
+
+	is_twt_cmd_in_progress =
+		mlme_twt_is_command_in_progress(
+			mac->psoc,
+			(struct qdf_mac_addr *)twt_params->peer_macaddr,
+			twt_params->dialog_id, WLAN_TWT_SETUP) ||
+		mlme_twt_is_command_in_progress(
+			mac->psoc,
+			(struct qdf_mac_addr *)twt_params->peer_macaddr,
+			twt_params->dialog_id, WLAN_TWT_TERMINATE);
+	if (is_twt_cmd_in_progress) {
+		sme_debug("Already TWT command is in progress");
+		return QDF_STATUS_E_AGAIN;
+	}
+
 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
 	if (!wma_handle)
 		return QDF_STATUS_E_FAILURE;
@@ -14004,6 +14116,11 @@ QDF_STATUS sme_del_dialog_cmd(mac_handle_t mac_handle,
 		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
 			  FL("Post twt del dialog msg fail"));
 		qdf_mem_free(cmd_params);
+	} else {
+		mlme_set_twt_command_in_progress(
+				mac->psoc,
+				(struct qdf_mac_addr *)twt_params->peer_macaddr,
+				twt_params->dialog_id, WLAN_TWT_TERMINATE);
 	}
 
 	SME_EXIT();
@@ -14017,10 +14134,21 @@ sme_pause_dialog_cmd(mac_handle_t mac_handle,
 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
 	struct wmi_twt_pause_dialog_cmd_param *cmd_params;
 	struct scheduler_msg twt_msg = {0};
+	bool is_twt_cmd_in_progress;
 	QDF_STATUS status;
 	void *wma_handle;
 
 	SME_ENTER();
+
+	is_twt_cmd_in_progress = mlme_twt_is_command_in_progress(
+			mac->psoc,
+			(struct qdf_mac_addr *)twt_params->peer_macaddr,
+			twt_params->dialog_id, WLAN_TWT_ANY);
+	if (is_twt_cmd_in_progress) {
+		sme_debug("Already TWT command is in progress");
+		return QDF_STATUS_E_AGAIN;
+	}
+
 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
 	if (!wma_handle)
 		return QDF_STATUS_E_FAILURE;
@@ -14052,6 +14180,11 @@ sme_pause_dialog_cmd(mac_handle_t mac_handle,
 		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
 			  FL("Post twt pause dialog msg fail"));
 		qdf_mem_free(cmd_params);
+	} else {
+		mlme_set_twt_command_in_progress(
+				mac->psoc,
+				(struct qdf_mac_addr *)twt_params->peer_macaddr,
+				twt_params->dialog_id, WLAN_TWT_SUSPEND);
 	}
 
 	SME_EXIT();
@@ -14067,10 +14200,20 @@ sme_nudge_dialog_cmd(mac_handle_t mac_handle,
 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
 	struct wmi_twt_nudge_dialog_cmd_param *cmd_params;
 	struct scheduler_msg twt_msg = {0};
+	bool is_twt_cmd_in_progress;
 	QDF_STATUS status;
 	void *wma_handle;
 
 	SME_ENTER();
+
+	is_twt_cmd_in_progress = mlme_twt_is_command_in_progress(
+			mac->psoc,
+			(struct qdf_mac_addr *)twt_params->peer_macaddr,
+			twt_params->dialog_id, WLAN_TWT_ANY);
+	if (is_twt_cmd_in_progress) {
+		sme_debug("Already TWT command is in progress");
+		return QDF_STATUS_E_AGAIN;
+	}
 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
 	if (!wma_handle) {
 		sme_err("wma_handle is NULL");
@@ -14113,6 +14256,11 @@ sme_nudge_dialog_cmd(mac_handle_t mac_handle,
 		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
 			  FL("Post twt nudge dialog msg fail"));
 		qdf_mem_free(cmd_params);
+	} else {
+		mlme_set_twt_command_in_progress(
+			mac->psoc,
+			(struct qdf_mac_addr *)twt_params->peer_macaddr,
+			twt_params->dialog_id, WLAN_TWT_NUDGE);
 	}
 
 	SME_EXIT();
@@ -14126,10 +14274,21 @@ sme_resume_dialog_cmd(mac_handle_t mac_handle,
 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
 	struct wmi_twt_resume_dialog_cmd_param *cmd_params;
 	struct scheduler_msg twt_msg = {0};
+	bool is_twt_cmd_in_progress;
 	QDF_STATUS status;
 	void *wma_handle;
 
 	SME_ENTER();
+
+	is_twt_cmd_in_progress = mlme_twt_is_command_in_progress(
+			mac->psoc,
+			(struct qdf_mac_addr *)twt_params->peer_macaddr,
+			twt_params->dialog_id, WLAN_TWT_ANY);
+	if (is_twt_cmd_in_progress) {
+		sme_debug("Already TWT command is in progress");
+		return QDF_STATUS_E_AGAIN;
+	}
+
 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
 	if (!wma_handle)
 		return QDF_STATUS_E_FAILURE;
@@ -14156,11 +14315,14 @@ sme_resume_dialog_cmd(mac_handle_t mac_handle,
 	status = scheduler_post_message(QDF_MODULE_ID_SME,
 					QDF_MODULE_ID_WMA,
 					QDF_MODULE_ID_WMA, &twt_msg);
-
 	if (QDF_IS_STATUS_ERROR(status)) {
-		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
-			  FL("Post twt resume dialog msg fail"));
+		sme_err("Post twt resume dialog msg fail");
 		qdf_mem_free(cmd_params);
+	} else {
+		mlme_set_twt_command_in_progress(
+				mac->psoc,
+				(struct qdf_mac_addr *)twt_params->peer_macaddr,
+				twt_params->dialog_id, WLAN_TWT_RESUME);
 	}
 
 	SME_EXIT();