qcacmn: Green AP UMAC componentization

Add APIs, structures for Green AP component.

Change-Id: I4a39470104c89c20eec5440b7ae251a764151fd5
CRs-Fixed: 2166428
diff --git a/umac/cmn_services/inc/wlan_cmn.h b/umac/cmn_services/inc/wlan_cmn.h
index 3b1230f..73d487a 100644
--- a/umac/cmn_services/inc/wlan_cmn.h
+++ b/umac/cmn_services/inc/wlan_cmn.h
@@ -122,6 +122,7 @@
  * @WLAN_UMAC_COMP_OFFCHAN_TXRX:  Offchan TxRx
  * @WLAN_UMAC_COMP_SPLITMAC:      SplitMAC
  * @WLAN_UMAC_COMP_DISA:          DISA encryption test
+ * @WLAN_UMAC_COMP_GREEN_AP:      Green AP
  *
  * This id is static.
  * On Adding new component, new id has to be assigned
@@ -149,6 +150,7 @@
 	WLAN_UMAC_COMP_SPECTRAL,
 	WLAN_UMAC_COMP_SPLITMAC,
 	WLAN_UMAC_COMP_DISA,
+	WLAN_UMAC_COMP_GREEN_AP,
 	WLAN_UMAC_COMP_ID_MAX,
 };
 
diff --git a/umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h b/umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h
index 4b77fca..493b6fe 100644
--- a/umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h
+++ b/umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -971,6 +971,19 @@
 		void *roam_profile, uint8_t *channel);
 
 /**
+ * policy_mgr_mode_specific_num_open_sessions() - to get number of open sessions
+ *                                                for a specific mode
+ * @psoc: PSOC object information
+ * @mode: device mode
+ * @num_sessions: to store num open sessions
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS policy_mgr_mode_specific_num_open_sessions(
+		struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE mode,
+		uint8_t *num_sessions);
+
+/**
  * policy_mgr_concurrent_open_sessions_running() - Checks for
  * concurrent open session
  * @psoc: PSOC object information
diff --git a/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c b/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c
index d477600..33483e0 100644
--- a/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c
+++ b/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c
@@ -2053,6 +2053,22 @@
 	return mode;
 }
 
+QDF_STATUS policy_mgr_mode_specific_num_open_sessions(
+		struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE mode,
+		uint8_t *num_sessions)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*num_sessions = pm_ctx->no_of_open_sessions[mode];
+	return QDF_STATUS_SUCCESS;
+}
+
 /**
  * policy_mgr_concurrent_open_sessions_running() - Checks for
  * concurrent open session
diff --git a/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h b/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h
index b5f9bc1..efc9dcc 100644
--- a/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h
+++ b/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h
@@ -539,11 +539,28 @@
 };
 #endif
 
+#ifdef WLAN_SUPPORT_GREEN_AP
+struct wlan_green_ap_egap_params;
+/**
+ * struct wlan_lmac_if_green_ap_tx_ops - structure of tx function
+ *                  pointers for green ap component
+ * @enable_egap: function pointer to send enable egap indication to fw
+ * @ps_on_off_send:  function pointer to send enable/disable green ap ps to fw
+ */
+struct wlan_lmac_if_green_ap_tx_ops {
+	QDF_STATUS (*enable_egap)(struct wlan_objmgr_pdev *pdev,
+				struct wlan_green_ap_egap_params *egap_params);
+	QDF_STATUS (*ps_on_off_send)(struct wlan_objmgr_pdev *pdev,
+				     bool value, uint8_t pdev_id);
+};
+#endif
+
 /**
  * struct wlan_lmac_if_tx_ops - south bound tx function pointers
  * @mgmt_txrx_tx_ops: mgmt txrx tx ops
  * @scan: scan tx ops
  * @dfs_tx_ops: dfs tx ops.
+ * @green_ap_tx_ops: green_ap tx_ops
  *
  * Callback function tabled to be registered with umac.
  * umac will use the functional table to send events/frames to lmac/wmi
@@ -599,6 +616,9 @@
 #ifdef DIRECT_BUF_RX_ENABLE
 	struct wlan_lmac_if_direct_buf_rx_tx_ops dbr_tx_ops;
 #endif
+#ifdef WLAN_SUPPORT_GREEN_AP
+	 struct wlan_lmac_if_green_ap_tx_ops green_ap_tx_ops;
+#endif
 };
 
 /**
diff --git a/umac/green_ap/core/src/wlan_green_ap_main.c b/umac/green_ap/core/src/wlan_green_ap_main.c
index 97288bf..999b5b7 100644
--- a/umac/green_ap/core/src/wlan_green_ap_main.c
+++ b/umac/green_ap/core/src/wlan_green_ap_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018 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
@@ -20,25 +20,258 @@
  * DOC: This file contains main green ap function definitions
  */
 
-#include <wlan_objmgr_pdev_obj.h>
 #include "wlan_green_ap_main_i.h"
 
-void wlan_green_ap_state_mc(struct wlan_objmgr_pdev *pdev,
-			   enum wlan_green_ap_ps_event event)
+struct wlan_lmac_if_green_ap_tx_ops *
+wlan_psoc_get_green_ap_tx_ops(struct wlan_pdev_green_ap_ctx *green_ap_ctx)
 {
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_pdev *pdev = green_ap_ctx->pdev;
 
+	if (!pdev) {
+		green_ap_err("pdev context obtained is NULL");
+		return NULL;
+	}
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	if (!psoc) {
+		green_ap_err("pdev context obtained is NULL");
+		return NULL;
+	}
+
+	return &((psoc->soc_cb.tx_ops.green_ap_tx_ops));
 }
 
