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
wlan_green_ap_get_capab(struct wlan_objmgr_pdev * pdev)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 */
wlan_green_ap_pdev_obj_create_notification(struct wlan_objmgr_pdev * pdev,void * arg)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 */
wlan_green_ap_pdev_obj_destroy_notification(struct wlan_objmgr_pdev * pdev,void * arg)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
wlan_green_ap_init(void)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
wlan_green_ap_deinit(void)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 */
wlan_green_ap_set_bcn_mult(struct wlan_objmgr_pdev * pdev)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 */
wlan_green_ap_init_cmd_count(struct wlan_pdev_green_ap_ctx * green_ap_ctx)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
wlan_green_ap_set_bcn_mult(struct wlan_objmgr_pdev * pdev)263 static inline void wlan_green_ap_set_bcn_mult(struct wlan_objmgr_pdev *pdev)
264 {
265 }
266
267 static inline
wlan_green_ap_init_cmd_count(struct wlan_pdev_green_ap_ctx * green_ap_ctx)268 void wlan_green_ap_init_cmd_count(struct wlan_pdev_green_ap_ctx *green_ap_ctx)
269 {
270 }
271 #endif
272
wlan_green_ap_pdev_open(struct wlan_objmgr_pdev * pdev)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
wlan_green_ap_start(struct wlan_objmgr_pdev * pdev)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
wlan_green_ap_stop(struct wlan_objmgr_pdev * pdev)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
wlan_green_ap_add_sta(struct wlan_objmgr_pdev * pdev)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
wlan_green_ap_add_multistream_sta(struct wlan_objmgr_pdev * pdev)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
wlan_green_ap_del_sta(struct wlan_objmgr_pdev * pdev)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
wlan_green_ap_del_multistream_sta(struct wlan_objmgr_pdev * pdev)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
wlan_green_ap_is_ps_enabled(struct wlan_objmgr_pdev * pdev)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
wlan_green_ap_suspend_handle(struct wlan_objmgr_pdev * pdev)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
wlan_green_ap_is_ps_waiting(struct wlan_objmgr_pdev * pdev)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