qcacmn: Greenap componentization follow up patch

Greenap APIs and calls

Change-Id: I1242db788155f68dd91b72b94a48f78869eb835f
CRs-Fixed: 2142183
diff --git a/spectral/Kbuild b/spectral/Kbuild
index 6d7469e..4fbd8d4 100644
--- a/spectral/Kbuild
+++ b/spectral/Kbuild
@@ -30,6 +30,10 @@
 INCS += -I$(obj)/$(DEPTH)/cmn_dev/umac/cmn_services/crypto/inc
 endif
 
+ifeq ($(WLAN_SUPPORT_GREEN_AP), 1)
+INCS += -I$(obj)/$(DEPTH)/cmn_dev/umac/green_ap/dispatcher/inc
+endif
+
 #Start of offload related deifines
 HOST_CMN_CONVG_SRC := $(DEPTH)/cmn_dev
 HOST_CMN_CONVG_HIF_SRC := $(DEPTH)/cmn_dev/hif/src
diff --git a/target_if/green_ap/inc/target_if_green_ap.h b/target_if/green_ap/inc/target_if_green_ap.h
index 7ca5809..4666606 100644
--- a/target_if/green_ap/inc/target_if_green_ap.h
+++ b/target_if/green_ap/inc/target_if_green_ap.h
@@ -58,4 +58,30 @@
  */
 QDF_STATUS target_if_green_ap_set_ps_on_off(struct wlan_objmgr_pdev *pdev,
 					    bool value, uint8_t pdev_id);
+
+/**
+ * target_if_green_ap_get_current_channel() - Get current channel
+ * @pdev: pdev pointer
+ *
+ * @Return: current channel freq
+ */
+uint16_t target_if_green_ap_get_current_channel(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * target_if_green_ap_get_current_channel_flags() - Get current channel flags
+ * @pdev: pdev pointer
+ *
+ * @Return: current channel flags
+ */
+uint64_t target_if_green_ap_get_current_channel_flags(
+				struct wlan_objmgr_pdev *pdev);
+
+/**
+ * target_if_green_ap_reset_dev() - Reset dev
+ * @pdev: pdev pointer
+ *
+ * @Return:  QDF_STATUS_SUCCESS if device resetted
+ */
+QDF_STATUS target_if_green_ap_reset_dev(struct wlan_objmgr_pdev *pdev);
+
 #endif
diff --git a/target_if/green_ap/src/target_if_green_ap.c b/target_if/green_ap/src/target_if_green_ap.c
index 4d51a19..185bca7 100644
--- a/target_if/green_ap/src/target_if_green_ap.c
+++ b/target_if/green_ap/src/target_if_green_ap.c
@@ -40,6 +40,10 @@
 
 	green_ap_tx_ops->enable_egap = target_if_green_ap_enable_egap;
 	green_ap_tx_ops->ps_on_off_send = target_if_green_ap_set_ps_on_off;
+	green_ap_tx_ops->reset_dev = NULL;
+	green_ap_tx_ops->get_current_channel = NULL;
+	green_ap_tx_ops->get_current_channel_flags = NULL;
+	green_ap_tx_ops->get_capab = NULL;
 
 	return QDF_STATUS_SUCCESS;
 }
diff --git a/umac/cmn_services/utils/inc/wlan_utility.h b/umac/cmn_services/utils/inc/wlan_utility.h
index d797ff8..68ce960 100644
--- a/umac/cmn_services/utils/inc/wlan_utility.h
+++ b/umac/cmn_services/utils/inc/wlan_utility.h
@@ -158,4 +158,13 @@
  * @id: vdev's interface name
  */
 uint8_t *wlan_util_vdev_get_if_name(struct wlan_objmgr_vdev *vdev);
+
+/*
+ * wlan_util_is_vap_active() - Check for vap active
+ * @pdev: pdev pointer
+ *
+ * @Return: QDF_STATUS_SUCCESS in case of vap active
+ */
+QDF_STATUS wlan_util_is_vap_active(struct wlan_objmgr_pdev *pdev);
+
 #endif /* _WLAN_UTILITY_H_ */
