xref: /wlan-dirver/qca-wifi-host-cmn/umac/green_ap/dispatcher/src/wlan_green_ap_api.c (revision 70a19e16789e308182f63b15c75decec7bf0b342)
1 /*
2  * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /**
21  * DOC: This file contains green ap north bound interface definitions
22  */
23 #include <wlan_green_ap_api.h>
24 #include <../../core/src/wlan_green_ap_main_i.h>
25 #include <wlan_objmgr_global_obj.h>
26 #include "cfg_green_ap_params.h"
27 #include "cfg_ucfg_api.h"
28 
29 QDF_STATUS wlan_green_ap_get_capab(
30 			struct wlan_objmgr_pdev *pdev)
31 {
32 	struct wlan_lmac_if_green_ap_tx_ops *green_ap_tx_ops;
33 	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
34 
35 	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(pdev,
36 					WLAN_UMAC_COMP_GREEN_AP);
37 
38 	if (!green_ap_ctx) {
39 		green_ap_err("green ap context obtained is NULL");
40 		return QDF_STATUS_E_FAILURE;
41 	}
42 
43 
44 	green_ap_tx_ops = wlan_psoc_get_green_ap_tx_ops(green_ap_ctx);
45 	if (!green_ap_tx_ops) {
46 		green_ap_err("green ap tx ops obtained are NULL");
47 		return QDF_STATUS_E_EXISTS;
48 	}
49 
50 	if (green_ap_tx_ops->get_capab)
51 		return green_ap_tx_ops->get_capab(pdev);
52 
53 	return QDF_STATUS_SUCCESS;
54 }
55 
56 /**
57  * wlan_green_ap_pdev_obj_create_notification() - called from objmgr when pdev
58  *                                                is created
59  * @pdev: pdev context
60  * @arg: argument
61  *
62  * This function gets called from object manager when pdev is being created and
63  * creates green ap context and attach it to objmgr.
64  *
65  * Return: QDF_STATUS_SUCCESS - in case of success
66  */
67 static QDF_STATUS wlan_green_ap_pdev_obj_create_notification(
68 			struct wlan_objmgr_pdev *pdev, void *arg)
69 {
70 	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
71 	QDF_STATUS status = QDF_STATUS_SUCCESS;
72 
73 	if (!pdev) {
74 		green_ap_err("pdev context passed is NULL");
75 		return QDF_STATUS_E_INVAL;
76 	}
77 
78 	green_ap_ctx = qdf_mem_malloc(sizeof(*green_ap_ctx));
79 	if (!green_ap_ctx)
80 		return QDF_STATUS_E_NOMEM;
81 
82 	green_ap_ctx->ps_state = WLAN_GREEN_AP_PS_IDLE_STATE;
83 	green_ap_ctx->ps_event = WLAN_GREEN_AP_PS_WAIT_EVENT;
84 	green_ap_ctx->ps_mode = WLAN_GREEN_AP_MODE_NO_STA;
85 	green_ap_ctx->num_nodes = 0;
86 	green_ap_ctx->num_nodes_multistream = 0;
87 	green_ap_ctx->ps_on_time = WLAN_GREEN_AP_PS_ON_TIME;
88 	green_ap_ctx->ps_trans_time = WLAN_GREEN_AP_PS_TRANS_TIME;
89 
90 	green_ap_ctx->pdev = pdev;
91 
92 	qdf_timer_init(NULL, &green_ap_ctx->ps_timer,
93 		       wlan_green_ap_timer_fn,
94 		       pdev, QDF_TIMER_TYPE_WAKE_APPS);
95 
96 	qdf_spinlock_create(&green_ap_ctx->lock);
97 	if (wlan_objmgr_pdev_component_obj_attach(pdev,
98 				WLAN_UMAC_COMP_GREEN_AP,
99 				green_ap_ctx, QDF_STATUS_SUCCESS)
100 			!= QDF_STATUS_SUCCESS) {
101 		green_ap_err("Failed to attach green ap ctx in pdev ctx");
102 		status = QDF_STATUS_E_FAILURE;
103 		goto err_pdev_attach;
104 	}
105 
106 	green_ap_info("Green AP creation successful, green ap ctx: %pK, pdev: %pK",
107 		      green_ap_ctx, pdev);
108 
109 	return QDF_STATUS_SUCCESS;
110 
111 err_pdev_attach:
112 	qdf_spinlock_destroy(&green_ap_ctx->lock);
113 	qdf_timer_free(&green_ap_ctx->ps_timer);
114 	qdf_mem_free(green_ap_ctx);
115 	return status;
116 }
117 
118 /**
119  * wlan_green_ap_pdev_obj_destroy_notification() - called from objmgr when
120  *                                                 pdev is destroyed
121  * @pdev: pdev context
122  * @arg: argument
123  *
124  * This function gets called from object manager when pdev is being destroyed
125  * and deletes green ap context and detach it from objmgr.
126  *
127  * Return: QDF_STATUS_SUCCESS - in case of success
128  */
129 static QDF_STATUS wlan_green_ap_pdev_obj_destroy_notification(
130 			struct wlan_objmgr_pdev *pdev, void *arg)
131 {
132 	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
133 
134 	if (!pdev) {
135 		green_ap_err("pdev context passed is NULL");
136 		return QDF_STATUS_E_INVAL;
137 	}
138 
139 	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
140 			pdev, WLAN_UMAC_COMP_GREEN_AP);
141 	if (!green_ap_ctx) {
142 		green_ap_err("green ap context is already NULL");
143 		return QDF_STATUS_E_FAILURE;
144 	}
145 
146 	green_ap_info("Deleting green ap pdev obj, green ap ctx: %pK, pdev: %pK",
147 		      green_ap_ctx, pdev);
148 
149 	if (wlan_objmgr_pdev_component_obj_detach(pdev,
150 				WLAN_UMAC_COMP_GREEN_AP, green_ap_ctx) !=
151 				QDF_STATUS_SUCCESS) {
152 		green_ap_err("Failed to detach green ap ctx in psoc ctx");
153 		return QDF_STATUS_E_FAILURE;
154 	}
155 
156 	qdf_timer_free(&green_ap_ctx->ps_timer);
157 	qdf_spinlock_destroy(&green_ap_ctx->lock);
158 
159 	qdf_mem_free(green_ap_ctx);
160 	green_ap_info("green ap deletion successful");
161 
162 	return QDF_STATUS_SUCCESS;
163 }
164 
165 QDF_STATUS wlan_green_ap_init(void)
166 {
167 	QDF_STATUS status = QDF_STATUS_SUCCESS;
168 
169 	status = wlan_objmgr_register_pdev_create_handler(
170 				WLAN_UMAC_COMP_GREEN_AP,
171 				wlan_green_ap_pdev_obj_create_notification,
172 				NULL);
173 	if (status != QDF_STATUS_SUCCESS) {
174 		green_ap_err("Failed to register green ap obj create handler");
175 		goto err_pdev_create;
176 	}
177 
178 	status = wlan_objmgr_register_pdev_destroy_handler(
179 				WLAN_UMAC_COMP_GREEN_AP,
180 				wlan_green_ap_pdev_obj_destroy_notification,
181 				NULL);
182 	if (status != QDF_STATUS_SUCCESS) {
183 		green_ap_err("Failed to register green ap obj destroy handler");
184 		goto err_pdev_delete;
185 	}
186 
187 	green_ap_info("Successfully registered create and destroy handlers with objmgr");
188 	return QDF_STATUS_SUCCESS;
189 
190 err_pdev_delete:
191 	wlan_objmgr_unregister_pdev_create_handler(
192 				WLAN_UMAC_COMP_GREEN_AP,
193 				wlan_green_ap_pdev_obj_create_notification,
194 				NULL);
195 err_pdev_create:
196 	return status;
197 }
198 
199 QDF_STATUS wlan_green_ap_deinit(void)
200 {
201 	if (wlan_objmgr_unregister_pdev_create_handler(
202 				WLAN_UMAC_COMP_GREEN_AP,
203 				wlan_green_ap_pdev_obj_create_notification,
204 				NULL)
205 			!= QDF_STATUS_SUCCESS) {
206 		return QDF_STATUS_E_FAILURE;
207 	}
208 
209 	if (wlan_objmgr_unregister_pdev_destroy_handler(
210 				WLAN_UMAC_COMP_GREEN_AP,
211 				wlan_green_ap_pdev_obj_destroy_notification,
212 				NULL)
213 			!= QDF_STATUS_SUCCESS) {
214 		return QDF_STATUS_E_FAILURE;
215 	}
216 
217 	green_ap_info("Successfully unregistered create and destroy handlers with objmgr");
218 	return QDF_STATUS_SUCCESS;
219 }
220 
221 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE
222 /**
223  * wlan_green_ap_set_bcn_mult() - API to set Green AP beacon
224  * multiplier
225  * @pdev: Pdev pointer
226  *
227  */
228 static void wlan_green_ap_set_bcn_mult(struct wlan_objmgr_pdev *pdev)
229 {
230 	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
231 	struct wlan_objmgr_psoc *psoc;
232 
233 	psoc = wlan_pdev_get_psoc(pdev);
234 
235 	if (!psoc) {
236 		green_ap_err("psoc is NULL");
237 		return;
238 	}
239 
240 	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
241 			pdev, WLAN_UMAC_COMP_GREEN_AP);
242 	if (!green_ap_ctx) {
243 		green_ap_err("green ap context obtained is NULL");
244 		return;
245 	}
246 
247 	green_ap_ctx->bcn_mult = cfg_get(psoc,
248 					 CFG_GAP_LL_PS_LOW_BEACON_MULT);
249 }
250 
251 /**
252  * wlan_green_ap_init_cmd_count() - Initialize command count.
253  * @green_ap_ctx: green ap ctx
254  */
255 static void wlan_green_ap_init_cmd_count(struct wlan_pdev_green_ap_ctx *green_ap_ctx)
256 {
257 	/* Disable cookie id will from 0,2,6,..*/
258 	qdf_atomic_init(&green_ap_ctx->ps_dis_cmd_cnt);
259 	/* Enable cookie id will be from 1,3,5,..*/
260 	qdf_atomic_set(&green_ap_ctx->ps_en_cmd_cnt, 1);
261 }
262 #else
263 static inline void wlan_green_ap_set_bcn_mult(struct wlan_objmgr_pdev *pdev)
264 {
265 }
266 
267 static inline
268 void wlan_green_ap_init_cmd_count(struct wlan_pdev_green_ap_ctx *green_ap_ctx)
269 {
270 }
271 #endif
272 
273 QDF_STATUS wlan_green_ap_pdev_open(struct wlan_objmgr_pdev *pdev)
274 {
275 	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
276 	struct wlan_objmgr_psoc *psoc;
277 
278 	if (!pdev) {
279 		green_ap_err("pdev is NULL");
280 		return QDF_STATUS_E_INVAL;
281 	}
282 
283 	psoc = wlan_pdev_get_psoc(pdev);
284 
285 	if (!psoc) {
286 		green_ap_err("psoc is NULL");
287 		return QDF_STATUS_E_INVAL;
288 	}
289 
290 	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
291 			pdev, WLAN_UMAC_COMP_GREEN_AP);
292 	if (!green_ap_ctx) {
293 		green_ap_err("green ap context obtained is NULL");
294 		return QDF_STATUS_E_FAILURE;
295 	}
296 
297 	qdf_spin_lock_bh(&green_ap_ctx->lock);
298 	green_ap_ctx->ps_enable = cfg_get(psoc,
299 					CFG_ENABLE_GREEN_AP_FEATURE);
300 	green_ap_ctx->egap_params.host_enable_egap = cfg_get(psoc,
301 					CFG_ENABLE_EGAP_FEATURE);
302 	green_ap_ctx->egap_params.egap_inactivity_time = cfg_get(psoc,
303 					CFG_EGAP_INACT_TIME_FEATURE);
304 	green_ap_ctx->egap_params.egap_wait_time = cfg_get(psoc,
305 					CFG_EGAP_WAIT_TIME_FEATURE);
306 	green_ap_ctx->egap_params.egap_feature_flags = cfg_get(psoc,
307 					CFG_EGAP_FLAGS_FEATURE);
308 
309 	wlan_green_ap_set_bcn_mult(pdev);
310 
311 	wlan_green_ap_init_cmd_count(green_ap_ctx);
312 
313 	qdf_spin_unlock_bh(&green_ap_ctx->lock);
314 
315 	return QDF_STATUS_SUCCESS;
316 }
317 
318 QDF_STATUS wlan_green_ap_start(struct wlan_objmgr_pdev *pdev)
319 {
320 	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
321 
322 	if (!pdev) {
323 		green_ap_err("pdev context passed is NULL");
324 		return QDF_STATUS_E_INVAL;
325 	}
326 
327 	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
328 			pdev, WLAN_UMAC_COMP_GREEN_AP);
329 	if (!green_ap_ctx) {
330 		green_ap_err("green ap context obtained is NULL");
331 		return QDF_STATUS_E_FAILURE;
332 	}
333 
334 	green_ap_debug("Green AP start received");
335 
336 	/* Make sure the start function does not get called 2 times */
337 	qdf_spin_lock_bh(&green_ap_ctx->lock);
338 
339 	if (wlan_is_egap_enabled(green_ap_ctx)) {
340 		qdf_spin_unlock_bh(&green_ap_ctx->lock);
341 		green_ap_debug("enhanced green ap support is enabled");
342 		return QDF_STATUS_SUCCESS;
343 	}
344 
345 	if (green_ap_ctx->ps_state == WLAN_GREEN_AP_PS_IDLE_STATE) {
346 		if (green_ap_ctx->ps_enable) {
347 			qdf_spin_unlock_bh(&green_ap_ctx->lock);
348 			return wlan_green_ap_state_mc(green_ap_ctx,
349 					      WLAN_GREEN_AP_PS_START_EVENT);
350 		}
351 	}
352 
353 	qdf_spin_unlock_bh(&green_ap_ctx->lock);
354 	return QDF_STATUS_E_ALREADY;
355 }
356 
357 QDF_STATUS wlan_green_ap_stop(struct wlan_objmgr_pdev *pdev)
358 {
359 	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
360 
361 	if (!pdev) {
362 		green_ap_err("pdev context passed is NULL");
363 		return QDF_STATUS_E_INVAL;
364 	}
365 
366 	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
367 			pdev, WLAN_UMAC_COMP_GREEN_AP);
368 	if (!green_ap_ctx) {
369 		green_ap_err("green ap context obtained is NULL");
370 		return QDF_STATUS_E_FAILURE;
371 	}
372 
373 	green_ap_debug("Green AP stop received");
374 
375 	qdf_spin_lock_bh(&green_ap_ctx->lock);
376 	if (wlan_is_egap_enabled(green_ap_ctx)) {
377 		qdf_spin_unlock_bh(&green_ap_ctx->lock);
378 		green_ap_debug("enhanced green ap support is enabled");
379 		return QDF_STATUS_SUCCESS;
380 	}
381 
382 	/* Delete the timer just to be sure */
383 	qdf_timer_stop(&green_ap_ctx->ps_timer);
384 
385 	/* Disable the power save */
386 	green_ap_ctx->ps_enable = WLAN_GREEN_AP_PS_DISABLE;
387 
388 	qdf_spin_unlock_bh(&green_ap_ctx->lock);
389 	return wlan_green_ap_state_mc(green_ap_ctx,
390 				      WLAN_GREEN_AP_PS_STOP_EVENT);
391 }
392 
393 QDF_STATUS wlan_green_ap_add_sta(struct wlan_objmgr_pdev *pdev)
394 {
395 	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
396 
397 	if (!pdev) {
398 		green_ap_err("pdev context passed is NULL");
399 		return QDF_STATUS_E_INVAL;
400 	}
401 
402 	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
403 			pdev, WLAN_UMAC_COMP_GREEN_AP);
404 	if (!green_ap_ctx) {
405 		green_ap_err("green ap context obtained is NULL");
406 		return QDF_STATUS_E_FAILURE;
407 	}
408 
409 	green_ap_debug("Green AP add sta received");
410 
411 	qdf_spin_lock_bh(&green_ap_ctx->lock);
412 	if (wlan_is_egap_enabled(green_ap_ctx)) {
413 		qdf_spin_unlock_bh(&green_ap_ctx->lock);
414 		green_ap_debug("enhanced green ap support is enabled");
415 		return QDF_STATUS_SUCCESS;
416 	}
417 	qdf_spin_unlock_bh(&green_ap_ctx->lock);
418 
419 	return wlan_green_ap_state_mc(green_ap_ctx,
420 				      WLAN_GREEN_AP_ADD_STA_EVENT);
421 }
422 
423 QDF_STATUS wlan_green_ap_add_multistream_sta(struct wlan_objmgr_pdev *pdev)
424 {
425 	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
426 
427 	if (!pdev) {
428 		green_ap_err("pdev context passed is NULL");
429 		return QDF_STATUS_E_INVAL;
430 	}
431 
432 	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
433 			pdev, WLAN_UMAC_COMP_GREEN_AP);
434 	if (!green_ap_ctx) {
435 		green_ap_err("green ap context obtained is NULL");
436 		return QDF_STATUS_E_FAILURE;
437 	}
438 
439 	green_ap_debug("Green AP add multistream sta received");
440 
441 	qdf_spin_lock_bh(&green_ap_ctx->lock);
442 	if (wlan_is_egap_enabled(green_ap_ctx)) {
443 		qdf_spin_unlock_bh(&green_ap_ctx->lock);
444 		green_ap_debug("enhanced green ap support is enabled");
445 		return QDF_STATUS_SUCCESS;
446 	}
447 	qdf_spin_unlock_bh(&green_ap_ctx->lock);
448 
449 	return wlan_green_ap_state_mc(green_ap_ctx,
450 			WLAN_GREEN_AP_ADD_MULTISTREAM_STA_EVENT);
451 }
452 
453 QDF_STATUS wlan_green_ap_del_sta(struct wlan_objmgr_pdev *pdev)
454 {
455 	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
456 
457 	if (!pdev) {
458 		green_ap_err("pdev context passed is NULL");
459 		return QDF_STATUS_E_INVAL;
460 	}
461 
462 	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
463 			pdev, WLAN_UMAC_COMP_GREEN_AP);
464 	if (!green_ap_ctx) {
465 		green_ap_err("green ap context obtained is NULL");
466 		return QDF_STATUS_E_FAILURE;
467 	}
468 
469 	green_ap_debug("Green AP del sta received");
470 
471 	qdf_spin_lock_bh(&green_ap_ctx->lock);
472 	if (wlan_is_egap_enabled(green_ap_ctx)) {
473 		qdf_spin_unlock_bh(&green_ap_ctx->lock);
474 		green_ap_debug("enhanced green ap support is enabled");
475 		return QDF_STATUS_SUCCESS;
476 	}
477 	qdf_spin_unlock_bh(&green_ap_ctx->lock);
478 
479 	return wlan_green_ap_state_mc(green_ap_ctx,
480 				      WLAN_GREEN_AP_DEL_STA_EVENT);
481 }
482 
483 QDF_STATUS wlan_green_ap_del_multistream_sta(struct wlan_objmgr_pdev *pdev)
484 {
485 	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
486 
487 	if (!pdev) {
488 		green_ap_err("pdev context passed is NULL");
489 		return QDF_STATUS_E_INVAL;
490 	}
491 
492 	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
493 			pdev, WLAN_UMAC_COMP_GREEN_AP);
494 	if (!green_ap_ctx) {
495 		green_ap_err("green ap context obtained is NULL");
496 		return QDF_STATUS_E_FAILURE;
497 	}
498 
499 	green_ap_debug("Green AP del multistream sta received");
500 
501 	qdf_spin_lock_bh(&green_ap_ctx->lock);
502 	if (wlan_is_egap_enabled(green_ap_ctx)) {
503 		qdf_spin_unlock_bh(&green_ap_ctx->lock);
504 		green_ap_info("enhanced green ap support is enabled");
505 		return QDF_STATUS_SUCCESS;
506 	}
507 	qdf_spin_unlock_bh(&green_ap_ctx->lock);
508 
509 	return wlan_green_ap_state_mc(green_ap_ctx,
510 			WLAN_GREEN_AP_DEL_MULTISTREAM_STA_EVENT);
511 }
512 
513 bool wlan_green_ap_is_ps_enabled(struct wlan_objmgr_pdev *pdev)
514 {
515 	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
516 
517 	if (!pdev) {
518 		green_ap_err("pdev context passed is NULL");
519 		return QDF_STATUS_E_INVAL;
520 	}
521 
522 	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
523 			pdev, WLAN_UMAC_COMP_GREEN_AP);
524 	if (!green_ap_ctx) {
525 		green_ap_err("green ap context obtained is NULL");
526 		return QDF_STATUS_E_FAILURE;
527 	}
528 
529 	if ((green_ap_ctx->ps_state == WLAN_GREEN_AP_PS_ON_STATE) &&
530 			(green_ap_ctx->ps_enable))
531 		return true;
532 
533 	return false;
534 
535 }
536 
537 void wlan_green_ap_suspend_handle(struct wlan_objmgr_pdev *pdev)
538 {
539 	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
540 
541 	if (!pdev) {
542 		green_ap_err("pdev context passed is NULL");
543 		return;
544 	}
545 
546 	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
547 				pdev, WLAN_UMAC_COMP_GREEN_AP);
548 
549 	if (!green_ap_ctx) {
550 		green_ap_err("green ap context obtained is NULL");
551 		return;
552 	}
553 
554 	wlan_green_ap_stop(pdev);
555 
556 	green_ap_ctx->ps_enable = WLAN_GREEN_AP_PS_SUSPEND;
557 }
558 
559 bool wlan_green_ap_is_ps_waiting(struct wlan_objmgr_pdev *pdev)
560 {
561 	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
562 
563 	if (!pdev) {
564 		green_ap_err("pdev context passed is NULL");
565 		return QDF_STATUS_E_INVAL;
566 	}
567 
568 	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
569 			pdev, WLAN_UMAC_COMP_GREEN_AP);
570 	if (!green_ap_ctx) {
571 		green_ap_err("green ap context obtained is NULL");
572 		return QDF_STATUS_E_FAILURE;
573 	}
574 
575 	if ((green_ap_ctx->ps_state == WLAN_GREEN_AP_PS_WAIT_STATE) &&
576 	    (green_ap_ctx->ps_enable)) {
577 		return true;
578 	}
579 
580 	return false;
581 }
582