xref: /wlan-dirver/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c (revision 4a8ee774c7e78db56bbacf6b864d68d2a91d1c08)
1 /*
2  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-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 /**
21  * DOC: wlan_policy_mgr_init_deinit.c
22  *
23  * WLAN Concurrenct Connection Management APIs
24  *
25  */
26 
27 /* Include files */
28 
29 #include "wlan_policy_mgr_api.h"
30 #include "wlan_policy_mgr_tables_no_dbs_i.h"
31 #include "wlan_policy_mgr_tables_1x1_dbs_i.h"
32 #include "wlan_policy_mgr_tables_2x2_dbs_i.h"
33 #include "wlan_policy_mgr_tables_2x2_5g_1x1_2g.h"
34 #include "wlan_policy_mgr_tables_2x2_2g_1x1_5g.h"
35 #include "wlan_policy_mgr_tables_2x2_dbs_sbs_i.h"
36 #include "wlan_policy_mgr_i.h"
37 #include "qdf_types.h"
38 #include "qdf_trace.h"
39 #include "wlan_objmgr_global_obj.h"
40 #include "target_if.h"
41 
42 static QDF_STATUS policy_mgr_psoc_obj_create_cb(struct wlan_objmgr_psoc *psoc,
43 		void *data)
44 {
45 	struct policy_mgr_psoc_priv_obj *policy_mgr_ctx;
46 
47 	policy_mgr_ctx = qdf_mem_malloc(
48 		sizeof(struct policy_mgr_psoc_priv_obj));
49 	if (!policy_mgr_ctx)
50 		return QDF_STATUS_E_FAILURE;
51 
52 	policy_mgr_ctx->psoc = psoc;
53 	policy_mgr_ctx->old_hw_mode_index = POLICY_MGR_DEFAULT_HW_MODE_INDEX;
54 	policy_mgr_ctx->new_hw_mode_index = POLICY_MGR_DEFAULT_HW_MODE_INDEX;
55 
56 	wlan_objmgr_psoc_component_obj_attach(psoc,
57 			WLAN_UMAC_COMP_POLICY_MGR,
58 			policy_mgr_ctx,
59 			QDF_STATUS_SUCCESS);
60 
61 	return QDF_STATUS_SUCCESS;
62 }
63 
64 static QDF_STATUS policy_mgr_psoc_obj_destroy_cb(struct wlan_objmgr_psoc *psoc,
65 		void *data)
66 {
67 	struct policy_mgr_psoc_priv_obj *policy_mgr_ctx;
68 
69 	policy_mgr_ctx = policy_mgr_get_context(psoc);
70 	wlan_objmgr_psoc_component_obj_detach(psoc,
71 					WLAN_UMAC_COMP_POLICY_MGR,
72 					policy_mgr_ctx);
73 	qdf_mem_free(policy_mgr_ctx);
74 
75 	return QDF_STATUS_SUCCESS;
76 }
77 
78 static void policy_mgr_psoc_obj_status_cb(struct wlan_objmgr_psoc *psoc,
79 		void *data, QDF_STATUS status)
80 {
81 	return;
82 }
83 
84 static QDF_STATUS policy_mgr_pdev_obj_create_cb(struct wlan_objmgr_pdev *pdev,
85 		void *data)
86 {
87 	struct policy_mgr_psoc_priv_obj *policy_mgr_ctx;
88 	struct wlan_objmgr_psoc *psoc;
89 
90 	psoc = wlan_pdev_get_psoc(pdev);
91 	policy_mgr_ctx = policy_mgr_get_context(psoc);
92 	if (!policy_mgr_ctx) {
93 		policy_mgr_err("invalid context");
94 		return QDF_STATUS_E_FAILURE;
95 	}
96 
97 	policy_mgr_ctx->pdev = pdev;
98 
99 	wlan_reg_register_chan_change_callback(psoc,
100 		policy_mgr_reg_chan_change_callback, NULL);
101 
102 	return QDF_STATUS_SUCCESS;
103 }
104 
105 static QDF_STATUS policy_mgr_pdev_obj_destroy_cb(struct wlan_objmgr_pdev *pdev,
106 		void *data)
107 {
108 	struct policy_mgr_psoc_priv_obj *policy_mgr_ctx;
109 	struct wlan_objmgr_psoc *psoc;
110 
111 	psoc = wlan_pdev_get_psoc(pdev);
112 	policy_mgr_ctx = policy_mgr_get_context(psoc);
113 	if (!policy_mgr_ctx) {
114 		policy_mgr_err("invalid context");
115 		return QDF_STATUS_E_FAILURE;
116 	}
117 
118 	policy_mgr_ctx->pdev = NULL;
119 	wlan_reg_unregister_chan_change_callback(psoc,
120 		policy_mgr_reg_chan_change_callback);
121 
122 	return QDF_STATUS_SUCCESS;
123 }
124 
125 static QDF_STATUS policy_mgr_vdev_obj_create_cb(struct wlan_objmgr_vdev *vdev,
126 		void *data)
127 {
128 	return QDF_STATUS_SUCCESS;
129 }
130 
131 static QDF_STATUS policy_mgr_vdev_obj_destroy_cb(struct wlan_objmgr_vdev *vdev,
132 		void *data)
133 {
134 	return QDF_STATUS_SUCCESS;
135 }
136 
137 static void policy_mgr_vdev_obj_status_cb(struct wlan_objmgr_vdev *vdev,
138 		void *data, QDF_STATUS status)
139 {
140 	return;
141 }
142 
143 #ifdef WLAN_FEATURE_11BE_MLO
144 static QDF_STATUS policy_mgr_register_link_switch_notifier(void)
145 {
146 	QDF_STATUS status;
147 
148 	status = mlo_mgr_register_link_switch_notifier(
149 			WLAN_UMAC_COMP_POLICY_MGR,
150 			policy_mgr_link_switch_notifier_cb);
151 	if (status == QDF_STATUS_E_NOSUPPORT) {
152 		status = QDF_STATUS_SUCCESS;
153 		policy_mgr_debug("Link switch not supported");
154 	} else if (status != QDF_STATUS_SUCCESS) {
155 		policy_mgr_err("Failed to register link switch notifier for policy mgr!");
156 	}
157 
158 	return status;
159 }
160 
161 static QDF_STATUS policy_mgr_unregister_link_switch_notifier(void)
162 {
163 	QDF_STATUS status;
164 
165 	status = mlo_mgr_unregister_link_switch_notifier(
166 			WLAN_UMAC_COMP_POLICY_MGR);
167 	if (status == QDF_STATUS_E_NOSUPPORT)
168 		status = QDF_STATUS_SUCCESS;
169 	else if (status != QDF_STATUS_SUCCESS)
170 		policy_mgr_err("Failed to unregister link switch notifier for policy mgr!");
171 
172 	return status;
173 }
174 #else
175 static QDF_STATUS policy_mgr_register_link_switch_notifier(void)
176 {
177 	return QDF_STATUS_SUCCESS;
178 }
179 
180 static QDF_STATUS policy_mgr_unregister_link_switch_notifier(void)
181 {
182 	return QDF_STATUS_SUCCESS;
183 }
184 #endif
185 
186 QDF_STATUS policy_mgr_init(void)
187 {
188 	QDF_STATUS status = QDF_STATUS_SUCCESS;
189 	status = wlan_objmgr_register_psoc_create_handler(
190 				WLAN_UMAC_COMP_POLICY_MGR,
191 				policy_mgr_psoc_obj_create_cb,
192 				NULL);
193 	if (status != QDF_STATUS_SUCCESS) {
194 		policy_mgr_err("Failed to register psoc obj create cback");
195 		goto err_psoc_create;
196 	}
197 
198 	status = wlan_objmgr_register_psoc_destroy_handler(
199 				WLAN_UMAC_COMP_POLICY_MGR,
200 				policy_mgr_psoc_obj_destroy_cb,
201 				NULL);
202 	if (status != QDF_STATUS_SUCCESS) {
203 		policy_mgr_err("Failed to register psoc obj delete cback");
204 		goto err_psoc_delete;
205 	}
206 
207 	status = wlan_objmgr_register_psoc_status_handler(
208 				WLAN_UMAC_COMP_POLICY_MGR,
209 				policy_mgr_psoc_obj_status_cb,
210 				NULL);
211 	if (status != QDF_STATUS_SUCCESS) {
212 		policy_mgr_err("Failed to register psoc obj status cback");
213 		goto err_psoc_status;
214 	}
215 
216 	status = wlan_objmgr_register_pdev_create_handler(
217 				WLAN_UMAC_COMP_POLICY_MGR,
218 				policy_mgr_pdev_obj_create_cb,
219 				NULL);
220 	if (status != QDF_STATUS_SUCCESS) {
221 		policy_mgr_err("Failed to register pdev obj create cback");
222 		goto err_pdev_create;
223 	}
224 
225 	status = wlan_objmgr_register_pdev_destroy_handler(
226 				WLAN_UMAC_COMP_POLICY_MGR,
227 				policy_mgr_pdev_obj_destroy_cb,
228 				NULL);
229 	if (status != QDF_STATUS_SUCCESS) {
230 		policy_mgr_err("Failed to register pdev obj delete cback");
231 		goto err_pdev_delete;
232 	}
233 
234 	status = wlan_objmgr_register_vdev_create_handler(
235 				WLAN_UMAC_COMP_POLICY_MGR,
236 				policy_mgr_vdev_obj_create_cb,
237 				NULL);
238 	if (status != QDF_STATUS_SUCCESS) {
239 		policy_mgr_err("Failed to register vdev obj create cback");
240 		goto err_vdev_create;
241 	}
242 
243 	status = wlan_objmgr_register_vdev_destroy_handler(
244 				WLAN_UMAC_COMP_POLICY_MGR,
245 				policy_mgr_vdev_obj_destroy_cb,
246 				NULL);
247 	if (status != QDF_STATUS_SUCCESS) {
248 		policy_mgr_err("Failed to register vdev obj delete cback");
249 		goto err_vdev_delete;
250 	}
251 
252 	status = wlan_objmgr_register_vdev_status_handler(
253 				WLAN_UMAC_COMP_POLICY_MGR,
254 				policy_mgr_vdev_obj_status_cb,
255 				NULL);
256 	if (status != QDF_STATUS_SUCCESS) {
257 		policy_mgr_err("Failed to register vdev obj status cback");
258 		goto err_vdev_status;
259 	}
260 
261 	status = policy_mgr_register_link_switch_notifier();
262 	if (status != QDF_STATUS_SUCCESS) {
263 		policy_mgr_err("Failed to register link switch cback");
264 		goto err_link_switch;
265 	}
266 
267 	policy_mgr_notice("Callbacks registered with obj mgr");
268 
269 	return QDF_STATUS_SUCCESS;
270 err_link_switch:
271 	wlan_objmgr_unregister_vdev_status_handler(
272 				WLAN_UMAC_COMP_POLICY_MGR,
273 				policy_mgr_vdev_obj_status_cb,
274 				NULL);
275 err_vdev_status:
276 	wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_POLICY_MGR,
277 						policy_mgr_vdev_obj_destroy_cb,
278 						NULL);
279 err_vdev_delete:
280 	wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_POLICY_MGR,
281 						policy_mgr_vdev_obj_create_cb,
282 						NULL);
283 err_vdev_create:
284 	wlan_objmgr_unregister_pdev_destroy_handler(WLAN_UMAC_COMP_POLICY_MGR,
285 						policy_mgr_pdev_obj_destroy_cb,
286 						NULL);
287 err_pdev_delete:
288 	wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_POLICY_MGR,
289 						policy_mgr_pdev_obj_create_cb,
290 						NULL);
291 err_pdev_create:
292 	wlan_objmgr_unregister_psoc_status_handler(WLAN_UMAC_COMP_POLICY_MGR,
293 						policy_mgr_psoc_obj_status_cb,
294 						NULL);
295 err_psoc_status:
296 	wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_POLICY_MGR,
297 						policy_mgr_psoc_obj_destroy_cb,
298 						NULL);
299 err_psoc_delete:
300 	wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_POLICY_MGR,
301 						policy_mgr_psoc_obj_create_cb,
302 						NULL);
303 err_psoc_create:
304 	return status;
305 }
306 
307 QDF_STATUS policy_mgr_deinit(void)
308 {
309 	QDF_STATUS status;
310 
311 	status = policy_mgr_unregister_link_switch_notifier();
312 	if (status != QDF_STATUS_SUCCESS)
313 		policy_mgr_err("Failed to deregister link switch cback");
314 
315 	status = wlan_objmgr_unregister_psoc_status_handler(
316 				WLAN_UMAC_COMP_POLICY_MGR,
317 				policy_mgr_psoc_obj_status_cb,
318 				NULL);
319 	if (status != QDF_STATUS_SUCCESS)
320 		policy_mgr_err("Failed to deregister psoc obj status cback");
321 
322 	status = wlan_objmgr_unregister_psoc_destroy_handler(
323 				WLAN_UMAC_COMP_POLICY_MGR,
324 				policy_mgr_psoc_obj_destroy_cb,
325 				NULL);
326 	if (status != QDF_STATUS_SUCCESS)
327 		policy_mgr_err("Failed to deregister psoc obj delete cback");
328 
329 	status = wlan_objmgr_unregister_psoc_create_handler(
330 				WLAN_UMAC_COMP_POLICY_MGR,
331 				policy_mgr_psoc_obj_create_cb,
332 				NULL);
333 	if (status != QDF_STATUS_SUCCESS)
334 		policy_mgr_err("Failed to deregister psoc obj create cback");
335 
336 	status = wlan_objmgr_unregister_pdev_destroy_handler(
337 				WLAN_UMAC_COMP_POLICY_MGR,
338 				policy_mgr_pdev_obj_destroy_cb,
339 				NULL);
340 	if (status != QDF_STATUS_SUCCESS)
341 		policy_mgr_err("Failed to deregister pdev obj delete cback");
342 
343 	status = wlan_objmgr_unregister_pdev_create_handler(
344 				WLAN_UMAC_COMP_POLICY_MGR,
345 				policy_mgr_pdev_obj_create_cb,
346 				NULL);
347 	if (status != QDF_STATUS_SUCCESS)
348 		policy_mgr_err("Failed to deregister pdev obj create cback");
349 
350 	status = wlan_objmgr_unregister_vdev_status_handler(
351 				WLAN_UMAC_COMP_POLICY_MGR,
352 				policy_mgr_vdev_obj_status_cb,
353 				NULL);
354 	if (status != QDF_STATUS_SUCCESS)
355 		policy_mgr_err("Failed to deregister vdev obj status cback");
356 
357 	status = wlan_objmgr_unregister_vdev_destroy_handler(
358 				WLAN_UMAC_COMP_POLICY_MGR,
359 				policy_mgr_vdev_obj_destroy_cb,
360 				NULL);
361 	if (status != QDF_STATUS_SUCCESS)
362 		policy_mgr_err("Failed to deregister vdev obj delete cback");
363 
364 	status = wlan_objmgr_unregister_vdev_create_handler(
365 				WLAN_UMAC_COMP_POLICY_MGR,
366 				policy_mgr_vdev_obj_create_cb,
367 				NULL);
368 	if (status != QDF_STATUS_SUCCESS)
369 		policy_mgr_err("Failed to deregister vdev obj create cback");
370 
371 	policy_mgr_info("deregistered callbacks with obj mgr successfully");
372 
373 	return status;
374 }
375 
376 QDF_STATUS policy_mgr_psoc_open(struct wlan_objmgr_psoc *psoc)
377 {
378 	struct policy_mgr_psoc_priv_obj *pm_ctx;
379 
380 	pm_ctx = policy_mgr_get_context(psoc);
381 	if (!pm_ctx) {
382 		policy_mgr_err("Invalid Context");
383 		return QDF_STATUS_E_FAILURE;
384 	}
385 
386 	if (!QDF_IS_STATUS_SUCCESS(qdf_mutex_create(
387 		&pm_ctx->qdf_conc_list_lock))) {
388 		policy_mgr_err("Failed to init qdf_conc_list_lock");
389 		QDF_ASSERT(0);
390 		return QDF_STATUS_E_FAILURE;
391 	}
392 
393 	pm_ctx->sta_ap_intf_check_work_info = qdf_mem_malloc(
394 		sizeof(struct sta_ap_intf_check_work_ctx));
395 	if (!pm_ctx->sta_ap_intf_check_work_info) {
396 		qdf_mutex_destroy(&pm_ctx->qdf_conc_list_lock);
397 		return QDF_STATUS_E_FAILURE;
398 	}
399 	pm_ctx->sta_ap_intf_check_work_info->psoc = psoc;
400 	pm_ctx->sta_ap_intf_check_work_info->go_plus_go_force_scc.vdev_id =
401 						WLAN_UMAC_VDEV_ID_MAX;
402 	pm_ctx->sta_ap_intf_check_work_info->sap_plus_go_force_scc.reason =
403 						CSA_REASON_UNKNOWN;
404 	if (QDF_IS_STATUS_ERROR(qdf_delayed_work_create(
405 				&pm_ctx->sta_ap_intf_check_work,
406 				policy_mgr_check_sta_ap_concurrent_ch_intf,
407 				pm_ctx))) {
408 		policy_mgr_err("Failed to create dealyed work queue");
409 		qdf_mutex_destroy(&pm_ctx->qdf_conc_list_lock);
410 		qdf_mem_free(pm_ctx->sta_ap_intf_check_work_info);
411 		return QDF_STATUS_E_FAILURE;
412 	}
413 
414 	return QDF_STATUS_SUCCESS;
415 }
416 
417 QDF_STATUS policy_mgr_psoc_close(struct wlan_objmgr_psoc *psoc)
418 {
419 	struct policy_mgr_psoc_priv_obj *pm_ctx;
420 
421 	pm_ctx = policy_mgr_get_context(psoc);
422 	if (!pm_ctx) {
423 		policy_mgr_err("Invalid Context");
424 		return QDF_STATUS_E_FAILURE;
425 	}
426 
427 	if (!QDF_IS_STATUS_SUCCESS(qdf_mutex_destroy(
428 		&pm_ctx->qdf_conc_list_lock))) {
429 		policy_mgr_err("Failed to destroy qdf_conc_list_lock");
430 		QDF_ASSERT(0);
431 		return QDF_STATUS_E_FAILURE;
432 	}
433 
434 	if (pm_ctx->hw_mode.hw_mode_list) {
435 		qdf_mem_free(pm_ctx->hw_mode.hw_mode_list);
436 		pm_ctx->hw_mode.hw_mode_list = NULL;
437 		policy_mgr_debug("HW list is freed");
438 	}
439 
440 	if (pm_ctx->sta_ap_intf_check_work_info) {
441 		qdf_delayed_work_destroy(&pm_ctx->sta_ap_intf_check_work);
442 		qdf_mem_free(pm_ctx->sta_ap_intf_check_work_info);
443 		pm_ctx->sta_ap_intf_check_work_info = NULL;
444 	}
445 
446 	return QDF_STATUS_SUCCESS;
447 }
448 
449 #ifdef FEATURE_NO_DBS_INTRABAND_MCC_SUPPORT
450 static void policy_mgr_init_non_dbs_pcl(struct wlan_objmgr_psoc *psoc)
451 {
452 	struct wmi_unified *wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
453 
454 	if (!wmi_handle) {
455 		policy_mgr_debug("Invalid WMI handle");
456 		return;
457 	}
458 
459 	if (wmi_service_enabled(wmi_handle,
460 				wmi_service_no_interband_mcc_support) &&
461 	    !wmi_service_enabled(wmi_handle,
462 				wmi_service_dual_band_simultaneous_support)) {
463 		second_connection_pcl_non_dbs_table =
464 		&second_connection_pcl_nodbs_no_interband_mcc_table;
465 		third_connection_pcl_non_dbs_table =
466 		&third_connection_pcl_nodbs_no_interband_mcc_table;
467 	} else {
468 		second_connection_pcl_non_dbs_table =
469 		&second_connection_pcl_nodbs_table;
470 		third_connection_pcl_non_dbs_table =
471 		&third_connection_pcl_nodbs_table;
472 	}
473 }
474 #else
475 static void policy_mgr_init_non_dbs_pcl(struct wlan_objmgr_psoc *psoc)
476 {
477 	second_connection_pcl_non_dbs_table =
478 	&second_connection_pcl_nodbs_table;
479 	third_connection_pcl_non_dbs_table =
480 	&third_connection_pcl_nodbs_table;
481 }
482 #endif
483 
484 #ifdef WLAN_FEATURE_11BE_MLO
485 static inline void policy_mgr_memzero_disabled_ml_list(void)
486 {
487 	qdf_mem_zero(pm_disabled_ml_links, sizeof(pm_disabled_ml_links));
488 }
489 
490 static QDF_STATUS
491 policy_mgr_init_ml_link_update(struct policy_mgr_psoc_priv_obj *pm_ctx)
492 {
493 	QDF_STATUS qdf_status;
494 
495 	qdf_atomic_init(&pm_ctx->link_in_progress);
496 	qdf_status = qdf_event_create(&pm_ctx->set_link_update_done_evt);
497 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
498 		policy_mgr_err("init event failed for for set_link_update_done_evt");
499 		return QDF_STATUS_E_FAILURE;
500 	}
501 
502 	return QDF_STATUS_SUCCESS;
503 }
504 
505 static QDF_STATUS
506 policy_mgr_deinit_ml_link_update(struct policy_mgr_psoc_priv_obj *pm_ctx)
507 {
508 	QDF_STATUS qdf_status;
509 
510 	qdf_atomic_set(&pm_ctx->link_in_progress, 0);
511 	qdf_status = qdf_event_destroy(&pm_ctx->set_link_update_done_evt);
512 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
513 		policy_mgr_err("deinit event failed for set_link_update_done_evt");
514 		return QDF_STATUS_E_FAILURE;
515 	}
516 
517 	return QDF_STATUS_SUCCESS;
518 }
519 
520 #else
521 static inline void policy_mgr_memzero_disabled_ml_list(void) {}
522 
523 static inline QDF_STATUS
524 policy_mgr_init_ml_link_update(struct policy_mgr_psoc_priv_obj *pm_ctx)
525 {
526 	return QDF_STATUS_SUCCESS;
527 }
528 
529 static inline QDF_STATUS
530 policy_mgr_deinit_ml_link_update(struct policy_mgr_psoc_priv_obj *pm_ctx)
531 {
532 	return QDF_STATUS_SUCCESS;
533 }
534 #endif
535 
536 QDF_STATUS policy_mgr_psoc_enable(struct wlan_objmgr_psoc *psoc)
537 {
538 	QDF_STATUS status;
539 	struct policy_mgr_psoc_priv_obj *pm_ctx;
540 	bool enable_mcc_adaptive_sch = false;
541 
542 	pm_ctx = policy_mgr_get_context(psoc);
543 	if (!pm_ctx) {
544 		policy_mgr_err("Invalid Context");
545 		return QDF_STATUS_E_FAILURE;
546 	}
547 
548 	policy_mgr_debug("Initializing the policy manager");
549 
550 	/* init pm_conc_connection_list */
551 	qdf_mem_zero(pm_conc_connection_list, sizeof(pm_conc_connection_list));
552 	policy_mgr_memzero_disabled_ml_list();
553 	policy_mgr_clear_concurrent_session_count(psoc);
554 	/* init dbs_opportunistic_timer */
555 	status = qdf_mc_timer_init(&pm_ctx->dbs_opportunistic_timer,
556 				QDF_TIMER_TYPE_SW,
557 				pm_dbs_opportunistic_timer_handler,
558 				(void *)psoc);
559 	if (!QDF_IS_STATUS_SUCCESS(status)) {
560 		policy_mgr_err("Failed to init DBS opportunistic timer");
561 		return status;
562 	}
563 
564 	status = policy_mgr_init_ml_link_update(pm_ctx);
565 	if (QDF_IS_STATUS_ERROR(status))
566 		return status;
567 
568 	/* init connection_update_done_evt */
569 	status = policy_mgr_init_connection_update(pm_ctx);
570 	if (!QDF_IS_STATUS_SUCCESS(status)) {
571 		policy_mgr_err("connection_update_done_evt init failed");
572 		return status;
573 	}
574 
575 	status = qdf_event_create(&pm_ctx->opportunistic_update_done_evt);
576 	if (!QDF_IS_STATUS_SUCCESS(status)) {
577 		policy_mgr_err("opportunistic_update_done_evt init failed");
578 		return status;
579 	}
580 
581 	status = qdf_event_create(&pm_ctx->channel_switch_complete_evt);
582 	if (!QDF_IS_STATUS_SUCCESS(status)) {
583 		policy_mgr_err("channel_switch_complete_evt init failed");
584 		return status;
585 	}
586 	policy_mgr_get_mcc_adaptive_sch(psoc, &enable_mcc_adaptive_sch);
587 	policy_mgr_set_dynamic_mcc_adaptive_sch(psoc, enable_mcc_adaptive_sch);
588 	pm_ctx->hw_mode_change_in_progress = POLICY_MGR_HW_MODE_NOT_IN_PROGRESS;
589 	/* reset sap mandatory channels */
590 	status = policy_mgr_reset_sap_mandatory_channels(psoc);
591 	if (QDF_IS_STATUS_ERROR(status)) {
592 		policy_mgr_err("failed to reset mandatory channels");
593 		return status;
594 	}
595 
596 	/* init PCL table & function pointers based on HW capability */
597 	if (policy_mgr_is_hw_dbs_2x2_capable(psoc) ||
598 	    policy_mgr_is_hw_dbs_required_for_band(psoc, HW_MODE_MAC_BAND_2G))
599 		policy_mgr_get_current_pref_hw_mode_ptr =
600 		policy_mgr_get_current_pref_hw_mode_dbs_2x2;
601 	else if (policy_mgr_is_2x2_1x1_dbs_capable(psoc))
602 		policy_mgr_get_current_pref_hw_mode_ptr =
603 		policy_mgr_get_current_pref_hw_mode_dual_dbs;
604 	else
605 		policy_mgr_get_current_pref_hw_mode_ptr =
606 		policy_mgr_get_current_pref_hw_mode_dbs_1x1;
607 
608 	if (policy_mgr_is_hw_dbs_2x2_capable(psoc) &&
609 	    policy_mgr_is_hw_sbs_capable(psoc))
610 		second_connection_pcl_dbs_table =
611 		&pm_second_connection_pcl_dbs_sbs_2x2_table;
612 	else if (policy_mgr_is_hw_dbs_2x2_capable(psoc) ||
613 	    policy_mgr_is_hw_dbs_required_for_band(psoc,
614 						   HW_MODE_MAC_BAND_2G) ||
615 	    policy_mgr_is_2x2_1x1_dbs_capable(psoc))
616 		second_connection_pcl_dbs_table =
617 		&pm_second_connection_pcl_dbs_2x2_table;
618 	else
619 		second_connection_pcl_dbs_table =
620 		&pm_second_connection_pcl_dbs_1x1_table;
621 
622 	if (policy_mgr_is_hw_dbs_2x2_capable(psoc) &&
623 	    policy_mgr_is_hw_sbs_capable(psoc))
624 		third_connection_pcl_dbs_table =
625 		&pm_third_connection_pcl_dbs_sbs_2x2_table;
626 	else if (policy_mgr_is_hw_dbs_2x2_capable(psoc) ||
627 	    policy_mgr_is_hw_dbs_required_for_band(psoc,
628 						   HW_MODE_MAC_BAND_2G) ||
629 	    policy_mgr_is_2x2_1x1_dbs_capable(psoc))
630 		third_connection_pcl_dbs_table =
631 		&pm_third_connection_pcl_dbs_2x2_table;
632 	else
633 		third_connection_pcl_dbs_table =
634 		&pm_third_connection_pcl_dbs_1x1_table;
635 
636 	/* Initialize non-DBS pcl table pointer to particular table*/
637 	policy_mgr_init_non_dbs_pcl(psoc);
638 
639 	if (policy_mgr_is_hw_dbs_2x2_capable(psoc)) {
640 		if (policy_mgr_is_hw_dbs_required_for_band(psoc,
641 							HW_MODE_MAC_BAND_2G)) {
642 			next_action_two_connection_table =
643 				&pm_next_action_two_connection_dbs_2x2_table;
644 			policy_mgr_debug("using hst/hsp policy manager table");
645 		} else {
646 			next_action_two_connection_table =
647 			      &pm_next_action_two_connection_dbs_2x2_table_v2;
648 			policy_mgr_debug("using hmt policy manager table");
649 		}
650 	} else if (policy_mgr_is_2x2_1x1_dbs_capable(psoc)) {
651 		next_action_two_connection_table =
652 		&pm_next_action_two_connection_dbs_2x2_5g_1x1_2g_table;
653 		next_action_two_connection_2x2_2g_1x1_5g_table =
654 		&pm_next_action_two_connection_dbs_2x2_2g_1x1_5g_table;
655 	} else {
656 		next_action_two_connection_table =
657 		&pm_next_action_two_connection_dbs_1x1_table;
658 	}
659 
660 	if (policy_mgr_is_hw_dbs_2x2_capable(psoc) ||
661 	    policy_mgr_is_hw_dbs_required_for_band(psoc,
662 						   HW_MODE_MAC_BAND_2G)) {
663 		next_action_three_connection_table =
664 		&pm_next_action_three_connection_dbs_2x2_table;
665 	} else if (policy_mgr_is_2x2_1x1_dbs_capable(psoc)) {
666 		next_action_three_connection_table =
667 		&pm_next_action_three_connection_dbs_2x2_5g_1x1_2g_table;
668 		next_action_three_connection_2x2_2g_1x1_5g_table =
669 		&pm_next_action_three_connection_dbs_2x2_2g_1x1_5g_table;
670 	} else {
671 		next_action_three_connection_table =
672 		&pm_next_action_three_connection_dbs_1x1_table;
673 	}
674 	policy_mgr_debug("is DBS Capable %d, is SBS Capable %d",
675 			 policy_mgr_is_hw_dbs_capable(psoc),
676 			 policy_mgr_is_hw_sbs_capable(psoc));
677 	policy_mgr_debug("is2x2 %d, 2g-on-dbs %d is2x2+1x1 %d, is2x2_5g+1x1_2g %d, is2x2_2g+1x1_5g %d",
678 			 policy_mgr_is_hw_dbs_2x2_capable(psoc),
679 			 policy_mgr_is_hw_dbs_required_for_band(
680 				psoc, HW_MODE_MAC_BAND_2G),
681 			 policy_mgr_is_2x2_1x1_dbs_capable(psoc),
682 			 policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(psoc),
683 			 policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(psoc));
684 
685 	return QDF_STATUS_SUCCESS;
686 }
687 
688 QDF_STATUS policy_mgr_psoc_disable(struct wlan_objmgr_psoc *psoc)
689 {
690 	QDF_STATUS status = QDF_STATUS_SUCCESS;
691 	struct policy_mgr_psoc_priv_obj *pm_ctx;
692 
693 	pm_ctx = policy_mgr_get_context(psoc);
694 	if (!pm_ctx) {
695 		policy_mgr_err("Invalid Context");
696 		return QDF_STATUS_E_FAILURE;
697 	}
698 
699 	/* destroy connection_update_done_evt */
700 	if (!QDF_IS_STATUS_SUCCESS(qdf_event_destroy
701 		(&pm_ctx->connection_update_done_evt))) {
702 		policy_mgr_err("Failed to destroy connection_update_done_evt");
703 		status = QDF_STATUS_E_FAILURE;
704 		QDF_ASSERT(0);
705 	}
706 
707 	/* destroy opportunistic_update_done_evt */
708 	if (!QDF_IS_STATUS_SUCCESS(qdf_event_destroy
709 		(&pm_ctx->opportunistic_update_done_evt))) {
710 		policy_mgr_err("Failed to destroy opportunistic_update_done_evt");
711 		status = QDF_STATUS_E_FAILURE;
712 		QDF_ASSERT(0);
713 	}
714 	/* destroy channel_switch_complete_evt */
715 	if (!QDF_IS_STATUS_SUCCESS(qdf_event_destroy
716 		(&pm_ctx->channel_switch_complete_evt))) {
717 		policy_mgr_err("Failed to destroy channel_switch_complete evt");
718 		status = QDF_STATUS_E_FAILURE;
719 		QDF_ASSERT(0);
720 	}
721 
722 	if (QDF_IS_STATUS_ERROR(policy_mgr_deinit_ml_link_update(pm_ctx))) {
723 		status = QDF_STATUS_E_FAILURE;
724 		QDF_ASSERT(0);
725 	}
726 
727 	/* deallocate dbs_opportunistic_timer */
728 	if (QDF_TIMER_STATE_RUNNING ==
729 			qdf_mc_timer_get_current_state(
730 				&pm_ctx->dbs_opportunistic_timer)) {
731 		qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer);
732 	}
733 
734 	if (!QDF_IS_STATUS_SUCCESS(qdf_mc_timer_destroy(
735 			&pm_ctx->dbs_opportunistic_timer))) {
736 		policy_mgr_err("Cannot deallocate dbs opportunistic timer");
737 		status = QDF_STATUS_E_FAILURE;
738 		QDF_ASSERT(0);
739 	}
740 
741 	/* reset sap mandatory channels */
742 	if (QDF_IS_STATUS_ERROR(
743 		policy_mgr_reset_sap_mandatory_channels(psoc))) {
744 		policy_mgr_err("failed to reset sap mandatory channels");
745 		status = QDF_STATUS_E_FAILURE;
746 		QDF_ASSERT(0);
747 	}
748 
749 	/* deinit pm_conc_connection_list */
750 	qdf_mem_zero(pm_conc_connection_list, sizeof(pm_conc_connection_list));
751 	policy_mgr_clear_concurrent_session_count(psoc);
752 
753 	return status;
754 }
755 
756 QDF_STATUS policy_mgr_register_conc_cb(struct wlan_objmgr_psoc *psoc,
757 				struct policy_mgr_conc_cbacks *conc_cbacks)
758 {
759 	struct policy_mgr_psoc_priv_obj *pm_ctx;
760 
761 	pm_ctx = policy_mgr_get_context(psoc);
762 	if (!pm_ctx) {
763 		policy_mgr_err("Invalid Context");
764 		return QDF_STATUS_E_FAILURE;
765 	}
766 
767 	pm_ctx->conc_cbacks.connection_info_update =
768 					conc_cbacks->connection_info_update;
769 	return QDF_STATUS_SUCCESS;
770 }
771 
772 QDF_STATUS policy_mgr_register_sme_cb(struct wlan_objmgr_psoc *psoc,
773 		struct policy_mgr_sme_cbacks *sme_cbacks)
774 {
775 	struct policy_mgr_psoc_priv_obj *pm_ctx;
776 
777 	pm_ctx = policy_mgr_get_context(psoc);
778 	if (!pm_ctx) {
779 		policy_mgr_err("Invalid Context");
780 		return QDF_STATUS_E_FAILURE;
781 	}
782 
783 	pm_ctx->sme_cbacks.sme_get_nss_for_vdev =
784 		sme_cbacks->sme_get_nss_for_vdev;
785 	pm_ctx->sme_cbacks.sme_nss_update_request =
786 		sme_cbacks->sme_nss_update_request;
787 	if (!policy_mgr_is_hwmode_offload_enabled(psoc))
788 		pm_ctx->sme_cbacks.sme_pdev_set_hw_mode =
789 			sme_cbacks->sme_pdev_set_hw_mode;
790 	pm_ctx->sme_cbacks.sme_soc_set_dual_mac_config =
791 		sme_cbacks->sme_soc_set_dual_mac_config;
792 	pm_ctx->sme_cbacks.sme_change_mcc_beacon_interval =
793 		sme_cbacks->sme_change_mcc_beacon_interval;
794 	pm_ctx->sme_cbacks.sme_rso_start_cb =
795 		sme_cbacks->sme_rso_start_cb;
796 	pm_ctx->sme_cbacks.sme_rso_stop_cb =
797 		sme_cbacks->sme_rso_stop_cb;
798 	pm_ctx->sme_cbacks.sme_change_sap_csa_count =
799 		sme_cbacks->sme_change_sap_csa_count;
800 	pm_ctx->sme_cbacks.sme_sap_update_ch_width =
801 		sme_cbacks->sme_sap_update_ch_width;
802 
803 	return QDF_STATUS_SUCCESS;
804 }
805 
806 /**
807  * policy_mgr_register_hdd_cb() - register HDD callbacks
808  * @psoc: PSOC object information
809  * @hdd_cbacks: function pointers from HDD
810  *
811  * API, allows HDD to register callbacks to be invoked by policy
812  * mgr
813  *
814  * Return: SUCCESS,
815  *         Failure (if registration fails)
816  */
817 QDF_STATUS policy_mgr_register_hdd_cb(struct wlan_objmgr_psoc *psoc,
818 		struct policy_mgr_hdd_cbacks *hdd_cbacks)
819 {
820 	struct policy_mgr_psoc_priv_obj *pm_ctx;
821 
822 	pm_ctx = policy_mgr_get_context(psoc);
823 	if (!pm_ctx) {
824 		policy_mgr_err("Invalid Context");
825 		return QDF_STATUS_E_FAILURE;
826 	}
827 
828 	pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb =
829 		hdd_cbacks->sap_restart_chan_switch_cb;
830 	pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart =
831 		hdd_cbacks->wlan_hdd_get_channel_for_sap_restart;
832 	pm_ctx->hdd_cbacks.get_mode_for_non_connected_vdev =
833 		hdd_cbacks->get_mode_for_non_connected_vdev;
834 	pm_ctx->hdd_cbacks.hdd_get_device_mode =
835 		hdd_cbacks->hdd_get_device_mode;
836 	pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress =
837 		hdd_cbacks->hdd_is_chan_switch_in_progress;
838 	pm_ctx->hdd_cbacks.hdd_is_cac_in_progress =
839 		hdd_cbacks->hdd_is_cac_in_progress;
840 	pm_ctx->hdd_cbacks.hdd_get_ap_6ghz_capable =
841 		hdd_cbacks->hdd_get_ap_6ghz_capable;
842 	pm_ctx->hdd_cbacks.wlan_hdd_indicate_active_ndp_cnt =
843 		hdd_cbacks->wlan_hdd_indicate_active_ndp_cnt;
844 	pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params =
845 		hdd_cbacks->wlan_get_ap_prefer_conc_ch_params;
846 	pm_ctx->hdd_cbacks.wlan_get_sap_acs_band =
847 		hdd_cbacks->wlan_get_sap_acs_band;
848 	pm_ctx->hdd_cbacks.wlan_check_cc_intf_cb =
849 		hdd_cbacks->wlan_check_cc_intf_cb;
850 	pm_ctx->hdd_cbacks.wlan_set_tx_rx_nss_cb =
851 		hdd_cbacks->wlan_set_tx_rx_nss_cb;
852 
853 	return QDF_STATUS_SUCCESS;
854 }
855 
856 QDF_STATUS policy_mgr_deregister_hdd_cb(struct wlan_objmgr_psoc *psoc)
857 {
858 	struct policy_mgr_psoc_priv_obj *pm_ctx;
859 
860 	pm_ctx = policy_mgr_get_context(psoc);
861 	if (!pm_ctx) {
862 		policy_mgr_err("Invalid Context");
863 		return QDF_STATUS_E_FAILURE;
864 	}
865 
866 	pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb = NULL;
867 	pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart = NULL;
868 	pm_ctx->hdd_cbacks.get_mode_for_non_connected_vdev = NULL;
869 	pm_ctx->hdd_cbacks.hdd_get_device_mode = NULL;
870 	pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress = NULL;
871 	pm_ctx->hdd_cbacks.hdd_is_cac_in_progress = NULL;
872 	pm_ctx->hdd_cbacks.hdd_get_ap_6ghz_capable = NULL;
873 	pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params = NULL;
874 	pm_ctx->hdd_cbacks.wlan_get_sap_acs_band = NULL;
875 	pm_ctx->hdd_cbacks.wlan_set_tx_rx_nss_cb = NULL;
876 
877 	return QDF_STATUS_SUCCESS;
878 }
879 
880 QDF_STATUS policy_mgr_register_wma_cb(struct wlan_objmgr_psoc *psoc,
881 		struct policy_mgr_wma_cbacks *wma_cbacks)
882 {
883 	struct policy_mgr_psoc_priv_obj *pm_ctx;
884 
885 	pm_ctx = policy_mgr_get_context(psoc);
886 	if (!pm_ctx) {
887 		policy_mgr_err("Invalid Context");
888 		return QDF_STATUS_E_FAILURE;
889 	}
890 
891 	pm_ctx->wma_cbacks.wma_get_connection_info =
892 		wma_cbacks->wma_get_connection_info;
893 
894 	return QDF_STATUS_SUCCESS;
895 }
896 
897 QDF_STATUS policy_mgr_register_cdp_cb(struct wlan_objmgr_psoc *psoc,
898 		struct policy_mgr_cdp_cbacks *cdp_cbacks)
899 {
900 	struct policy_mgr_psoc_priv_obj *pm_ctx;
901 
902 	pm_ctx = policy_mgr_get_context(psoc);
903 	if (!pm_ctx) {
904 		policy_mgr_err("Invalid Context");
905 		return QDF_STATUS_E_FAILURE;
906 	}
907 
908 	pm_ctx->cdp_cbacks.cdp_update_mac_id =
909 		cdp_cbacks->cdp_update_mac_id;
910 
911 	return QDF_STATUS_SUCCESS;
912 }
913 
914 QDF_STATUS policy_mgr_register_dp_cb(struct wlan_objmgr_psoc *psoc,
915 		struct policy_mgr_dp_cbacks *dp_cbacks)
916 {
917 	struct policy_mgr_psoc_priv_obj *pm_ctx;
918 
919 	pm_ctx = policy_mgr_get_context(psoc);
920 	if (!pm_ctx) {
921 		policy_mgr_err("Invalid Context");
922 		return QDF_STATUS_E_FAILURE;
923 	}
924 
925 	pm_ctx->dp_cbacks.hdd_disable_rx_ol_in_concurrency =
926 		dp_cbacks->hdd_disable_rx_ol_in_concurrency;
927 	pm_ctx->dp_cbacks.hdd_set_rx_mode_rps_cb =
928 		dp_cbacks->hdd_set_rx_mode_rps_cb;
929 	pm_ctx->dp_cbacks.hdd_ipa_set_mcc_mode_cb =
930 		dp_cbacks->hdd_ipa_set_mcc_mode_cb;
931 	pm_ctx->dp_cbacks.hdd_v2_flow_pool_map =
932 		dp_cbacks->hdd_v2_flow_pool_map;
933 	pm_ctx->dp_cbacks.hdd_v2_flow_pool_unmap =
934 		dp_cbacks->hdd_v2_flow_pool_unmap;
935 	pm_ctx->dp_cbacks.hdd_ipa_set_perf_level_bw =
936 		dp_cbacks->hdd_ipa_set_perf_level_bw;
937 
938 	return QDF_STATUS_SUCCESS;
939 }
940 
941 QDF_STATUS policy_mgr_register_tdls_cb(struct wlan_objmgr_psoc *psoc,
942 		struct policy_mgr_tdls_cbacks *tdls_cbacks)
943 {
944 	struct policy_mgr_psoc_priv_obj *pm_ctx;
945 
946 	pm_ctx = policy_mgr_get_context(psoc);
947 	if (!pm_ctx) {
948 		policy_mgr_err("Invalid Context");
949 		return QDF_STATUS_E_FAILURE;
950 	}
951 
952 	pm_ctx->tdls_cbacks.tdls_notify_increment_session =
953 		tdls_cbacks->tdls_notify_increment_session;
954 	pm_ctx->tdls_cbacks.tdls_notify_decrement_session =
955 		tdls_cbacks->tdls_notify_decrement_session;
956 
957 	return QDF_STATUS_SUCCESS;
958 }
959 
960 QDF_STATUS policy_mgr_register_mode_change_cb(struct wlan_objmgr_psoc *psoc,
961 	send_mode_change_event_cb mode_change_cb)
962 {
963 	struct policy_mgr_psoc_priv_obj *pm_ctx;
964 
965 	pm_ctx = policy_mgr_get_context(psoc);
966 	if (!pm_ctx) {
967 		policy_mgr_err("Invalid Context");
968 		return QDF_STATUS_E_FAILURE;
969 	}
970 
971 	pm_ctx->mode_change_cb = mode_change_cb;
972 
973 	return QDF_STATUS_SUCCESS;
974 }
975 
976 QDF_STATUS policy_mgr_deregister_mode_change_cb(struct wlan_objmgr_psoc *psoc)
977 {
978 	struct policy_mgr_psoc_priv_obj *pm_ctx;
979 
980 	pm_ctx = policy_mgr_get_context(psoc);
981 	if (!pm_ctx) {
982 		policy_mgr_err("Invalid Context");
983 		return QDF_STATUS_E_FAILURE;
984 	}
985 
986 	pm_ctx->mode_change_cb = NULL;
987 
988 	return QDF_STATUS_SUCCESS;
989 }
990