diff --git a/umac/cmn_services/utils/src/wlan_utility.c b/umac/cmn_services/utils/src/wlan_utility.c
index b8bf766..15a9e66 100644
--- a/umac/cmn_services/utils/src/wlan_utility.c
+++ b/umac/cmn_services/utils/src/wlan_utility.c
@@ -237,3 +237,36 @@
 	return name;
 }
 EXPORT_SYMBOL(wlan_util_vdev_get_if_name);
+
+static void wlan_vap_active(struct wlan_objmgr_pdev *pdev,
+			void *object,
+			void *arg)
+{
+	struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object;
+	uint8_t *flag = (uint8_t *)arg;
+
+	wlan_vdev_obj_lock(vdev);
+	if ((wlan_vdev_mlme_get_state(vdev) == WLAN_VDEV_S_RUN) ||
+		(wlan_vdev_mlme_get_state(vdev) == WLAN_VDEV_S_DFS_WAIT)) {
+		*flag = 1;
+	}
+	wlan_vdev_obj_unlock(vdev);
+}
+
+QDF_STATUS wlan_util_is_vap_active(struct wlan_objmgr_pdev *pdev)
+{
+	uint8_t flag = 0;
+
+	if (!pdev)
+		return QDF_STATUS_E_INVAL;
+
+	wlan_objmgr_pdev_iterate_obj_list(pdev,
+				WLAN_VDEV_OP,
+				wlan_vap_active,
+				&flag, 0, WLAN_OBJMGR_ID);
+
+	if (flag == 1)
+		return QDF_STATUS_SUCCESS;
+
+	return QDF_STATUS_E_INVAL;
+}
diff --git a/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_api.h b/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_api.h
index 812c523..578a6fc 100644
--- a/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_api.h
+++ b/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_api.h
@@ -101,6 +101,25 @@
 	return &psoc->soc_cb.rx_ops.reg_rx_ops;
 }
 
