Parcourir la source

qcacld-3.0: Move TWT test config code to wlan_hdd_twt file

Move TWT test config interface code to wlan_hdd_twt.c file

CRs-Fixed: 2745940
Change-Id: If77f40de36677029b4e06592f5ccfa95ace7871f
Rajasekaran Kalidoss il y a 4 ans
Parent
commit
f7f6741e9f

+ 41 - 19
core/hdd/inc/wlan_hdd_twt.h

@@ -39,12 +39,8 @@ struct wmi_twt_del_dialog_param;
 struct wmi_twt_pause_dialog_cmd_param;
 struct wmi_twt_resume_dialog_cmd_param;
 
-extern const struct nla_policy qca_wlan_vendor_twt_add_dialog_policy[
-		QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1];
-
 extern const struct nla_policy
-wlan_hdd_wifi_twt_config_policy[
-	QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX + 1];
+wlan_hdd_wifi_twt_config_policy[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX + 1];
 
 #ifdef WLAN_SUPPORT_TWT
 /**
@@ -142,6 +138,34 @@ void wlan_hdd_twt_init(struct hdd_context *hdd_ctx);
  */
 void wlan_hdd_twt_deinit(struct hdd_context *hdd_ctx);
 
+/**
+ * hdd_test_config_twt_setup_session() - Process TWT setup
+ * operation in the received test config vendor command and
+ * send it to firmare
+ * @adapter: adapter pointer
+ * @tb: nl attributes
+ *
+ * Handles QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP
+ *
+ * Return: 0 for Success and negative value for failure
+ */
+int hdd_test_config_twt_setup_session(struct hdd_adapter *adapter,
+				      struct nlattr **tb);
+
+/**
+ * hdd_test_config_twt_terminate_session() - Process TWT terminate
+ * operation in the received test config vendor command and send
+ * it to firmare
+ * @adapter: adapter pointer
+ * @tb: nl attributes
+ *
+ * Handles QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_TERMINATE
+ *
+ * Return: 0 for Success and negative value for failure
+ */
+int hdd_test_config_twt_terminate_session(struct hdd_adapter *adapter,
+					  struct nlattr **tb);
+
 #define FEATURE_VENDOR_SUBCMD_WIFI_CONFIG_TWT                            \
 {                                                                        \
 	.info.vendor_id = QCA_NL80211_VENDOR_ID,                         \
@@ -155,16 +179,6 @@ void wlan_hdd_twt_deinit(struct hdd_context *hdd_ctx);
 			      QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX)       \
 },
 
-/**
- * hdd_twt_setup_req_type_to_cmd() - Converts twt setup request type to twt cmd
- * @req_type: twt setup request type
- * @twt_cmd: pointer to store twt command
- *
- * Return: QDF_STATUS_SUCCESS on success, else other qdf error values
- */
-QDF_STATUS
-hdd_twt_setup_req_type_to_cmd(u8 req_type, enum WMI_HOST_TWT_COMMAND *twt_cmd);
-
 #else
 static inline void hdd_update_tgt_twt_cap(struct hdd_context *hdd_ctx,
 					  struct wma_tgt_cfg *cfg)
@@ -188,12 +202,20 @@ static inline void wlan_hdd_twt_deinit(struct hdd_context *hdd_ctx)
 {
 }
 
-enum WMI_HOST_TWT_COMMAND;
-static inline QDF_STATUS
-hdd_twt_setup_req_type_to_cmd(u8 req_type, enum WMI_HOST_TWT_COMMAND *twt_cmd)
+static inline
+int hdd_test_config_twt_setup_session(struct hdd_adapter *adapter,
+				      struct nlattr **tb)
 {
-	return QDF_STATUS_E_INVAL;
+	return -EINVAL;
 }
+
+static inline
+int hdd_test_config_twt_terminate_session(struct hdd_adapter *adapter,
+					  struct nlattr **tb)
+{
+	return -EINVAL;
+}
+
 #define FEATURE_VENDOR_SUBCMD_WIFI_CONFIG_TWT
 
 #endif

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

@@ -159,9 +159,6 @@
 #include "wlan_reg_ucfg_api.h"
 #include "wlan_hdd_twt.h"
 
-#define TWT_FLOW_TYPE_ANNOUNCED 0
-#define TWT_FLOW_TYPE_UNANNOUNCED 1
-
 #ifdef WLAN_FEATURE_INTERFACE_MGR
 #include "wlan_if_mgr_ucfg_api.h"
 #include "wlan_if_mgr_public_struct.h"