-void wlan_green_ap_ps_event_state_update(struct wlan_objmgr_pdev *pdev,
-			 enum wlan_green_ap_ps_state state,
-			 enum wlan_green_ap_ps_event event)
+bool wlan_is_egap_enabled(struct wlan_pdev_green_ap_ctx *green_ap_ctx)
 {
+	struct wlan_green_ap_egap_params *egap_params;
 
+	if (!green_ap_ctx) {
+		green_ap_err("green ap context passed is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+	egap_params = &green_ap_ctx->egap_params;
+
+	if (egap_params->fw_egap_support &&
+	    egap_params->host_enable_egap &&
+	    egap_params->egap_feature_flags)
+		return true;
+	return false;
 }
 
-int wlan_green_ap_timer_fn(struct wlan_objmgr_pdev *pdev)
+/**
+ * wlan_green_ap_ps_event_state_update() - Update PS state and event
+ * @pdev: pdev pointer
+ * @state: ps state
+ * @event: ps event
+ *
+ * @Return: Success or Failure
+ */
+static QDF_STATUS wlan_green_ap_ps_event_state_update(
+			struct wlan_pdev_green_ap_ctx *green_ap_ctx,
+			enum wlan_green_ap_ps_state state,
+			enum wlan_green_ap_ps_event event)
 {
+	if (!green_ap_ctx) {
+		green_ap_err("green ap context obtained is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
 
-	return 0;
+	green_ap_ctx->ps_state = state;
+	green_ap_ctx->ps_event = event;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_green_ap_state_mc(struct wlan_pdev_green_ap_ctx *green_ap_ctx,
+				  enum wlan_green_ap_ps_event event)
+{
+	struct wlan_lmac_if_green_ap_tx_ops *green_ap_tx_ops;
+	uint8_t pdev_id;
+
+	if (!green_ap_ctx) {
+		green_ap_err("green ap context obtained is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!green_ap_ctx->pdev) {
+		green_ap_err("pdev obtained is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	pdev_id = wlan_objmgr_pdev_get_pdev_id(green_ap_ctx->pdev);
+
+	green_ap_tx_ops = wlan_psoc_get_green_ap_tx_ops(green_ap_ctx);
+	if (!green_ap_tx_ops) {
+		green_ap_err("green ap tx ops obtained are NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!green_ap_tx_ops->ps_on_off_send) {
+		green_ap_err("tx op for sending enbale/disable green ap is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_spin_lock_bh(&green_ap_ctx->lock);
+
+	/* handle the green ap ps event */
+	switch (event) {
+	case WLAN_GREEN_AP_ADD_STA_EVENT:
+		green_ap_ctx->num_nodes++;
+		break;
+
+	case WLAN_GREEN_AP_DEL_STA_EVENT:
+		if (green_ap_ctx->num_nodes)
+			green_ap_ctx->num_nodes--;
+		break;
+
+	case WLAN_GREEN_AP_PS_START_EVENT:
+	case WLAN_GREEN_AP_PS_STOP_EVENT:
+	case WLAN_GREEN_AP_PS_ON_EVENT:
+	case WLAN_GREEN_AP_PS_WAIT_EVENT:
+		break;
+
+	default:
+		green_ap_err("Invalid event: %d", event);
+		break;
+	}
+
+	green_ap_debug("Green-AP event: %d, state: %d, num_nodes: %d",
+		       event, green_ap_ctx->ps_state, green_ap_ctx->num_nodes);
+
+	/* Confirm that power save is enabled before doing state transitions */
+	if (!green_ap_ctx->ps_enable) {
+		green_ap_debug("Green-AP is disabled");
+		wlan_green_ap_ps_event_state_update(
+				green_ap_ctx,
+				WLAN_GREEN_AP_PS_IDLE_STATE,
+				WLAN_GREEN_AP_PS_WAIT_EVENT);
+		if (green_ap_tx_ops->ps_on_off_send(green_ap_ctx->pdev,
+						    false, pdev_id))
+			green_ap_err("failed to set green ap mode");
+		goto done;
+	}
+
+	/* handle the green ap ps state */
+	switch (green_ap_ctx->ps_state) {
+	case WLAN_GREEN_AP_PS_IDLE_STATE:
+		if (green_ap_ctx->num_nodes) {
+			/* Active nodes present, Switchoff the power save */
+			green_ap_info("Transition to OFF from IDLE");
+			wlan_green_ap_ps_event_state_update(
+					green_ap_ctx,
+					WLAN_GREEN_AP_PS_OFF_STATE,
+					WLAN_GREEN_AP_PS_WAIT_EVENT);
+		} else {
+			/* No Active nodes, get into power save */
+			green_ap_info("Transition to WAIT from IDLE");
+			wlan_green_ap_ps_event_state_update(
+					green_ap_ctx,
+					WLAN_GREEN_AP_PS_WAIT_STATE,
+					WLAN_GREEN_AP_PS_WAIT_EVENT);
+			qdf_timer_start(&green_ap_ctx->ps_timer,
+					green_ap_ctx->ps_trans_time);
+		}
+		break;
+
+	case WLAN_GREEN_AP_PS_OFF_STATE:
+		if (!green_ap_ctx->num_nodes) {
+			green_ap_info("Transition to WAIT from OFF");
+			wlan_green_ap_ps_event_state_update(
+						green_ap_ctx,
+						WLAN_GREEN_AP_PS_WAIT_STATE,
+						WLAN_GREEN_AP_PS_WAIT_EVENT);
+			qdf_timer_start(&green_ap_ctx->ps_timer,
+					green_ap_ctx->ps_trans_time);
+		}
+		break;
+
+	case WLAN_GREEN_AP_PS_WAIT_STATE:
+		if (!green_ap_ctx->num_nodes) {
+			wlan_green_ap_ps_event_state_update(
+						green_ap_ctx,
+						WLAN_GREEN_AP_PS_ON_STATE,
+						WLAN_GREEN_AP_PS_WAIT_EVENT);
+
+			green_ap_info("Transition to ON from WAIT");
+			green_ap_tx_ops->ps_on_off_send(green_ap_ctx->pdev,
+							true, pdev_id);
+			if (green_ap_ctx->ps_on_time)
+				qdf_timer_start(&green_ap_ctx->ps_timer,
+						green_ap_ctx->ps_on_time);
+		} else {
+			green_ap_info("Transition to OFF from WAIT");
+			qdf_timer_stop(&green_ap_ctx->ps_timer);
+			wlan_green_ap_ps_event_state_update(
+						green_ap_ctx,
+						WLAN_GREEN_AP_PS_OFF_STATE,
+						WLAN_GREEN_AP_PS_WAIT_EVENT);
+		}
+		break;
+
+	case WLAN_GREEN_AP_PS_ON_STATE:
+		if (green_ap_ctx->num_nodes) {
+			qdf_timer_stop(&green_ap_ctx->ps_timer);
+			if (green_ap_tx_ops->ps_on_off_send(
+					green_ap_ctx->pdev, false, pdev_id)) {
+				green_ap_err("Failed to set Green AP mode");
+				goto done;
+			}
+			green_ap_info("Transition to OFF from ON\n");
+			wlan_green_ap_ps_event_state_update(
+						green_ap_ctx,
+						WLAN_GREEN_AP_PS_OFF_STATE,
+						WLAN_GREEN_AP_PS_WAIT_EVENT);
+		} else if ((green_ap_ctx->ps_event ==
+					WLAN_GREEN_AP_PS_WAIT_EVENT) &&
+			   (green_ap_ctx->ps_on_time)) {
+			/* ps_on_time timeout, switch to ps wait */
+			wlan_green_ap_ps_event_state_update(
+						green_ap_ctx,
+						WLAN_GREEN_AP_PS_WAIT_STATE,
+						WLAN_GREEN_AP_PS_ON_EVENT);
+
+			if (green_ap_tx_ops->ps_on_off_send(
+					green_ap_ctx->pdev, false, pdev_id)) {
+				green_ap_err("Failed to set Green AP mode");
+				goto done;
+			}
+
+			green_ap_info("Transition to WAIT from ON\n");
+			qdf_timer_start(&green_ap_ctx->ps_timer,
+					green_ap_ctx->ps_trans_time);
+		}
+		break;
+
+	default:
+		green_ap_err("invalid state %d", green_ap_ctx->ps_state);
+		wlan_green_ap_ps_event_state_update(
+						green_ap_ctx,
+						WLAN_GREEN_AP_PS_OFF_STATE,
+						WLAN_GREEN_AP_PS_WAIT_EVENT);
+		break;
+	}
+
+done:
+	qdf_spin_unlock_bh(&green_ap_ctx->lock);
+	return QDF_STATUS_SUCCESS;
+}
+
+void wlan_green_ap_timer_fn(void *pdev)
+{
+	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
+	struct wlan_objmgr_pdev *pdev_ctx = (struct wlan_objmgr_pdev *)pdev;
+
+	if (!pdev_ctx) {
+		green_ap_err("pdev context passed is NULL");
+		return;
+	}
+
+	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
+			pdev_ctx, WLAN_UMAC_COMP_GREEN_AP);
+	if (!green_ap_ctx) {
+		green_ap_err("green ap context obtained is NULL");
+		return;
+	}
+	wlan_green_ap_state_mc(green_ap_ctx, green_ap_ctx->ps_event);
 }
 
diff --git a/umac/green_ap/core/src/wlan_green_ap_main_i.h b/umac/green_ap/core/src/wlan_green_ap_main_i.h
index 6b5b36f..3e387ad 100644
--- a/umac/green_ap/core/src/wlan_green_ap_main_i.h
+++ b/umac/green_ap/core/src/wlan_green_ap_main_i.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018 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
@@ -24,6 +24,34 @@
 #ifndef _WLAN_GREEN_AP_MAIN_I_H_
 #define _WLAN_GREEN_AP_MAIN_I_H_
 
+#include <wlan_objmgr_cmn.h>
+#include <wlan_objmgr_pdev_obj.h>
+#include <wlan_green_ap_api.h>
+#include <qdf_types.h>
+#include <qdf_status.h>
+#include <qdf_timer.h>
+
+#define WLAN_GREEN_AP_PS_ON_TIME        (0)
+#define WLAN_GREEN_AP_PS_TRANS_TIME     (20)
+
+#define green_ap_log(level, args...) \
+			QDF_TRACE(QDF_MODULE_ID_GREEN_AP, level, ## args)
+#define green_ap_logfl(level, format, args...) \
+			green_ap_log(level, FL(format), ## args)
+
+#define green_ap_alert(format, args...) \
+		green_ap_logfl(QDF_TRACE_LEVEL_FATAL, format, ## args)
+#define green_ap_err(format, args...) \
+		green_ap_logfl(QDF_TRACE_LEVEL_ERROR, format, ## args)
+#define green_apwarn(format, args...) \
+		green_ap_logfl(QDF_TRACE_LEVEL_WARN, format, ## args)
+#define green_ap_notice(format, args...) \
+		green_ap_logfl(QDF_TRACE_LEVEL_INFO, format, ## args)
+#define green_ap_info(format, args...) \
+		green_ap_logfl(QDF_TRACE_LEVEL_INFO_HIGH, format, ## args)
+#define green_ap_debug(format, args...) \
+		green_ap_logfl(QDF_TRACE_LEVEL_DEBUG, format, ## args)
+
 /**
  * enum wlan_green_ap_ps_state - PS states
  * @WLAN_GREEN_AP_PS_IDLE_STATE - Idle
@@ -59,54 +87,61 @@
 /**
  * struct wlan_pdev_green_ap_ctx - green ap context
  * @pdev - Pdev pointer
- * @green_ap_ps_enable  - Enable PS
- * @green_ap_ps_on_time - PS on time, once enabled
- * @green_ap_ps_trans_time - PS transition time
- * @green_ap_num_node - Number of nodes associated to radio
+ * @ps_enable  - Enable PS
+ * @ps_on_time - PS on time, once enabled
+ * @ps_trans_time - PS transition time
+ * @num_nodes - Number of nodes associated to radio
  * @ps_state - PS state
  * @ps_event - PS event
- * @green_ap_ps_timer - Timer
- * @green_ap_egap_support - Enhanced green ap support
+ * @ps_timer - Timer
+ * @lock: green ap spinlock
+ * @egap_params - Enhanced green ap params
  */
 struct wlan_pdev_green_ap_ctx {
 	struct wlan_objmgr_pdev *pdev;
-	uint8_t green_ap_ps_enable;
-	uint8_t green_ap_ps_on_time;
-	uint32_t green_ap_ps_trans_time;
-	uint32_t green_ap_num_nodes;
+	uint8_t ps_enable;
+	uint8_t ps_on_time;
+	uint32_t ps_trans_time;
+	uint32_t num_nodes;
 	enum wlan_green_ap_ps_state ps_state;
 	enum wlan_green_ap_ps_event ps_event;
-	qdf_timer_t green_ap_ps_timer;
-	bool green_ap_egap_support;
+	qdf_timer_t ps_timer;
+	qdf_spinlock_t lock;
+	struct wlan_green_ap_egap_params egap_params;
 };
 
 /**
- * wlan_green_ap_state_mc() - Green ap state machine
- * @pdev: pdev pointer
- * @event: ps event
+ * wlan_psoc_get_green_ap_tx_ops() - Obtain green ap tx ops from green ap ctx
+ * @green_ap_ctx: green ap context
  *
- * @Return: None
+ * @Return: green ap tx ops pointer
  */
-void wlan_green_ap_state_mc(struct wlan_objmgr_pdev *pdev,
-			   enum wlan_green_ap_ps_event event);
+struct wlan_lmac_if_green_ap_tx_ops *
+wlan_psoc_get_green_ap_tx_ops(struct wlan_pdev_green_ap_ctx *green_ap_ctx);
 
 /**
- * wlan_green_ap_ps_event_state_update() - Update PS state and event
- * @pdev: pdev pointer
- * @state: ps state
+ * wlan_is_egap_enabled() - Get Enhance Green AP feature status
+ * @green_ap_ctx: green ap context
+ *
+ * Return: true if firmware, feature_flag and ini are all egap enabled
+ */
+bool wlan_is_egap_enabled(struct wlan_pdev_green_ap_ctx *green_ap_ctx);
+
+/**
+ * wlan_green_ap_state_mc() - Green ap state machine
+ * @green_ap_ctx: green ap context
  * @event: ps event
  *
- * @Return: None
+ * @Return: Success or Failure
  */
-void wlan_green_ap_ps_event_state_update(struct wlan_objmgr_pdev *pdev,
-			 enum wlan_green_ap_ps_state state,
-			 enum wlan_green_ap_ps_event event);
+QDF_STATUS wlan_green_ap_state_mc(struct wlan_pdev_green_ap_ctx *green_ap_ctx,
+				  enum wlan_green_ap_ps_event event);
 
 /**
  * wlan_green_ap_timer_fn() - Green ap timer callback
  * @pdev: pdev pointer
  *
- * @Return: status
+ * @Return: None
  */
-int wlan_green_ap_timer_fn(struct wlan_objmgr_pdev *pdev);
+void wlan_green_ap_timer_fn(void *pdev);
 #endif  /* _WLAN_GREEN_AP_MAIN_I_H_ */
diff --git a/umac/green_ap/dispatcher/inc/wlan_green_ap_api.h b/umac/green_ap/dispatcher/inc/wlan_green_ap_api.h
index 39c7e25..b4632c2 100644
--- a/umac/green_ap/dispatcher/inc/wlan_green_ap_api.h
+++ b/umac/green_ap/dispatcher/inc/wlan_green_ap_api.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018 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
@@ -23,7 +23,25 @@
 #ifndef _WLAN_GREEN_AP_API_H_
 #define _WLAN_GREEN_AP_API_H_
 
+#include <wlan_objmgr_cmn.h>
 #include <wlan_objmgr_pdev_obj.h>
+#include <qdf_status.h>
+
+/**
+ * struct wlan_green_ap_egap_params - enhance green ap params
+ * @fw_egap_support: fw enhance green ap support
+ * @host_enable_egap: HOST enhance green ap support
+ * @egap_inactivity_time: inactivity time
+ * @egap_wait_time: wait time
+ * @egap_feature_flags: feature flags
+ */
+struct wlan_green_ap_egap_params {
+	bool fw_egap_support;
+	bool host_enable_egap;
+	uint32_t egap_inactivity_time;
+	uint32_t egap_wait_time;
+	uint32_t egap_feature_flags;
+};
 
 /**
  * wlan_green_ap_init() - initialize green ap component
@@ -43,7 +61,7 @@
  * wlan_green_ap_start() - Start green ap
  * @pdev: pdev pointer
  *
- * Call this function when the first vdev comes up
+ * Call this function when the first SAP comes up
  *
  * Return: Success or Failure
  */
@@ -53,7 +71,7 @@
  * wlan_green_ap_stop() - Stop green ap
  * @pdev: pdev pointer
  *
- * Call this function when the last vdev goes down
+ * Call this function when the last SAP goes down
  *
  * Return: Success or Failure
  */
@@ -73,10 +91,9 @@
  * wlan_green_ap_del_sta() - On disassociation
  * @pdev: pdev pointer
  *
- * Call this function when new node is associated
+ * Call this function when new node is disassociated
  *
  * Return: Success or Failure
  */
 QDF_STATUS wlan_green_ap_del_sta(struct wlan_objmgr_pdev *pdev);
-
 #endif /* _WLAN_GREEN_AP_API_H_ */
diff --git a/umac/green_ap/dispatcher/inc/wlan_green_ap_ucfg_api.h b/umac/green_ap/dispatcher/inc/wlan_green_ap_ucfg_api.h
index b31212c..2ad95ae 100644
--- a/umac/green_ap/dispatcher/inc/wlan_green_ap_ucfg_api.h
+++ b/umac/green_ap/dispatcher/inc/wlan_green_ap_ucfg_api.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018 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
@@ -23,7 +23,97 @@
 #ifndef _WLAN_GREEN_AP_UCFG_API_H_
 #define _WLAN_GREEN_AP_UCFG_API_H_
 
+#include <wlan_objmgr_cmn.h>
 #include <wlan_objmgr_pdev_obj.h>
+#include <qdf_status.h>
 
+/**
+ * struct green_ap_user_cfg - green ap user cfg
+ * @host_enable_egap: HOST enhance green ap support
+ * @egap_inactivity_time: inactivity time
+ * @egap_wait_time: wait time
+ * @egap_feature_flags: feature flags
+ */
+struct green_ap_user_cfg {
+	bool host_enable_egap;
+	uint32_t egap_inactivity_time;
+	uint32_t egap_wait_time;
+	uint32_t egap_feature_flags;
+};
+
+/**
+ * ucfg_green_ap_update_user_config() - Updates user cfg for green ap
+ * @pdev: pdev pointer
+ * @green_ap_cfg: pointer to green ap user cfg structure
+ *
+ * Return: Success or Failure
+ */
+QDF_STATUS ucfg_green_ap_update_user_config(
+			struct wlan_objmgr_pdev *pdev,
+			struct green_ap_user_cfg *green_ap_cfg);
+
+/**
+ * ucfg_green_ap_enable_egap() - Enable enhanced green ap
+ * @pdev: pdev pointer
+ *
+ * Return: Success or Failure
+ */
+QDF_STATUS ucfg_green_ap_enable_egap(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * ucfg_green_ap_target_config() - Handle Green AP target configuration
+ * @pdev: pdev pointer
+ * @fw_egap_support: fw egap support
+ *
+ * This API stores the fw enhanced green AP support capability
+ * in green ap ctx.
+ *
+ * Return: Success or Failure
+ */
+QDF_STATUS ucfg_green_ap_target_config(struct wlan_objmgr_pdev *pdev,
+				       bool fw_egap_support);
+
+/**
+ * ucfg_green_ap_set_ps_config() - Set ps value
+ * @pdev: pdev pointer
+ * @value - value to be set
+ *
+ * Return: Success or Failure
+ */
+QDF_STATUS ucfg_green_ap_set_ps_config(struct wlan_objmgr_pdev *pdev,
+				       uint8_t value);
+/**
+ * ucfg_green_ap_get_ps_config() - Check if ps is enabled or not
+ * @pdev: pdev pointer
+ * @ps_enable: pointer to ps enable config value
+ *
+ * Return: Success or Failure
+ */
+QDF_STATUS ucfg_green_ap_get_ps_config(struct wlan_objmgr_pdev *pdev,
+				       uint8_t *ps_enable);
+
+/**
+ * ucfg_green_ap_set_transition_time() - Set transition time
+ * @pdev: pdev pointer
+ * @val: transition time
+ *
+ * This API sets custom transition time
+ *
+ * Return: Success or Failure
+ */
+QDF_STATUS ucfg_green_ap_set_transition_time(struct wlan_objmgr_pdev *pdev,
+					     uint32_t val);
+
+/**
+ * ucfg_green_ap_get_transition_time() - Get transition time
+ * @pdev: pdev pointer
+ * @ps_trans_time: pointer to transition time
+ *
+ * This API gets transition time
+ *
+ * Return: Success or Failure
+ */
+QDF_STATUS ucfg_green_ap_get_transition_time(struct wlan_objmgr_pdev *pdev,
+					     uint32_t *ps_trans_time);
 
 #endif /* _WLAN_GREEN_AP_UCFG_API_H_ */
diff --git a/umac/green_ap/dispatcher/src/wlan_green_ap_api.c b/umac/green_ap/dispatcher/src/wlan_green_ap_api.c
index 5b1ef78..4d3c82e 100644
--- a/umac/green_ap/dispatcher/src/wlan_green_ap_api.c
+++ b/umac/green_ap/dispatcher/src/wlan_green_ap_api.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018 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
@@ -19,48 +19,307 @@
 /**
  * DOC: This file contains green ap north bound interface definitions
  */
-
-#include <qdf_status.h>
 #include <wlan_green_ap_api.h>
+#include <../../core/src/wlan_green_ap_main_i.h>
+#include <wlan_objmgr_global_obj.h>
+
+/**
+ * wlan_green_ap_pdev_obj_create_notification() - called from objmgr when pdev
+ *                                                is created
+ * @pdev: pdev context
+ * @arg: argument
+ *
+ * This function gets called from object manager when pdev is being created and
+ * creates green ap context and attach it to objmgr.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success
+ */
+static QDF_STATUS wlan_green_ap_pdev_obj_create_notification(
+			struct wlan_objmgr_pdev *pdev, void *arg)
+{
+	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (!pdev) {
+		green_ap_err("pdev context passed is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	green_ap_ctx = qdf_mem_malloc(sizeof(*green_ap_ctx));
+	if (!green_ap_ctx) {
+		green_ap_err("Memory allocation for Green AP context failed!");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	green_ap_ctx->ps_state = WLAN_GREEN_AP_PS_IDLE_STATE;
+	green_ap_ctx->ps_event = WLAN_GREEN_AP_PS_WAIT_EVENT;
+	green_ap_ctx->num_nodes = 0;
+	green_ap_ctx->ps_on_time = WLAN_GREEN_AP_PS_ON_TIME * 1000;
+	green_ap_ctx->ps_trans_time = WLAN_GREEN_AP_PS_TRANS_TIME * 1000;
+
+	green_ap_ctx->pdev = pdev;
+
+	qdf_timer_init(NULL, &green_ap_ctx->ps_timer,
+		       wlan_green_ap_timer_fn,
+		       pdev, QDF_TIMER_TYPE_WAKE_APPS);
+
+	qdf_spinlock_create(&green_ap_ctx->lock);
+	if (wlan_objmgr_pdev_component_obj_attach(pdev,
+				WLAN_UMAC_COMP_GREEN_AP,
+				green_ap_ctx, QDF_STATUS_SUCCESS)
+			!= QDF_STATUS_SUCCESS) {
+		green_ap_err("Failed to attach green ap ctx in pdev ctx");
+		status = QDF_STATUS_E_FAILURE;
+		goto err_pdev_attach;
+	}
+
+	green_ap_info("Green AP creation successful, green ap ctx: %pK, pdev: %pK",
+		      green_ap_ctx, pdev);
+
+	return QDF_STATUS_SUCCESS;
+
+err_pdev_attach:
+	qdf_spinlock_destroy(&green_ap_ctx->lock);
+	qdf_timer_free(&green_ap_ctx->ps_timer);
+	qdf_mem_free(green_ap_ctx);
+	return status;
+}
+
+/**
+ * wlan_green_ap_pdev_obj_destroy_notification() - called from objmgr when
+ *                                                 pdev is destroyed
+ * @pdev: pdev context
+ * @arg: argument
+ *
+ * This function gets called from object manager when pdev is being destroyed
+ * and deletes green ap context and detach it from objmgr.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success
+ */
+static QDF_STATUS wlan_green_ap_pdev_obj_destroy_notification(
+			struct wlan_objmgr_pdev *pdev, void *arg)
+{
+	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
+
+	if (!pdev) {
+		green_ap_err("pdev context passed is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
+			pdev, WLAN_UMAC_COMP_GREEN_AP);
+	if (!green_ap_ctx) {
+		green_ap_err("green ap context is already NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	green_ap_info("Deleting green ap pdev obj, green ap ctx: %pK, pdev: %pK",
+		      green_ap_ctx, pdev);
+
+	if (wlan_objmgr_pdev_component_obj_detach(pdev,
+				WLAN_UMAC_COMP_GREEN_AP, green_ap_ctx) !=
+				QDF_STATUS_SUCCESS) {
+		green_ap_err("Failed to detach green ap ctx in psoc ctx");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_timer_free(&green_ap_ctx->ps_timer);
+	qdf_spinlock_destroy(&green_ap_ctx->lock);
+
+	qdf_mem_free(green_ap_ctx);
+	green_ap_info("green ap deletion successful, pdev: %pK", pdev);
+
+	return QDF_STATUS_SUCCESS;
+}
 
 QDF_STATUS wlan_green_ap_init(void)
 {
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 
+	status = wlan_objmgr_register_pdev_create_handler(
+				WLAN_UMAC_COMP_GREEN_AP,
+				wlan_green_ap_pdev_obj_create_notification,
+				NULL);
+	if (status != QDF_STATUS_SUCCESS) {
+		green_ap_err("Failed to register green ap obj create handler");
+		goto err_pdev_create;
+	}
+
+	status = wlan_objmgr_register_pdev_destroy_handler(
+				WLAN_UMAC_COMP_GREEN_AP,
+				wlan_green_ap_pdev_obj_destroy_notification,
+				NULL);
+	if (status != QDF_STATUS_SUCCESS) {
+		green_ap_err("Failed to register green ap obj destroy handler");
+		goto err_pdev_delete;
+	}
+
+	green_ap_info("Successfully registered create and destroy handlers with objmgr");
+	return QDF_STATUS_SUCCESS;
+
+err_pdev_delete:
+	wlan_objmgr_unregister_pdev_create_handler(
+				WLAN_UMAC_COMP_GREEN_AP,
+				wlan_green_ap_pdev_obj_create_notification,
+				NULL);
+err_pdev_create:
 	return status;
 }
 
 QDF_STATUS wlan_green_ap_deinit(void)
 {
-	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	if (wlan_objmgr_unregister_pdev_create_handler(
+				WLAN_UMAC_COMP_GREEN_AP,
+				wlan_green_ap_pdev_obj_create_notification,
+				NULL)
+			!= QDF_STATUS_SUCCESS) {
+		return QDF_STATUS_E_FAILURE;
+	}
 
-	return status;
+	if (wlan_objmgr_unregister_pdev_destroy_handler(
+				WLAN_UMAC_COMP_GREEN_AP,
+				wlan_green_ap_pdev_obj_destroy_notification,
+				NULL)
+			!= QDF_STATUS_SUCCESS) {
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	green_ap_info("Successfully unregistered create and destroy handlers with objmgr");
+	return QDF_STATUS_SUCCESS;
 }
 
 QDF_STATUS wlan_green_ap_start(struct wlan_objmgr_pdev *pdev)
 {
-	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
 
-	return status;
+	if (!pdev) {
+		green_ap_err("pdev context passed is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
+			pdev, WLAN_UMAC_COMP_GREEN_AP);
+	if (!green_ap_ctx) {
+		green_ap_err("green ap context obtained is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	green_ap_debug("Green AP start received");
+
+	/* Make sure the start function does not get called 2 times */
+	qdf_spin_lock_bh(&green_ap_ctx->lock);
+
+	if (wlan_is_egap_enabled(green_ap_ctx)) {
+		qdf_spin_unlock_bh(&green_ap_ctx->lock);
+		green_ap_debug("enhanced green ap support is enabled");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	if (green_ap_ctx->ps_state == WLAN_GREEN_AP_PS_IDLE_STATE) {
+		if (green_ap_ctx->ps_enable) {
+			qdf_spin_unlock_bh(&green_ap_ctx->lock);
+			return wlan_green_ap_state_mc(green_ap_ctx,
+					      WLAN_GREEN_AP_PS_START_EVENT);
+		}
+	}
+
+	qdf_spin_unlock_bh(&green_ap_ctx->lock);
+	return QDF_STATUS_E_ALREADY;
 }
 
 QDF_STATUS wlan_green_ap_stop(struct wlan_objmgr_pdev *pdev)
 {
-	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
 
-	return status;
+	if (!pdev) {
+		green_ap_err("pdev context passed is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
+			pdev, WLAN_UMAC_COMP_GREEN_AP);
+	if (!green_ap_ctx) {
+		green_ap_err("green ap context obtained is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	green_ap_debug("Green AP stop received");
+
+	qdf_spin_lock_bh(&green_ap_ctx->lock);
+
+	if (wlan_is_egap_enabled(green_ap_ctx)) {
+		qdf_spin_unlock_bh(&green_ap_ctx->lock);
+		green_ap_debug("enhanced green ap support is enabled");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	/* Delete the timer just to be sure */
+	qdf_timer_stop(&green_ap_ctx->ps_timer);
+
+	/* Disable the power save */
+	green_ap_ctx->ps_enable = 0;
+
+	qdf_spin_unlock_bh(&green_ap_ctx->lock);
+	return wlan_green_ap_state_mc(green_ap_ctx,
+				      WLAN_GREEN_AP_PS_STOP_EVENT);
 }
 
 QDF_STATUS wlan_green_ap_add_sta(struct wlan_objmgr_pdev *pdev)
 {
-	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
 
-	return status;
+	if (!pdev) {
+		green_ap_err("pdev context passed is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
+			pdev, WLAN_UMAC_COMP_GREEN_AP);
+	if (!green_ap_ctx) {
+		green_ap_err("green ap context obtained is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	green_ap_debug("Green AP add sta received");
+
+	qdf_spin_lock_bh(&green_ap_ctx->lock);
+	if (wlan_is_egap_enabled(green_ap_ctx)) {
+		qdf_spin_unlock_bh(&green_ap_ctx->lock);
+		green_ap_debug("enhanced green ap support is enabled");
+		return QDF_STATUS_SUCCESS;
+	}
+	qdf_spin_unlock_bh(&green_ap_ctx->lock);
+
+	return wlan_green_ap_state_mc(green_ap_ctx,
+				      WLAN_GREEN_AP_ADD_STA_EVENT);
 }
 
 QDF_STATUS wlan_green_ap_del_sta(struct wlan_objmgr_pdev *pdev)
 {
-	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
 
-	return status;
+	if (!pdev) {
+		green_ap_err("pdev context passed is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
+			pdev, WLAN_UMAC_COMP_GREEN_AP);
+	if (!green_ap_ctx) {
+		green_ap_err("green ap context obtained is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	green_ap_debug("Green AP del sta received");
+
+	qdf_spin_lock_bh(&green_ap_ctx->lock);
+	if (wlan_is_egap_enabled(green_ap_ctx)) {
+		qdf_spin_unlock_bh(&green_ap_ctx->lock);
+		green_ap_info("enhanced green ap support is enabled");
+		return QDF_STATUS_SUCCESS;
+	}
+	qdf_spin_unlock_bh(&green_ap_ctx->lock);
+
+	return wlan_green_ap_state_mc(green_ap_ctx,
+				      WLAN_GREEN_AP_DEL_STA_EVENT);
 }
diff --git a/umac/green_ap/dispatcher/src/wlan_green_ap_ucfg_api.c b/umac/green_ap/dispatcher/src/wlan_green_ap_ucfg_api.c
index 1abc91d..8997f05 100644
--- a/umac/green_ap/dispatcher/src/wlan_green_ap_ucfg_api.c
+++ b/umac/green_ap/dispatcher/src/wlan_green_ap_ucfg_api.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018 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
@@ -22,4 +22,209 @@
 
 #include <qdf_status.h>
 #include <wlan_green_ap_ucfg_api.h>
+#include <../../core/src/wlan_green_ap_main_i.h>
 
+QDF_STATUS ucfg_green_ap_update_user_config(
+			struct wlan_objmgr_pdev *pdev,
+			struct green_ap_user_cfg *green_ap_cfg)
+{
+	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
+	struct wlan_green_ap_egap_params *egap_params;
+
+	if (!pdev) {
+		green_ap_err("pdev context passed is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
+			pdev, WLAN_UMAC_COMP_GREEN_AP);
+	if (!green_ap_ctx) {
+		green_ap_err("green ap context obtained is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_spin_lock_bh(&green_ap_ctx->lock);
+	egap_params = &green_ap_ctx->egap_params;
+
+	egap_params->host_enable_egap = green_ap_cfg->host_enable_egap;
+	egap_params->egap_inactivity_time = green_ap_cfg->egap_inactivity_time;
+	egap_params->egap_wait_time = green_ap_cfg->egap_wait_time;
+	egap_params->egap_feature_flags = green_ap_cfg->egap_feature_flags;
+	qdf_spin_unlock_bh(&green_ap_ctx->lock);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_green_ap_enable_egap(struct wlan_objmgr_pdev *pdev)
+{
+	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
+	struct wlan_lmac_if_green_ap_tx_ops *green_ap_tx_ops;
+
+	if (!pdev) {
+		green_ap_err("pdev context passed is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
+			pdev, WLAN_UMAC_COMP_GREEN_AP);
+	if (!green_ap_ctx) {
+		green_ap_err("green ap context obtained is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	green_ap_tx_ops = wlan_psoc_get_green_ap_tx_ops(green_ap_ctx);
+	if (!green_ap_tx_ops) {
+		green_ap_err("green ap tx ops obtained are NULL");
+		return  QDF_STATUS_E_FAILURE;
+	}
+
+	if (!green_ap_tx_ops->enable_egap) {
+		green_ap_err("tx op for sending enbale/disable green ap is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return green_ap_tx_ops->enable_egap(pdev, &green_ap_ctx->egap_params);
+}
+
+QDF_STATUS ucfg_green_ap_target_config(struct wlan_objmgr_pdev *pdev,
+				       bool fw_egap_support)
+{
+	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
+
+	if (!pdev) {
+		green_ap_err("pdev context passed is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
+			pdev, WLAN_UMAC_COMP_GREEN_AP);
+	if (!green_ap_ctx) {
+		green_ap_err("green ap context obtained is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_spin_lock_bh(&green_ap_ctx->lock);
+	green_ap_ctx->egap_params.fw_egap_support = fw_egap_support;
+	qdf_spin_unlock_bh(&green_ap_ctx->lock);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_green_ap_set_ps_config(struct wlan_objmgr_pdev *pdev,
+				       uint8_t value)
+{
+	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
+
+	if (!pdev) {
+		green_ap_err("pdev context passed is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
+			pdev, WLAN_UMAC_COMP_GREEN_AP);
+	if (!green_ap_ctx) {
+		green_ap_err("green ap context obtained is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_spin_lock_bh(&green_ap_ctx->lock);
+	if (wlan_is_egap_enabled(green_ap_ctx)) {
+		qdf_spin_unlock_bh(&green_ap_ctx->lock);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	green_ap_ctx->ps_enable = value;
+	qdf_spin_unlock_bh(&green_ap_ctx->lock);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_green_ap_get_ps_config(struct wlan_objmgr_pdev *pdev,
+				       uint8_t *ps_enable)
+{
+	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
+
+	if (!pdev) {
+		green_ap_err("pdev context passed is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
+				pdev, WLAN_UMAC_COMP_GREEN_AP);
+
+	if (!green_ap_ctx) {
+		green_ap_err("green ap context obtained is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_spin_lock_bh(&green_ap_ctx->lock);
+	if (wlan_is_egap_enabled(green_ap_ctx)) {
+		qdf_spin_unlock_bh(&green_ap_ctx->lock);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	*ps_enable = green_ap_ctx->ps_enable;
+	qdf_spin_unlock_bh(&green_ap_ctx->lock);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_green_ap_set_transition_time(struct wlan_objmgr_pdev *pdev,
+					     uint32_t val)
+{
+	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
+
+	if (!pdev) {
+		green_ap_err("pdev context passed is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
+			pdev, WLAN_UMAC_COMP_GREEN_AP);
+
+	if (!green_ap_ctx) {
+		green_ap_err("green ap context obtained is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_spin_lock_bh(&green_ap_ctx->lock);
+	if (wlan_is_egap_enabled(green_ap_ctx)) {
+		qdf_spin_unlock_bh(&green_ap_ctx->lock);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	green_ap_ctx->ps_trans_time = val;
+	qdf_spin_unlock_bh(&green_ap_ctx->lock);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS ucfg_green_ap_get_transition_time(struct wlan_objmgr_pdev *pdev,
+					     uint32_t *ps_trans_time)
+{
+	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
+
+	if (!pdev) {
+		green_ap_err("pdev context passed is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
+			pdev, WLAN_UMAC_COMP_GREEN_AP);
+
+	if (!green_ap_ctx) {
+		green_ap_err("green ap context obtained is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_spin_lock_bh(&green_ap_ctx->lock);
+	if (wlan_is_egap_enabled(green_ap_ctx)) {
+		qdf_spin_unlock_bh(&green_ap_ctx->lock);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	*ps_trans_time = green_ap_ctx->ps_trans_time;
+	qdf_spin_unlock_bh(&green_ap_ctx->lock);
+
+	return QDF_STATUS_SUCCESS;
+}