+#ifdef WLAN_SUPPORT_GREEN_AP
+/**
+ * wlan_lmac_if_get_green_ap_rx_ops() - retrieve the green ap rx_ops
+ * @psoc: psoc context
+ *
+ * API to retrieve the dfs rx_ops from the psoc context
+ *
+ * Return: green_ap_rx_ops pointer
+ */
+static inline struct wlan_lmac_if_green_ap_rx_ops *
+wlan_lmac_if_get_green_ap_rx_ops(struct wlan_objmgr_psoc *psoc)
+{
+	if (!psoc)
+		return NULL;
+
+	return &psoc->soc_cb.rx_ops.green_ap_rx_ops;
+}
+#endif
+
 /**
  * mgmt_txrx_get_nbuf() - retrieve nbuf from mgmt desc_id
  * @pdev: pdev context
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 efc9dcc..f397d1b 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
@@ -552,6 +552,10 @@
 				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);
+	QDF_STATUS (*reset_dev)(struct wlan_objmgr_pdev *pdev);
+	uint16_t (*get_current_channel)(struct wlan_objmgr_pdev *pdev);
+	uint64_t (*get_current_channel_flags)(struct wlan_objmgr_pdev *pdev);
+	QDF_STATUS (*get_capab)(struct  wlan_objmgr_pdev *pdev);
 };
 #endif
 
@@ -997,6 +1001,17 @@
 			uint8_t vdev_id);
 	void (*wlan_mlme_end_scan)(struct wlan_objmgr_pdev *pdev);
 };
+
+#ifdef WLAN_SUPPORT_GREEN_AP
+struct wlan_lmac_if_green_ap_rx_ops {
+	bool (*is_ps_enabled)(struct wlan_objmgr_pdev *pdev);
+	bool (*is_dbg_print_enabled)(struct wlan_objmgr_pdev *pdev);
+	QDF_STATUS (*ps_get)(struct wlan_objmgr_pdev *pdev, uint8_t *value);
+	QDF_STATUS (*ps_set)(struct wlan_objmgr_pdev *pdev, uint8_t value);
+	void (*suspend_handle)(struct wlan_objmgr_pdev *pdev);
+};
+#endif
+
 /**
  * struct wlan_lmac_if_rx_ops - south bound rx function pointers
  * @mgmt_txrx_tx_ops: mgmt txrx rx ops
@@ -1044,6 +1059,9 @@
 	struct wlan_lmac_if_tdls_rx_ops tdls_rx_ops;
 #endif
 	struct wlan_lmac_if_mlme_rx_ops mops;
+#ifdef WLAN_SUPPORT_GREEN_AP
+	struct wlan_lmac_if_green_ap_rx_ops green_ap_rx_ops;
+#endif
 };
 
 /* Function pointer to call legacy tx_ops registration in OL/WMA.
diff --git a/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c b/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c
index 71c97de..054b0d6 100644
--- a/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c
+++ b/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c
@@ -50,6 +50,10 @@
 #include <wlan_dfs_tgt_api.h>
 #include <wlan_dfs_utils_api.h>
 #endif
+#ifdef WLAN_SUPPORT_GREEN_AP
+#include <wlan_green_ap_api.h>
+#include <wlan_green_ap_ucfg_api.h>
+#endif
 
 /* Function pointer for OL/WMA specific UMAC tx_ops
  * registration.
@@ -286,6 +290,27 @@
 }
 #endif
 
+#ifdef WLAN_SUPPORT_GREEN_AP
+static QDF_STATUS
+wlan_lmac_if_umac_green_ap_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops)
+{
+	rx_ops->green_ap_rx_ops.is_ps_enabled = wlan_green_ap_is_ps_enabled;
+	rx_ops->green_ap_rx_ops.is_dbg_print_enabled =
+					ucfg_green_ap_get_debug_prints;
+	rx_ops->green_ap_rx_ops.ps_set = ucfg_green_ap_set_ps_config;
+	rx_ops->green_ap_rx_ops.ps_get = ucfg_green_ap_get_ps_config;
+	rx_ops->green_ap_rx_ops.suspend_handle = wlan_green_ap_suspend_handle;
+
+	return QDF_STATUS_SUCCESS;
+}
+#else
+static QDF_STATUS
+wlan_lmac_if_umac_green_ap_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
 /**
  * wlan_lmac_if_umac_rx_ops_register() - UMAC rx handler register
  * @rx_ops: Pointer to rx_ops structure to be populated
@@ -349,6 +374,8 @@
 	/* DFS rx_ops */
 	wlan_lmac_if_umac_dfs_rx_ops_register(rx_ops);
 
+	wlan_lmac_if_umac_green_ap_rx_ops_register(rx_ops);
+
 	return QDF_STATUS_SUCCESS;
 }
 
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 999b5b7..542069c 100644
--- a/umac/green_ap/core/src/wlan_green_ap_main.c
+++ b/umac/green_ap/core/src/wlan_green_ap_main.c
@@ -22,6 +22,48 @@
 
 #include "wlan_green_ap_main_i.h"
 
+/*
+ * wlan_green_ap_ant_ps_reset() - Reset function
+ * @green_ap - green ap context
+ *
+ * Reset fiunction, so that Antenna Mask can come into effect.
+ *                This applies for only few of the hardware chips
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS wlan_green_ap_ant_ps_reset
+		(struct wlan_pdev_green_ap_ctx *green_ap_ctx)
+{
+	struct wlan_lmac_if_green_ap_tx_ops *green_ap_tx_ops;
+	struct wlan_objmgr_pdev *pdev;
+
+	if (!green_ap_ctx) {
+		green_ap_err("green ap context obtained is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	pdev = 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->reset_dev)
+		return QDF_STATUS_SUCCESS;
+
+	/*
+	 * Add protection against green AP enabling interrupts
+	 * when not valid or no VAPs exist
+	 */
+	if (wlan_util_is_vap_active(pdev) == QDF_STATUS_SUCCESS)
+		green_ap_tx_ops->reset_dev(pdev);
+	else
+		green_ap_err("Green AP tried to enable IRQs when invalid");
+
+	return QDF_STATUS_SUCCESS;
+}
+
 struct wlan_lmac_if_green_ap_tx_ops *
 wlan_psoc_get_green_ap_tx_ops(struct wlan_pdev_green_ap_ctx *green_ap_ctx)
 {
@@ -58,6 +100,7 @@
 		return true;
 	return false;
 }
