xref: /wlan-dirver/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_init_deinit_api.c (revision 901120c066e139c7f8a2c8e4820561fdd83c67ef) !
1 /*
2  * Copyright (c) 2016-2021 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 init/deint functions for DFS module.
22  */
23 
24 #include "wlan_dfs_ucfg_api.h"
25 #include "wlan_dfs_tgt_api.h"
26 #include <wlan_objmgr_vdev_obj.h>
27 #include "wlan_dfs_utils_api.h"
28 #ifndef MOBILE_DFS_SUPPORT
29 #include "ieee80211_mlme_dfs_interface.h"
30 #endif
31 #include "wlan_objmgr_global_obj.h"
32 #include "wlan_dfs_init_deinit_api.h"
33 #include "wlan_dfs_lmac_api.h"
34 #include "../../core/src/dfs.h"
35 #include "a_types.h"
36 #include "wlan_serialization_api.h"
37 #include <qdf_trace.h>
38 #include "wlan_scan_ucfg_api.h"
39 #include "wlan_dfs_mlme_api.h"
40 #include "../../core/src/dfs_zero_cac.h"
41 
42 struct dfs_to_mlme global_dfs_to_mlme;
43 
44 struct wlan_dfs *wlan_pdev_get_dfs_obj(struct wlan_objmgr_pdev *pdev)
45 {
46 	struct wlan_dfs *dfs;
47 	dfs = wlan_objmgr_pdev_get_comp_private_obj(pdev,
48 			WLAN_UMAC_COMP_DFS);
49 
50 	return dfs;
51 }
52 
53 /*
54  * register_dfs_precac_auto_chan_callbacks_freq() - Register auto chan switch
55  * frequency based APIs callback.
56  * @mlme_callback: Pointer to dfs_to_mlme.
57  */
58 #ifndef MOBILE_DFS_SUPPORT
59 #if defined(WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT) && defined(CONFIG_CHAN_FREQ_API)
60 static inline void
61 register_dfs_precac_auto_chan_callbacks_freq(struct dfs_to_mlme *mlme_callback)
62 {
63 	if (!mlme_callback)
64 		return;
65 
66 	mlme_callback->mlme_precac_chan_change_csa_for_freq =
67 		mlme_dfs_precac_chan_change_csa_for_freq;
68 }
69 #else
70 static inline void
71 register_dfs_precac_auto_chan_callbacks_freq(struct dfs_to_mlme *mlme_callback)
72 {
73 }
74 #endif
75 #endif
76 
77 /**
78  * register_dfs_postnol_csa_callback - Register CSA callback
79  * @mlme_callback: Pointer to dfs_to_mlme.
80  */
81 #ifndef MOBILE_DFS_SUPPORT
82 #if defined(QCA_SUPPORT_DFS_CHAN_POSTNOL) || defined(QCA_DFS_BW_EXPAND)
83 static inline void
84 register_dfs_postnol_csa_callback(struct dfs_to_mlme *mlme_callback)
85 {
86 	if (!mlme_callback)
87 		return;
88 
89 	mlme_callback->mlme_postnol_chan_switch =
90 		mlme_dfs_postnol_chan_switch;
91 }
92 #else
93 static inline void
94 register_dfs_postnol_csa_callback(struct dfs_to_mlme *mlme_callback)
95 {
96 }
97 #endif
98 #endif
99 
100 /*
101  * register_dfs_callbacks_for_freq() - Register dfs callbacks.
102  * @mlme_callback: Pointer to dfs_to_mlme.
103  */
104 #ifndef MOBILE_DFS_SUPPORT
105 #ifdef CONFIG_CHAN_FREQ_API
106 static inline void
107 register_dfs_callbacks_for_freq(struct dfs_to_mlme *mlme_callback)
108 {
109 	if (!mlme_callback)
110 		return;
111 
112 	mlme_callback->mlme_find_dot11_chan_for_freq =
113 		mlme_dfs_find_dot11_chan_for_freq;
114 	mlme_callback->mlme_get_cac_timeout_for_freq =
115 		mlme_dfs_get_cac_timeout_for_freq;
116 	mlme_callback->mlme_get_extchan_for_freq =
117 		mlme_dfs_get_extchan_for_freq;
118 	mlme_callback->mlme_start_csa_for_freq = mlme_dfs_start_csa_for_freq;
119 }
120 #endif
121 #endif
122 
123 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST)
124 static void register_dfs_callbacks_spoof_success_failure(
125 		struct dfs_to_mlme *tmp_dfs_to_mlme)
126 {
127 	tmp_dfs_to_mlme->mlme_rebuild_chan_list_with_non_dfs_channels =
128 		mlme_dfs_rebuild_chan_list_with_non_dfs_channels;
129 	tmp_dfs_to_mlme->mlme_proc_spoof_success =
130 		mlme_dfs_proc_spoof_success;
131 }
132 #else
133 static inline void register_dfs_callbacks_spoof_success_failure(
134 		struct dfs_to_mlme *tmp_dfs_to_mlme)
135 {
136 }
137 #endif
138 
139 #ifndef MOBILE_DFS_SUPPORT
140 void register_dfs_callbacks(void)
141 {
142 	struct dfs_to_mlme *tmp_dfs_to_mlme = &global_dfs_to_mlme;
143 
144 	tmp_dfs_to_mlme->pdev_component_obj_attach =
145 		wlan_objmgr_pdev_component_obj_attach;
146 	tmp_dfs_to_mlme->pdev_component_obj_detach =
147 		wlan_objmgr_pdev_component_obj_detach;
148 
149 	tmp_dfs_to_mlme->dfs_start_rcsa = mlme_dfs_start_rcsa;
150 	tmp_dfs_to_mlme->mlme_proc_cac = mlme_dfs_proc_cac;
151 	tmp_dfs_to_mlme->mlme_deliver_event_up_after_cac =
152 		mlme_dfs_deliver_event_up_after_cac;
153 	tmp_dfs_to_mlme->mlme_set_no_chans_available =
154 		mlme_dfs_set_no_chans_available;
155 	tmp_dfs_to_mlme->mlme_ieee2mhz = mlme_dfs_ieee2mhz;
156 	tmp_dfs_to_mlme->mlme_dfs_ch_flags_ext = mlme_dfs_dfs_ch_flags_ext;
157 	tmp_dfs_to_mlme->mlme_channel_change_by_precac =
158 		mlme_dfs_channel_change_by_precac;
159 	tmp_dfs_to_mlme->mlme_nol_timeout_notification =
160 		mlme_dfs_nol_timeout_notification;
161 	tmp_dfs_to_mlme->mlme_clist_update = mlme_dfs_clist_update;
162 
163 	register_dfs_callbacks_spoof_success_failure(tmp_dfs_to_mlme);
164 
165 	tmp_dfs_to_mlme->mlme_restart_vaps_with_non_dfs_chan =
166 		mlme_dfs_restart_vaps_with_non_dfs_chan;
167 	tmp_dfs_to_mlme->mlme_is_opmode_sta =
168 		mlme_dfs_is_opmode_sta;
169 	tmp_dfs_to_mlme->mlme_check_allowed_prim_chanlist =
170 		mlme_dfs_check_allowed_prim_chanlist;
171 	tmp_dfs_to_mlme->mlme_update_scan_channel_list =
172 		mlme_dfs_update_scan_channel_list;
173 	tmp_dfs_to_mlme->mlme_bringdown_vaps =
174 		mlme_dfs_bringdown_vaps;
175 	tmp_dfs_to_mlme->mlme_dfs_deliver_event =
176 		mlme_dfs_deliver_event;
177 	tmp_dfs_to_mlme->mlme_is_inter_band_chan_switch_allowed =
178 		mlme_is_inter_band_chan_switch_allowed;
179 
180 	tmp_dfs_to_mlme->mlme_acquire_radar_mode_switch_lock =
181 		mlme_acquire_radar_mode_switch_lock;
182 	tmp_dfs_to_mlme->mlme_release_radar_mode_switch_lock =
183 		mlme_release_radar_mode_switch_lock;
184 	tmp_dfs_to_mlme->mlme_mark_dfs =
185 		mlme_dfs_mark_dfs;
186 	/*
187 	 * Register precac auto channel switch feature related callbacks
188 	 */
189 	register_dfs_precac_auto_chan_callbacks_freq(tmp_dfs_to_mlme);
190 	/* Register freq based callbacks */
191 	register_dfs_callbacks_for_freq(tmp_dfs_to_mlme);
192 	register_dfs_postnol_csa_callback(tmp_dfs_to_mlme);
193 }
194 #else
195 void register_dfs_callbacks(void)
196 {
197 	struct dfs_to_mlme *tmp_dfs_to_mlme = &global_dfs_to_mlme;
198 
199 	tmp_dfs_to_mlme->pdev_component_obj_attach =
200 		wlan_objmgr_pdev_component_obj_attach;
201 	tmp_dfs_to_mlme->pdev_component_obj_detach =
202 		wlan_objmgr_pdev_component_obj_detach;
203 }
204 #endif
205 
206 /**
207  * dfs_psoc_obj_create_notification() - dfs psoc create notification handler
208  * @psoc: psoc object
209  * @arg_list: Argument list
210  *
211  * Return: QDF_STATUS
212  */
213 static QDF_STATUS dfs_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc,
214 					     void *arg_list)
215 {
216 	QDF_STATUS status;
217 	struct dfs_soc_priv_obj *dfs_soc_obj;
218 
219 	dfs_soc_obj = qdf_mem_malloc(sizeof(*dfs_soc_obj));
220 	if (!dfs_soc_obj)
221 		return QDF_STATUS_E_NOMEM;
222 
223 	dfs_soc_obj->psoc = psoc;
224 
225 	status = wlan_objmgr_psoc_component_obj_attach(psoc,
226 						       WLAN_UMAC_COMP_DFS,
227 						       (void *)dfs_soc_obj,
228 						       QDF_STATUS_SUCCESS);
229 
230 	if (QDF_IS_STATUS_ERROR(status)) {
231 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
232 			"Failed to attach psoc dfs component");
233 		qdf_mem_free(dfs_soc_obj);
234 		return status;
235 	}
236 	/* Initialize precac timer here*/
237 	dfs_zero_cac_timer_init(dfs_soc_obj);
238 
239 	/* Initialize Rolling CAC timer */
240 	dfs_rcac_timer_init(dfs_soc_obj);
241 
242 	/* DFS Agile SM initialization */
243 	dfs_agile_sm_create(dfs_soc_obj);
244 
245 	dfs_debug(NULL, WLAN_DEBUG_DFS1,
246 		"DFS obj attach to psoc successfully");
247 
248 	return status;
249 }
250 
251 /**
252  * dfs_psoc_obj_destroy_notification() - dfs psoc destroy notification handler
253  * @psoc: psoc object
254  * @arg_list: Argument list
255  *
256  * Return: QDF_STATUS
257  */
258 static QDF_STATUS dfs_psoc_obj_destroy_notification(struct wlan_objmgr_psoc *psoc,
259 					      void *arg_list)
260 {
261 	QDF_STATUS status;
262 	struct dfs_soc_priv_obj *dfs_soc_obj;
263 
264 	dfs_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
265 						WLAN_UMAC_COMP_DFS);
266 	if (!dfs_soc_obj) {
267 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
268 			"Failed to get dfs obj in psoc");
269 		return QDF_STATUS_E_FAILURE;
270 	}
271 
272 	/* Delete DFS Agile SM */
273 	dfs_agile_sm_destroy(dfs_soc_obj);
274 
275 	dfs_rcac_timer_deinit(dfs_soc_obj);
276 	dfs_zero_cac_timer_detach(dfs_soc_obj);
277 
278 	status = wlan_objmgr_psoc_component_obj_detach(psoc,
279 						       WLAN_UMAC_COMP_DFS,
280 						       dfs_soc_obj);
281 
282 	if (QDF_IS_STATUS_ERROR(status))
283 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
284 			"Failed to detach psoc dfs component");
285 
286 	qdf_mem_free(dfs_soc_obj);
287 
288 	return status;
289 }
290 
291 QDF_STATUS dfs_init(void)
292 {
293 	QDF_STATUS status;
294 
295 	status = wlan_objmgr_register_psoc_create_handler(WLAN_UMAC_COMP_DFS,
296 			dfs_psoc_obj_create_notification,
297 			NULL);
298 
299 	if (QDF_IS_STATUS_ERROR(status)) {
300 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
301 			"Failed to register psoc create handler for dfs");
302 		goto err_psoc_create;
303 	}
304 
305 	status = wlan_objmgr_register_psoc_destroy_handler(WLAN_UMAC_COMP_DFS,
306 			dfs_psoc_obj_destroy_notification,
307 			NULL);
308 
309 	if (QDF_IS_STATUS_ERROR(status)) {
310 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
311 			"Failed to register psoc delete handler for dfs");
312 		goto err_psoc_delete;
313 	}
314 
315 	register_dfs_callbacks();
316 
317 	status = wlan_objmgr_register_pdev_create_handler(WLAN_UMAC_COMP_DFS,
318 			wlan_dfs_pdev_obj_create_notification,
319 			NULL);
320 
321 	if (QDF_IS_STATUS_ERROR(status)) {
322 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
323 			"Failed to register pdev create handler for dfs");
324 		goto err_pdev_create;
325 	}
326 
327 	status = wlan_objmgr_register_pdev_destroy_handler(WLAN_UMAC_COMP_DFS,
328 			wlan_dfs_pdev_obj_destroy_notification,
329 			NULL);
330 
331 	if (QDF_IS_STATUS_ERROR(status)) {
332 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
333 			"Failed to register pdev delete handler for dfs");
334 		goto err_pdev_delete;
335 	}
336 
337 	status = qdf_print_set_category_verbose(qdf_get_pidx(),
338 						QDF_MODULE_ID_DFS,
339 						QDF_TRACE_LEVEL_DEBUG,
340 						true);
341 
342 	if (QDF_IS_STATUS_ERROR(status)) {
343 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
344 			"Failed to set verbose for category");
345 		goto err_category_verbose;
346 	}
347 
348 	return QDF_STATUS_SUCCESS;
349 
350 err_category_verbose:
351 	wlan_objmgr_unregister_pdev_destroy_handler(WLAN_UMAC_COMP_DFS,
352 			wlan_dfs_pdev_obj_destroy_notification,
353 			NULL);
354 err_pdev_delete:
355 	wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_DFS,
356 			wlan_dfs_pdev_obj_create_notification,
357 			NULL);
358 err_pdev_create:
359 	wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_DFS,
360 			dfs_psoc_obj_destroy_notification,
361 			NULL);
362 err_psoc_delete:
363 	wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_DFS,
364 			dfs_psoc_obj_create_notification,
365 			NULL);
366 err_psoc_create:
367 	return status;
368 }
369 
370 QDF_STATUS dfs_deinit(void)
371 {
372 	QDF_STATUS status;
373 
374 	status = wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_DFS,
375 			dfs_psoc_obj_create_notification,
376 			NULL);
377 
378 	if (QDF_IS_STATUS_ERROR(status))
379 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
380 			"Failed to deregister dfs psoc obj create");
381 
382 	status = wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_DFS,
383 			dfs_psoc_obj_destroy_notification,
384 			NULL);
385 
386 	if (QDF_IS_STATUS_ERROR(status))
387 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
388 			"Failed to deregister dfs psoc obj destroy");
389 
390 	status = wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_DFS,
391 			wlan_dfs_pdev_obj_create_notification,
392 			NULL);
393 
394 	if (QDF_IS_STATUS_ERROR(status))
395 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
396 			"Failed to deregister dfs pdev obj create");
397 
398 	status = wlan_objmgr_unregister_pdev_destroy_handler(WLAN_UMAC_COMP_DFS,
399 			wlan_dfs_pdev_obj_destroy_notification,
400 			NULL);
401 
402 	if (QDF_IS_STATUS_ERROR(status))
403 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
404 			"Failed to deregister dfs pdev obj destroy");
405 
406 	return QDF_STATUS_SUCCESS;
407 }
408 
409 QDF_STATUS wlan_dfs_pdev_obj_create_notification(struct wlan_objmgr_pdev *pdev,
410 		void *arg)
411 {
412 	struct wlan_dfs *dfs = NULL;
413 	struct wlan_objmgr_psoc *psoc;
414 	struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops;
415 	struct dfs_soc_priv_obj *dfs_soc_obj;
416 	uint8_t pdev_id;
417 	QDF_STATUS status;
418 	bool is_5ghz = false;
419 	bool is_6ghz_only_pdev;
420 	qdf_freq_t low_5g, high_5g;
421 
422 	if (!pdev) {
423 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null pdev");
424 		return QDF_STATUS_E_FAILURE;
425 	}
426 
427 	psoc = wlan_pdev_get_psoc(pdev);
428 	if (!psoc) {
429 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null psoc");
430 		return QDF_STATUS_E_FAILURE;
431 	}
432 
433 	wlan_reg_get_freq_range(pdev, NULL, NULL, &low_5g, &high_5g);
434 	is_6ghz_only_pdev = wlan_reg_is_range_only6g(low_5g, high_5g);
435 
436 	if (is_6ghz_only_pdev) {
437 		pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
438 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
439 			 "Do not allocate DFS object for 6G, pdev_id = %d",
440 			 pdev_id);
441 		return QDF_STATUS_SUCCESS;
442 	}
443 
444 	dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc);
445 	if (!(dfs_tx_ops && dfs_tx_ops->dfs_is_pdev_5ghz)) {
446 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs_tx_ops is null");
447 		return QDF_STATUS_E_FAILURE;
448 	}
449 
450 	status = dfs_tx_ops->dfs_is_pdev_5ghz(pdev, &is_5ghz);
451 	if (QDF_IS_STATUS_ERROR(status)) {
452 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "Failed to get is_5ghz value");
453 		return QDF_STATUS_E_FAILURE;
454 	}
455 
456 	if (!is_5ghz) {
457 		pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
458 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
459 				"Do not allocate DFS object for 2G, pdev_id = %d",
460 				pdev_id);
461 		return QDF_STATUS_SUCCESS;
462 	}
463 
464 	if (dfs_create_object(&dfs) == 1) {
465 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "failed to create object");
466 		return QDF_STATUS_E_FAILURE;
467 	}
468 
469 	status = global_dfs_to_mlme.pdev_component_obj_attach(pdev,
470 		WLAN_UMAC_COMP_DFS, (void *)dfs, QDF_STATUS_SUCCESS);
471 	if (QDF_IS_STATUS_ERROR(status)) {
472 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "obj attach failed");
473 		dfs_destroy_object(dfs);
474 		return QDF_STATUS_E_FAILURE;
475 	}
476 
477 	dfs->dfs_pdev_obj = pdev;
478 
479 	if (!dfs_tx_ops->dfs_is_tgt_offload) {
480 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,
481 			"dfs_is_tgt_offload is null");
482 		dfs_destroy_object(dfs);
483 		return QDF_STATUS_E_FAILURE;
484 	}
485 
486 	dfs->dfs_is_offload_enabled = dfs_tx_ops->dfs_is_tgt_offload(psoc);
487 	dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs_offload %d",
488 		 dfs->dfs_is_offload_enabled);
489 
490 	if (!dfs_tx_ops->dfs_is_tgt_bangradar_320_supp) {
491 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,
492 			"dfs_is_tgt_bangradar_320_supp is null");
493 		dfs_destroy_object(dfs);
494 		return QDF_STATUS_E_FAILURE;
495 	}
496 
497 	dfs->dfs_is_bangradar_320_supported =
498 				dfs_tx_ops->dfs_is_tgt_bangradar_320_supp(psoc);
499 	dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs_bangradar_320_support %d",
500 		 dfs->dfs_is_bangradar_320_supported);
501 
502 	if (!dfs_tx_ops->dfs_is_tgt_radar_found_chan_freq_eq_center_freq) {
503 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,
504 			"dfs_is_radar_found_chan_freq_eq_center_freq is null");
505 		dfs_destroy_object(dfs);
506 		return QDF_STATUS_E_FAILURE;
507 	}
508 
509 	dfs->dfs_is_radar_found_chan_freq_eq_center_freq =
510 	    dfs_tx_ops->dfs_is_tgt_radar_found_chan_freq_eq_center_freq(psoc);
511 	dfs_info(dfs, WLAN_DEBUG_DFS,
512 		 "dfs_is_radar_found_chan_freq_eq_center_freq %d",
513 		 dfs->dfs_is_radar_found_chan_freq_eq_center_freq);
514 
515 	dfs_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
516 							    WLAN_UMAC_COMP_DFS);
517 	dfs->dfs_soc_obj = dfs_soc_obj;
518 	dfs_agile_soc_obj_init(dfs, psoc);
519 
520 	if (dfs_attach(dfs) == 1) {
521 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs_attch failed");
522 		dfs_destroy_object(dfs);
523 		return QDF_STATUS_E_FAILURE;
524 	}
525 
526 	return QDF_STATUS_SUCCESS;
527 }
528 
529 QDF_STATUS wlan_dfs_pdev_obj_destroy_notification(struct wlan_objmgr_pdev *pdev,
530 		void *arg)
531 {
532 	struct wlan_dfs *dfs = NULL;
533 
534 	if (!pdev) {
535 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "PDEV is NULL");
536 		return QDF_STATUS_E_FAILURE;
537 	}
538 
539 	dfs = wlan_pdev_get_dfs_obj(pdev);
540 
541 	/* DFS is NULL during unload. should we call this function before */
542 	if (dfs) {
543 		dfs_detach(dfs);
544 		global_dfs_to_mlme.pdev_component_obj_detach(pdev,
545 				WLAN_UMAC_COMP_DFS,
546 				(void *)dfs);
547 
548 		dfs->dfs_pdev_obj = NULL;
549 		dfs_destroy_object(dfs);
550 	}
551 
552 	return QDF_STATUS_SUCCESS;
553 }
554 
555 static void dfs_scan_serialization_comp_info_cb(
556 		struct wlan_objmgr_vdev *vdev,
557 		union wlan_serialization_rules_info *comp_info,
558 		struct wlan_serialization_command *cmd)
559 {
560 	struct wlan_dfs *dfs = NULL;
561 	struct wlan_objmgr_pdev *pdev;
562 
563 	if (!comp_info) {
564 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "comp_info is NULL");
565 		return;
566 	}
567 
568 	if (!vdev) {
569 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "vdev is NULL");
570 		return;
571 	}
572 
573 	pdev = wlan_vdev_get_pdev(vdev);
574 	if (!pdev) {
575 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "pdev is NULL");
576 		return;
577 	}
578 
579 	comp_info->scan_info.is_cac_in_progress = false;
580 
581 	if (!tgt_dfs_is_5ghz_supported_in_pdev(pdev))
582 		return;
583 
584 	dfs = wlan_pdev_get_dfs_obj(pdev);
585 	if (!dfs) {
586 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs is NULL");
587 		return;
588 	}
589 
590 	if (dfs_is_ap_cac_timer_running(dfs))
591 		comp_info->scan_info.is_cac_in_progress = true;
592 }
593 
594 QDF_STATUS wifi_dfs_psoc_enable(struct wlan_objmgr_psoc *psoc)
595 {
596 	QDF_STATUS status;
597 
598 	status = tgt_dfs_reg_ev_handler(psoc);
599 	if (status != QDF_STATUS_SUCCESS) {
600 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,  "tgt_dfs_reg_ev_handler failed");
601 		return QDF_STATUS_E_FAILURE;
602 	}
603 
604 	status = wlan_serialization_register_comp_info_cb(psoc,
605 			WLAN_UMAC_COMP_DFS,
606 			WLAN_SER_CMD_SCAN,
607 			dfs_scan_serialization_comp_info_cb);
608 	if (status != QDF_STATUS_SUCCESS) {
609 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,  "Serialize scan cmd register failed");
610 		return status;
611 	}
612 
613 	return QDF_STATUS_SUCCESS;
614 }
615 
616 QDF_STATUS wifi_dfs_psoc_disable(struct wlan_objmgr_psoc *psoc)
617 {
618 	QDF_STATUS status;
619 
620 	status = wlan_serialization_deregister_comp_info_cb(psoc,
621 			WLAN_UMAC_COMP_DFS,
622 			WLAN_SER_CMD_SCAN);
623 	if (status != QDF_STATUS_SUCCESS) {
624 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,  "Serialize scan cmd deregister failed");
625 		return status;
626 	}
627 
628 	return QDF_STATUS_SUCCESS;
629 }
630