Explorar el Código

qcacld-3.0: Serialize TWT commands to allow one command for TWT operation

Post message to the scheduler to send twt wmi command and receive the
response event. check twt callback in sme_context to allow only one
twt command for a particular twt operation at any time. Return EBUSY
if a TWT operation is already in progress.

CRs-Fixed: 2769378
Change-Id: I7d3bce413e12c2775a7b2e8e2c5259a8b8e55131
Rajasekaran Kalidoss hace 4 años
padre
commit
3e35bdbafe

+ 3 - 5
core/hdd/src/wlan_hdd_cfg80211.c

@@ -9527,7 +9527,7 @@ int hdd_twt_get_add_dialog_values(struct nlattr **tb,
 		params->wake_intvl_us = params->wake_intvl_mantis;
 	}
 
-	hdd_debug("twt: dialod_id %d, vdev %d, wake intvl_us %d, mantis %d",
+	hdd_debug("twt: dialog_id %d, vdev %d, wake intvl_us %d, mantis %d",
 		  params->dialog_id, params->vdev_id, params->wake_intvl_us,
 		  params->wake_intvl_mantis);
 	hdd_debug("twt: wake dura %d, sp_offset %d, cmd %d",
@@ -10075,8 +10075,7 @@ __wlan_hdd_cfg80211_set_wifi_test_config(struct wiphy *wiphy,
 						hdd_ctx->psoc, 0);
 				hdd_send_twt_enable_cmd(hdd_ctx);
 			}
-			ret_val = qdf_status_to_os_return(
-					wma_twt_process_add_dialog(&params));
+			ret_val = qdf_status_to_os_return(sme_test_config_twt_setup(&params));
 			if (ret_val)
 				goto send_err;
 		}
@@ -10100,8 +10099,7 @@ __wlan_hdd_cfg80211_set_wifi_test_config(struct wiphy *wiphy,
 		params.vdev_id = adapter->vdev_id;
 		params.dialog_id = 0;
 		hdd_debug("twt_terminate: vdev_id %d", params.vdev_id);
-		ret_val = qdf_status_to_os_return(
-				wma_twt_process_del_dialog(&params));
+		ret_val = qdf_status_to_os_return(sme_test_config_twt_terminate(&params));
 		if (ret_val)
 			goto send_err;
 	}

+ 26 - 33
core/hdd/src/wlan_hdd_twt.c

@@ -63,19 +63,6 @@ struct twt_resume_dialog_comp_ev_priv {
 	struct wmi_twt_resume_dialog_complete_event_param res_dialog_comp_ev_buf;
 };
 
-/**
- * struct twt_add_dialog_complete_event - TWT add dialog complete event
- * @params: Fixed parameters for TWT add dialog complete event
- * @additional_params: additional parameters for TWT add dialog complete event
- *
- * Holds the fixed and additional parameters from add dialog
- * complete event
- */
-struct twt_add_dialog_complete_event {
-	struct wmi_twt_add_dialog_complete_event_param params;
-	struct wmi_twt_add_dialog_additional_params additional_params;
-};
-
 /**
  * struct twt_add_dialog_comp_ev_priv - private struct for twt add dialog
  * @add_dialog_comp_ev_buf: buffer from TWT add dialog complete_event
@@ -652,10 +639,9 @@ wmi_twt_add_status_to_vendor_twt_status(enum WMI_HOST_ADD_TWT_STATUS status)
  * Return: QDF_STATUS_SUCCESS on Success, other QDF_STATUS error codes
  * on failure
  */
