1 /*
2 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2023-2024 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 * DOC: define utility API related to the pmo component
21 * called by other components
22 */
23
24 #include "wlan_pmo_obj_mgmt_api.h"
25 #include "wlan_pmo_tgt_api.h"
26 #include "wlan_pmo_static_config.h"
27 #include "wlan_pmo_main.h"
28 #include "target_if_pmo.h"
29
pmo_init(void)30 QDF_STATUS pmo_init(void)
31 {
32 QDF_STATUS status;
33 struct wlan_pmo_ctx *pmo_ctx;
34
35 pmo_enter();
36 if (pmo_allocate_ctx() != QDF_STATUS_SUCCESS) {
37 pmo_err("unable to allocate psoc ctx");
38 status = QDF_STATUS_E_FAULT;
39 goto out;
40 }
41
42 pmo_ctx = pmo_get_context();
43 if (!pmo_ctx) {
44 pmo_err("unable to get pmo ctx");
45 status = QDF_STATUS_E_INVAL;
46 goto out;
47 }
48
49 status = wlan_objmgr_register_psoc_create_handler(
50 WLAN_UMAC_COMP_PMO,
51 pmo_psoc_object_created_notification,
52 (void *)pmo_ctx);
53 if (status != QDF_STATUS_SUCCESS) {
54 pmo_err("unable to register psoc create handle");
55 goto out;
56 }
57
58 status = wlan_objmgr_register_psoc_destroy_handler(
59 WLAN_UMAC_COMP_PMO,
60 pmo_psoc_object_destroyed_notification,
61 (void *)pmo_ctx);
62 if (status != QDF_STATUS_SUCCESS) {
63 pmo_err("unable to register psoc create handle");
64 goto out;
65 }
66
67 status = wlan_objmgr_register_vdev_create_handler(
68 WLAN_UMAC_COMP_PMO,
69 pmo_vdev_object_created_notification,
70 (void *)pmo_ctx);
71 if (status != QDF_STATUS_SUCCESS) {
72 pmo_err("unable to register vdev create handle");
73 goto out;
74 }
75
76 status = wlan_objmgr_register_vdev_destroy_handler(
77 WLAN_UMAC_COMP_PMO,
78 pmo_vdev_object_destroyed_notification,
79 (void *)pmo_ctx);
80 if (status != QDF_STATUS_SUCCESS)
81 pmo_err("unable to register vdev create handle");
82 out:
83 pmo_exit();
84
85 return status;
86 }
87
pmo_deinit(void)88 QDF_STATUS pmo_deinit(void)
89 {
90 QDF_STATUS status;
91 struct wlan_pmo_ctx *pmo_ctx;
92
93 pmo_enter();
94 pmo_ctx = pmo_get_context();
95 if (!pmo_ctx) {
96 pmo_err("unable to get pmo ctx");
97 status = QDF_STATUS_E_FAILURE;
98 goto out;
99 }
100
101 status = wlan_objmgr_unregister_psoc_create_handler(
102 WLAN_UMAC_COMP_PMO,
103 pmo_psoc_object_created_notification,
104 (void *)pmo_ctx);
105 if (status != QDF_STATUS_SUCCESS) {
106 pmo_err("unable to unregister psoc create handle");
107 goto out;
108 }
109
110 status = wlan_objmgr_unregister_psoc_destroy_handler(
111 WLAN_UMAC_COMP_PMO,
112 pmo_psoc_object_destroyed_notification,
113 (void *)pmo_ctx);
114 if (status != QDF_STATUS_SUCCESS) {
115 pmo_err("unable to unregister psoc create handle");
116 goto out;
117 }
118
119 status = wlan_objmgr_unregister_vdev_create_handler(
120 WLAN_UMAC_COMP_PMO,
121 pmo_vdev_object_created_notification,
122 (void *)pmo_ctx);
123 if (status != QDF_STATUS_SUCCESS) {
124 pmo_err("unable to unregister vdev create handle");
125 goto out;
126 }
127
128 status = wlan_objmgr_unregister_vdev_destroy_handler(
129 WLAN_UMAC_COMP_PMO,
130 pmo_vdev_object_destroyed_notification,
131 (void *)pmo_ctx);
132 if (status != QDF_STATUS_SUCCESS) {
133 pmo_err("unable to unregister vdev create handle");
134 goto out;
135 }
136
137 out:
138 pmo_free_ctx();
139 pmo_exit();
140
141 return status;
142 }
143
pmo_psoc_object_created_notification(struct wlan_objmgr_psoc * psoc,void * arg)144 QDF_STATUS pmo_psoc_object_created_notification(
145 struct wlan_objmgr_psoc *psoc, void *arg)
146 {
147 struct pmo_psoc_priv_obj *psoc_ctx = NULL;
148 QDF_STATUS status;
149 struct wlan_pmo_ctx *pmo_ctx;
150
151 pmo_enter();
152 pmo_ctx = pmo_get_context();
153 if (!pmo_ctx) {
154 QDF_ASSERT(0);
155 pmo_err("unable to get pmo ctx");
156 status = QDF_STATUS_E_FAILURE;
157 goto out;
158 }
159
160 psoc_ctx = qdf_mem_malloc(sizeof(*psoc_ctx));
161 if (!psoc_ctx) {
162 status = QDF_STATUS_E_NOMEM;
163 goto out;
164 }
165
166 status = wlan_objmgr_psoc_component_obj_attach(psoc,
167 WLAN_UMAC_COMP_PMO,
168 psoc_ctx,
169 QDF_STATUS_SUCCESS);
170 if (status != QDF_STATUS_SUCCESS) {
171 pmo_err("Failed to attach psoc_ctx with psoc");
172 qdf_mem_free(psoc_ctx);
173 status = QDF_STATUS_E_FAILURE;
174 goto out;
175 }
176 qdf_spinlock_create(&psoc_ctx->lock);
177 qdf_wake_lock_create(&psoc_ctx->wow.wow_wake_lock, "pmo_wow_wl");
178 status = qdf_event_create(&psoc_ctx->wow.target_suspend);
179 if (status != QDF_STATUS_SUCCESS) {
180 pmo_err("target suspend event initialization failed");
181 status = QDF_STATUS_E_FAILURE;
182 goto out;
183 }
184 status = qdf_event_create(&psoc_ctx->wow.target_resume);
185 if (status != QDF_STATUS_SUCCESS) {
186 pmo_err("target resume event initialization failed");
187 status = QDF_STATUS_E_FAILURE;
188 goto out;
189 }
190
191 qdf_atomic_init(&psoc_ctx->wow.wow_initial_wake_up);
192 /* Register PMO tx ops*/
193 target_if_pmo_register_tx_ops(&psoc_ctx->pmo_tx_ops);
194 out:
195 pmo_exit();
196
197 return status;
198 }
199
pmo_psoc_object_destroyed_notification(struct wlan_objmgr_psoc * psoc,void * arg)200 QDF_STATUS pmo_psoc_object_destroyed_notification(
201 struct wlan_objmgr_psoc *psoc, void *arg)
202 {
203 struct pmo_psoc_priv_obj *psoc_ctx = NULL;
204 QDF_STATUS status;
205
206 pmo_enter();
207
208 psoc_ctx = pmo_psoc_get_priv(psoc);
209
210 status = wlan_objmgr_psoc_component_obj_detach(psoc,
211 WLAN_UMAC_COMP_PMO,
212 psoc_ctx);
213 if (status != QDF_STATUS_SUCCESS) {
214 pmo_err("Failed to detach psoc_ctx from psoc");
215 status = QDF_STATUS_E_FAILURE;
216 goto out;
217 }
218
219 qdf_spinlock_destroy(&psoc_ctx->lock);
220 qdf_event_destroy(&psoc_ctx->wow.target_suspend);
221 qdf_event_destroy(&psoc_ctx->wow.target_resume);
222 qdf_wake_lock_destroy(&psoc_ctx->wow.wow_wake_lock);
223 qdf_mem_zero(psoc_ctx, sizeof(*psoc_ctx));
224 qdf_mem_free(psoc_ctx);
225 out:
226 pmo_exit();
227
228 return status;
229 }
230
231 #ifdef FEATURE_WLAN_DYNAMIC_ARP_NS_OFFLOAD
232 static inline void
pmo_vdev_dynamic_arp_ns_offload_init(struct pmo_vdev_priv_obj * vdev_ctx)233 pmo_vdev_dynamic_arp_ns_offload_init(struct pmo_vdev_priv_obj *vdev_ctx)
234 {
235 qdf_runtime_lock_init(&vdev_ctx->dyn_arp_ns_offload_rt_lock);
236 }
237
238 static inline void
pmo_vdev_dynamic_arp_ns_offload_deinit(struct pmo_vdev_priv_obj * vdev_ctx)239 pmo_vdev_dynamic_arp_ns_offload_deinit(struct pmo_vdev_priv_obj *vdev_ctx)
240 {
241 qdf_runtime_lock_deinit(&vdev_ctx->dyn_arp_ns_offload_rt_lock);
242 }
243 #else
244 static inline void
pmo_vdev_dynamic_arp_ns_offload_init(struct pmo_vdev_priv_obj * vdev_ctx)245 pmo_vdev_dynamic_arp_ns_offload_init(struct pmo_vdev_priv_obj *vdev_ctx) {}
246
247 static inline void
pmo_vdev_dynamic_arp_ns_offload_deinit(struct pmo_vdev_priv_obj * vdev_ctx)248 pmo_vdev_dynamic_arp_ns_offload_deinit(struct pmo_vdev_priv_obj *vdev_ctx) {}
249 #endif
250
pmo_vdev_object_created_notification(struct wlan_objmgr_vdev * vdev,void * arg)251 QDF_STATUS pmo_vdev_object_created_notification(
252 struct wlan_objmgr_vdev *vdev, void *arg)
253 {
254 struct pmo_psoc_priv_obj *psoc_ctx = NULL;
255 struct wlan_objmgr_psoc *psoc;
256 struct pmo_vdev_priv_obj *vdev_ctx;
257 QDF_STATUS status;
258
259 pmo_enter();
260
261 psoc = pmo_vdev_get_psoc(vdev);
262
263 psoc_ctx = pmo_psoc_get_priv(psoc);
264
265 vdev_ctx = qdf_mem_malloc(sizeof(*vdev_ctx));
266 if (!vdev_ctx) {
267 status = QDF_STATUS_E_NOMEM;
268 goto out;
269 }
270
271 status = wlan_objmgr_vdev_component_obj_attach(vdev,
272 WLAN_UMAC_COMP_PMO,
273 (void *)vdev_ctx, QDF_STATUS_SUCCESS);
274 if (status != QDF_STATUS_SUCCESS) {
275 pmo_err("Failed to attach vdev_ctx with vdev");
276 qdf_mem_free(vdev_ctx);
277 goto out;
278 }
279
280 qdf_spinlock_create(&vdev_ctx->pmo_vdev_lock);
281 vdev_ctx->magic_ptrn_enable =
282 psoc_ctx->psoc_cfg.magic_ptrn_enable;
283 vdev_ctx->ptrn_match_enable =
284 psoc_ctx->psoc_cfg.ptrn_match_enable_all_vdev;
285 vdev_ctx->pmo_psoc_ctx = psoc_ctx;
286 qdf_atomic_init(&vdev_ctx->gtk_err_enable);
287 pmo_vdev_dynamic_arp_ns_offload_init(vdev_ctx);
288 /*
289 * Update Powersave mode
290 * 0 - PMO_PS_ADVANCED_POWER_SAVE_DISABLE
291 * 1 - PMO_PS_ADVANCED_POWER_SAVE_ENABLE
292 * 2 - PMO_PS_ADVANCED_POWER_SAVE_USER_DEFINED
293 */
294 vdev_ctx->ps_params.opm_mode = psoc_ctx->psoc_cfg.power_save_mode;
295 vdev_ctx->ps_params.ps_ito = PMO_PS_DATA_INACTIVITY_TIMEOUT;
296 vdev_ctx->ps_params.spec_wake = PMO_PS_DATA_SPEC_WAKE;
297
298 out:
299 pmo_exit();
300
301 return QDF_STATUS_SUCCESS;
302 }
303
pmo_vdev_ready(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr * bridgeaddr)304 QDF_STATUS pmo_vdev_ready(struct wlan_objmgr_vdev *vdev,
305 struct qdf_mac_addr *bridgeaddr)
306 {
307 QDF_STATUS status;
308
309 status = pmo_vdev_get_ref(vdev);
310 if (QDF_IS_STATUS_ERROR(status))
311 return status;
312
313 /* Set Bridge MAC address */
314 pmo_set_vdev_bridge_addr(vdev, bridgeaddr);
315
316 /* Register static configuration with firmware */
317 pmo_register_wow_wakeup_events(vdev);
318
319 /* Register default wow patterns with firmware */
320 pmo_register_wow_default_patterns(vdev);
321
322 wlan_objmgr_vdev_release_ref(vdev, WLAN_PMO_ID);
323
324 /*
325 * The above APIs should return a status but don't.
326 * Just return success for now.
327 */
328 return QDF_STATUS_SUCCESS;
329 }
330
pmo_vdev_object_destroyed_notification(struct wlan_objmgr_vdev * vdev,void * arg)331 QDF_STATUS pmo_vdev_object_destroyed_notification(
332 struct wlan_objmgr_vdev *vdev, void *arg)
333 {
334 struct pmo_vdev_priv_obj *vdev_ctx = NULL;
335 QDF_STATUS status = QDF_STATUS_SUCCESS;
336
337 vdev_ctx = pmo_vdev_get_priv(vdev);
338
339 status = wlan_objmgr_vdev_component_obj_detach(vdev,
340 WLAN_UMAC_COMP_PMO,
341 (void *)vdev_ctx);
342 if (status != QDF_STATUS_SUCCESS)
343 pmo_err("Failed to detach vdev_ctx with vdev");
344
345 qdf_spinlock_destroy(&vdev_ctx->pmo_vdev_lock);
346 pmo_vdev_dynamic_arp_ns_offload_deinit(vdev_ctx);
347 qdf_mem_free(vdev_ctx);
348
349 return status;
350 }
351
pmo_register_suspend_handler(enum wlan_umac_comp_id id,pmo_psoc_suspend_handler handler,void * arg)352 QDF_STATUS pmo_register_suspend_handler(
353 enum wlan_umac_comp_id id,
354 pmo_psoc_suspend_handler handler,
355 void *arg)
356 {
357 struct wlan_pmo_ctx *pmo_ctx;
358 QDF_STATUS status = QDF_STATUS_SUCCESS;
359
360 pmo_enter();
361 pmo_ctx = pmo_get_context();
362 if (!pmo_ctx) {
363 QDF_ASSERT(0);
364 pmo_err("unable to get pmo ctx");
365 status = QDF_STATUS_E_FAILURE;
366 goto out;
367 }
368
369 if (id < 0 || id >= WLAN_UMAC_MAX_COMPONENTS) {
370 pmo_err("component id: %d is %s then valid components id",
371 id, id < 0 ? "Less" : "More");
372 status = QDF_STATUS_E_FAILURE;
373 goto out;
374 }
375
376 qdf_spin_lock_bh(&pmo_ctx->lock);
377 pmo_ctx->pmo_suspend_handler[id] = handler;
378 pmo_ctx->pmo_suspend_handler_arg[id] = arg;
379 qdf_spin_unlock_bh(&pmo_ctx->lock);
380 out:
381 pmo_exit();
382
383 return status;
384 }
385
pmo_unregister_suspend_handler(enum wlan_umac_comp_id id,pmo_psoc_suspend_handler handler)386 QDF_STATUS pmo_unregister_suspend_handler(
387 enum wlan_umac_comp_id id,
388 pmo_psoc_suspend_handler handler)
389 {
390 struct wlan_pmo_ctx *pmo_ctx;
391 QDF_STATUS status = QDF_STATUS_SUCCESS;
392
393 pmo_enter();
394 pmo_ctx = pmo_get_context();
395 if (!pmo_ctx) {
396 QDF_ASSERT(0);
397 pmo_err("unable to get pmo ctx");
398 status = QDF_STATUS_E_FAILURE;
399 goto out;
400 }
401
402 if (id < 0 || id >= WLAN_UMAC_MAX_COMPONENTS) {
403 pmo_err("component id: %d is %s then valid components id",
404 id, id < 0 ? "Less" : "More");
405 status = QDF_STATUS_E_FAILURE;
406 goto out;
407 }
408
409 qdf_spin_lock_bh(&pmo_ctx->lock);
410 if (pmo_ctx->pmo_suspend_handler[id] == handler) {
411 pmo_ctx->pmo_suspend_handler[id] = NULL;
412 pmo_ctx->pmo_suspend_handler_arg[id] = NULL;
413 qdf_spin_unlock_bh(&pmo_ctx->lock);
414 } else {
415 qdf_spin_unlock_bh(&pmo_ctx->lock);
416 pmo_err("can't find suspend handler for component id: %d ", id);
417 status = QDF_STATUS_E_FAILURE;
418 }
419 out:
420 pmo_exit();
421
422 return status;
423 }
424
pmo_register_resume_handler(enum wlan_umac_comp_id id,pmo_psoc_resume_handler handler,void * arg)425 QDF_STATUS pmo_register_resume_handler(
426 enum wlan_umac_comp_id id,
427 pmo_psoc_resume_handler handler,
428 void *arg)
429 {
430 struct wlan_pmo_ctx *pmo_ctx;
431 QDF_STATUS status = QDF_STATUS_SUCCESS;
432
433 pmo_enter();
434 pmo_ctx = pmo_get_context();
435 if (!pmo_ctx) {
436 pmo_err("unable to get pmo ctx");
437 status = QDF_STATUS_E_FAILURE;
438 goto out;
439 }
440
441 if (id < 0 || id >= WLAN_UMAC_MAX_COMPONENTS) {
442 pmo_err("component id: %d is %s then valid components id",
443 id, id < 0 ? "Less" : "More");
444 status = QDF_STATUS_E_FAILURE;
445 goto out;
446 }
447
448 qdf_spin_lock_bh(&pmo_ctx->lock);
449 pmo_ctx->pmo_resume_handler[id] = handler;
450 pmo_ctx->pmo_resume_handler_arg[id] = arg;
451 qdf_spin_unlock_bh(&pmo_ctx->lock);
452 out:
453 pmo_exit();
454
455 return status;
456 }
457
pmo_unregister_resume_handler(enum wlan_umac_comp_id id,pmo_psoc_resume_handler handler)458 QDF_STATUS pmo_unregister_resume_handler(
459 enum wlan_umac_comp_id id,
460 pmo_psoc_resume_handler handler)
461 {
462 struct wlan_pmo_ctx *pmo_ctx;
463 QDF_STATUS status = QDF_STATUS_SUCCESS;
464
465 pmo_enter();
466 pmo_ctx = pmo_get_context();
467 if (!pmo_ctx) {
468 pmo_err("unable to get pmo ctx");
469 status = QDF_STATUS_E_FAILURE;
470 goto out;
471 }
472
473 if (id < 0 || id >= WLAN_UMAC_MAX_COMPONENTS) {
474 pmo_err("component id: %d is %s then valid components id",
475 id, id < 0 ? "Less" : "More");
476 status = QDF_STATUS_E_FAILURE;
477 goto out;
478 }
479
480 qdf_spin_lock_bh(&pmo_ctx->lock);
481 if (pmo_ctx->pmo_resume_handler[id] == handler) {
482 pmo_ctx->pmo_resume_handler[id] = NULL;
483 pmo_ctx->pmo_resume_handler_arg[id] = NULL;
484 qdf_spin_unlock_bh(&pmo_ctx->lock);
485 } else {
486 qdf_spin_unlock_bh(&pmo_ctx->lock);
487 pmo_err("can't find resume handler for component id: %d ", id);
488 status = QDF_STATUS_E_FAILURE;
489 }
490 out:
491 pmo_exit();
492
493 return status;
494 }
495
pmo_suspend_all_components(struct wlan_objmgr_psoc * psoc,enum qdf_suspend_type suspend_type)496 QDF_STATUS pmo_suspend_all_components(struct wlan_objmgr_psoc *psoc,
497 enum qdf_suspend_type suspend_type)
498 {
499 QDF_STATUS status = QDF_STATUS_SUCCESS;
500 QDF_STATUS resume_status;
501 struct wlan_pmo_ctx *pmo_ctx;
502 int i;
503 pmo_psoc_suspend_handler handler;
504 void *arg;
505
506 pmo_ctx = pmo_get_context();
507 if (!pmo_ctx) {
508 pmo_err("unable to get pmo ctx");
509 status = QDF_STATUS_E_FAILURE;
510 goto exit_with_status;
511 }
512
513 /* call each component's suspend handler */
514 for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) {
515 qdf_spin_lock_bh(&pmo_ctx->lock);
516 handler = pmo_ctx->pmo_suspend_handler[i];
517 arg = pmo_ctx->pmo_suspend_handler_arg[i];
518 qdf_spin_unlock_bh(&pmo_ctx->lock);
519
520 if (!handler)
521 continue;
522
523 status = handler(psoc, arg);
524 if (QDF_IS_STATUS_ERROR(status)) {
525 pmo_err("component %d failed to suspend; status: %d",
526 i, status);
527 goto suspend_recovery;
528 }
529 }
530
531 goto exit_with_status;
532
533 suspend_recovery:
534 /* resume, starting with the last successfully suspended component */
535 for (i -= 1; i >= 0; i--) {
536 qdf_spin_lock_bh(&pmo_ctx->lock);
537 handler = pmo_ctx->pmo_resume_handler[i];
538 arg = pmo_ctx->pmo_resume_handler_arg[i];
539 qdf_spin_unlock_bh(&pmo_ctx->lock);
540
541 if (!handler)
542 continue;
543
544 resume_status = handler(psoc, arg);
545 if (QDF_IS_STATUS_ERROR(resume_status))
546 QDF_DEBUG_PANIC("component %d failed resume; status:%d",
547 i, resume_status);
548 }
549
550 exit_with_status:
551 return status;
552 }
553
pmo_resume_all_components(struct wlan_objmgr_psoc * psoc,enum qdf_suspend_type suspend_type)554 QDF_STATUS pmo_resume_all_components(struct wlan_objmgr_psoc *psoc,
555 enum qdf_suspend_type suspend_type)
556 {
557 QDF_STATUS status = QDF_STATUS_SUCCESS;
558 struct wlan_pmo_ctx *pmo_ctx;
559 uint8_t i;
560 pmo_psoc_suspend_handler handler;
561 void *arg;
562
563 pmo_ctx = pmo_get_context();
564 if (!pmo_ctx) {
565 pmo_err("unable to get pmo ctx");
566 QDF_ASSERT(0);
567 status = QDF_STATUS_E_FAILURE;
568 goto exit_with_status;
569 }
570
571 /* call each component's resume handler */
572 for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) {
573 qdf_spin_lock_bh(&pmo_ctx->lock);
574 handler = pmo_ctx->pmo_resume_handler[i];
575 arg = pmo_ctx->pmo_resume_handler_arg[i];
576 qdf_spin_unlock_bh(&pmo_ctx->lock);
577
578 if (!handler)
579 continue;
580
581 status = handler(psoc, arg);
582 if (QDF_IS_STATUS_ERROR(status)) {
583 pmo_fatal("Non-recoverable failure occurred!");
584 pmo_fatal("component %d failed to resume; status: %d",
585 i, status);
586 QDF_BUG(0);
587 }
588 }
589
590 exit_with_status:
591 return status;
592 }
593
pmo_register_pause_bitmap_notifier(struct wlan_objmgr_psoc * psoc,pmo_notify_pause_bitmap handler)594 QDF_STATUS pmo_register_pause_bitmap_notifier(struct wlan_objmgr_psoc *psoc,
595 pmo_notify_pause_bitmap handler)
596 {
597 struct pmo_psoc_priv_obj *psoc_ctx;
598 QDF_STATUS status;
599
600 if (!psoc) {
601 pmo_err("psoc is null");
602 return QDF_STATUS_E_NULL_VALUE;
603 }
604
605 if (!handler) {
606 pmo_err("pmo_notify_vdev_pause_bitmap is null");
607 return QDF_STATUS_E_NULL_VALUE;
608 }
609
610 status = pmo_psoc_get_ref(psoc);
611 if (status != QDF_STATUS_SUCCESS) {
612 pmo_err("pmo cannot get the reference out of psoc");
613 return status;
614 }
615
616 pmo_psoc_with_ctx(psoc, psoc_ctx) {
617 psoc_ctx->pause_bitmap_notifier = handler;
618 }
619
620 pmo_psoc_put_ref(psoc);
621
622 return QDF_STATUS_SUCCESS;
623 }
624
pmo_unregister_pause_bitmap_notifier(struct wlan_objmgr_psoc * psoc)625 QDF_STATUS pmo_unregister_pause_bitmap_notifier(struct wlan_objmgr_psoc *psoc)
626 {
627 struct pmo_psoc_priv_obj *psoc_ctx;
628 QDF_STATUS status;
629
630 if (!psoc) {
631 pmo_err("psoc is null");
632 return QDF_STATUS_E_NULL_VALUE;
633 }
634
635 status = pmo_psoc_get_ref(psoc);
636 if (status != QDF_STATUS_SUCCESS) {
637 pmo_err("pmo cannot get the reference out of psoc");
638 return status;
639 }
640
641 pmo_psoc_with_ctx(psoc, psoc_ctx) {
642 psoc_ctx->pause_bitmap_notifier = NULL;
643 }
644
645 pmo_psoc_put_ref(psoc);
646
647 return QDF_STATUS_SUCCESS;
648 }
649
pmo_register_get_pause_bitmap(struct wlan_objmgr_psoc * psoc,pmo_get_pause_bitmap handler)650 QDF_STATUS pmo_register_get_pause_bitmap(struct wlan_objmgr_psoc *psoc,
651 pmo_get_pause_bitmap handler)
652 {
653 struct pmo_psoc_priv_obj *psoc_ctx;
654 QDF_STATUS status;
655
656 if (!psoc) {
657 pmo_err("psoc is null");
658 return QDF_STATUS_E_NULL_VALUE;
659 }
660
661 if (!handler) {
662 pmo_err("pmo_get_pause_bitmap is null");
663 return QDF_STATUS_E_NULL_VALUE;
664 }
665
666 status = pmo_psoc_get_ref(psoc);
667 if (status != QDF_STATUS_SUCCESS) {
668 pmo_err("pmo cannot get the reference out of psoc");
669 return status;
670 }
671
672 pmo_psoc_with_ctx(psoc, psoc_ctx) {
673 psoc_ctx->get_pause_bitmap = handler;
674 }
675
676 pmo_psoc_put_ref(psoc);
677
678 return QDF_STATUS_SUCCESS;
679 }
680
pmo_unregister_get_pause_bitmap(struct wlan_objmgr_psoc * psoc)681 QDF_STATUS pmo_unregister_get_pause_bitmap(struct wlan_objmgr_psoc *psoc)
682 {
683 struct pmo_psoc_priv_obj *psoc_ctx;
684 QDF_STATUS status;
685
686 if (!psoc) {
687 pmo_err("psoc is null");
688 return QDF_STATUS_E_NULL_VALUE;
689 }
690
691 status = pmo_psoc_get_ref(psoc);
692 if (status != QDF_STATUS_SUCCESS) {
693 pmo_err("pmo cannot get the reference out of psoc");
694 return status;
695 }
696
697 pmo_psoc_with_ctx(psoc, psoc_ctx) {
698 psoc_ctx->get_pause_bitmap = NULL;
699 }
700
701 pmo_psoc_put_ref(psoc);
702
703 return QDF_STATUS_SUCCESS;
704 }
705
pmo_register_is_device_in_low_pwr_mode(struct wlan_objmgr_psoc * psoc,pmo_is_device_in_low_pwr_mode handler)706 QDF_STATUS pmo_register_is_device_in_low_pwr_mode(struct wlan_objmgr_psoc *psoc,
707 pmo_is_device_in_low_pwr_mode handler)
708 {
709 struct pmo_psoc_priv_obj *psoc_ctx;
710 QDF_STATUS status;
711
712 if (!psoc) {
713 pmo_err("psoc is null");
714 return QDF_STATUS_E_NULL_VALUE;
715 }
716
717 if (!handler) {
718 pmo_err("pmo_get_pause_bitmap is null");
719 return QDF_STATUS_E_NULL_VALUE;
720 }
721
722 status = pmo_psoc_get_ref(psoc);
723 if (status != QDF_STATUS_SUCCESS) {
724 pmo_err("pmo cannot get the reference out of psoc");
725 return status;
726 }
727
728 pmo_psoc_with_ctx(psoc, psoc_ctx) {
729 psoc_ctx->is_device_in_low_pwr_mode = handler;
730 }
731
732 pmo_psoc_put_ref(psoc);
733
734 return QDF_STATUS_SUCCESS;
735 }
736
737 QDF_STATUS
pmo_unregister_is_device_in_low_pwr_mode(struct wlan_objmgr_psoc * psoc)738 pmo_unregister_is_device_in_low_pwr_mode(struct wlan_objmgr_psoc *psoc)
739 {
740 struct pmo_psoc_priv_obj *psoc_ctx;
741 QDF_STATUS status;
742
743 if (!psoc) {
744 pmo_err("psoc is null");
745 return QDF_STATUS_E_NULL_VALUE;
746 }
747
748 status = pmo_psoc_get_ref(psoc);
749 if (status != QDF_STATUS_SUCCESS) {
750 pmo_err("pmo cannot get the reference out of psoc");
751 return status;
752 }
753
754 pmo_psoc_with_ctx(psoc, psoc_ctx) {
755 psoc_ctx->is_device_in_low_pwr_mode = NULL;
756 }
757
758 pmo_psoc_put_ref(psoc);
759
760 return QDF_STATUS_SUCCESS;
761 }
762
pmo_register_get_dtim_period_callback(struct wlan_objmgr_psoc * psoc,pmo_get_dtim_period handler)763 QDF_STATUS pmo_register_get_dtim_period_callback(struct wlan_objmgr_psoc *psoc,
764 pmo_get_dtim_period handler)
765 {
766 struct pmo_psoc_priv_obj *psoc_ctx;
767 QDF_STATUS status;
768
769 if (!psoc) {
770 pmo_err("psoc is null");
771 return QDF_STATUS_E_NULL_VALUE;
772 }
773
774 if (!handler) {
775 pmo_err("pmo_get_dtim_period is null");
776 return QDF_STATUS_E_NULL_VALUE;
777 }
778
779 status = pmo_psoc_get_ref(psoc);
780 if (status != QDF_STATUS_SUCCESS) {
781 pmo_err("pmo cannot get the reference out of psoc");
782 return status;
783 }
784
785 pmo_psoc_with_ctx(psoc, psoc_ctx) {
786 psoc_ctx->get_dtim_period = handler;
787 }
788 pmo_psoc_put_ref(psoc);
789
790 return QDF_STATUS_SUCCESS;
791 }
792
793 QDF_STATUS
pmo_unregister_get_dtim_period_callback(struct wlan_objmgr_psoc * psoc)794 pmo_unregister_get_dtim_period_callback(struct wlan_objmgr_psoc *psoc)
795 {
796 struct pmo_psoc_priv_obj *psoc_ctx;
797 QDF_STATUS status;
798
799 if (!psoc) {
800 pmo_err("psoc is null");
801 return QDF_STATUS_E_NULL_VALUE;
802 }
803
804 status = pmo_psoc_get_ref(psoc);
805 if (status != QDF_STATUS_SUCCESS) {
806 pmo_err("pmo cannot get the reference out of psoc");
807 return status;
808 }
809
810 pmo_psoc_with_ctx(psoc, psoc_ctx) {
811 psoc_ctx->get_dtim_period = NULL;
812 }
813 pmo_psoc_put_ref(psoc);
814
815 return QDF_STATUS_SUCCESS;
816 }
817
818 QDF_STATUS
pmo_register_get_beacon_interval_callback(struct wlan_objmgr_psoc * psoc,pmo_get_beacon_interval handler)819 pmo_register_get_beacon_interval_callback(struct wlan_objmgr_psoc *psoc,
820 pmo_get_beacon_interval handler)
821 {
822 struct pmo_psoc_priv_obj *psoc_ctx;
823 QDF_STATUS status;
824
825 if (!psoc) {
826 pmo_err("psoc is null");
827 return QDF_STATUS_E_NULL_VALUE;
828 }
829
830 if (!handler) {
831 pmo_err("pmo_get_beacon_interval is null");
832 return QDF_STATUS_E_NULL_VALUE;
833 }
834
835 status = pmo_psoc_get_ref(psoc);
836 if (status != QDF_STATUS_SUCCESS) {
837 pmo_err("pmo cannot get the reference out of psoc");
838 return status;
839 }
840
841 pmo_psoc_with_ctx(psoc, psoc_ctx) {
842 psoc_ctx->get_beacon_interval = handler;
843 }
844 pmo_psoc_put_ref(psoc);
845
846 return QDF_STATUS_SUCCESS;
847 }
848
849 QDF_STATUS
pmo_unregister_get_beacon_interval_callback(struct wlan_objmgr_psoc * psoc)850 pmo_unregister_get_beacon_interval_callback(struct wlan_objmgr_psoc *psoc)
851 {
852 struct pmo_psoc_priv_obj *psoc_ctx;
853 QDF_STATUS status;
854
855 if (!psoc) {
856 pmo_err("psoc is null");
857 return QDF_STATUS_E_NULL_VALUE;
858 }
859
860 status = pmo_psoc_get_ref(psoc);
861 if (status != QDF_STATUS_SUCCESS) {
862 pmo_err("pmo cannot get the reference out of psoc");
863 return status;
864 }
865
866 pmo_psoc_with_ctx(psoc, psoc_ctx) {
867 psoc_ctx->get_beacon_interval = NULL;
868 }
869 pmo_psoc_put_ref(psoc);
870
871 return QDF_STATUS_SUCCESS;
872 }
873
874 bool
wlan_pmo_get_sap_mode_bus_suspend(struct wlan_objmgr_psoc * psoc)875 wlan_pmo_get_sap_mode_bus_suspend(struct wlan_objmgr_psoc *psoc)
876 {
877 struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
878
879 if (!pmo_psoc_ctx)
880 return false;
881
882 return pmo_psoc_ctx->psoc_cfg.is_bus_suspend_enabled_in_sap_mode;
883 }
884
885 bool
wlan_pmo_get_go_mode_bus_suspend(struct wlan_objmgr_psoc * psoc)886 wlan_pmo_get_go_mode_bus_suspend(struct wlan_objmgr_psoc *psoc)
887 {
888 struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
889
890 if (!pmo_psoc_ctx)
891 return false;
892
893 return pmo_psoc_ctx->psoc_cfg.is_bus_suspend_enabled_in_go_mode;
894 }
895
wlan_pmo_no_op_on_page_fault(struct wlan_objmgr_psoc * psoc)896 bool wlan_pmo_no_op_on_page_fault(struct wlan_objmgr_psoc *psoc)
897 {
898 return pmo_no_op_on_page_fault(psoc);
899 }
900
wlan_pmo_enable_ssr_on_page_fault(struct wlan_objmgr_psoc * psoc)901 bool wlan_pmo_enable_ssr_on_page_fault(struct wlan_objmgr_psoc *psoc)
902 {
903 return pmo_enable_ssr_on_page_fault(psoc);
904 }
905
906 uint8_t
wlan_pmo_get_min_pagefault_wakeups_for_action(struct wlan_objmgr_psoc * psoc)907 wlan_pmo_get_min_pagefault_wakeups_for_action(struct wlan_objmgr_psoc *psoc)
908 {
909 return pmo_get_min_pagefault_wakeups_for_action(psoc);
910 }
911
912 uint32_t
wlan_pmo_get_interval_for_pagefault_wakeup_counts(struct wlan_objmgr_psoc * psoc)913 wlan_pmo_get_interval_for_pagefault_wakeup_counts(struct wlan_objmgr_psoc *psoc)
914 {
915 return pmo_get_interval_for_pagefault_wakeup_counts(psoc);
916 }
917
wlan_pmo_get_listen_interval(struct wlan_objmgr_vdev * vdev,uint32_t * listen_interval)918 QDF_STATUS wlan_pmo_get_listen_interval(struct wlan_objmgr_vdev *vdev,
919 uint32_t *listen_interval)
920 {
921 return pmo_core_get_listen_interval(vdev, listen_interval);
922 }
923
wlan_pmo_set_ps_params(struct wlan_objmgr_vdev * vdev,struct pmo_ps_params * ps_params)924 void wlan_pmo_set_ps_params(struct wlan_objmgr_vdev *vdev,
925 struct pmo_ps_params *ps_params)
926 {
927 pmo_core_vdev_set_ps_params(vdev, ps_params);
928 }
929
wlan_pmo_get_ps_params(struct wlan_objmgr_vdev * vdev,struct pmo_ps_params * ps_params)930 QDF_STATUS wlan_pmo_get_ps_params(struct wlan_objmgr_vdev *vdev,
931 struct pmo_ps_params *ps_params)
932 {
933 return pmo_core_vdev_get_ps_params(vdev, ps_params);
934 }
935