@@ -771,21 +768,6 @@ static struct ieee80211_iface_combination
 
 static struct cfg80211_ops wlan_hdd_cfg80211_ops;
 
-const struct nla_policy qca_wlan_vendor_twt_add_dialog_policy[
-		QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1] = {
-	[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP] = {.type = NLA_U8 },
-	[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST] = {.type = NLA_FLAG },
-	[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE] = {.type = NLA_U8 },
-	[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER] = {.type = NLA_FLAG },
-	[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID] = {.type = NLA_U8 },
-	[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE] = {.type = NLA_U8 },
-	[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION] = {.type = NLA_FLAG },
-	[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME] = {.type = NLA_U32 },
-	[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION] = {.type = NLA_U32 },
-	[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA] = {
-		.type = NLA_U32 },
-};
-
 #ifdef WLAN_NL80211_TESTMODE
 enum wlan_hdd_tm_attr {
 	WLAN_HDD_TM_ATTR_INVALID = 0,
@@ -9430,125 +9412,6 @@ static void hdd_disable_runtime_pm_for_user(struct hdd_context *hdd_ctx)
 	qdf_runtime_pm_prevent_suspend(&ctx->user);
 }
 
-int hdd_twt_get_add_dialog_values(struct nlattr **tb,
-				  struct wmi_twt_add_dialog_param *params)
-{
-	uint32_t wake_intvl_exp, result;
-	int cmd_id;
-	QDF_STATUS qdf_status;
-
-	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID;
-	if (tb[cmd_id]) {
-		params->dialog_id = nla_get_u8(tb[cmd_id]);
-	} else {
-		params->dialog_id = 0;
-		hdd_debug("TWT_SETUP_FLOW_ID not specified. set to zero");
-	}
-
-	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP;
-	if (!tb[cmd_id]) {
-		hdd_err_rl("TWT_SETUP_WAKE_INTVL_EXP is must");
-		return -EINVAL;
-	}
-	wake_intvl_exp = nla_get_u8(tb[cmd_id]);
-	if (wake_intvl_exp > TWT_SETUP_WAKE_INTVL_EXP_MAX) {
-		hdd_err_rl("Invalid wake_intvl_exp %u > %u",
-			   wake_intvl_exp,
-			   TWT_SETUP_WAKE_INTVL_EXP_MAX);
-		return -EINVAL;
-	}
-
-	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST;
-	params->flag_bcast = nla_get_flag(tb[cmd_id]);
-
-	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE;
-	if (!tb[cmd_id]) {
-		hdd_err_rl("TWT_SETUP_REQ_TYPE is must");
-		return -EINVAL;
-	}
-	qdf_status = hdd_twt_setup_req_type_to_cmd(nla_get_u8(tb[cmd_id]),
-						   &params->twt_cmd);
-	if (QDF_IS_STATUS_ERROR(qdf_status))
-		return qdf_status_to_os_return(qdf_status);
-
-	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER;
-	params->flag_trigger = nla_get_flag(tb[cmd_id]);
-
-	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE;
-	if (!tb[cmd_id]) {
-		hdd_err_rl("TWT_SETUP_FLOW_TYPE is must");
-		return -EINVAL;
-	}
-	params->flag_flow_type = nla_get_u8(tb[cmd_id]);
-	if (params->flag_flow_type != TWT_FLOW_TYPE_ANNOUNCED &&
-	    params->flag_flow_type != TWT_FLOW_TYPE_UNANNOUNCED)
-		return -EINVAL;
-
-	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION;
-	params->flag_protection = nla_get_flag(tb[cmd_id]);
-
-	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME;
-	if (tb[cmd_id])
-		params->sp_offset_us = nla_get_u32(tb[cmd_id]);
-
-	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION;
-	if (!tb[cmd_id]) {
-		hdd_err_rl("TWT_SETUP_WAKE_DURATION is must");
-		return -EINVAL;
-	}
-	params->wake_dura_us = TWT_WAKE_DURATION_MULTIPLICATION_FACTOR *
-			       nla_get_u32(tb[cmd_id]);
-	if (params->wake_dura_us > TWT_SETUP_WAKE_DURATION_MAX) {
-		hdd_err_rl("Invalid wake_dura_us %u",
-			   params->wake_dura_us);
-		return -EINVAL;
-	}
-
-	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA;
-	if (!tb[cmd_id]) {
-		hdd_err_rl("SETUP_WAKE_INTVL_MANTISSA is must");
-		return -EINVAL;
-	}
-	params->wake_intvl_mantis = nla_get_u32(tb[cmd_id]);
-	if (params->wake_intvl_mantis >
-	    TWT_SETUP_WAKE_INTVL_MANTISSA_MAX) {
-		hdd_err_rl("Invalid wake_intvl_mantis %u",
-			   params->wake_dura_us);
-		return -EINVAL;
-	}
-
-	if (wake_intvl_exp && params->wake_intvl_mantis) {
-		result = 2 << (wake_intvl_exp - 1);
-		if (result >
-		    (UINT_MAX / params->wake_intvl_mantis)) {
-			hdd_err_rl("Invalid exp %d mantissa %d",
-				   wake_intvl_exp,
-				   params->wake_intvl_mantis);
-			return -EINVAL;
-		}
-		params->wake_intvl_us =
-			params->wake_intvl_mantis * result;
-	} else {
-		params->wake_intvl_us = params->wake_intvl_mantis;
-	}
-
-	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",
-		  params->wake_dura_us, params->sp_offset_us,
-		  params->twt_cmd);
-	hdd_debug("twt: bcast %d, trigger %d, flow_type %d, prot %d",
-		  params->flag_bcast, params->flag_trigger,
-		  params->flag_flow_type,
-		  params->flag_protection);
-	hdd_debug("twt: peer mac_addr "
-		  QDF_MAC_ADDR_FMT,
-		  QDF_MAC_ADDR_REF(params->peer_macaddr));
-
-	return 0;
-}
-
 /**
  * __wlan_hdd_cfg80211_set_wifi_test_config() - Wifi test configuration
  * vendor command
@@ -10027,84 +9890,13 @@ __wlan_hdd_cfg80211_set_wifi_test_config(struct wiphy *wiphy,
 	}
 
 	if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP]) {
-		struct wmi_twt_add_dialog_param params = {0};
-		struct hdd_station_ctx *hdd_sta_ctx =
-			WLAN_HDD_GET_STATION_CTX_PTR(adapter);
-		struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1];
-		struct nlattr *twt_session;
-		int tmp, rc;
-		uint32_t congestion_timeout = 0;
-
-		if ((adapter->device_mode != QDF_STA_MODE &&
-		     adapter->device_mode != QDF_P2P_CLIENT_MODE) ||
-		    hdd_sta_ctx->conn_info.conn_state !=
-		    eConnectionState_Associated) {
-			hdd_err_rl("Invalid state, vdev %d mode %d state %d",
-				   adapter->vdev_id, adapter->device_mode,
-				   hdd_sta_ctx->conn_info.conn_state);
+		ret_val = hdd_test_config_twt_setup_session(adapter, tb);
+		if (ret_val)
 			goto send_err;
-		}
-
-		qdf_mem_copy(params.peer_macaddr,
-			     hdd_sta_ctx->conn_info.bssid.bytes,
-			     QDF_MAC_ADDR_SIZE);
-		params.vdev_id = adapter->vdev_id;
-		params.dialog_id = 0;
-
-		cmd_id = QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP;
-		nla_for_each_nested(twt_session, tb[cmd_id], tmp) {
-			rc = wlan_cfg80211_nla_parse(
-					tb2, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX,
-					nla_data(twt_session),
-					nla_len(twt_session),
-					qca_wlan_vendor_twt_add_dialog_policy);
-			if (rc) {
-				hdd_err_rl("Invalid twt ATTR");
-				goto send_err;
-			}
-
-			ret_val = hdd_twt_get_add_dialog_values(tb2, &params);
-			if (ret_val)
-				goto send_err;
-
-			ucfg_mlme_get_twt_congestion_timeout(hdd_ctx->psoc,
-							&congestion_timeout);
-			if (congestion_timeout) {
-				ret_val = qdf_status_to_os_return(
-					hdd_send_twt_disable_cmd(hdd_ctx));
-				if (ret_val) {
-					hdd_err("Failed to disable TWT");
-					goto send_err;
-				}
-				ucfg_mlme_set_twt_congestion_timeout(
-						hdd_ctx->psoc, 0);
-				hdd_send_twt_enable_cmd(hdd_ctx);
-			}
-			ret_val = qdf_status_to_os_return(sme_test_config_twt_setup(&params));
-			if (ret_val)
-				goto send_err;
-		}
 	}
 
 	if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_TERMINATE]) {
-		struct wmi_twt_del_dialog_param params = {0};
-
-		if ((adapter->device_mode != QDF_STA_MODE &&
-		     adapter->device_mode != QDF_P2P_CLIENT_MODE) ||
-		    hdd_sta_ctx->conn_info.conn_state !=
-		    eConnectionState_Associated) {
-			hdd_err("Invalid state, vdev %d mode %d state %d",
-				adapter->vdev_id, adapter->device_mode,
-				hdd_sta_ctx->conn_info.conn_state);
-			goto send_err;
-		}
-		qdf_mem_copy(params.peer_macaddr,
-			     hdd_sta_ctx->conn_info.bssid.bytes,
-			     QDF_MAC_ADDR_SIZE);
-		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(sme_test_config_twt_terminate(&params));
+		ret_val = hdd_test_config_twt_terminate_session(adapter, tb);
 		if (ret_val)
 			goto send_err;
 	}

+ 0 - 12
core/hdd/src/wlan_hdd_cfg80211.h

@@ -875,16 +875,4 @@ static inline void hdd_send_update_owe_info_event(struct hdd_adapter *adapter,
  */
 bool hdd_is_legacy_connection(struct hdd_adapter *adapter);
 
