Ver Fonte

qcacld-3.0: Create TWT context in peer private object

Create TWT context in peer object to store the TWT session
related parameters. Introduce mlme api to get/set various
twt session parameters for the peer.
Block the below commands till TWT setup is complete.
TWT GET
TWT Pause
TWT resume
TWT terminate

Add new files for TWT specific functionality in MLME component:
components/mlme/core/inc/wlan_mlme_twt_api.h
components/mlme/dispatcher/inc/wlan_mlme_twt_public_struct.h
components/mlme/dispatcher/inc/wlan_mlme_twt_ucfg_api.h
components/mlme/core/src/wlan_mlme_twt_api.c
components/mlme/dispatcher/src/wlan_mlme_twt_ucfg_api.c

Also return error to userspace if back to back TWT setup
command is received before TWT setup response is received from
firmware or already TWT setup is complete for given dialog id

Change-Id: I61e24dd41dc9dcb78fdfe33ef8fa0ecb374a4a72
CRs-Fixed: 2847213
Pragaspathi Thilagaraj há 4 anos atrás
pai
commit
1a9311161a

+ 5 - 0
Kbuild

@@ -1291,6 +1291,11 @@ MLME_OBJS :=	$(MLME_DIR)/core/src/wlan_mlme_main.o \
 
 MLME_OBJS += $(MLME_DIR)/core/src/wlan_mlme_vdev_mgr_interface.o
 
+ifeq ($(CONFIG_WLAN_FEATURE_TWT), y)
+MLME_OBJS += $(MLME_DIR)/core/src/wlan_mlme_twt_api.o
+MLME_OBJS += $(MLME_DIR)/dispatcher/src/wlan_mlme_twt_ucfg_api.o
+endif
+
 CM_DIR := components/umac/mlme/connection_mgr
 CM_TGT_IF_DIR := components/target_if/connection_mgr
 

+ 13 - 0
components/mlme/core/inc/wlan_mlme_main.h

