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