-/**
- * hdd_twt_get_add_dialog_values() - Get TWT add dialog parameter
- * values from QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS
- * @tb: nl attributes
- * @params: wmi twt add dialog parameters
- *
- * Handles QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX
- *
- * Return: 0 or -EINVAL.
- */
-int hdd_twt_get_add_dialog_values(struct nlattr **tb2,
-			       struct wmi_twt_add_dialog_param *params);
 #endif

+ 249 - 1
core/hdd/src/wlan_hdd_twt.c

@@ -41,6 +41,9 @@
 #define TWT_PAUSE_COMPLETE_TIMEOUT 4000
 #define TWT_RESUME_COMPLETE_TIMEOUT 4000
 
+#define TWT_FLOW_TYPE_ANNOUNCED 0
+#define TWT_FLOW_TYPE_UNANNOUNCED 1
+
 /**
  * struct twt_pause_dialog_comp_ev_priv - private struct for twt pause dialog
  * @pause_dialog_comp_ev_buf: buffer from TWT pause dialog complete_event
@@ -85,6 +88,20 @@ struct twt_del_dialog_comp_ev_priv {
 	struct wmi_twt_del_dialog_complete_event_param del_dialog_comp_ev_buf;
 };
 
+static const struct nla_policy
+qca_wlan_vendor_twt_add_dialog_policy[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP] = {.type = NLA_U8 },
+	[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST] = {.type = NLA_FLAG },
+	[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE] = {.type = NLA_U8 },
+	[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER] = {.type = NLA_FLAG },
+	[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID] = {.type = NLA_U8 },
+	[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE] = {.type = NLA_U8 },
+	[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION] = {.type = NLA_FLAG },
+	[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME] = {.type = NLA_U32 },
+	[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION] = {.type = NLA_U32 },
+	[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA] = {.type = NLA_U32 },
+};
+
 static const struct nla_policy
 qca_wlan_vendor_twt_resume_dialog_policy[QCA_WLAN_VENDOR_ATTR_TWT_RESUME_MAX + 1] = {
 	[QCA_WLAN_VENDOR_ATTR_TWT_RESUME_FLOW_ID] = {.type = NLA_U8 },
@@ -102,7 +119,14 @@ wlan_hdd_wifi_twt_config_policy[
 			.type = NLA_NESTED},
 };
 
-QDF_STATUS
+/**
+ * hdd_twt_setup_req_type_to_cmd() - Converts twt setup request type to twt cmd
+ * @req_type: twt setup request type
+ * @twt_cmd: pointer to store twt command
+ *
+ * Return: QDF_STATUS_SUCCESS on success, else other qdf error values
+ */
+static QDF_STATUS
 hdd_twt_setup_req_type_to_cmd(u8 req_type, enum WMI_HOST_TWT_COMMAND *twt_cmd)
 {
 	if (req_type == QCA_WLAN_VENDOR_TWT_SETUP_REQUEST) {
@@ -118,6 +142,230 @@ hdd_twt_setup_req_type_to_cmd(u8 req_type, enum WMI_HOST_TWT_COMMAND *twt_cmd)
 	return QDF_STATUS_SUCCESS;
 }
 
+/**
+ * hdd_twt_get_add_dialog_values() - Get TWT add dialog parameter
+ * values from QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS
+ * @tb: nl attributes
+ * @params: wmi twt add dialog parameters
+ *
+ * Handles QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX
+ *
+ * Return: 0 or -EINVAL.
+ */
+static
+int hdd_twt_get_add_dialog_values(struct nlattr **tb,
+				  struct wmi_twt_add_dialog_param *params)
+{
+	uint32_t wake_intvl_exp, result;
+	int cmd_id;
+	QDF_STATUS qdf_status;
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID;
+	if (tb[cmd_id]) {
+		params->dialog_id = nla_get_u8(tb[cmd_id]);
+	} else {
+		params->dialog_id = 0;
+		hdd_debug("TWT_SETUP_FLOW_ID not specified. set to zero");
+	}
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP;
+	if (!tb[cmd_id]) {
+		hdd_err_rl("TWT_SETUP_WAKE_INTVL_EXP is must");
+		return -EINVAL;
+	}
+	wake_intvl_exp = nla_get_u8(tb[cmd_id]);
+	if (wake_intvl_exp > TWT_SETUP_WAKE_INTVL_EXP_MAX) {
+		hdd_err_rl("Invalid wake_intvl_exp %u > %u",
+			   wake_intvl_exp,
+			   TWT_SETUP_WAKE_INTVL_EXP_MAX);
+		return -EINVAL;
+	}
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST;
+	params->flag_bcast = nla_get_flag(tb[cmd_id]);
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE;
+	if (!tb[cmd_id]) {
+		hdd_err_rl("TWT_SETUP_REQ_TYPE is must");
+		return -EINVAL;
+	}
+	qdf_status = hdd_twt_setup_req_type_to_cmd(nla_get_u8(tb[cmd_id]),
+						   &params->twt_cmd);
+	if (QDF_IS_STATUS_ERROR(qdf_status))
+		return qdf_status_to_os_return(qdf_status);
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER;
+	params->flag_trigger = nla_get_flag(tb[cmd_id]);
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE;
+	if (!tb[cmd_id]) {
+		hdd_err_rl("TWT_SETUP_FLOW_TYPE is must");
+		return -EINVAL;
+	}
+	params->flag_flow_type = nla_get_u8(tb[cmd_id]);
+	if (params->flag_flow_type != TWT_FLOW_TYPE_ANNOUNCED &&
+	    params->flag_flow_type != TWT_FLOW_TYPE_UNANNOUNCED)
+		return -EINVAL;
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION;
+	params->flag_protection = nla_get_flag(tb[cmd_id]);
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME;
+	if (tb[cmd_id])
+		params->sp_offset_us = nla_get_u32(tb[cmd_id]);
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION;
+	if (!tb[cmd_id]) {
+		hdd_err_rl("TWT_SETUP_WAKE_DURATION is must");
+		return -EINVAL;
+	}
+	params->wake_dura_us = TWT_WAKE_DURATION_MULTIPLICATION_FACTOR *
+			       nla_get_u32(tb[cmd_id]);
+	if (params->wake_dura_us > TWT_SETUP_WAKE_DURATION_MAX) {
+		hdd_err_rl("Invalid wake_dura_us %u",
+			   params->wake_dura_us);
+		return -EINVAL;
+	}
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA;
+	if (!tb[cmd_id]) {
+		hdd_err_rl("SETUP_WAKE_INTVL_MANTISSA is must");
+		return -EINVAL;
+	}
+	params->wake_intvl_mantis = nla_get_u32(tb[cmd_id]);
+	if (params->wake_intvl_mantis >
+	    TWT_SETUP_WAKE_INTVL_MANTISSA_MAX) {
+		hdd_err_rl("Invalid wake_intvl_mantis %u",
+			   params->wake_dura_us);
+		return -EINVAL;
+	}
+
+	if (wake_intvl_exp && params->wake_intvl_mantis) {
+		result = 2 << (wake_intvl_exp - 1);
+		if (result >
+		    (UINT_MAX / params->wake_intvl_mantis)) {
+			hdd_err_rl("Invalid exp %d mantissa %d",
+				   wake_intvl_exp,
+				   params->wake_intvl_mantis);
+			return -EINVAL;
+		}
+		params->wake_intvl_us =
+			params->wake_intvl_mantis * result;
+	} else {
+		params->wake_intvl_us = params->wake_intvl_mantis;
+	}
+
+	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",
+		  params->wake_dura_us, params->sp_offset_us,
+		  params->twt_cmd);
+	hdd_debug("twt: bcast %d, trigger %d, flow_type %d, prot %d",
+		  params->flag_bcast, params->flag_trigger,
+		  params->flag_flow_type,
+		  params->flag_protection);
+	hdd_debug("twt: peer mac_addr "
+		  QDF_MAC_ADDR_FMT,
+		  QDF_MAC_ADDR_REF(params->peer_macaddr));
+
+	return 0;
+}
+
+int hdd_test_config_twt_setup_session(struct hdd_adapter *adapter,
+				      struct nlattr **tb)
+{
+	struct nlattr *twt_session;
+	int tmp, rc;
+	struct hdd_station_ctx *hdd_sta_ctx = NULL;
+	struct wmi_twt_add_dialog_param params = {0};
+	struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1];
+	uint32_t congestion_timeout = 0;
+	int ret = 0;
+	int cmd_id;
+
+	if (adapter->device_mode != QDF_STA_MODE &&
+	    adapter->device_mode != QDF_P2P_CLIENT_MODE) {
+		return -EOPNOTSUPP;
+	}
+
+	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	if (hdd_sta_ctx->conn_info.conn_state != eConnectionState_Associated) {
+		hdd_err_rl("Invalid state, vdev %d mode %d state %d",
+			   adapter->vdev_id, adapter->device_mode,
+			   hdd_sta_ctx->conn_info.conn_state);
+		return -EINVAL;
+	}
+
+	qdf_mem_copy(params.peer_macaddr, hdd_sta_ctx->conn_info.bssid.bytes,
+		     QDF_MAC_ADDR_SIZE);
+	params.vdev_id = adapter->vdev_id;
+
+	cmd_id = QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP;
+	nla_for_each_nested(twt_session, tb[cmd_id], tmp) {
+		rc = wlan_cfg80211_nla_parse(tb2,
+					     QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX,
+					     nla_data(twt_session),
+					     nla_len(twt_session),
+					     qca_wlan_vendor_twt_add_dialog_policy);
+		if (rc) {
+			hdd_err_rl("Invalid twt ATTR");
+			return -EINVAL;
+		}
+
+		ret = hdd_twt_get_add_dialog_values(tb2, &params);
+		if (ret)
+			return ret;
+
+		ucfg_mlme_get_twt_congestion_timeout(adapter->hdd_ctx->psoc,
+						     &congestion_timeout);
+		if (congestion_timeout) {
+			ret = qdf_status_to_os_return(
+				hdd_send_twt_disable_cmd(adapter->hdd_ctx));
+			if (ret) {
+				hdd_err("Failed to disable TWT");
+				return ret;
+			}
+			ucfg_mlme_set_twt_congestion_timeout(adapter->hdd_ctx->psoc, 0);
+			hdd_send_twt_enable_cmd(adapter->hdd_ctx);
+		}
+
+		ret = qdf_status_to_os_return(sme_test_config_twt_setup(&params));
+	}
+	return ret;
+}
+
+int hdd_test_config_twt_terminate_session(struct hdd_adapter *adapter,
+					  struct nlattr **tb)
+{
+	struct hdd_station_ctx *hdd_sta_ctx = NULL;
+	struct wmi_twt_del_dialog_param params = {0};
+	int ret_val;
+
+	if (adapter->device_mode != QDF_STA_MODE &&
+	    adapter->device_mode != QDF_P2P_CLIENT_MODE) {
+		return -EOPNOTSUPP;
+	}
+
+	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	if (hdd_sta_ctx->conn_info.conn_state != eConnectionState_Associated) {
+		hdd_err_rl("Invalid state, vdev %d mode %d state %d",
+			   adapter->vdev_id, adapter->device_mode,
+			   hdd_sta_ctx->conn_info.conn_state);
+		return -EINVAL;
+	}
+
+	qdf_mem_copy(params.peer_macaddr,
+		     hdd_sta_ctx->conn_info.bssid.bytes,
+		     QDF_MAC_ADDR_SIZE);
+	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(sme_test_config_twt_terminate(&params));
+	return ret_val;
+}
+
 /**
  * hdd_twt_get_params_resp_len() - Calculates the length
  * of twt get_params nl response

+ 2 - 2
core/sme/src/common/sme_api.c

@@ -14485,7 +14485,7 @@ QDF_STATUS sme_test_config_twt_setup(struct wmi_twt_add_dialog_param *params)
 	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");
+			  "wma handle is NULL");
 		return QDF_STATUS_E_FAILURE;
 	}
 
@@ -14500,7 +14500,7 @@ sme_test_config_twt_terminate(struct wmi_twt_del_dialog_param *params)
 	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");
+			  "wma handle is NULL");
 		return QDF_STATUS_E_FAILURE;
 	}