@@ -88,6 +88,7 @@ struct sae_auth_retry {
  * @is_pmf_enabled: True if PMF is enabled
  * @last_assoc_received_time: last assoc received time
  * @last_disassoc_deauth_received_time: last disassoc/deauth received time
+ * @twt_ctx: TWT context
  */
 struct peer_mlme_priv_obj {
 	uint8_t last_pn_valid;
@@ -96,6 +97,9 @@ struct peer_mlme_priv_obj {
 	bool is_pmf_enabled;
 	qdf_time_t last_assoc_received_time;
 	qdf_time_t last_disassoc_deauth_received_time;
+#ifdef WLAN_SUPPORT_TWT
+	struct twt_context twt_ctx;
+#endif
 };
 
 /**
@@ -388,6 +392,15 @@ uint8_t *mlme_get_dynamic_oce_flags(struct wlan_objmgr_vdev *vdev);
 struct wlan_mlme_nss_chains *mlme_get_dynamic_vdev_config(
 					struct wlan_objmgr_vdev *vdev);
 
+/**
+ * mlme_get_vdev_he_ops()  - Get vdev HE operations IE info
+ * @psoc: Pointer to PSOC object
+ * @vdev_id: vdev id
+ *
+ * Return: HE ops IE
+ */
+uint32_t mlme_get_vdev_he_ops(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id);
+
 /**
  * mlme_get_ini_vdev_config() - get the vdev ini config params
  * @vdev: vdev pointer

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

@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: declare internal API related to the mlme TWT functionality
+ */
+
+#ifndef _WLAN_MLME_TWT_API_H_
+#define _WLAN_MLME_TWT_API_H_
+
+#include <wlan_mlme_public_struct.h>
+#include <wlan_mlme_twt_public_struct.h>
+#include <wlan_objmgr_psoc_obj.h>
+#include <wlan_objmgr_global_obj.h>
+#include <wlan_cmn.h>
+#include <wlan_objmgr_vdev_obj.h>
+#include <wlan_objmgr_peer_obj.h>
+#include "wlan_cm_roam_public_struct.h"
+
+#ifdef WLAN_SUPPORT_TWT
+/**
+ * mlme_is_twt_setup_in_progress() - Get if TWT setup command is in progress
+ * for given dialog id
+ * @psoc: Pointer to global psoc object
+ * @peer_mac: Global peer mac address
+ * @dialog_id: Dialog ID
+ *
+ * Return: True if Setup is in progress
+ */
+bool mlme_is_twt_setup_in_progress(struct wlan_objmgr_psoc *psoc,
+				   struct qdf_mac_addr *peer_mac,
+				   uint8_t dialog_id);
+
+/**
+ * mlme_add_twt_session()  - Add TWT session entry in the TWT context
+ * @psoc: Pointer to global psoc object
+ * @peer_mac: Global peer mac address
+ * @dialog_id: Dialog ID
+ *
+ * Return: None
+ */
+void mlme_add_twt_session(struct wlan_objmgr_psoc *psoc,
+			  struct qdf_mac_addr *peer_mac,
+			  uint8_t dialog_id);
+
+/**
+ * mlme_set_twt_setup_done()  - Set TWT setup complete for given dialog ID
+ * @psoc: Pointer to psoc object
+ * @peer_mac: Pointer to peer mac address
+ * @dialog_id: Dialog id
+ * @is_set: Set or clear the setup done flag
+ *
+ * Return: None
+ */
+void mlme_set_twt_setup_done(struct wlan_objmgr_psoc *psoc,
+			     struct qdf_mac_addr *peer_mac,
+			     uint8_t dialog_id, bool is_set);
+
+/**
+ * mlme_is_twt_setup_done()  - Get if TWT session is established for given
+ * dialog id.
+ * @psoc: Pointer to psoc object
+ * @peer_mac: Pointer to peer mac address
+ * @dialog_id: Dialog id
+ *
+ * Return: Return true if TWT session exists for given dialog ID.
+ */
+bool mlme_is_twt_setup_done(struct wlan_objmgr_psoc *psoc,
+			    struct qdf_mac_addr *peer_mac, uint8_t dialog_id);
+
+/**
+ * mlme_set_twt_session_state() - Set the TWT session state for the given dialog
+ * id in TWT context
+ * @peer: Pointer to peer object
+ * @dialog_id: Dialog id
+ * @state: TWT session state
+ *
+ * Return: None
+ */
+void mlme_set_twt_session_state(struct wlan_objmgr_peer *peer,
+				uint8_t dialog_id,
+				enum wlan_twt_session_state state);
+/**
+ * mlme_get_twt_session_state()  - Get TWT session state for given dialog id
+ * @peer: Pointer to peer object
+ * @dialog_id: Dialog id
+ *
+ * Return:  TWT session state.
+ */
+enum wlan_twt_session_state
+mlme_get_twt_session_state(struct wlan_objmgr_peer *peer, uint8_t dialog_id);
+
+/**
+ * mlme_get_twt_peer_capabilities  - Get TWT peer capabilities
+ * @psoc: Pointer to psoc object
+ * @peer_mac: Pointer to peer mac address
+ *
+ * Return: Peer TWT capabilities
+ */
+uint8_t mlme_get_twt_peer_capabilities(struct wlan_objmgr_psoc *psoc,
+				       struct qdf_mac_addr *peer_mac);
+
+/**
+ * mlme_set_twt_peer_capabilities() - Set the TWT peer capabilities in TWT
+ * context
+ * @psoc: Pointer to psoc object
+ * @peer_mac: Pointer to peer mac address
+ * @he_cap: Pointer to HE capabilities IE
+ * @he_op: Pointer to HE operations IE
+ */
+void mlme_set_twt_peer_capabilities(struct wlan_objmgr_psoc *psoc,
+				    struct qdf_mac_addr *peer_mac,
+				    tDot11fIEhe_cap *he_cap,
+				    tDot11fIEhe_op *he_op);
+
+/**
+ * mlme_init_twt_context() - Initialize TWT context structure
+ * @psoc: Pointer to psoc object
+ * @peer_mac: Pointer to peer mac address
+ * @dialog_id: Dialog id
+ *
+ * This API will be called on disconnection from AP.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS mlme_init_twt_context(struct wlan_objmgr_psoc *psoc,
+				 struct qdf_mac_addr *peer_mac,
+				 uint8_t dialog_id);
+
+/**
+ * mlme_twt_is_notify_done()  - Check if notify is done.
+ * @psoc: Pointer to psoc object
+ * @peer_mac: Pointer to peer mac address
+ *
+ * Return: True if notify is done
+ */
+bool mlme_twt_is_notify_done(struct wlan_objmgr_psoc *psoc,
+			     struct qdf_mac_addr *peer_mac);
+
+/**
+ * mlme_twt_set_wait_for_notify()  - Set wait for notify flag.
+ * @psoc: Pointer to psoc object
+ * @peer_mac: Pointer to peer mac address
+ * @is_set: Set or clear notify flag
+ *
+ * Return: None
+ */
+void mlme_twt_set_wait_for_notify(struct wlan_objmgr_psoc *psoc,
+				  struct qdf_mac_addr *peer_mac,
+				  bool is_set);
+
+/**
+ * mlme_is_flexible_twt_enabled() - Check if flexible TWT is enabled.
+ * @psoc: Pointer to psoc object
+ *
+ * Return: True if flexible TWT is supported
+ */
+bool mlme_is_flexible_twt_enabled(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * mlme_get_twt_bcast_requestor_tgt_cap() - Get broadcast requestor target
+ * capability.
+ * @psoc: Pointer to psoc object
+ *
+ * Return: True if tgt cap is advertised.
+ */
+bool mlme_get_twt_bcast_requestor_tgt_cap(struct wlan_objmgr_psoc *psoc);
+#else
+static inline
+void mlme_set_twt_peer_capabilities(struct wlan_objmgr_psoc *psoc,
+				    struct qdf_mac_addr *peer_mac,
+				    tDot11fIEhe_cap *he_cap,
+				    tDot11fIEhe_op *he_op)
+{}
+#endif /* WLAN_SUPPORT_TWT */
+#endif /* _WLAN_MLME_TWT_API_H_ */

+ 24 - 0
components/mlme/core/src/wlan_mlme_main.c

@@ -53,6 +53,30 @@ struct wlan_mlme_nss_chains *mlme_get_dynamic_vdev_config(
 	return &mlme_priv->dynamic_cfg;
 }
 
+uint32_t mlme_get_vdev_he_ops(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
+{
+	struct vdev_mlme_obj *mlme_obj;
+	uint32_t he_ops = 0;
+	struct wlan_objmgr_vdev *vdev;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_MLME_NB_ID);
+	if (!vdev)
+		return he_ops;
+
+	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);
+		return he_ops;
+	}
+
+	he_ops = mlme_obj->proto.he_ops_info.he_ops;
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
+
+	return he_ops;
+}
+
 struct wlan_mlme_nss_chains *mlme_get_ini_vdev_config(
 				struct wlan_objmgr_vdev *vdev)
 {

+ 413 - 0
components/mlme/core/src/wlan_mlme_twt_api.c

@@ -0,0 +1,413 @@
+/*
+ * 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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: define internal APIs related to the mlme TWT functionality
+ */
+
+#include "cfg_mlme_twt.h"
+#include "cfg_ucfg_api.h"
+#include "wlan_mlme_main.h"
+#include "wlan_psoc_mlme_api.h"
+#include "wlan_vdev_mlme_api.h"
+#include "wlan_mlme_api.h"
+#include "wlan_mlme_twt_api.h"
+
+bool mlme_is_twt_setup_in_progress(struct wlan_objmgr_psoc *psoc,
+				   struct qdf_mac_addr *peer_mac,
+				   uint8_t dialog_id)
+{
+	struct peer_mlme_priv_obj *peer_priv;
+	struct wlan_objmgr_peer *peer;
+	uint8_t existing_session_dialog_id;
+	uint8_t i;
+
+	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) {
+		mlme_legacy_err("peer mlme component object is NULL");
+		wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
+		return false;
+	}
+
+	for (i = 0; i < peer_priv->twt_ctx.num_twt_sessions; i++) {
+		existing_session_dialog_id =
+			peer_priv->twt_ctx.session_info[i].dialog_id;
+		if (existing_session_dialog_id == dialog_id &&
+		    existing_session_dialog_id != WLAN_ALL_SESSIONS_DIALOG_ID) {
+			wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
+			return true;
+		}
+	}
+	wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
+
+	return false;
+}
+
+void mlme_add_twt_session(struct wlan_objmgr_psoc *psoc,
+			  struct qdf_mac_addr *peer_mac,
+			  uint8_t dialog_id)
+{
+	struct peer_mlme_priv_obj *peer_priv;
+	struct wlan_objmgr_peer *peer;
+	uint8_t i;
+
+	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;
+	}
+
+	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;
+	}
+
+	for (i = 0; i < peer_priv->twt_ctx.num_twt_sessions; i++) {
+		if (peer_priv->twt_ctx.session_info[i].dialog_id ==
+		    WLAN_ALL_SESSIONS_DIALOG_ID) {
+			peer_priv->twt_ctx.session_info[i].dialog_id =
+							dialog_id;
+			break;
+		}
+	}
+
+	wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
+}
+
+void mlme_set_twt_setup_done(struct wlan_objmgr_psoc *psoc,
+			     struct qdf_mac_addr *peer_mac,
+			     uint8_t dialog_id, bool is_set)
+{
+	struct peer_mlme_priv_obj *peer_priv;
+	struct wlan_objmgr_peer *peer;
+	uint8_t i;
+
+	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;
+	}
+
+	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;
+	}
+
+	for (i = 0; i < peer_priv->twt_ctx.num_twt_sessions; i++) {
+		if (peer_priv->twt_ctx.session_info[i].dialog_id == dialog_id) {
+			peer_priv->twt_ctx.session_info[i].setup_done = is_set;
+			mlme_legacy_debug("setup done dialog:%d",
+					  dialog_id);
+			break;
+		}
+	}
+
+	wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
+}
+
+QDF_STATUS mlme_init_twt_context(struct wlan_objmgr_psoc *psoc,
+				 struct qdf_mac_addr *peer_mac,
+				 uint8_t dialog_id)
+{
+	struct peer_mlme_priv_obj *peer_priv;
+	struct wlan_objmgr_peer *peer;
+	uint8_t i;
+
+	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;
+	}
+
+	peer_priv->twt_ctx.num_twt_sessions = WLAN_MAX_TWT_SESSIONS_PER_PEER;
+	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].setup_done = false;
+			peer_priv->twt_ctx.session_info[i].dialog_id =
+					WLAN_ALL_SESSIONS_DIALOG_ID;
+		}
+	}
+
+	mlme_legacy_debug("init done");
+
+	wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+bool mlme_is_twt_setup_done(struct wlan_objmgr_psoc *psoc,
+			    struct qdf_mac_addr *peer_mac, uint8_t dialog_id)
+{
+	struct peer_mlme_priv_obj *peer_priv;
+	struct wlan_objmgr_peer *peer;
+	bool is_setup_done = false;
+	uint8_t i;
+
+	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++) {
+		if (peer_priv->twt_ctx.session_info[i].dialog_id == dialog_id) {
+			is_setup_done =
+				peer_priv->twt_ctx.session_info[i].setup_done;
+			break;
+		}
+	}
+
+	wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
+
+	return is_setup_done;
+}
+
+void mlme_twt_set_wait_for_notify(struct wlan_objmgr_psoc *psoc,
+				  struct qdf_mac_addr *peer_mac,
+				  bool is_set)
+{
+	struct peer_mlme_priv_obj *peer_priv;
+	struct wlan_objmgr_peer *peer;
+
+	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;
+	}
+
+	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;
+	}
+
+	peer_priv->twt_ctx.wait_for_notify = is_set;
+
+	wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
+}
+
+bool mlme_twt_is_notify_done(struct wlan_objmgr_psoc *psoc,
+			     struct qdf_mac_addr *peer_mac)
+{
+	struct peer_mlme_priv_obj *peer_priv;
+	struct wlan_objmgr_peer *peer;
+	bool notify_done;
+
+	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) {
+		mlme_legacy_err(" peer mlme component object is NULL");
+		wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
+		return false;
+	}
+
+	notify_done = peer_priv->twt_ctx.wait_for_notify;
+	wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
+
+	return notify_done;
+}
+
+void mlme_set_twt_session_state(struct wlan_objmgr_peer *peer,
+				uint8_t dialog_id,
+				enum wlan_twt_session_state state)
+{
+	struct peer_mlme_priv_obj *peer_priv;
+	uint8_t i;
+
+	peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer,
+							  WLAN_UMAC_COMP_MLME);
+	if (!peer_priv) {
+		mlme_err(" peer mlme component object is NULL");
+		return;
+	}
+
+	mlme_debug("set_state:%d for dialog_id:%d", state, dialog_id);
+	for (i = 0; i < peer_priv->twt_ctx.num_twt_sessions; i++) {
+		if (peer_priv->twt_ctx.session_info[i].dialog_id == dialog_id) {
+			peer_priv->twt_ctx.session_info[i].state = state;
+			break;
+		}
+	}
+}
+
+enum wlan_twt_session_state
+mlme_get_twt_session_state(struct wlan_objmgr_peer *peer,
+			   uint8_t dialog_id)
+{
+	struct peer_mlme_priv_obj *peer_priv;
+	uint8_t i;
+
+	peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer,
+							  WLAN_UMAC_COMP_MLME);
+	if (!peer_priv) {
+		mlme_legacy_err(" peer mlme object is NULL");
+		return WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED;
+	}
+
+	for (i = 0; i < peer_priv->twt_ctx.num_twt_sessions; i++) {
+		if (peer_priv->twt_ctx.session_info[i].dialog_id == dialog_id)
+			return peer_priv->twt_ctx.session_info[i].state;
+	}
+
+	return WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED;
+}
+
+uint8_t mlme_get_twt_peer_capabilities(struct wlan_objmgr_psoc *psoc,
+				       struct qdf_mac_addr *peer_mac)
+{
+	struct peer_mlme_priv_obj *peer_priv;
+	struct wlan_objmgr_peer *peer;
+
+	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);
+	wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
+	if (!peer_priv) {
+		mlme_legacy_err("peer mlme object is NULL");
+		return 0;
+	}
+
+	return peer_priv->twt_ctx.peer_capability;
+}
+
+void mlme_set_twt_peer_capabilities(struct wlan_objmgr_psoc *psoc,
+				    struct qdf_mac_addr *peer_mac,
+				    tDot11fIEhe_cap *he_cap,
+				    tDot11fIEhe_op *he_op)
+{
+	struct wlan_objmgr_peer *peer;
+	struct peer_mlme_priv_obj *peer_priv;
+	uint8_t caps = 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;
+	}
+
+	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 object is NULL");
+		return;
+	}
+
+	if (he_cap->twt_request)
+		caps |= WLAN_TWT_CAPA_REQUESTOR;
+
+	if (he_cap->twt_responder)
+		caps |= WLAN_TWT_CAPA_RESPONDER;
+
+	if (he_cap->broadcast_twt)
+		caps |= WLAN_TWT_CAPA_BROADCAST;
+
+	if (he_cap->flex_twt_sched)
+		caps |= WLAN_TWT_CAPA_FLEXIBLE;
+
+	if (he_op->twt_required)
+		caps |= WLAN_TWT_CAPA_REQUIRED;
+
+	peer_priv->twt_ctx.peer_capability = caps;
+	wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
+}
+
+bool mlme_is_twt_enabled(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_mlme_psoc_ext_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_ext_obj(psoc);
+	if (!mlme_obj)
+		return cfg_default(CFG_ENABLE_TWT);
+
+	return mlme_obj->cfg.twt_cfg.is_twt_enabled;
+}
+
+#ifdef WLAN_FEATURE_11AX
+bool mlme_is_flexible_twt_enabled(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_mlme_psoc_ext_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_ext_obj(psoc);
+	if (!mlme_obj)
+		return false;
+
+	return mlme_obj->cfg.he_caps.dot11_he_cap.flex_twt_sched;
+}
+#endif
+
+bool mlme_get_twt_bcast_requestor_tgt_cap(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_mlme_psoc_ext_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_ext_obj(psoc);
+	if (!mlme_obj)
+		return false;
+
+	return mlme_obj->cfg.twt_cfg.bcast_requestor_tgt_cap;
+}