+qdf_export_symbol(wlan_is_egap_enabled);
 
 /**
  * wlan_green_ap_ps_event_state_update() - Update PS state and event
@@ -89,6 +132,13 @@
 	struct wlan_lmac_if_green_ap_tx_ops *green_ap_tx_ops;
 	uint8_t pdev_id;
 
+	/*
+	 * Remove the assignments once channel info is available for
+	 * converged component.
+	 */
+	uint16_t channel = 1;
+	uint32_t channel_flags = 1;
+
 	if (!green_ap_ctx) {
 		green_ap_err("green ap context obtained is NULL");
 		return QDF_STATUS_E_FAILURE;
@@ -113,6 +163,14 @@
 
 	qdf_spin_lock_bh(&green_ap_ctx->lock);
 
+	if (green_ap_tx_ops->get_current_channel)
+		channel = green_ap_tx_ops->get_current_channel(
+						green_ap_ctx->pdev);
+
+	if (green_ap_tx_ops->get_current_channel_flags)
+		channel_flags = green_ap_tx_ops->get_current_channel_flags(
+							green_ap_ctx->pdev);
+
 	/* handle the green ap ps event */
 	switch (event) {
 	case WLAN_GREEN_AP_ADD_STA_EVENT:
@@ -145,9 +203,12 @@
 				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");
+		if (green_ap_ctx->ps_state == WLAN_GREEN_AP_PS_ON_STATE) {
+			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");
+			wlan_green_ap_ant_ps_reset(green_ap_ctx);
+		}
 		goto done;
 	}
 
@@ -187,17 +248,28 @@
 
 	case WLAN_GREEN_AP_PS_WAIT_STATE:
 		if (!green_ap_ctx->num_nodes) {
-			wlan_green_ap_ps_event_state_update(
+			if ((channel == 0) || (channel_flags == 0)) {
+			/*
+			 * Stay in the current state and restart the
+			 * timer to check later.
+			 */
+				qdf_timer_start(&green_ap_ctx->ps_timer,
+					green_ap_ctx->ps_on_time);
+			} else {
+				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_info("Transition to ON from WAIT");
+				green_ap_tx_ops->ps_on_off_send(
+					green_ap_ctx->pdev, true, pdev_id);
+				wlan_green_ap_ant_ps_reset(green_ap_ctx);
+
+				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);
@@ -216,6 +288,7 @@
 				green_ap_err("Failed to set Green AP mode");
 				goto done;
 			}
+			wlan_green_ap_ant_ps_reset(green_ap_ctx);
 			green_ap_info("Transition to OFF from ON\n");
 			wlan_green_ap_ps_event_state_update(
 						green_ap_ctx,
@@ -236,6 +309,7 @@
 				goto done;
 			}
 
+			wlan_green_ap_ant_ps_reset(green_ap_ctx);
 			green_ap_info("Transition to WAIT from ON\n");
 			qdf_timer_start(&green_ap_ctx->ps_timer,
 					green_ap_ctx->ps_trans_time);
@@ -275,3 +349,17 @@
 	wlan_green_ap_state_mc(green_ap_ctx, green_ap_ctx->ps_event);
 }
 
+void wlan_green_ap_check_mode(struct wlan_objmgr_pdev *pdev,
+		void *object,
+		void *arg)
+{
+	struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object;
+	uint8_t *flag = (uint8_t *)arg;
+
+	wlan_vdev_obj_lock(vdev);
+	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_SAP_MODE)
+		*flag = 1;
+
+	wlan_vdev_obj_unlock(vdev);
+}
+
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 3e387ad..9a98cec 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
@@ -30,6 +30,8 @@
 #include <qdf_types.h>
 #include <qdf_status.h>
 #include <qdf_timer.h>