-static
-QDF_STATUS hdd_twt_setup_pack_resp_nlmsg(
-	 struct sk_buff *reply_skb,
-	 struct twt_add_dialog_complete_event *event)
+static QDF_STATUS
+hdd_twt_setup_pack_resp_nlmsg(struct sk_buff *reply_skb,
+			      struct twt_add_dialog_complete_event *event)
 {
 	uint64_t sp_offset_tsf;
 	enum qca_wlan_vendor_twt_status vendor_status;
@@ -669,7 +655,7 @@ QDF_STATUS hdd_twt_setup_pack_resp_nlmsg(
 
 	if (nla_put_u8(reply_skb, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID,
 		       event->params.dialog_id)) {
-		hdd_debug("TWT: Failed to put dialog_id");
+		hdd_err("TWT: Failed to put dialog_id");
 		return QDF_STATUS_E_FAILURE;
 	}
 
@@ -769,10 +755,17 @@ QDF_STATUS hdd_twt_setup_pack_resp_nlmsg(
 	return QDF_STATUS_SUCCESS;
 }
 
+/**
+ * hdd_twt_add_dialog_comp_cb() - HDD callback for twt add dialog
+ * complete event
+ * @hdd_ctx: HDD Context
+ * @add_dialog_event: Pointer to Add dialog complete event structure
+ *
+ * Return: None
+ */
 static void
 hdd_twt_add_dialog_comp_cb(void *context,
-			   struct wmi_twt_add_dialog_complete_event_param *params,
-			   struct wmi_twt_add_dialog_additional_params *additional_params)
+			   struct twt_add_dialog_complete_event *add_dialog_event)
 {
 	struct osif_request *request;
 	struct twt_add_dialog_comp_ev_priv *priv;
@@ -787,18 +780,16 @@ hdd_twt_add_dialog_comp_cb(void *context,
 
 	priv = osif_request_priv(request);
 
-	qdf_mem_copy(&priv->add_dialog_comp_ev_buf.params, params,
-		     sizeof(*params));
-	qdf_mem_copy(&priv->add_dialog_comp_ev_buf.additional_params,
-		     additional_params,
-		     sizeof(*additional_params));
+	qdf_mem_copy(&priv->add_dialog_comp_ev_buf, add_dialog_event,
+		     sizeof(*add_dialog_event));
 	osif_request_complete(request);
 	osif_request_put(request);
 
 	hdd_debug("TWT: add dialog_id:%d, status:%d vdev_id %d peer mac_addr "
-		  QDF_MAC_ADDR_FMT, params->dialog_id,
-		  params->status, params->vdev_id,
-		  QDF_MAC_ADDR_REF(params->peer_macaddr));
+		  QDF_MAC_ADDR_FMT, add_dialog_event->params.dialog_id,
+		  add_dialog_event->params.status,
+		  add_dialog_event->params.vdev_id,
+		  QDF_MAC_ADDR_REF(add_dialog_event->params.peer_macaddr));
 
 	hdd_exit();
 }
@@ -871,7 +862,7 @@ int hdd_send_twt_add_dialog_cmd(struct hdd_context *hdd_ctx,
 
 	status = hdd_twt_setup_pack_resp_nlmsg(reply_skb,
 					       add_dialog_comp_ev_params);
-	if (!QDF_IS_STATUS_SUCCESS(status)) {
+	if (QDF_IS_STATUS_ERROR(status)) {
 		hdd_err("Failed to pack nl add dialog response");
 		ret = qdf_status_to_os_return(status);
 		goto err;
@@ -978,7 +969,8 @@ static uint32_t hdd_get_twt_event_len(void)
  * @reply_skb: skb to store the response
  * @params: Pointer to del dialog complete event buffer
  *
- * Return: QDF_STATUS
+ * Return: QDF_STATUS_SUCCESS on Success, QDF_STATUS_E_FAILURE
+ * on failure
  */
 static QDF_STATUS
 hdd_twt_terminate_pack_resp_nlmsg(struct sk_buff *reply_skb,
@@ -1044,7 +1036,7 @@ hdd_twt_del_dialog_comp_cb(void *context,
  * @hdd_ctx: HDD Context
  * @twt_params: Pointer to del dialog cmd params structure
  *
- * Return: QDF_STATUS
+ * Return: 0 on success, negative value on failure
  */
 static
 int hdd_send_twt_del_dialog_cmd(struct hdd_context *hdd_ctx,
@@ -1255,8 +1247,7 @@ hdd_twt_pause_pack_resp_nlmsg(struct sk_buff *reply_skb,
  * @hdd_ctx: HDD Context
  * @twt_params: Pointer to pause dialog cmd params structure
  *
- * Return: QDF_STATUS_SUCCESS on Success, other QDF_STATUS error codes
- * on failure
+ * Return: 0 on success, negative value on failure
  */
 static
 int hdd_send_twt_pause_dialog_cmd(struct hdd_context *hdd_ctx,
@@ -1876,6 +1867,8 @@ void wlan_hdd_twt_init(struct hdd_context *hdd_ctx)
 	QDF_STATUS status;
 
 	hdd_ctx->twt_state = TWT_INIT;
+
+	sme_init_twt_complete_cb(hdd_ctx->mac_handle);
 	status = sme_register_twt_enable_complete_cb(hdd_ctx->mac_handle,
 						     hdd_twt_enable_comp_cb);
 	if (!QDF_IS_STATUS_SUCCESS(status)) {

+ 5 - 1
core/mac/inc/wni_api.h

@@ -251,7 +251,11 @@ enum eWniMsgTypes {
 #ifndef ROAM_OFFLOAD_V1
 	eWNI_SME_ROAM_DISABLE_CFG = SIR_SME_MSG_TYPES_BEGIN + 164,
 #endif
-	eWNI_SME_MSG_TYPES_END = SIR_SME_MSG_TYPES_BEGIN + 165
+	eWNI_SME_TWT_ADD_DIALOG_EVENT = SIR_SME_MSG_TYPES_BEGIN + 165,
+	eWNI_SME_TWT_DEL_DIALOG_EVENT = SIR_SME_MSG_TYPES_BEGIN + 166,
+	eWNI_SME_TWT_PAUSE_DIALOG_EVENT = SIR_SME_MSG_TYPES_BEGIN + 167,
+	eWNI_SME_TWT_RESUME_DIALOG_EVENT = SIR_SME_MSG_TYPES_BEGIN + 168,
+	eWNI_SME_MSG_TYPES_END = SIR_SME_MSG_TYPES_BEGIN + 169
 };
 
 typedef struct sAniCfgTxRateCtrs {

+ 5 - 0
core/mac/src/include/sir_params.h

@@ -650,6 +650,11 @@ struct sir_cfg_action_frm_tb_ppdu {
 #define SIR_HAL_REQ_SEND_DELBA_REQ_IND     (SIR_HAL_ITC_MSG_TYPES_BEGIN + 415)
 #define SIR_HAL_SEND_MAX_TX_POWER          (SIR_HAL_ITC_MSG_TYPES_BEGIN + 416)
 
+#define SIR_HAL_TWT_ADD_DIALOG_REQUEST     (SIR_HAL_ITC_MSG_TYPES_BEGIN + 417)
+#define SIR_HAL_TWT_DEL_DIALOG_REQUEST     (SIR_HAL_ITC_MSG_TYPES_BEGIN + 418)
+#define SIR_HAL_TWT_PAUSE_DIALOG_REQUEST   (SIR_HAL_ITC_MSG_TYPES_BEGIN + 419)
+#define SIR_HAL_TWT_RESUME_DIALOG_REQUEST  (SIR_HAL_ITC_MSG_TYPES_BEGIN + 420)
+
 #define SIR_HAL_MSG_TYPES_END               (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
 
 /* LIM message types */

+ 6 - 0
core/mac/src/sys/legacy/src/utils/src/mac_trace.c

@@ -557,6 +557,12 @@ uint8_t *mac_trace_get_wma_msg_string(uint16_t wma_msg)
 		CASE_RETURN_STRING(WMA_UPDATE_RX_NSS);
 #ifdef WLAN_FEATURE_NAN
 		CASE_RETURN_STRING(WMA_NAN_REQUEST);
+#endif
+#ifdef WLAN_SUPPORT_TWT
+		CASE_RETURN_STRING(WMA_TWT_ADD_DIALOG_REQUEST);
+		CASE_RETURN_STRING(WMA_TWT_DEL_DIALOG_REQUEST);
+		CASE_RETURN_STRING(WMA_TWT_PAUSE_DIALOG_REQUEST);
+		CASE_RETURN_STRING(WMA_TWT_RESUME_DIALOG_REQUEST);
 #endif
 		CASE_RETURN_STRING(WMA_RX_SCAN_EVENT);
 		CASE_RETURN_STRING(WMA_RX_CHN_STATUS_EVENT);

+ 45 - 0
core/sme/inc/sme_api.h

@@ -156,6 +156,7 @@ struct sme_config_params {
 #endif /* FEATURE_WLAN_TDLS */
 
 struct wmi_twt_add_dialog_param;
+struct wmi_twt_del_dialog_param;
 
 /* Thermal Mitigation*/
 typedef struct {
@@ -3615,6 +3616,37 @@ uint8_t sme_get_mcs_idx(uint16_t raw_rate, enum tx_rate_info rate_flags,
 			enum tx_rate_info *mcs_rate_flags);
 
 #ifdef WLAN_SUPPORT_TWT
+
+/**
+ * sme_test_config_twt_terminate() - send TWT del dialog wmi command
+ * to firmware
+ * @params: TWT del dialog parameters
+ *
+ * Return: QDF_STATUS_SUCCESS on Success, other QDF_STATUS error codes
+ * on failure
+ */
+QDF_STATUS
+sme_test_config_twt_terminate(struct wmi_twt_del_dialog_param *params);
+
+/**
+ * sme_test_config_twt_setup() - send TWT add dialog wmi command
+ * to firmware
+ * @params: TWT add dialog parameters
+ *
+ * Return: QDF_STATUS_SUCCESS on Success, other QDF_STATUS error codes
+ * on failure
+ */
+QDF_STATUS sme_test_config_twt_setup(struct wmi_twt_add_dialog_param *params);
+
+/**
+ * sme_init_twt_complete_cb() - Initialize TWT callbacks
+ * @mac_handle: MAC handle
+ *
+ * Return: QDF_STATUS_SUCCESS on Success, other QDF_STATUS error codes
+ * on failure
+ */
+QDF_STATUS sme_init_twt_complete_cb(mac_handle_t mac_handle);
+
 /**
  * sme_register_twt_enable_complete_cb() - TWT enable registrar
  * @mac_handle: MAC handle
@@ -3714,6 +3746,19 @@ QDF_STATUS sme_deregister_twt_enable_complete_cb(mac_handle_t mac_handle);
  * Return: QDF Status
  */
 QDF_STATUS sme_deregister_twt_disable_complete_cb(mac_handle_t mac_handle);
+#else
+
+static inline
+QDF_STATUS sme_test_config_twt_setup(struct wmi_twt_add_dialog_param *params)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+sme_test_config_twt_terminate(struct wmi_twt_del_dialog_param *params)
+{
+	return QDF_STATUS_E_FAILURE;
+}
 #endif
 
 /**

+ 7 - 5
core/sme/inc/sme_internal.h

@@ -39,6 +39,7 @@
 #include "wmi_unified.h"
 #include "wmi_unified_param.h"
 
+struct twt_add_dialog_complete_event;
 struct wmi_twt_add_dialog_complete_event_param;
 struct wmi_twt_enable_complete_event_param;
 /*--------------------------------------------------------------------------
@@ -163,12 +164,10 @@ typedef void (*twt_disable_cb)(hdd_handle_t hdd_handle);
  * typedef twt_add_dialog_cb - TWT add dialog callback signature.
  * @context: Opaque context that the client can use to associate the
  *           callback with the request.
- * @params: TWT add dialog complete event fixed parameters.
- * @params: TWT add dialog complete event additional parameters.
+ * @add_dialog_event: pointer to event buf containing twt response parameters
  */
 typedef void (*twt_add_dialog_cb)(void *context,
-				  struct wmi_twt_add_dialog_complete_event_param *params,
-				  struct wmi_twt_add_dialog_additional_params *additional_params);
+				  struct twt_add_dialog_complete_event *add_dialog_event);
 
 /**
  * typedef twt_del_dialog_cb - TWT delete dialog callback signature.
@@ -411,7 +410,10 @@ struct sme_context {
 	twt_del_dialog_cb twt_del_dialog_cb;
 	twt_pause_dialog_cb twt_pause_dialog_cb;
 	twt_resume_dialog_cb twt_resume_dialog_cb;
-	void *twt_context;
+	void *twt_add_dialog_context;
+	void *twt_del_dialog_context;
+	void *twt_pause_dialog_context;
+	void *twt_resume_dialog_context;
 #endif
 #ifdef FEATURE_WLAN_APF
 	apf_get_offload_cb apf_get_offload_cb;

+ 307 - 29
core/sme/src/common/sme_api.c

@@ -2060,6 +2060,121 @@ static QDF_STATUS sme_process_antenna_mode_resp(struct mac_context *mac,
 	return QDF_STATUS_SUCCESS;
 }
 
+#ifdef WLAN_SUPPORT_TWT
+/**
+ * sme_process_twt_add_dialog_event() - Process twt add dialog event
+ * response from firmware
+ * @mac: Global MAC pointer
+ * @add_dialog_event: pointer to event buf containing twt response parameters
+ *
+ * Return: None
+ */
+static void
+sme_process_twt_add_dialog_event(struct mac_context *mac,
+				 struct twt_add_dialog_complete_event *add_dialog_event)
+{
+	twt_add_dialog_cb callback;
+	void *context;
+
+	callback = mac->sme.twt_add_dialog_cb;
+	context = mac->sme.twt_add_dialog_context;
+	mac->sme.twt_add_dialog_cb = NULL;
+	if (callback)
+		callback(context, add_dialog_event);
+}
+
+/**
+ * sme_process_twt_del_dialog_event() - Process twt del dialog event
+ * response from firmware
+ * @mac: Global MAC pointer
+ * @param: pointer to wmi_twt_del_dialog_complete_event_param buffer
+ *
+ * Return: None
+ */
+static void
+sme_process_twt_del_dialog_event(struct mac_context *mac,
+				 struct wmi_twt_del_dialog_complete_event_param *param)
+{
+	twt_del_dialog_cb callback;
+	void *context;
+
+	callback = mac->sme.twt_del_dialog_cb;
+	context = mac->sme.twt_del_dialog_context;
+	mac->sme.twt_del_dialog_cb = NULL;
+	if (callback)
+		callback(context, param);
+}
+
+/**
+ * sme_process_twt_pause_dialog_event() - Process twt pause dialog event
+ * response from firmware
+ * @mac: Global MAC pointer
+ * @param: pointer to wmi_twt_pause_dialog_complete_event_param buffer
+ *
+ * Return: None
+ */
+static void
+sme_process_twt_pause_dialog_event(struct mac_context *mac,
+				   struct wmi_twt_pause_dialog_complete_event_param *param)
+{
+	twt_pause_dialog_cb callback;
+	void *context;
+
+	callback = mac->sme.twt_pause_dialog_cb;
+	context = mac->sme.twt_pause_dialog_context;
+	mac->sme.twt_pause_dialog_cb = NULL;
+	if (callback)
+		callback(context, param);
+}
+
+/**
+ * sme_process_twt_resume_dialog_event() - Process twt resume dialog event
+ * response from firmware
+ * @mac: Global MAC pointer
+ * @param: pointer to wmi_twt_resume_dialog_complete_event_param buffer
+ *
+ * Return: None
+ */
+static void
+sme_process_twt_resume_dialog_event(struct mac_context *mac,
+				    struct wmi_twt_resume_dialog_complete_event_param *param)
+{
+	twt_resume_dialog_cb callback;
+	void *context;
+
+	callback = mac->sme.twt_resume_dialog_cb;
+	context = mac->sme.twt_resume_dialog_context;
+	mac->sme.twt_resume_dialog_cb = NULL;
+	if (callback)
+		callback(context, param);
+}
+#else
+
+static void
+sme_process_twt_add_dialog_event(struct mac_context *mac,
+				 struct twt_add_dialog_complete_event *add_dialog_event)
+{
+}
+
+static void
+sme_process_twt_del_dialog_event(struct mac_context *mac,
+				 struct wmi_twt_del_dialog_complete_event_param *param)
+{
+}
+
+static void
+sme_process_twt_pause_dialog_event(struct mac_context *mac,
+				   struct wmi_twt_pause_dialog_complete_event_param *param)
+{
+}
+
+static void
+sme_process_twt_resume_dialog_event(struct mac_context *mac,
+				    struct wmi_twt_resume_dialog_complete_event_param *param)
+{
+}
+#endif
+
 QDF_STATUS sme_process_msg(struct mac_context *mac, struct scheduler_msg *pMsg)
 {
 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
@@ -2363,6 +2478,22 @@ QDF_STATUS sme_process_msg(struct mac_context *mac, struct scheduler_msg *pMsg)
 	case eWNI_SME_MONITOR_MODE_VDEV_UP:
 		status = sme_process_monitor_mode_vdev_up_evt(pMsg->bodyval);
 		break;
+	case eWNI_SME_TWT_ADD_DIALOG_EVENT:
+		sme_process_twt_add_dialog_event(mac, pMsg->bodyptr);
+		qdf_mem_free(pMsg->bodyptr);
+		break;
+	case eWNI_SME_TWT_DEL_DIALOG_EVENT:
+		sme_process_twt_del_dialog_event(mac, pMsg->bodyptr);
+		qdf_mem_free(pMsg->bodyptr);
+		break;
+	case eWNI_SME_TWT_PAUSE_DIALOG_EVENT:
+		sme_process_twt_pause_dialog_event(mac, pMsg->bodyptr);
+		qdf_mem_free(pMsg->bodyptr);
+		break;
+	case eWNI_SME_TWT_RESUME_DIALOG_EVENT:
+		sme_process_twt_resume_dialog_event(mac, pMsg->bodyptr);
+		qdf_mem_free(pMsg->bodyptr);
+		break;
 	default:
 
 		if ((pMsg->type >= eWNI_SME_MSG_TYPES_BEGIN)
@@ -14347,6 +14478,54 @@ QDF_STATUS sme_deregister_tx_queue_cb(mac_handle_t mac_handle)
 
 #ifdef WLAN_SUPPORT_TWT
 
+QDF_STATUS sme_test_config_twt_setup(struct wmi_twt_add_dialog_param *params)
+{
+	t_wma_handle *wma_handle;
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma_handle) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"wma handle is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return wma_twt_process_add_dialog(wma_handle, params);
+}
+
+QDF_STATUS
+sme_test_config_twt_terminate(struct wmi_twt_del_dialog_param *params)
+{
+	t_wma_handle *wma_handle;
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma_handle) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"wma handle is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return wma_twt_process_del_dialog(wma_handle, params);
+}
+
+QDF_STATUS sme_init_twt_complete_cb(mac_handle_t mac_handle)
+{
+	QDF_STATUS status;
+	struct mac_context *mac = MAC_CONTEXT(mac_handle);
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		mac->sme.twt_add_dialog_cb = NULL;
+		mac->sme.twt_del_dialog_cb = NULL;
+		mac->sme.twt_pause_dialog_cb = NULL;
+		mac->sme.twt_resume_dialog_cb = NULL;
+		sme_release_global_lock(&mac->sme);
+
+		sme_debug("TWT: callbacks Initialized");
+	}
+
+	return status;
+}
+
 QDF_STATUS sme_register_twt_enable_complete_cb(mac_handle_t mac_handle,
 					       twt_enable_cb twt_enable_cb)
 {
@@ -14395,8 +14574,10 @@ QDF_STATUS sme_add_dialog_cmd(mac_handle_t mac_handle,
 			      void *context)
 {
 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
+	struct scheduler_msg twt_msg = {0};
 	QDF_STATUS status;
 	void *wma_handle;
+	struct wmi_twt_del_dialog_param *cmd_params;
 
 	SME_ENTER();
 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
@@ -14405,21 +14586,43 @@ QDF_STATUS sme_add_dialog_cmd(mac_handle_t mac_handle,
 		return QDF_STATUS_E_FAILURE;
 	}
 
+	/*bodyptr should be freeable*/
+	cmd_params = qdf_mem_malloc(sizeof(*cmd_params));
+	if (!cmd_params)
+		return QDF_STATUS_E_NOMEM;
+
+	qdf_mem_copy(cmd_params, twt_params, sizeof(*cmd_params));
+
 	status = sme_acquire_global_lock(&mac->sme);
-	if (QDF_IS_STATUS_SUCCESS(status)) {
-		mac->sme.twt_add_dialog_cb = twt_add_dialog_cb;
-		mac->sme.twt_context = context;
-		sme_release_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		sme_err("failed to register add dialog callback");
+		qdf_mem_free(cmd_params);
+		return status;
 	}
 
-	if (!QDF_IS_STATUS_SUCCESS(status)) {
-		sme_err("failed to register add dlg callback");
-		return status;
+	if (mac->sme.twt_add_dialog_cb) {
+		sme_release_global_lock(&mac->sme);
+		qdf_mem_free(cmd_params);
+		sme_err_rl("TWT: Command in progress - STATUS E_BUSY");
+		return QDF_STATUS_E_BUSY;
 	}
 
-	status = wma_twt_process_add_dialog(twt_params);
-	if (!QDF_IS_STATUS_SUCCESS(status))
-		sme_err("failed to call wma_start_oem_data_cmd.");
+	/* Serialize the req through MC thread */
+	mac->sme.twt_add_dialog_cb = twt_add_dialog_cb;
+	mac->sme.twt_add_dialog_context = context;
+	twt_msg.bodyptr = cmd_params;
+	twt_msg.type = WMA_TWT_ADD_DIALOG_REQUEST;
+	sme_release_global_lock(&mac->sme);
+
+	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 add dialog msg fail"));
+		qdf_mem_free(cmd_params);
+	}
 
 	SME_EXIT();
 	return status;
@@ -14431,8 +14634,10 @@ QDF_STATUS sme_del_dialog_cmd(mac_handle_t mac_handle,
 			      void *context)
 {
 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
+	struct scheduler_msg twt_msg = {0};
 	QDF_STATUS status;
 	void *wma_handle;
+	struct wmi_twt_add_dialog_param *cmd_params;
 
 	SME_ENTER();
 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
@@ -14441,21 +14646,43 @@ QDF_STATUS sme_del_dialog_cmd(mac_handle_t mac_handle,
 		return QDF_STATUS_E_FAILURE;
 	}
 
+	/*bodyptr should be freeable*/
+	cmd_params = qdf_mem_malloc(sizeof(*cmd_params));
+	if (!cmd_params)
+		return QDF_STATUS_E_NOMEM;
+
+	qdf_mem_copy(cmd_params, twt_params, sizeof(*cmd_params));
+
 	status = sme_acquire_global_lock(&mac->sme);
-	if (QDF_IS_STATUS_SUCCESS(status)) {
-		mac->sme.twt_del_dialog_cb = del_dialog_cb;
-		mac->sme.twt_context = context;
-		sme_release_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		sme_err("failed to register del dialog callback");
+		qdf_mem_free(cmd_params);
+		return status;
 	}
 
-	if (!QDF_IS_STATUS_SUCCESS(status)) {
-		sme_err("failed to register del dlg callback");
-		return status;
+	if (mac->sme.twt_del_dialog_cb) {
+		sme_release_global_lock(&mac->sme);
+		qdf_mem_free(cmd_params);
+		sme_err_rl("TWT: Command in progress - STATUS E_BUSY");
+		return QDF_STATUS_E_BUSY;
 	}
 
-	status = wma_twt_process_del_dialog(twt_params);
-	if (!QDF_IS_STATUS_SUCCESS(status))
-		sme_err("failed to call wma_twt_process_del_dialog");
+	/* Serialize the req through MC thread */
+	mac->sme.twt_del_dialog_cb = del_dialog_cb;
+	mac->sme.twt_del_dialog_context = context;
+	twt_msg.bodyptr = cmd_params;
+	twt_msg.type = WMA_TWT_DEL_DIALOG_REQUEST;
+	sme_release_global_lock(&mac->sme);
+
+	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 del dialog msg fail"));
+		qdf_mem_free(cmd_params);
+	}
 
 	SME_EXIT();
 	return status;
@@ -14468,6 +14695,8 @@ sme_pause_dialog_cmd(mac_handle_t mac_handle,
 		     void *context)
 {
 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
+	struct wmi_twt_pause_dialog_cmd_param *cmd_params;
+	struct scheduler_msg twt_msg = {0};
 	QDF_STATUS status;
 	void *wma_handle;
 
@@ -14478,19 +14707,43 @@ sme_pause_dialog_cmd(mac_handle_t mac_handle,
 		return QDF_STATUS_E_FAILURE;
 	}
 
+	/*bodyptr should be freeable*/
+	cmd_params = qdf_mem_malloc(sizeof(*cmd_params));
+	if (!cmd_params)
+		return QDF_STATUS_E_NOMEM;
+
+	qdf_mem_copy(cmd_params, twt_params, sizeof(*cmd_params));
+
 	status = sme_acquire_global_lock(&mac->sme);
 	if (QDF_IS_STATUS_ERROR(status)) {
 		sme_err("failed to register pause dialog callback");
+		qdf_mem_free(cmd_params);
 		return status;
 	}
 
+	if (mac->sme.twt_pause_dialog_cb) {
+		sme_release_global_lock(&mac->sme);
+		qdf_mem_free(cmd_params);
+		sme_err_rl("TWT: Command in progress - STATUS E_BUSY");
+		return QDF_STATUS_E_BUSY;
+	}
+
+	/* Serialize the req through MC thread */
 	mac->sme.twt_pause_dialog_cb = pause_dialog_cb;
-	mac->sme.twt_context = context;
+	mac->sme.twt_pause_dialog_context = context;
+	twt_msg.bodyptr = cmd_params;
+	twt_msg.type = WMA_TWT_PAUSE_DIALOG_REQUEST;
 	sme_release_global_lock(&mac->sme);
 
-	status = wma_twt_process_pause_dialog(twt_params);
-	if (QDF_IS_STATUS_ERROR(status))
-		sme_err("failed to call wma_twt_process_pause_dialog");
+	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 pause dialog msg fail"));
+		qdf_mem_free(cmd_params);
+	}
 
 	SME_EXIT();
 	return status;
@@ -14503,6 +14756,8 @@ sme_resume_dialog_cmd(mac_handle_t mac_handle,
 		      void *context)
 {
 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
+	struct wmi_twt_resume_dialog_cmd_param *cmd_params;
+	struct scheduler_msg twt_msg = {0};
 	QDF_STATUS status;
 	void *wma_handle;
 
@@ -14513,24 +14768,47 @@ sme_resume_dialog_cmd(mac_handle_t mac_handle,
 		return QDF_STATUS_E_FAILURE;
 	}
 
+	/*bodyptr should be freeable*/
+	cmd_params = qdf_mem_malloc(sizeof(*cmd_params));
+	if (!cmd_params)
+		return QDF_STATUS_E_NOMEM;
+
+	qdf_mem_copy(cmd_params, twt_params, sizeof(*cmd_params));
+
 	status = sme_acquire_global_lock(&mac->sme);
 	if (QDF_IS_STATUS_ERROR(status)) {
 		sme_err("failed to register resume dialog callback");
+		qdf_mem_free(cmd_params);
 		return status;
 	}
 
+	if (mac->sme.twt_resume_dialog_cb) {
+		sme_release_global_lock(&mac->sme);
+		qdf_mem_free(cmd_params);
+		sme_err_rl("TWT: Command in progress - STATUS E_BUSY");
+		return QDF_STATUS_E_BUSY;
+	}
+
+	/* Serialize the req through MC thread */
 	mac->sme.twt_resume_dialog_cb = resume_dialog_cb;
-	mac->sme.twt_context = context;
+	mac->sme.twt_resume_dialog_context = context;
+	twt_msg.bodyptr = cmd_params;
+	twt_msg.type = WMA_TWT_RESUME_DIALOG_REQUEST;
 	sme_release_global_lock(&mac->sme);
 
-	status = wma_twt_process_resume_dialog(twt_params);
-	if (QDF_IS_STATUS_ERROR(status))
-		sme_err("failed to call wma_twt_process_resume_dialog");
+	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"));
+		qdf_mem_free(cmd_params);
+	}
 
 	SME_EXIT();
 	return status;
 }
-
 #endif
 
 QDF_STATUS sme_set_smps_cfg(uint32_t vdev_id, uint32_t param_id,

+ 46 - 21
core/wma/inc/wma_twt.h

@@ -23,6 +23,19 @@
 #include "wmi_unified_twt_param.h"
 
 #ifdef WLAN_SUPPORT_TWT
+/**
+ * struct twt_add_dialog_complete_event - TWT add dialog complete event
+ * @params: Fixed parameters for TWT add dialog complete event
+ * @additional_params: additional parameters for TWT add dialog complete event
+ *
+ * Holds the fixed and additional parameters from add dialog
+ * complete event
+ */
+struct twt_add_dialog_complete_event {
+	struct wmi_twt_add_dialog_complete_event_param params;
+	struct wmi_twt_add_dialog_additional_params additional_params;
+};
+
 /**
  * wma_send_twt_enable_cmd() - Send TWT Enable command to firmware
  * @pdev_id: pdev id
@@ -55,39 +68,50 @@ void wma_send_twt_disable_cmd(uint32_t pdev_id);
 
 /**
  * wma_twt_process_add_dialog() - Process twt add dialog command
- * @params: add dialog configuration param
+ * @wma_handle: wma handle
+ * @params: add dialog configuration parameters
  *
- * Return: QDF_STATUS
+ * Return: QDF_STATUS_SUCCESS on success, other QDF_STATUS error code
+ * on failure
  */
-QDF_STATUS wma_twt_process_add_dialog(struct wmi_twt_add_dialog_param *params);
+
+QDF_STATUS wma_twt_process_add_dialog(t_wma_handle *wma_handle,
+				      struct wmi_twt_add_dialog_param *params);
 
 /**
  * wma_twt_process_del_dialog() - Process del dialog command
- * @params: del dialog configuration param
+ * @wma_handle: wma handle
+ * @params: del dialog configuration parameters
  *
- * Return: QDF_STATUS
+ * Return: QDF_STATUS_SUCCESS on success, other QDF_STATUS error code
+ * on failure
  */
-QDF_STATUS wma_twt_process_del_dialog(struct wmi_twt_del_dialog_param *params);
+QDF_STATUS wma_twt_process_del_dialog(t_wma_handle *wma_handle,
+				      struct wmi_twt_del_dialog_param *params);
 
 /**
  * wma_twt_process_pause_dialog() - Process pause dialog command
- * @params: pause dialog configuration param
+ * @wma_handle: wma handle
+ * @params: pause dialog configuration parameters
  *
  * Return: QDF_STATUS_SUCCESS on success, other QDF_STATUS error code
  * on failure
  */
 QDF_STATUS
-wma_twt_process_pause_dialog(struct wmi_twt_pause_dialog_cmd_param *params);
+wma_twt_process_pause_dialog(t_wma_handle *wma_handle,
+			     struct wmi_twt_pause_dialog_cmd_param *params);
 
 /**
  * wma_twt_process_resume_dialog() - Process resume dialog command
- * @params: resume dialog configuration param
+ * @wma_handle: wma handle
+ * @params: resume dialog configuration parameters
  *
  * Return: QDF_STATUS_SUCCESS on success, other QDF_STATUS error code
  * on failure
  */
 QDF_STATUS
-wma_twt_process_resume_dialog(struct wmi_twt_resume_dialog_cmd_param *params);
+wma_twt_process_resume_dialog(t_wma_handle *wma_handle,
+			      struct wmi_twt_resume_dialog_cmd_param *params);
 
 #else
 static inline void wma_send_twt_enable_cmd(uint32_t pdev_id,
@@ -106,40 +130,41 @@ static inline void wma_set_twt_peer_caps(tpAddStaParams params,
 {
 }
 
-static inline QDF_STATUS wma_twt_process_add_dialog(
-		struct wmi_twt_add_dialog_param *params)
+static inline
+QDF_STATUS wma_twt_process_add_dialog(t_wma_handle *wma_handle,
+				      struct wmi_twt_add_dialog_param *params)
 {
 	wma_debug("TWT not supported as WLAN_SUPPORT_TWT is disabled");
 
 	return QDF_STATUS_E_INVAL;
 }
 
-static inline QDF_STATUS wma_twt_process_del_dialog(
-		struct wmi_twt_del_dialog_param *params)
+static inline
+QDF_STATUS wma_twt_process_del_dialog(t_wma_handle *wma_handle,
+				      struct wmi_twt_del_dialog_param *params)
 {
 	wma_debug("TWT not supported as WLAN_SUPPORT_TWT is disabled");
 
 	return QDF_STATUS_E_INVAL;
 }
 
-static inline QDF_STATUS wma_twt_process_pause_dialog(
-		struct wmi_twt_pause_dialog_cmd_param *params)
-
+static inline QDF_STATUS
+wma_twt_process_pause_dialog(t_wma_handle *wma_handle,
+			     struct wmi_twt_pause_dialog_cmd_param *params)
 {
 	wma_debug("TWT not supported as WLAN_SUPPORT_TWT is disabled");
 
 	return QDF_STATUS_E_INVAL;
 }
 
-static inline QDF_STATUS wma_twt_process_resume_dialog(
-		struct wmi_twt_resume_dialog_cmd_param *params)
-
+static inline QDF_STATUS
+wma_twt_process_resume_dialog(t_wma_handle *wma_handle,
+			      struct wmi_twt_resume_dialog_cmd_param *params)
 {
 	wma_debug("TWT not supported as WLAN_SUPPORT_TWT is disabled");
 
 	return QDF_STATUS_E_INVAL;
 }
-
 #endif
 
 #endif /* __WMA_HE_H */

+ 4 - 0
core/wma/inc/wma_types.h

@@ -451,6 +451,10 @@ enum wmamsgtype {
 	WMA_ROAM_DISABLE_CFG = SIR_HAL_INIT_ROAM_DISABLE_CFG,
 
 #endif
+	WMA_TWT_ADD_DIALOG_REQUEST = SIR_HAL_TWT_ADD_DIALOG_REQUEST,
+	WMA_TWT_DEL_DIALOG_REQUEST = SIR_HAL_TWT_DEL_DIALOG_REQUEST,
+	WMA_TWT_PAUSE_DIALOG_REQUEST = SIR_HAL_TWT_PAUSE_DIALOG_REQUEST,
+	WMA_TWT_RESUME_DIALOG_REQUEST =  SIR_HAL_TWT_RESUME_DIALOG_REQUEST,
 };
 
 #define WMA_DATA_STALL_TRIGGER 6

+ 17 - 0
core/wma/src/wma_main.c

@@ -101,6 +101,7 @@
 #include "init_cmd_api.h"
 #include "nan_ucfg_api.h"
 #include "wma_coex.h"
+#include "wma_twt.h"
 #include "target_if_vdev_mgr_rx_ops.h"
 #include "wlan_tdls_cfg_api.h"
 #include "wlan_policy_mgr_i.h"
@@ -8992,6 +8993,22 @@ static QDF_STATUS wma_mc_process_msg(struct scheduler_msg *msg)
 	case WMA_ROAM_SCAN_CH_REQ:
 		wma_get_roam_scan_ch(wma_handle->wmi_handle, msg->bodyval);
 		break;
+	case WMA_TWT_ADD_DIALOG_REQUEST:
+		wma_twt_process_add_dialog(wma_handle, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_TWT_DEL_DIALOG_REQUEST:
+		wma_twt_process_del_dialog(wma_handle, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_TWT_PAUSE_DIALOG_REQUEST:
+		wma_twt_process_pause_dialog(wma_handle, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
+	case WMA_TWT_RESUME_DIALOG_REQUEST:
+		wma_twt_process_resume_dialog(wma_handle, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
 	default:
 		wma_debug("Unhandled WMA message of type %d", msg->type);
 		if (msg->bodyptr)

+ 76 - 41
core/wma/src/wma_twt.c

@@ -143,10 +143,9 @@ void wma_set_twt_peer_caps(tpAddStaParams params, struct peer_assoc_params *cmd)
 		cmd->twt_responder = 1;
 }
 
-QDF_STATUS wma_twt_process_add_dialog(
-		struct wmi_twt_add_dialog_param *params)
+QDF_STATUS wma_twt_process_add_dialog(t_wma_handle *wma_handle,
+				      struct wmi_twt_add_dialog_param *params)
 {
-	t_wma_handle *wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
 	wmi_unified_t wmi_handle;
 
 	if (!wma_handle) {
@@ -176,8 +175,8 @@ static
 int wma_twt_add_dialog_complete_event_handler(void *handle,
 					      uint8_t *event, uint32_t len)
 {
-	struct wmi_twt_add_dialog_complete_event_param param = {0};
-	struct wmi_twt_add_dialog_additional_params additional_params = {0};
+	struct twt_add_dialog_complete_event *add_dialog_event;
+	struct scheduler_msg sme_msg = {0};
 	tp_wma_handle wma_handle = handle;
 	wmi_unified_t wmi_handle;
 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
@@ -185,48 +184,56 @@ int wma_twt_add_dialog_complete_event_handler(void *handle,
 
 	if (!wma_handle) {
 		wma_err("Invalid wma handle for TWT add dialog complete");
-		return status;
+		return -EINVAL;
 	}
 
 	if (!mac) {
 		wma_err("Invalid MAC context");
-		return status;
+		return -EINVAL;
 	}
 
 	wmi_handle = (wmi_unified_t)wma_handle->wmi_handle;
 	if (!wmi_handle) {
 		wma_err("Invalid wma handle for TWT add dialog complete");
-		return status;
+		return -EINVAL;
 	}
 
+	add_dialog_event = qdf_mem_malloc(sizeof(*add_dialog_event));
+	if (!add_dialog_event)
+		return -ENOMEM;
+
 	status = wmi_extract_twt_add_dialog_comp_event(wmi_handle, event,
-						       &param);
+						       &add_dialog_event->params);
 	if (QDF_IS_STATUS_ERROR(status))
 		return qdf_status_to_os_return(status);
 
-	if (param.num_additional_twt_params) {
+	if (add_dialog_event->params.num_additional_twt_params) {
 		status = wmi_extract_twt_add_dialog_comp_additional_params(wmi_handle,
 									   event,
 									   len, 0,
-									   &additional_params);
+									   &add_dialog_event->additional_params);
 		if (QDF_IS_STATUS_ERROR(status))
 			return qdf_status_to_os_return(status);
 	}
 
 	wma_debug("TWT: Extract TWT add dialog event :%d", status);
 
-	if (mac->sme.twt_add_dialog_cb)
-		mac->sme.twt_add_dialog_cb(mac->sme.twt_context, &param,
-					   &additional_params);
-	mac->sme.twt_add_dialog_cb = NULL;
+	sme_msg.type = eWNI_SME_TWT_ADD_DIALOG_EVENT;
+	sme_msg.bodyptr = add_dialog_event;
+	sme_msg.bodyval = 0;
+	status = scheduler_post_message(QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_SME, &sme_msg);
+	if (QDF_IS_STATUS_ERROR(status))
+		return -EINVAL;
 
 	return status;
 }
 
-QDF_STATUS wma_twt_process_del_dialog(
-		struct wmi_twt_del_dialog_param *params)
+QDF_STATUS
+wma_twt_process_del_dialog(t_wma_handle *wma_handle,
+			   struct wmi_twt_del_dialog_param *params)
 {
-	t_wma_handle *wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
 	wmi_unified_t wmi_handle;
 
 	if (!wma_handle) {
@@ -256,7 +263,8 @@ static
 int wma_twt_del_dialog_complete_event_handler(void *handle,
 					      uint8_t *event, uint32_t len)
 {
-	struct wmi_twt_del_dialog_complete_event_param param;
+	struct wmi_twt_del_dialog_complete_event_param *param;
+	struct scheduler_msg sme_msg = {0};
 	tp_wma_handle wma_handle = handle;
 	wmi_unified_t wmi_handle;
 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
@@ -275,22 +283,31 @@ int wma_twt_del_dialog_complete_event_handler(void *handle,
 		wma_err("Invalid MAC context");
 		return status;
 	}
+
+	param = qdf_mem_malloc(sizeof(*param));
+	if (!param)
+		return -ENOMEM;
+
 	status = wmi_extract_twt_del_dialog_comp_event(wmi_handle, event,
-						       &param);
+						       param);
 	wma_debug("TWT: Extract TWT del dlg comp event, status:%d", status);
 
-	if (mac->sme.twt_del_dialog_cb)
-		mac->sme.twt_del_dialog_cb(mac->sme.twt_context, &param);
-
-	mac->sme.twt_del_dialog_cb = NULL;
+	sme_msg.type = eWNI_SME_TWT_DEL_DIALOG_EVENT;
+	sme_msg.bodyptr = param;
+	sme_msg.bodyval = 0;
+	status = scheduler_post_message(QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_SME, &sme_msg);
+	if (QDF_IS_STATUS_ERROR(status))
+		return -EINVAL;
 
 	return status;
 }
 
 QDF_STATUS
-wma_twt_process_pause_dialog(struct wmi_twt_pause_dialog_cmd_param *params)
+wma_twt_process_pause_dialog(t_wma_handle *wma_handle,
+			     struct wmi_twt_pause_dialog_cmd_param *params)
 {
-	t_wma_handle *wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
 	wmi_unified_t wmi_handle;
 
 	if (!wma_handle) {
@@ -320,7 +337,8 @@ static
 int wma_twt_pause_dialog_complete_event_handler(void *handle, uint8_t *event,
 						uint32_t len)
 {
-	struct wmi_twt_pause_dialog_complete_event_param param;
+	struct wmi_twt_pause_dialog_complete_event_param *param;
+	struct scheduler_msg sme_msg = {0};
 	tp_wma_handle wma_handle = handle;
 	wmi_unified_t wmi_handle;
 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
@@ -342,24 +360,32 @@ int wma_twt_pause_dialog_complete_event_handler(void *handle, uint8_t *event,
 		return status;
 	}
 
+	param = qdf_mem_malloc(sizeof(*param));
+	if (!param)
+		return -ENOMEM;
+
 	if (wmi_handle->ops->extract_twt_pause_dialog_comp_event)
 		status = wmi_handle->ops->extract_twt_pause_dialog_comp_event(wmi_handle,
 									      event,
-									      &param);
+									      param);
 	wma_debug("TWT: Extract pause dialog comp event status:%d", status);
 
-	if (mac->sme.twt_pause_dialog_cb)
-		mac->sme.twt_pause_dialog_cb(mac->sme.twt_context, &param);
-
-	mac->sme.twt_pause_dialog_cb = NULL;
+	sme_msg.type = eWNI_SME_TWT_PAUSE_DIALOG_EVENT;
+	sme_msg.bodyptr = param;
+	sme_msg.bodyval = 0;
+	status = scheduler_post_message(QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_SME, &sme_msg);
+	if (QDF_IS_STATUS_ERROR(status))
+		return -EINVAL;
 
 	return status;
 }
 
-QDF_STATUS wma_twt_process_resume_dialog(
-		struct wmi_twt_resume_dialog_cmd_param *params)
+QDF_STATUS
+wma_twt_process_resume_dialog(t_wma_handle *wma_handle,
+			      struct wmi_twt_resume_dialog_cmd_param *params)
 {
-	t_wma_handle *wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
 	wmi_unified_t wmi_handle;
 
 	if (!wma_handle) {
@@ -389,7 +415,8 @@ static
 int wma_twt_resume_dialog_complete_event_handler(void *handle, uint8_t *event,
 						 uint32_t len)
 {
-	struct wmi_twt_resume_dialog_complete_event_param param;
+	struct wmi_twt_resume_dialog_complete_event_param *param;
+	struct scheduler_msg sme_msg = {0};
 	tp_wma_handle wma_handle = handle;
 	wmi_unified_t wmi_handle;
 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
@@ -411,16 +438,24 @@ int wma_twt_resume_dialog_complete_event_handler(void *handle, uint8_t *event,
 		return status;
 	}
 
+	param = qdf_mem_malloc(sizeof(*param));
+	if (!param)
+		return -ENOMEM;
+
 	if (wmi_handle->ops->extract_twt_resume_dialog_comp_event)
 		status = wmi_handle->ops->extract_twt_resume_dialog_comp_event(wmi_handle,
 									       event,
-									       &param);
+									       param);
 	wma_debug("TWT: Extract resume dialog comp event status:%d", status);
 
-	if (mac->sme.twt_resume_dialog_cb)
-		mac->sme.twt_resume_dialog_cb(mac->sme.twt_context, &param);
-
-	mac->sme.twt_resume_dialog_cb = NULL;
+	sme_msg.type = eWNI_SME_TWT_RESUME_DIALOG_EVENT;
+	sme_msg.bodyptr = param;
+	sme_msg.bodyval = 0;
+	status = scheduler_post_message(QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_SME, &sme_msg);
+	if (QDF_IS_STATUS_ERROR(status))
+		return -EINVAL;
 
 	return status;
 }