+ 1 - 0
components/mlme/dispatcher/inc/wlan_mlme_public_struct.h

@@ -28,6 +28,7 @@
 #include <wmi_unified_param.h>
 #include <sir_api.h>
 #include "wlan_cm_roam_public_struct.h"
+#include "wlan_mlme_twt_public_struct.h"
 #include "cfg_mlme_generic.h"
 
 #define OWE_TRANSITION_OUI_TYPE "\x50\x6f\x9a\x1c"

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

@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: This file contains definitions for MLME TWT functionality.
+ */
+
+#ifndef _WLAN_MLME_TWT_STRUCT_H_
+#define _WLAN_MLME_TWT_STRUCT_H_
+
+/**
+ * enum wlan_twt_capabilities  - Represents the Bitmap of TWT capabilities
+ * supported by device and peer.
+ * @WLAN_TWT_CAPA_REQUESTOR: TWT requestor support is advertised by TWT
+ * non-scheduling STA.
+ * @WLAN_TWT_CAPA_RESPONDER: TWT responder support is advertised by TWT
+ * AP.
+ * @WLAN_TWT_CAPA_BROADCAST: This indicates support for the role of broadcast
+ * TWT scheduling/receiving functionality.
+ * @WLAN_TWT_CAPA_FLEXIBLE: Device supports flexible TWT schedule.
+ * @WLAN_TWT_CAPA_REQUIRED: The TWT Required is advertised by AP to indicate
+ * that it mandates the associated HE STAs to support TWT.
+ */
+enum wlan_twt_capabilities {
+	WLAN_TWT_CAPA_REQUESTOR = BIT(0),
+	WLAN_TWT_CAPA_RESPONDER = BIT(1),
+	WLAN_TWT_CAPA_BROADCAST = BIT(2),
+	WLAN_TWT_CAPA_FLEXIBLE =  BIT(3),
+	WLAN_TWT_CAPA_REQUIRED =  BIT(4),
+};
+
+/**
+ * enum wlan_twt_session_state  - TWT session state for a dialog id
+ * @WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED: Session doesn't exist
+ * @WLAN_TWT_SETUP_STATE_ACTIVE: TWT session is active
+ * @WLAN_TWT_SETUP_STATE_SUSPEND: TWT session is suspended
+ */
+enum wlan_twt_session_state {
+	WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED = 0,
+	WLAN_TWT_SETUP_STATE_ACTIVE = 1,
+	WLAN_TWT_SETUP_STATE_SUSPEND = 2,
+};
+
+#define WLAN_ALL_SESSIONS_DIALOG_ID 255
+
+#ifdef WLAN_SUPPORT_TWT
+#define WLAN_MAX_TWT_SESSIONS_PER_PEER 1
+
+/**
+ * struct twt_session_info  - TWT session related parameters
+ * @dialog_id: TWT session dialog id
+ * @state: TWT session state
+ * @setup_done: TWT session setup is complete
+ */
+struct twt_session_info {
+	uint8_t dialog_id;
+	uint8_t state;
+	bool setup_done;
+};
+
+/**
+ * struct twt_context  - TWT context
+ * @peer_capability: TWT peer capability bitmap. Refer enum
+ * wlan_twt_capabilities for representation.
+ * @wait_for_notify: TWT session teardown received, wait for
+ * notify event from firmware before next TWT setup is done.
+ * @num_twt_sessions: Maximum supported TWT sessions.
+ * @session_info: TWT session related parameters for each session
+ */
+struct twt_context {
+	uint8_t peer_capability;
+	bool wait_for_notify;
+	uint8_t num_twt_sessions;
+	struct twt_session_info session_info[WLAN_MAX_TWT_SESSIONS_PER_PEER];
+};
+#endif /* WLAN_SUPPORT_TWT */
+#endif /* _WLAN_MLME_TWT_STRUCT_H_ */

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