+#include "wlan_utility.h"
+#include <qdf_module.h>
 
 #define WLAN_GREEN_AP_PS_ON_TIME        (0)
 #define WLAN_GREEN_AP_PS_TRANS_TIME     (20)
@@ -52,6 +54,9 @@
 #define green_ap_debug(format, args...) \
 		green_ap_logfl(QDF_TRACE_LEVEL_DEBUG, format, ## args)
 
+#define WLAN_GREEN_AP_PS_DISABLE 0
+#define WLAN_GREEN_AP_PS_ENABLE 1
+#define WLAN_GREEN_AP_PS_SUSPEND 2
 /**
  * enum wlan_green_ap_ps_state - PS states
  * @WLAN_GREEN_AP_PS_IDLE_STATE - Idle
@@ -108,6 +113,7 @@
 	qdf_timer_t ps_timer;
 	qdf_spinlock_t lock;
 	struct wlan_green_ap_egap_params egap_params;
+	bool dbg_enable;
 };
 
 /**
@@ -144,4 +150,18 @@
  * @Return: None
  */
 void wlan_green_ap_timer_fn(void *pdev);
+
+/**
+ * wlan_green_ap_check_mode() - Check for mode
+ * @pdev: pdev pointer
+ * @object:  vdev object
+ * @arg: flag to be set
+ *
+ * Callback to check if all modes on radio are configured as AP
+ *
+ * @Return: None
+ */
+void wlan_green_ap_check_mode(struct wlan_objmgr_pdev *pdev,
+		void *object,
+		void *arg);
 #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 b4632c2..c94001c 100644
--- a/umac/green_ap/dispatcher/inc/wlan_green_ap_api.h
+++ b/umac/green_ap/dispatcher/inc/wlan_green_ap_api.h
@@ -96,4 +96,30 @@
  * Return: Success or Failure
  */
 QDF_STATUS wlan_green_ap_del_sta(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * wlan_green_ap_is_ps_enabled() - is power save enabled
+ * @pdev: pdev pointer
+ *
+ * Check if power save is enabled in FW
+ *
+ * Return: Success or Failure
+ */
+bool wlan_green_ap_is_ps_enabled(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * wlan_green_ap_suspend_handle() - handle driver suspend
+ * @pdev: pdev pointer
+ *
+ * Return: None
+ */
+void wlan_green_ap_suspend_handle(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * wlan_green_ap_get_capab() - get lmac capability
+ * @pdev: pdev pointer
+ *
+ * Return: Appropriate status
+ */
+QDF_STATUS wlan_green_ap_get_capab(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 2ad95ae..8d8dde1 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
@@ -26,6 +26,7 @@
 #include <wlan_objmgr_cmn.h>
 #include <wlan_objmgr_pdev_obj.h>
 #include <qdf_status.h>
+#include "wlan_utility.h"
 
 /**
  * struct green_ap_user_cfg - green ap user cfg
@@ -116,4 +117,28 @@
 QDF_STATUS ucfg_green_ap_get_transition_time(struct wlan_objmgr_pdev *pdev,
 					     uint32_t *ps_trans_time);
 
+/**
+ * ucfg_green_ap_config() - Config green AP
+ * @pdev: pdev pointer
+ *
+ * Return: Success or Failure
+ */
+QDF_STATUS ucfg_green_ap_config(struct wlan_objmgr_pdev *pdev, uint8_t val);
+
+/**
+ * ucfg_green_ap_enable_debug_prints() - Enable debugs
+ * @pdev: pdev pointer
+ *
+ * Return: None
+ */
+void ucfg_green_ap_enable_debug_prints(struct wlan_objmgr_pdev *pdev,
+					uint32_t val);
+
+/**
+ * ucfg_green_ap_get_debug_prints() - Check if debug enabled
+ * @pdev: pdev pointer
+ *
+ * Return: Debug value
+ */
+bool ucfg_green_ap_get_debug_prints(struct wlan_objmgr_pdev *pdev);
 #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 4d3c82e..d396e89 100644
--- a/umac/green_ap/dispatcher/src/wlan_green_ap_api.c
+++ b/umac/green_ap/dispatcher/src/wlan_green_ap_api.c
@@ -23,6 +23,33 @@
 #include <../../core/src/wlan_green_ap_main_i.h>
 #include <wlan_objmgr_global_obj.h>
 
+QDF_STATUS wlan_green_ap_get_capab(
+			struct wlan_objmgr_pdev *pdev)
+{
+	struct wlan_lmac_if_green_ap_tx_ops *green_ap_tx_ops;
+	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
+
+	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_EXISTS;
+	}
+
+	if (green_ap_tx_ops->get_capab)
+		return green_ap_tx_ops->get_capab(pdev);
+
+	return QDF_STATUS_SUCCESS;
+}
+
 /**
  * wlan_green_ap_pdev_obj_create_notification() - called from objmgr when pdev
  *                                                is created
@@ -246,7 +273,6 @@
 	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");
@@ -257,7 +283,7 @@
 	qdf_timer_stop(&green_ap_ctx->ps_timer);
 
 	/* Disable the power save */
-	green_ap_ctx->ps_enable = 0;
+	green_ap_ctx->ps_enable = WLAN_GREEN_AP_PS_DISABLE;
 
 	qdf_spin_unlock_bh(&green_ap_ctx->lock);
 	return wlan_green_ap_state_mc(green_ap_ctx,
@@ -323,3 +349,49 @@
 	return wlan_green_ap_state_mc(green_ap_ctx,
 				      WLAN_GREEN_AP_DEL_STA_EVENT);
 }
+
+bool wlan_green_ap_is_ps_enabled(struct wlan_objmgr_pdev *pdev)
+{
+	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;
+	}
+
+	if ((green_ap_ctx->ps_state == WLAN_GREEN_AP_PS_ON_STATE) &&
+			(green_ap_ctx->ps_enable))
+		return true;
+
+	return false;
+
+}
+
+void wlan_green_ap_suspend_handle(struct wlan_objmgr_pdev *pdev)
+{
+	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
+
+	if (!pdev) {
+		green_ap_err("pdev context passed is NULL");
+		return;
+	}
+
+	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;
+	}
+
+	wlan_green_ap_stop(pdev);
+
+	green_ap_ctx->ps_enable = WLAN_GREEN_AP_PS_SUSPEND;
+}
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 8997f05..423b663 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
@@ -228,3 +228,76 @@
 
 	return QDF_STATUS_SUCCESS;
 }
+
+QDF_STATUS ucfg_green_ap_config(struct wlan_objmgr_pdev *pdev, uint8_t val)
+{
+
+	uint8_t flag;
+
+	if (wlan_green_ap_get_capab(pdev) == QDF_STATUS_E_NOSUPPORT) {
+		green_ap_err("GreenAP not supported on radio\n");
+		return QDF_STATUS_E_NOSUPPORT;
+	}
+
+	if (val) {
+	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
+		wlan_objmgr_pdev_iterate_obj_list(pdev,
+					WLAN_VDEV_OP,
+					wlan_green_ap_check_mode,
+					&flag, 0, WLAN_OBJMGR_ID);
+		if (flag == 1) {
+			green_ap_err("Radio not in AP mode."
+					"Feature not supported");
+			return QDF_STATUS_E_NOSUPPORT;
+		}
+
+		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_NOSUPPORT;
+		}
+
+		ucfg_green_ap_set_ps_config(pdev, val);
+
+		if (wlan_util_is_vap_active(pdev) == QDF_STATUS_SUCCESS)
+			wlan_green_ap_start(pdev);
+	} else {
+		wlan_green_ap_stop(pdev);
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void ucfg_green_ap_enable_debug_prints(struct wlan_objmgr_pdev *pdev,
+				uint32_t val)
+{
+	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
+
+	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;
+	}
+
+	green_ap_ctx->dbg_enable = val;
+}
+
+bool ucfg_green_ap_get_debug_prints(struct wlan_objmgr_pdev *pdev)
+{
+	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
+
+	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 false;
+	}
+
+	return green_ap_ctx->dbg_enable;
+}
+