@@ -0,0 +1,504 @@
+/*
+ * Copyright (c) 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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: declare UCFG APIs for TWT exposed by the mlme component
+ */
+
+#ifndef _WLAN_MLME_TWT_UCFG_API_H_
+#define _WLAN_MLME_TWT_UCFG_API_H_
+
+#include <cfg_ucfg_api.h>
+#include <wlan_mlme_public_struct.h>
+#include <wlan_mlme_twt_public_struct.h>
+#include <wlan_objmgr_psoc_obj.h>
+#include <wlan_objmgr_global_obj.h>
+#include <wlan_mlme_api.h>
+#include <wlan_mlme_main.h>
+#include <wlan_mlme_twt_api.h>
+
+#if defined(WLAN_SUPPORT_TWT) && defined(WLAN_FEATURE_11AX)
+/**
+ * ucfg_mlme_get_twt_requestor() - Get twt requestor
+ * @psoc: pointer to psoc object
+ * @val:  Pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_mlme_get_twt_requestor(struct wlan_objmgr_psoc *psoc,
+			    bool *val);
+
+/**
+ * ucfg_mlme_set_twt_requestor() - Set twt requestor
+ * @psoc: pointer to psoc object
+ * @val:  value that needs to set to this config
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_mlme_set_twt_requestor(struct wlan_objmgr_psoc *psoc,
+			    bool val);
+
+/**
+ * ucfg_mlme_get_twt_responder() - Get twt responder
+ * @psoc: pointer to psoc object
+ * @val:  Pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_mlme_get_twt_responder(struct wlan_objmgr_psoc *psoc,
+			    bool *val);
+
+/**
+ * ucfg_mlme_set_twt_responder() - Set twt responder
+ * @psoc: pointer to psoc object
+ * @val:  value that needs to set to this config
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_mlme_set_twt_responder(struct wlan_objmgr_psoc *psoc,
+			    bool val);
+
+/**
+ * ucfg_mlme_get_bcast_twt() - Get bcast twt
+ * @psoc: pointer to psoc object
+ * @val:  Pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_mlme_get_bcast_twt(struct wlan_objmgr_psoc *psoc,
+			bool *val);
+
+/**
+ * ucfg_mlme_set_bcast_twt() - Set bcast twt
+ * @psoc: pointer to psoc object
+ * @val:  value that needs to set to this config
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_mlme_set_bcast_twt(struct wlan_objmgr_psoc *psoc,
+			bool val);
+
+/**
+ * ucfg_mlme_get_twt_congestion_timeout() - Get twt congestion timeout
+ * @psoc: pointer to psoc object
+ * @val:  Pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_mlme_get_twt_congestion_timeout(struct wlan_objmgr_psoc *psoc,
+				     uint32_t *val);
+
+/**
+ * ucfg_mlme_set_twt_congestion_timeout() - Set twt congestion timeout
+ * @psoc: pointer to psoc object
+ * @val:  value that needs to set to this config
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_mlme_set_twt_congestion_timeout(struct wlan_objmgr_psoc *psoc,
+				     uint32_t val);
+
+/**
+ * ucfg_mlme_is_twt_enabled() - Get global twt config support
+ * @psoc: pointer to psoc object
+ *
+ * Return: True if TWT is enabled else false.
+ */
+static inline bool
+ucfg_mlme_is_twt_enabled(struct wlan_objmgr_psoc *psoc)
+{
+	return mlme_is_twt_enabled(psoc);
+}
+
+/**
+ * ucfg_mlme_set_enable_twt() - Set global twt config support
+ * @psoc: pointer to psoc object
+ * @val:  value that needs to set to this config
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_mlme_set_enable_twt(struct wlan_objmgr_psoc *psoc,
+			 bool val);
+
+/**
+ * ucfg_mlme_get_twt_bcast_requestor() - Get twt requestor enabled
+ * @psoc: pointer to psoc object
+ * @val:  Pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_mlme_get_twt_bcast_requestor(struct wlan_objmgr_psoc *psoc,
+				  bool *val);
+
+/**
+ * ucfg_mlme_set_twt_bcast_requestor() - Set Global twt bcast requestor support
+ * @psoc: pointer to psoc object
+ * @val:  Value to be set to config
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_mlme_set_twt_bcast_requestor(struct wlan_objmgr_psoc *psoc,
+				  bool val);
+
+/**
+ * ucfg_mlme_get_twt_bcast_responder() - Get twt responder enabled
+ * @psoc: pointer to psoc object
+ * @val:  Pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_mlme_get_twt_bcast_responder(struct wlan_objmgr_psoc *psoc,
+				  bool *val);
+
+/**
+ * ucfg_mlme_set_twt_bcast_responder() - Set Global twt bcast responder support
+ * @psoc: pointer to psoc object
+ * @val:  Value to be set to config
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_mlme_set_twt_bcast_responder(struct wlan_objmgr_psoc *psoc,
+				  bool val);
+
+/**
+ * ucfg_mlme_set_twt_bcast_requestor_tgt_cap() - Update the broadast requestor
+ * target capability
+ * @psoc: pointer to psoc object
+ * @val:  Value to be set to config
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_mlme_set_twt_bcast_requestor_tgt_cap(struct wlan_objmgr_psoc *psoc,
+					  bool val);
+
+/**
+ * ucfg_mlme_get_twt_bcast_requestor_tgt_cap() - Get broadcast requestor TGT
+ * capability.
+ * @psoc: pointer to psoc object
+ *
+ * Return: True if broadcast requestor target capability is present.
+ */
+static inline bool
+ucfg_mlme_get_twt_bcast_requestor_tgt_cap(struct wlan_objmgr_psoc *psoc)
+{
+	return mlme_get_twt_bcast_requestor_tgt_cap(psoc);
+}
+
+/**
+ * ucfg_mlme_set_twt_bcast_responder_tgt_cap() - Update the broadast responder
+ * target capability
+ * @psoc: pointer to psoc object
+ * @val:  Value to be set to config
+ *
+ * Return: QDF Status
+ */
+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
+ * @psoc: Pointer to global PSOC object
+ * @peer_mac: Global peer mac address
+ * @dialog_id: Dialog id
+ *
+ * Return: True if already the TWT setup is in progress
+ */
+static inline bool
+ucfg_mlme_is_twt_setup_in_progress(struct wlan_objmgr_psoc *psoc,
+				   struct qdf_mac_addr *peer_mac,
+				   uint8_t dialog_id)
+{
+	return mlme_is_twt_setup_in_progress(psoc, peer_mac, dialog_id);
+}
+
+/**
+ * ucfg_mlme_set_twt_setup_done() - Set TWT setup done flag
+ * @psoc: Pointer to global PSOC object
+ * @peer_mac: Global peer mac address
+ * @dialog_id: TWT session dialog id
+ * @is_set: true if setup done flag needs to be set
+ *
+ * Return: None
+ */
+static inline void
+ucfg_mlme_set_twt_setup_done(struct wlan_objmgr_psoc *psoc,
+			     struct qdf_mac_addr *peer_mac,
+			     uint8_t dialog_id, bool is_set)
+{
+	mlme_set_twt_setup_done(psoc, peer_mac, dialog_id, is_set);
+}
+
+/**
+ * ucfg_mlme_is_twt_setup_done() - Get if the TWT setup for given dialog id
+ * is complete.
+ * @psoc: Pointer to global psoc object
+ * @peer_mac:  Pointer to peer mac address
+ * @dialog_id: TWT session dialog id
+ *
+ * Return: True if TWT setup is successful for the 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)
+{
+	return mlme_is_twt_setup_done(psoc, peer_mac, dialog_id);
+}
+
+/**
+ * ucfg_mlme_is_flexible_twt_enabled() - Get if flexible TWT is enabled
+ * @psoc: Pointer to global psoc object
+ *
+ * Return: True if flexible TWT is supported
+ */
+static inline
+bool ucfg_mlme_is_flexible_twt_enabled(struct wlan_objmgr_psoc *psoc)
+{
+	return mlme_is_flexible_twt_enabled(psoc);
+}
+
+/**
+ * ucfg_mlme_get_twt_peer_capabilities() - Get peer capabilities
+ * @psoc: Pointer to global psoc object
+ * @peer_mac: Pointer to peer mac address
+ *
+ * Return: Peer capabilities bitmap
+ */
+static inline
+uint8_t ucfg_mlme_get_twt_peer_capabilities(struct wlan_objmgr_psoc *psoc,
+					    struct qdf_mac_addr *peer_mac)
+{
+	return mlme_get_twt_peer_capabilities(psoc, peer_mac);
+}
+
+/**
+ * ucfg_mlme_init_twt_context() - Initialize TWT context
+ * @psoc: Pointer to global psoc object
+ * @peer_mac: Pointer to peer mac address
+ * @dialog_id: Dialog id
+ *
+ * Return: QDF_STATUS
+ */
+static inline
+QDF_STATUS ucfg_mlme_init_twt_context(struct wlan_objmgr_psoc *psoc,
+				      struct qdf_mac_addr *peer_mac,
+				      uint8_t dialog_id)
+{
+	return mlme_init_twt_context(psoc, peer_mac, dialog_id);
+}
+#else
+static inline QDF_STATUS
+ucfg_mlme_get_twt_requestor(struct wlan_objmgr_psoc *psoc,
+			    bool *val)
+{
+	*val = false;
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
+static inline QDF_STATUS
+ucfg_mlme_set_twt_requestor(struct wlan_objmgr_psoc *psoc,
+			    bool val)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
+static inline QDF_STATUS
+ucfg_mlme_get_twt_responder(struct wlan_objmgr_psoc *psoc,
+			    bool *val)
+{
+	*val = false;
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
+static inline QDF_STATUS
+ucfg_mlme_set_twt_responder(struct wlan_objmgr_psoc *psoc,
+			    bool val)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
+static inline QDF_STATUS
+ucfg_mlme_get_bcast_twt(struct wlan_objmgr_psoc *psoc,
+			bool *val)
+{
+	*val = false;
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
+static inline QDF_STATUS
+ucfg_mlme_set_bcast_twt(struct wlan_objmgr_psoc *psoc,
+			bool val)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
+static inline QDF_STATUS
+ucfg_mlme_get_twt_congestion_timeout(struct wlan_objmgr_psoc *psoc,
+				     uint32_t *val)
+{
+	*val = 0;
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
+static inline QDF_STATUS
+ucfg_mlme_set_twt_congestion_timeout(struct wlan_objmgr_psoc *psoc,
+				     uint32_t val)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
+static inline bool
+ucfg_mlme_is_twt_enabled(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
+static inline QDF_STATUS
+ucfg_mlme_set_enable_twt(struct wlan_objmgr_psoc *psoc,
+			 bool val)
+{
+	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)
+{
+	return 0;
+}
+
+static inline void
+ucfg_mlme_set_twt_setup_done(struct wlan_objmgr_psoc *psoc,
+			     struct qdf_mac_addr *peer_mac,
+			     uint8_t dialog_id, bool is_set)
+{}
+
+static inline bool
+ucfg_mlme_is_twt_setup_in_progress(struct wlan_objmgr_psoc *psoc,
+				   struct qdf_mac_addr *peer_mac,
+				   uint8_t dialog_id)
+{
+	return false;
+}
+
+static inline QDF_STATUS
+ucfg_mlme_get_twt_bcast_requestor(struct wlan_objmgr_psoc *psoc,
+				  bool *val)
+{
+	*val = false;
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
+static inline QDF_STATUS
+ucfg_mlme_set_twt_bcast_requestor(struct wlan_objmgr_psoc *psoc,
+				  bool val)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
+static inline QDF_STATUS
+ucfg_mlme_get_twt_bcast_responder(struct wlan_objmgr_psoc *psoc,
+				  bool *val)
+{
+	*val = false;
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
+static inline QDF_STATUS
+ucfg_mlme_set_twt_bcast_responder(struct wlan_objmgr_psoc *psoc,
+				  bool val)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
+static inline QDF_STATUS
+ucfg_mlme_set_twt_bcast_requestor_tgt_cap(struct wlan_objmgr_psoc *psoc,
+					  bool val)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
+static inline QDF_STATUS
+ucfg_mlme_set_twt_bcast_responder_tgt_cap(struct wlan_objmgr_psoc *psoc,
+					  bool val)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
+static inline
+bool ucfg_mlme_is_flexible_twt_enabled(struct wlan_objmgr_psoc *psoc)
+{
+	return false;
+}
+
+static inline bool
+ucfg_mlme_get_twt_bcast_requestor_tgt_cap(struct wlan_objmgr_psoc *psoc)
+{
+	return false;
+}
+
+static inline
+uint8_t ucfg_mlme_get_twt_peer_capabilities(struct wlan_objmgr_psoc *psoc,
+					    struct qdf_mac_addr *peer_mac)
+{
+	return 0;
+}
+
+static inline
+QDF_STATUS ucfg_mlme_init_twt_context(struct wlan_objmgr_psoc *psoc,
+				      struct qdf_mac_addr *peer_mac,
+				      uint8_t dialog_id)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+#endif /* defined(WLAN_SUPPORT_TWT) && defined(WLAN_FEATURE_11AX) */
+#endif /* _WLAN_MLME_TWT_UCFG_API_H_ */

+ 0 - 297
components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h

@@ -889,303 +889,6 @@ QDF_STATUS
 ucfg_mlme_set_pmkid_modes(struct wlan_objmgr_psoc *psoc,
 			  uint32_t val);
 
-#if defined(WLAN_SUPPORT_TWT) && defined(WLAN_FEATURE_11AX)
-/**
- * ucfg_mlme_get_twt_requestor() - Get twt requestor
- * @psoc: pointer to psoc object
- * @val:  Pointer to the value which will be filled for the caller
- *
- * Return: QDF Status
- */
-QDF_STATUS
-ucfg_mlme_get_twt_requestor(struct wlan_objmgr_psoc *psoc,
-			    bool *val);
-
-/**
- * ucfg_mlme_set_twt_requestor() - Set twt requestor
- * @psoc: pointer to psoc object
- * @val:  value that needs to set to this config
- *
- * Return: QDF Status
- */
-QDF_STATUS
-ucfg_mlme_set_twt_requestor(struct wlan_objmgr_psoc *psoc,
-			    bool val);
-
-/**
- * ucfg_mlme_get_twt_responder() - Get twt responder
- * @psoc: pointer to psoc object
- * @val:  Pointer to the value which will be filled for the caller
- *
- * Return: QDF Status
- */
-QDF_STATUS
-ucfg_mlme_get_twt_responder(struct wlan_objmgr_psoc *psoc,
-			    bool *val);
-
-/**
- * ucfg_mlme_set_twt_responder() - Set twt responder
- * @psoc: pointer to psoc object
- * @val:  value that needs to set to this config
- *
- * Return: QDF Status
- */
-QDF_STATUS
-ucfg_mlme_set_twt_responder(struct wlan_objmgr_psoc *psoc,
-			    bool val);
-
-/**
- * ucfg_mlme_get_bcast_twt() - Get bcast twt
- * @psoc: pointer to psoc object
- * @val:  Pointer to the value which will be filled for the caller
- *
- * Return: QDF Status
- */
-QDF_STATUS
-ucfg_mlme_get_bcast_twt(struct wlan_objmgr_psoc *psoc,
-			bool *val);
-
-/**
- * ucfg_mlme_set_bcast_twt() - Set bcast twt
- * @psoc: pointer to psoc object
- * @val:  value that needs to set to this config
- *
- * Return: QDF Status
- */
-QDF_STATUS
-ucfg_mlme_set_bcast_twt(struct wlan_objmgr_psoc *psoc,
-			bool val);
-
-/**
- * ucfg_mlme_get_twt_congestion_timeout() - Get twt congestion timeout
- * @psoc: pointer to psoc object
- * @val:  Pointer to the value which will be filled for the caller
- *
- * Return: QDF Status
- */
-QDF_STATUS
-ucfg_mlme_get_twt_congestion_timeout(struct wlan_objmgr_psoc *psoc,
-				     uint32_t *val);
-
-/**
- * ucfg_mlme_set_twt_congestion_timeout() - Set twt congestion timeout
- * @psoc: pointer to psoc object
- * @val:  value that needs to set to this config
- *
- * Return: QDF Status
- */
-QDF_STATUS
-ucfg_mlme_set_twt_congestion_timeout(struct wlan_objmgr_psoc *psoc,
-				     uint32_t val);
-
-/**
- * ucfg_mlme_is_twt_enabled() - Get global twt config support
- * @psoc: pointer to psoc object
- *
- * Return: True if TWT is enabled else false.
- */
-static inline bool
-ucfg_mlme_is_twt_enabled(struct wlan_objmgr_psoc *psoc)
-{
-	return mlme_is_twt_enabled(psoc);
-}
-
-/**
- * ucfg_mlme_set_enable_twt() - Set global twt config support
- * @psoc: pointer to psoc object
- * @val:  value that needs to set to this config
- *
- * Return: QDF Status
- */
-QDF_STATUS
-ucfg_mlme_set_enable_twt(struct wlan_objmgr_psoc *psoc,
-			 bool val);
-
-/**
- * ucfg_mlme_get_twt_bcast_requestor() - Get twt requestor enabled
- * @psoc: pointer to psoc object
- * @val:  Pointer to the value which will be filled for the caller
- *
- * Return: QDF Status
- */
-QDF_STATUS
-ucfg_mlme_get_twt_bcast_requestor(struct wlan_objmgr_psoc *psoc,
-				  bool *val);
-
-/**
- * ucfg_mlme_set_twt_bcast_requestor() - Set Global twt bcast requestor support
- * @psoc: pointer to psoc object
- * @val:  Value to be set to config
- *
- * Return: QDF Status
- */
-QDF_STATUS
-ucfg_mlme_set_twt_bcast_requestor(struct wlan_objmgr_psoc *psoc,
-				  bool val);
-/**
- * ucfg_mlme_get_twt_bcast_responder() - Get twt responder enabled
- * @psoc: pointer to psoc object
- * @val:  Pointer to the value which will be filled for the caller
- *
- * Return: QDF Status
- */
-QDF_STATUS
-ucfg_mlme_get_twt_bcast_responder(struct wlan_objmgr_psoc *psoc,
-				  bool *val);
-
-/**
- * ucfg_mlme_set_twt_bcast_responder() - Set Global twt bcast responder support
- * @psoc: pointer to psoc object
- * @val:  Value to be set to config
- *
- * Return: QDF Status
- */
-QDF_STATUS
-ucfg_mlme_set_twt_bcast_responder(struct wlan_objmgr_psoc *psoc,
-				  bool val);
-
-/**
- * ucfg_mlme_set_twt_bcast_requestor_tgt_cap() - Update the broadast requestor
- * target capability
- * @psoc: pointer to psoc object
- * @val:  Value to be set to config
- *
- * Return: QDF Status
- */
-QDF_STATUS
-ucfg_mlme_set_twt_bcast_requestor_tgt_cap(struct wlan_objmgr_psoc *psoc,
-					  bool val);
-
-/**
- * ucfg_mlme_set_twt_bcast_responder_tgt_cap() - Update the broadast responder
- * target capability
- * @psoc: pointer to psoc object
- * @val:  Value to be set to config
- *
- * Return: QDF Status
- */
-QDF_STATUS
-ucfg_mlme_set_twt_bcast_responder_tgt_cap(struct wlan_objmgr_psoc *psoc,
-					  bool val);
-#else
-static inline QDF_STATUS
-ucfg_mlme_get_twt_requestor(struct wlan_objmgr_psoc *psoc,
-			    bool *val)
-{
-	*val = false;
-	return QDF_STATUS_E_NOSUPPORT;
-}
-
-static inline QDF_STATUS
-ucfg_mlme_set_twt_requestor(struct wlan_objmgr_psoc *psoc,
-			    bool val)
-{
-	return QDF_STATUS_E_NOSUPPORT;
-}
-
-static inline QDF_STATUS
-ucfg_mlme_get_twt_responder(struct wlan_objmgr_psoc *psoc,
-			    bool *val)
-{
-	*val = false;
-	return QDF_STATUS_E_NOSUPPORT;
-}
-
-static inline QDF_STATUS
-ucfg_mlme_set_twt_responder(struct wlan_objmgr_psoc *psoc,
-			    bool val)
-{
-	return QDF_STATUS_E_NOSUPPORT;
-}
-
-static inline QDF_STATUS
-ucfg_mlme_get_bcast_twt(struct wlan_objmgr_psoc *psoc,
-			bool *val)
-{
-	*val = false;
-	return QDF_STATUS_E_NOSUPPORT;
-}
-
-static inline QDF_STATUS
-ucfg_mlme_set_bcast_twt(struct wlan_objmgr_psoc *psoc,
-			bool val)
-{
-	return QDF_STATUS_E_NOSUPPORT;
-}
-
-static inline QDF_STATUS
-ucfg_mlme_get_twt_congestion_timeout(struct wlan_objmgr_psoc *psoc,
-				     uint32_t *val)
-{
-	*val = 0;
-	return QDF_STATUS_E_NOSUPPORT;
-}
-
-static inline QDF_STATUS
-ucfg_mlme_set_twt_congestion_timeout(struct wlan_objmgr_psoc *psoc,
-				     uint32_t val)
-{
-	return QDF_STATUS_E_NOSUPPORT;
-}
-
-static inline bool
-ucfg_mlme_is_twt_enabled(struct wlan_objmgr_psoc *psoc)
-{
-	return QDF_STATUS_E_NOSUPPORT;
-}
-
-static inline QDF_STATUS
-ucfg_mlme_set_enable_twt(struct wlan_objmgr_psoc *psoc,
-			 bool val)
-{
-	return QDF_STATUS_E_NOSUPPORT;
-}
-
-static inline QDF_STATUS
-ucfg_mlme_get_twt_bcast_requestor(struct wlan_objmgr_psoc *psoc,
-				  bool *val)
-{
-	*val = false;
-	return QDF_STATUS_E_NOSUPPORT;
-}
-
-static inline QDF_STATUS
-ucfg_mlme_set_twt_bcast_requestor(struct wlan_objmgr_psoc *psoc,
-				  bool val)
-{
-	return QDF_STATUS_E_NOSUPPORT;
-}
-
-static inline QDF_STATUS
-ucfg_mlme_get_twt_bcast_responder(struct wlan_objmgr_psoc *psoc,
-				  bool *val)
-{
-	*val = false;
-	return QDF_STATUS_E_NOSUPPORT;
-}
-
-static inline QDF_STATUS
-ucfg_mlme_set_twt_bcast_responder(struct wlan_objmgr_psoc *psoc,
-				  bool val)
-{
-	return QDF_STATUS_E_NOSUPPORT;
-}
-
-static inline QDF_STATUS
-ucfg_mlme_set_twt_bcast_requestor_tgt_cap(struct wlan_objmgr_psoc *psoc,
-					  bool val)
-{
-	return QDF_STATUS_E_NOSUPPORT;
-}
-
-static inline QDF_STATUS
-ucfg_mlme_set_twt_bcast_responder_tgt_cap(struct wlan_objmgr_psoc *psoc,
-					  bool val)
-{
-	return QDF_STATUS_E_NOSUPPORT;
-}
-#endif
-
 /**
  * ucfg_mlme_get_dot11p_mode() - Get the setting about 802.11p mode
  * @psoc: pointer to psoc object

+ 2 - 16
components/mlme/dispatcher/src/wlan_mlme_api.c

@@ -626,9 +626,8 @@ QDF_STATUS mlme_update_tgt_he_caps_in_cfg(struct wlan_objmgr_psoc *psoc,
 			mlme_obj->cfg.he_caps.dot11_he_cap.broadcast_twt);
 	mlme_obj->cfg.he_caps.dot11_he_cap.broadcast_twt = value;
 
-	value = QDF_MIN(he_cap->flex_twt_sched,
-			mlme_obj->cfg.he_caps.dot11_he_cap.flex_twt_sched);
-	mlme_obj->cfg.he_caps.dot11_he_cap.flex_twt_sched = value;
+	mlme_obj->cfg.he_caps.dot11_he_cap.flex_twt_sched =
+			he_cap->flex_twt_sched;
 
 	mlme_obj->cfg.he_caps.dot11_he_cap.ba_32bit_bitmap =
 					he_cap->ba_32bit_bitmap;
@@ -4708,16 +4707,3 @@ bool wlan_mlme_is_sta_mon_conc_supported(struct wlan_objmgr_psoc *psoc)
 
 	return false;
 }
-
-#ifdef WLAN_SUPPORT_TWT
-bool mlme_is_twt_enabled(struct wlan_objmgr_psoc *psoc)
-{
-	struct wlan_mlme_psoc_ext_obj *mlme_obj;
-
-	mlme_obj = mlme_get_psoc_ext_obj(psoc);
-	if (!mlme_obj)
-		return cfg_default(CFG_ENABLE_TWT);
-
-	return mlme_obj->cfg.twt_cfg.is_twt_enabled;
-}
-#endif

+ 270 - 0
components/mlme/dispatcher/src/wlan_mlme_twt_ucfg_api.c

@@ -0,0 +1,270 @@
+/*
+ * 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
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: define UCFG APIs exposed for TWT by the mlme component
+ */
+
+#include "wlan_mlme_main.h"
+#include "wlan_mlme_api.h"
+#include "wlan_mlme_ucfg_api.h"
+#include "cfg_mlme_twt.h"
+#include "wlan_mlme_twt_ucfg_api.h"
+
+#if defined(WLAN_SUPPORT_TWT) && defined(WLAN_FEATURE_11AX)
+QDF_STATUS
+ucfg_mlme_get_twt_requestor(struct wlan_objmgr_psoc *psoc,
+			    bool *val)
+{
+	struct wlan_mlme_psoc_ext_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_ext_obj(psoc);
+	if (!mlme_obj) {
+		*val = cfg_default(CFG_TWT_REQUESTOR);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	*val = mlme_obj->cfg.he_caps.dot11_he_cap.twt_request;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ucfg_mlme_set_twt_requestor(struct wlan_objmgr_psoc *psoc,
+			    bool val)
+{
+	struct wlan_mlme_psoc_ext_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_ext_obj(psoc);
+	if (!mlme_obj)
+		return QDF_STATUS_E_INVAL;
+
+	mlme_obj->cfg.he_caps.dot11_he_cap.twt_request = val;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ucfg_mlme_get_twt_responder(struct wlan_objmgr_psoc *psoc,
+			    bool *val)
+{
+	struct wlan_mlme_psoc_ext_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_ext_obj(psoc);
+	if (!mlme_obj) {
+		*val = cfg_default(CFG_TWT_RESPONDER);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	*val = mlme_obj->cfg.he_caps.dot11_he_cap.twt_responder;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ucfg_mlme_set_twt_responder(struct wlan_objmgr_psoc *psoc,
+			    bool val)
+{
+	struct wlan_mlme_psoc_ext_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_ext_obj(psoc);
+	if (!mlme_obj)
+		return QDF_STATUS_E_INVAL;
+
+	mlme_obj->cfg.he_caps.dot11_he_cap.twt_responder = val;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ucfg_mlme_get_bcast_twt(struct wlan_objmgr_psoc *psoc,
+			bool *val)
+{
+	struct wlan_mlme_psoc_ext_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_ext_obj(psoc);
+	if (!mlme_obj) {
+		*val = cfg_default(CFG_BCAST_TWT);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	*val = mlme_obj->cfg.he_caps.dot11_he_cap.broadcast_twt;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ucfg_mlme_set_bcast_twt(struct wlan_objmgr_psoc *psoc,
+			bool val)
+{
+	struct wlan_mlme_psoc_ext_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_ext_obj(psoc);
+	if (!mlme_obj)
+		return QDF_STATUS_E_INVAL;
+
+	mlme_obj->cfg.he_caps.dot11_he_cap.broadcast_twt = val;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ucfg_mlme_get_twt_congestion_timeout(struct wlan_objmgr_psoc *psoc,
+				     uint32_t *val)
+{
+	struct wlan_mlme_psoc_ext_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_ext_obj(psoc);
+	if (!mlme_obj) {
+		*val = cfg_default(CFG_TWT_CONGESTION_TIMEOUT);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	*val = mlme_obj->cfg.twt_cfg.twt_congestion_timeout;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ucfg_mlme_set_twt_congestion_timeout(struct wlan_objmgr_psoc *psoc,
+				     uint32_t val)
+{
+	struct wlan_mlme_psoc_ext_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_ext_obj(psoc);
+	if (!mlme_obj)
+		return QDF_STATUS_E_INVAL;
+
+	mlme_obj->cfg.twt_cfg.twt_congestion_timeout = val;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ucfg_mlme_set_enable_twt(struct wlan_objmgr_psoc *psoc,
+			 bool val)
+{
+	struct wlan_mlme_psoc_ext_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_ext_obj(psoc);
+	if (!mlme_obj)
+		return QDF_STATUS_E_INVAL;
+
+	mlme_obj->cfg.twt_cfg.is_twt_enabled = val;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ucfg_mlme_get_twt_bcast_requestor(struct wlan_objmgr_psoc *psoc,
+				  bool *val)
+{
+	struct wlan_mlme_psoc_ext_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_ext_obj(psoc);
+	if (!mlme_obj) {
+		uint32_t b_req_res;
+
+		b_req_res = cfg_default(CFG_BCAST_TWT_REQ_RESP);
+		*val = CFG_TWT_GET_BCAST_REQ(b_req_res);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	*val = mlme_obj->cfg.twt_cfg.is_bcast_requestor_enabled;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ucfg_mlme_get_twt_bcast_responder(struct wlan_objmgr_psoc *psoc,
+				  bool *val)
+{
+	struct wlan_mlme_psoc_ext_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_ext_obj(psoc);
+	if (!mlme_obj) {
+		uint32_t b_req_res;
+
+		b_req_res = cfg_default(CFG_BCAST_TWT_REQ_RESP);
+		*val = CFG_TWT_GET_BCAST_RES(b_req_res);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	*val = mlme_obj->cfg.twt_cfg.is_bcast_responder_enabled;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ucfg_mlme_set_twt_bcast_requestor(struct wlan_objmgr_psoc *psoc,
+				  bool val)
+{
+	struct wlan_mlme_psoc_ext_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_ext_obj(psoc);
+	if (!mlme_obj)
+		return QDF_STATUS_E_INVAL;
+
+	mlme_obj->cfg.twt_cfg.is_bcast_requestor_enabled = val;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ucfg_mlme_set_twt_bcast_responder(struct wlan_objmgr_psoc *psoc,
+				  bool val)
+{
+	struct wlan_mlme_psoc_ext_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_ext_obj(psoc);
+	if (!mlme_obj)
+		return QDF_STATUS_E_INVAL;
+
+	mlme_obj->cfg.twt_cfg.is_bcast_responder_enabled = val;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ucfg_mlme_set_twt_bcast_requestor_tgt_cap(struct wlan_objmgr_psoc *psoc,
+					  bool val)
+{
+	struct wlan_mlme_psoc_ext_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_ext_obj(psoc);
+	if (!mlme_obj)
+		return QDF_STATUS_E_INVAL;
+
+	mlme_obj->cfg.twt_cfg.bcast_requestor_tgt_cap = val;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+ucfg_mlme_set_twt_bcast_responder_tgt_cap(struct wlan_objmgr_psoc *psoc,
+					  bool val)
+{
+	struct wlan_mlme_psoc_ext_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_ext_obj(psoc);
+	if (!mlme_obj)
+		return QDF_STATUS_E_INVAL;
+
+	mlme_obj->cfg.twt_cfg.bcast_responder_tgt_cap = val;
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif

+ 0 - 245
components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c

@@ -508,251 +508,6 @@ ucfg_mlme_set_pmkid_modes(struct wlan_objmgr_psoc *psoc,
 	return QDF_STATUS_SUCCESS;
 }
 
-#if defined(WLAN_SUPPORT_TWT) && defined(WLAN_FEATURE_11AX)
-QDF_STATUS
-ucfg_mlme_get_twt_requestor(struct wlan_objmgr_psoc *psoc,
-			    bool *val)
-{
-	struct wlan_mlme_psoc_ext_obj *mlme_obj;
-
-	mlme_obj = mlme_get_psoc_ext_obj(psoc);
-	if (!mlme_obj) {
-		*val = cfg_default(CFG_TWT_REQUESTOR);
-		return QDF_STATUS_E_INVAL;
-	}
-
-	*val = mlme_obj->cfg.he_caps.dot11_he_cap.twt_request;
-
-	return QDF_STATUS_SUCCESS;
-}
-
-QDF_STATUS
-ucfg_mlme_set_twt_requestor(struct wlan_objmgr_psoc *psoc,
-			    bool val)
-{
-	struct wlan_mlme_psoc_ext_obj *mlme_obj;
-
-	mlme_obj = mlme_get_psoc_ext_obj(psoc);
-	if (!mlme_obj)
-		return QDF_STATUS_E_INVAL;
-
-	mlme_obj->cfg.he_caps.dot11_he_cap.twt_request = val;
-
-	return QDF_STATUS_SUCCESS;
-}
-
-QDF_STATUS
-ucfg_mlme_get_twt_responder(struct wlan_objmgr_psoc *psoc,
-			    bool *val)
-{
-	struct wlan_mlme_psoc_ext_obj *mlme_obj;
-
-	mlme_obj = mlme_get_psoc_ext_obj(psoc);
-	if (!mlme_obj) {
-		*val = cfg_default(CFG_TWT_RESPONDER);
-		return QDF_STATUS_E_INVAL;
-	}
-
-	*val = mlme_obj->cfg.he_caps.dot11_he_cap.twt_responder;
-
-	return QDF_STATUS_SUCCESS;
-}
-
-QDF_STATUS
-ucfg_mlme_set_twt_responder(struct wlan_objmgr_psoc *psoc,
-			    bool val)
-{
-	struct wlan_mlme_psoc_ext_obj *mlme_obj;
-
-	mlme_obj = mlme_get_psoc_ext_obj(psoc);
-	if (!mlme_obj)
-		return QDF_STATUS_E_INVAL;
-
-	mlme_obj->cfg.he_caps.dot11_he_cap.twt_responder = val;
-
-	return QDF_STATUS_SUCCESS;
-}
-
-QDF_STATUS
-ucfg_mlme_get_bcast_twt(struct wlan_objmgr_psoc *psoc,
-			bool *val)
-{
-	struct wlan_mlme_psoc_ext_obj *mlme_obj;
-
-	mlme_obj = mlme_get_psoc_ext_obj(psoc);
-	if (!mlme_obj) {
-		*val = cfg_default(CFG_BCAST_TWT);
-		return QDF_STATUS_E_INVAL;
-	}
-
-	*val = mlme_obj->cfg.he_caps.dot11_he_cap.broadcast_twt;
-
-	return QDF_STATUS_SUCCESS;
-}
-
-QDF_STATUS
-ucfg_mlme_set_bcast_twt(struct wlan_objmgr_psoc *psoc,
-			bool val)
-{
-	struct wlan_mlme_psoc_ext_obj *mlme_obj;
-
-	mlme_obj = mlme_get_psoc_ext_obj(psoc);
-	if (!mlme_obj)
-		return QDF_STATUS_E_INVAL;
-
-	mlme_obj->cfg.he_caps.dot11_he_cap.broadcast_twt = val;
-
-	return QDF_STATUS_SUCCESS;
-}
-
-QDF_STATUS
-ucfg_mlme_get_twt_congestion_timeout(struct wlan_objmgr_psoc *psoc,
-				     uint32_t *val)
-{
-	struct wlan_mlme_psoc_ext_obj *mlme_obj;
-
-	mlme_obj = mlme_get_psoc_ext_obj(psoc);
-	if (!mlme_obj) {
-		*val = cfg_default(CFG_TWT_CONGESTION_TIMEOUT);
-		return QDF_STATUS_E_INVAL;
-	}
-
-	*val = mlme_obj->cfg.twt_cfg.twt_congestion_timeout;
-
-	return QDF_STATUS_SUCCESS;
-}
-
-QDF_STATUS
-ucfg_mlme_set_twt_congestion_timeout(struct wlan_objmgr_psoc *psoc,
-				     uint32_t val)
-{
-	struct wlan_mlme_psoc_ext_obj *mlme_obj;
-
-	mlme_obj = mlme_get_psoc_ext_obj(psoc);
-	if (!mlme_obj)
-		return QDF_STATUS_E_INVAL;
-
-	mlme_obj->cfg.twt_cfg.twt_congestion_timeout = val;
-
-	return QDF_STATUS_SUCCESS;
-}
-
-QDF_STATUS
-ucfg_mlme_set_enable_twt(struct wlan_objmgr_psoc *psoc,
-			 bool val)
-{
-	struct wlan_mlme_psoc_ext_obj *mlme_obj;
-
-	mlme_obj = mlme_get_psoc_ext_obj(psoc);
-	if (!mlme_obj)
-		return QDF_STATUS_E_INVAL;
-
-	mlme_obj->cfg.twt_cfg.is_twt_enabled = val;
-
-	return QDF_STATUS_SUCCESS;
-}
-
-QDF_STATUS
-ucfg_mlme_get_twt_bcast_requestor(struct wlan_objmgr_psoc *psoc,
-				  bool *val)
-{
-	struct wlan_mlme_psoc_ext_obj *mlme_obj;
-
-	mlme_obj = mlme_get_psoc_ext_obj(psoc);
-	if (!mlme_obj) {
-		uint32_t b_req_res;
-
-		b_req_res = cfg_default(CFG_BCAST_TWT_REQ_RESP);
-		*val = CFG_TWT_GET_BCAST_REQ(b_req_res);
-		return QDF_STATUS_E_INVAL;
-	}
-
-	*val = mlme_obj->cfg.twt_cfg.is_bcast_requestor_enabled;
-
-	return QDF_STATUS_SUCCESS;
-}
-
-QDF_STATUS
-ucfg_mlme_get_twt_bcast_responder(struct wlan_objmgr_psoc *psoc,
-				  bool *val)
-{
-	struct wlan_mlme_psoc_ext_obj *mlme_obj;
-
-	mlme_obj = mlme_get_psoc_ext_obj(psoc);
-	if (!mlme_obj) {
-		uint32_t b_req_res;
-
-		b_req_res = cfg_default(CFG_BCAST_TWT_REQ_RESP);
-		*val = CFG_TWT_GET_BCAST_RES(b_req_res);
-		return QDF_STATUS_E_INVAL;
-	}
-
-	*val = mlme_obj->cfg.twt_cfg.is_bcast_responder_enabled;
-
-	return QDF_STATUS_SUCCESS;
-}
-
-QDF_STATUS
-ucfg_mlme_set_twt_bcast_requestor(struct wlan_objmgr_psoc *psoc,
-				  bool val)
-{
-	struct wlan_mlme_psoc_ext_obj *mlme_obj;
-
-	mlme_obj = mlme_get_psoc_ext_obj(psoc);
-	if (!mlme_obj)
-		return QDF_STATUS_E_INVAL;
-
-	mlme_obj->cfg.twt_cfg.is_bcast_requestor_enabled = val;
-
-	return QDF_STATUS_SUCCESS;
-}
-
-QDF_STATUS
-ucfg_mlme_set_twt_bcast_responder(struct wlan_objmgr_psoc *psoc,
-				  bool val)
-{
-	struct wlan_mlme_psoc_ext_obj *mlme_obj;
-
-	mlme_obj = mlme_get_psoc_ext_obj(psoc);
-	if (!mlme_obj)
-		return QDF_STATUS_E_INVAL;
-
-	mlme_obj->cfg.twt_cfg.is_bcast_responder_enabled = val;
-
-	return QDF_STATUS_SUCCESS;
-}
-
-QDF_STATUS
-ucfg_mlme_set_twt_bcast_requestor_tgt_cap(struct wlan_objmgr_psoc *psoc,
-					  bool val)
-{
-	struct wlan_mlme_psoc_ext_obj *mlme_obj;
-
-	mlme_obj = mlme_get_psoc_ext_obj(psoc);
-	if (!mlme_obj)
-		return QDF_STATUS_E_INVAL;
-
-	mlme_obj->cfg.twt_cfg.bcast_requestor_tgt_cap = val;
-
-	return QDF_STATUS_SUCCESS;
-}
-
-QDF_STATUS
-ucfg_mlme_set_twt_bcast_responder_tgt_cap(struct wlan_objmgr_psoc *psoc,
-					  bool val)
-{
-	struct wlan_mlme_psoc_ext_obj *mlme_obj;
-
-	mlme_obj = mlme_get_psoc_ext_obj(psoc);
-	if (!mlme_obj)
-		return QDF_STATUS_E_INVAL;
-
-	mlme_obj->cfg.twt_cfg.bcast_responder_tgt_cap = val;
-
-	return QDF_STATUS_SUCCESS;
-}
-#endif
-
 QDF_STATUS
 ucfg_mlme_get_dot11p_mode(struct wlan_objmgr_psoc *psoc,
 			  enum dot11p_mode *out_mode)

+ 6 - 0
core/hdd/src/wlan_hdd_assoc.c

@@ -65,6 +65,7 @@
 #include "wlan_hdd_scan.h"
 #include "wlan_crypto_global_api.h"
 #include "wlan_hdd_bcn_recv.h"
+#include "wlan_mlme_twt_ucfg_api.h"
 
 #include "wlan_hdd_nud_tracking.h"
 #include <wlan_cfg80211_crypto.h>
@@ -3198,7 +3199,12 @@ hdd_association_completion_handler(struct hdd_adapter *adapter,
 			/* Inform FTM TIME SYNC about the connection with AP */
 			hdd_ftm_time_sync_sta_state_notify(
 					adapter, FTM_TIME_SYNC_STA_CONNECTED);
+
+			ucfg_mlme_init_twt_context(hdd_ctx->psoc,
+						   &roam_info->bssid,
+						   WLAN_ALL_SESSIONS_DIALOG_ID);
 		}
+
 		/*
 		 * Following code will be cleaned once the interface manager
 		 * module is enabled.

+ 1 - 1
core/hdd/src/wlan_hdd_cfg80211.c

@@ -123,9 +123,9 @@
 #include <wlan_hdd_ota_test.h>
 #include "wlan_policy_mgr_ucfg.h"
 #include "wlan_mlme_ucfg_api.h"
+#include "wlan_mlme_twt_ucfg_api.h"
 #include "wlan_mlme_public_struct.h"
 #include "wlan_extscan_ucfg_api.h"
-#include "wlan_mlme_ucfg_api.h"
 #include "wlan_pmo_cfg.h"
 #include "cfg_ucfg_api.h"
 

+ 1 - 0
core/hdd/src/wlan_hdd_main.c

@@ -160,6 +160,7 @@
 #include "wlan_tdls_cfg_api.h"
 #include <wlan_hdd_rssi_monitor.h>
 #include "wlan_mlme_ucfg_api.h"
+#include "wlan_mlme_twt_ucfg_api.h"
 #include "wlan_fwol_ucfg_api.h"
 #include "wlan_policy_mgr_ucfg.h"
 #include "qdf_func_tracker.h"

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

@@ -35,6 +35,7 @@
 #include "wlan_osif_request_manager.h"
 #include "cfg_ucfg_api.h"
 #include <wlan_cp_stats_mc_ucfg_api.h>
+#include <wlan_mlme_twt_ucfg_api.h>
 
 #define TWT_DISABLE_COMPLETE_TIMEOUT 4000
 #define TWT_NUDGE_COMPLETE_TIMEOUT 4000
@@ -669,6 +670,14 @@ static int hdd_twt_get_session_params(struct hdd_adapter *adapter,
 	else
 		params[0].dialog_id = 0;
 
+	if (!ucfg_mlme_is_twt_setup_done(adapter->hdd_ctx->psoc,
+					 &hdd_sta_ctx->conn_info.bssid,
+					 params[0].dialog_id)) {
+		hdd_debug("vdev%d: TWT session %d setup incomplete",
+			  adapter->vdev_id, params[0].dialog_id);
+		return -EINVAL;
+	}
+
 	hdd_debug("TWT: get_params dialog_id %d", params[0].dialog_id);
 
 	if (params[0].dialog_id <= TWT_MAX_DIALOG_ID) {
@@ -1161,6 +1170,14 @@ hdd_twt_add_dialog_comp_cb(struct wlan_objmgr_psoc *psoc,
 		  add_dialog_event->params.status, vdev_id,
 		  QDF_MAC_ADDR_REF(add_dialog_event->params.peer_macaddr));
 	hdd_send_twt_setup_response(adapter, add_dialog_event);
+
+	if (add_dialog_event->params.status)
+		return;
+
+	ucfg_mlme_set_twt_setup_done(
+		adapter->hdd_ctx->psoc,
+		(struct qdf_mac_addr *)add_dialog_event->params.peer_macaddr,
+		add_dialog_event->params.dialog_id, true);
 }
 
 /**
@@ -1253,7 +1270,30 @@ static int hdd_twt_setup_session(struct hdd_adapter *adapter,
 		ucfg_mlme_set_twt_congestion_timeout(adapter->hdd_ctx->psoc, 0);
 		hdd_send_twt_enable_cmd(adapter->hdd_ctx);
 	}
+
+	if (ucfg_mlme_is_twt_setup_in_progress(adapter->hdd_ctx->psoc,
+					       &hdd_sta_ctx->conn_info.bssid,
+					       params.dialog_id) ||
+	    ucfg_mlme_is_twt_setup_done(adapter->hdd_ctx->psoc,
+					&hdd_sta_ctx->conn_info.bssid,
+					params.dialog_id)) {
+		hdd_err_rl("TWT session exists for dialog:%d",
+			   params.dialog_id);
+		return -EALREADY;
+	}
+
 	ret = hdd_send_twt_add_dialog_cmd(adapter->hdd_ctx, &params);
+	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;
 }
 
@@ -1381,6 +1421,13 @@ hdd_twt_del_dialog_comp_cb(struct wlan_objmgr_psoc *psoc,
 	}
 
 	wlan_cfg80211_vendor_event(twt_vendor_event, GFP_KERNEL);
+	ucfg_mlme_set_twt_setup_done(
+				adapter->hdd_ctx->psoc,
+				(struct qdf_mac_addr *)params->peer_macaddr,
+				params->dialog_id, false);
+	mlme_init_twt_context(hdd_ctx->psoc,
+			      (struct qdf_mac_addr *)params->peer_macaddr,
+			      params->dialog_id);
 
 	hdd_exit();
 
@@ -1465,6 +1512,14 @@ static int hdd_twt_terminate_session(struct hdd_adapter *adapter,
 		hdd_debug("TWT_TERMINATE_FLOW_ID not specified. set to zero");
 	}
 
+	if (!ucfg_mlme_is_twt_setup_done(adapter->hdd_ctx->psoc,
+					 &hdd_sta_ctx->conn_info.bssid,
+					 params.dialog_id)) {
+		hdd_debug("vdev%d: TWT session %d setup incomplete",
+			  params.vdev_id, params.dialog_id);
+		return -EINVAL;
+	}
+
 	hdd_debug("twt_terminate: vdev_id %d dialog_id %d peer mac_addr "
 		  QDF_MAC_ADDR_FMT, params.vdev_id, params.dialog_id,
 		  QDF_MAC_ADDR_REF(params.peer_macaddr));
@@ -1728,6 +1783,14 @@ static int hdd_twt_pause_session(struct hdd_adapter *adapter,
 		hdd_debug("TWT: FLOW_ID not specified. set to zero");
 	}
 
+	if (!ucfg_mlme_is_twt_setup_done(adapter->hdd_ctx->psoc,
+					 &hdd_sta_ctx->conn_info.bssid,
+					 params.dialog_id)) {
+		hdd_debug("vdev%d: TWT session %d setup incomplete",
+			  params.vdev_id, params.dialog_id);
+		return -EINVAL;
+	}
+
 	hdd_debug("twt_pause: vdev_id %d dialog_id %d peer mac_addr "
 		  QDF_MAC_ADDR_FMT, params.vdev_id, params.dialog_id,
 		  QDF_MAC_ADDR_REF(params.peer_macaddr));
@@ -1885,6 +1948,14 @@ static int hdd_twt_nudge_session(struct hdd_adapter *adapter,
 	}
 	params.next_twt_size = nla_get_u32(tb[id]);
 
+	if (!ucfg_mlme_is_twt_setup_done(adapter->hdd_ctx->psoc,
+					 &hdd_sta_ctx->conn_info.bssid,
+					 params.dialog_id)) {
+		hdd_debug("vdev%d: TWT session %d setup incomplete",
+			  params.vdev_id, params.dialog_id);
+		return -EINVAL;
+	}
+
 	hdd_debug("twt_nudge: vdev_id %d dialog_id %d ", params.vdev_id,
 		  params.dialog_id);
 	hdd_debug("twt_nudge: suspend_duration %d next_twt_size %d",
@@ -2037,12 +2108,15 @@ static QDF_STATUS
 hdd_twt_pack_get_capabilities_resp(struct hdd_adapter *adapter)
 {
 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	struct hdd_station_ctx *sta_ctx =
+		WLAN_HDD_GET_STATION_CTX_PTR(adapter);
 	struct nlattr *config_attr;
 	struct sk_buff *reply_skb;
 	size_t skb_len = NLMSG_HDRLEN;
 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
 	uint8_t peer_cap = 0, self_cap = 0;
 	bool twt_req = false, twt_bcast_req = false;
+	bool enable_bcast_twt = false, bcast_tgt_cap;
 
 	/*
 	 * Length of attribute QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_SELF &
@@ -2065,15 +2139,30 @@ hdd_twt_pack_get_capabilities_resp(struct hdd_adapter *adapter)
 		goto free_skb;
 	}
 
+	/* fill the self_capability bitmap  */
 	ucfg_mlme_get_twt_requestor(hdd_ctx->psoc, &twt_req);
 	if (twt_req)
 		self_cap |= QCA_WLAN_TWT_CAPA_REQUESTOR;
 
+	ucfg_mlme_get_bcast_twt(hdd_ctx->psoc, &enable_bcast_twt);
+	bcast_tgt_cap = ucfg_mlme_get_twt_bcast_requestor_tgt_cap(
+						hdd_ctx->psoc);
 	ucfg_mlme_get_twt_bcast_requestor(hdd_ctx->psoc,
 					  &twt_bcast_req);
-	if (twt_bcast_req)
+	if (bcast_tgt_cap && enable_bcast_twt)
+		self_cap |= (twt_bcast_req ?
+			     QCA_WLAN_TWT_CAPA_BROADCAST : 0);
+	else if (twt_bcast_req)
 		self_cap |= QCA_WLAN_TWT_CAPA_BROADCAST;
 
+	if (ucfg_mlme_is_flexible_twt_enabled(hdd_ctx->psoc))
+		self_cap |= QCA_WLAN_TWT_CAPA_FLEXIBLE;
+
+	/* Fill the Peer capability bitmap */
+	peer_cap = ucfg_mlme_get_twt_peer_capabilities(
+		hdd_ctx->psoc,
+		(struct qdf_mac_addr *)sta_ctx->conn_info.bssid.bytes);
+
 	if (nla_put_u16(reply_skb, QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_SELF,
 			self_cap)) {
 		hdd_err("TWT: Failed to fill capabilities");
@@ -2196,6 +2285,14 @@ static int hdd_twt_resume_session(struct hdd_adapter *adapter,
 		hdd_debug("TWT_RESUME_FLOW_ID not specified. set to zero");
 	}
 
+	if (!ucfg_mlme_is_twt_setup_done(adapter->hdd_ctx->psoc,
+					 &hdd_sta_ctx->conn_info.bssid,
+					 params.dialog_id)) {
+		hdd_debug("vdev%d: TWT session %d setup incomplete",
+			  params.vdev_id, params.dialog_id);
+		return -EINVAL;
+	}
+
 	id = QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT_TWT;
 	id2 = QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT2_TWT;
 	if (tb[id2])

+ 9 - 1
core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-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
@@ -42,6 +42,7 @@
 #include "lim_send_messages.h"
 #include "lim_process_fils.h"
 #include "wlan_blm_api.h"
+#include "wlan_mlme_twt_api.h"
 
 /**
  * lim_update_stads_htcap() - Updates station Descriptor HT capability
@@ -929,6 +930,13 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
 		lim_update_obss_scanparams(session_entry,
 				&assoc_rsp->obss_scanparams);
 
+	if (lim_is_session_he_capable(session_entry))
+		mlme_set_twt_peer_capabilities(
+				mac_ctx->psoc,
+				(struct qdf_mac_addr *)current_bssid,
+				&assoc_rsp->he_cap,
+				&assoc_rsp->he_op);
+
 	lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_ROAM_ASSOC_COMP_EVENT,
 			      session_entry,
 			      (assoc_rsp->status_code ? QDF_STATUS_E_FAILURE :