xref: /wlan-dirver/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_init_deinit_api.c (revision 6d768494e5ce14eb1603a695c86739d12ecc6ec2)
1 /*
2  * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
3  *
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 QCA_MCL_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 QCA_MCL_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_callbacks_for_freq() - Register dfs callbacks.
79  * @mlme_callback: Pointer to dfs_to_mlme.
80  */
81 #ifndef QCA_MCL_DFS_SUPPORT
82 #ifdef CONFIG_CHAN_FREQ_API
83 static inline void
84 register_dfs_callbacks_for_freq(struct dfs_to_mlme *mlme_callback)
85 {
86 	if (!mlme_callback)
87 		return;
88 
89 	mlme_callback->mlme_mark_dfs_for_freq = mlme_dfs_mark_dfs_for_freq;
90 	mlme_callback->mlme_find_dot11_chan_for_freq =
91 		mlme_dfs_find_dot11_chan_for_freq;
92 	mlme_callback->mlme_get_dfs_channels_for_freq =
93 		mlme_dfs_get_dfs_channels_for_freq;
94 	mlme_callback->mlme_get_cac_timeout_for_freq =
95 		mlme_dfs_get_cac_timeout_for_freq;
96 	mlme_callback->mlme_get_extchan_for_freq =
97 		mlme_dfs_get_extchan_for_freq;
98 	mlme_callback->mlme_start_csa_for_freq = mlme_dfs_start_csa_for_freq;
99 }
100 #endif
101 #endif
102 
103 #ifndef QCA_MCL_DFS_SUPPORT
104 void register_dfs_callbacks(void)
105 {
106 	struct dfs_to_mlme *tmp_dfs_to_mlme = &global_dfs_to_mlme;
107 
108 	tmp_dfs_to_mlme->pdev_component_obj_attach =
109 		wlan_objmgr_pdev_component_obj_attach;
110 	tmp_dfs_to_mlme->pdev_component_obj_detach =
111 		wlan_objmgr_pdev_component_obj_detach;
112 
113 	tmp_dfs_to_mlme->dfs_start_rcsa = mlme_dfs_start_rcsa;
114 	tmp_dfs_to_mlme->mlme_proc_cac = mlme_dfs_proc_cac;
115 	tmp_dfs_to_mlme->mlme_deliver_event_up_after_cac =
116 		mlme_dfs_deliver_event_up_after_cac;
117 	tmp_dfs_to_mlme->mlme_get_dfs_ch_nchans = mlme_dfs_get_dfs_ch_nchans;
118 	tmp_dfs_to_mlme->mlme_set_no_chans_available =
119 		mlme_dfs_set_no_chans_available;
120 	tmp_dfs_to_mlme->mlme_ieee2mhz = mlme_dfs_ieee2mhz;
121 	tmp_dfs_to_mlme->mlme_dfs_ch_flags_ext = mlme_dfs_dfs_ch_flags_ext;
122 	tmp_dfs_to_mlme->mlme_channel_change_by_precac =
123 		mlme_dfs_channel_change_by_precac;
124 	tmp_dfs_to_mlme->mlme_nol_timeout_notification =
125 		mlme_dfs_nol_timeout_notification;
126 	tmp_dfs_to_mlme->mlme_clist_update = mlme_dfs_clist_update;
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_restart_vaps_with_non_dfs_chan =
130 		mlme_dfs_restart_vaps_with_non_dfs_chan;
131 	tmp_dfs_to_mlme->mlme_is_opmode_sta =
132 		mlme_dfs_is_opmode_sta;
133 	tmp_dfs_to_mlme->mlme_check_allowed_prim_chanlist =
134 		mlme_dfs_check_allowed_prim_chanlist;
135 	tmp_dfs_to_mlme->mlme_update_scan_channel_list =
136 		mlme_dfs_update_scan_channel_list;
137 	tmp_dfs_to_mlme->mlme_bringdown_vaps =
138 		mlme_dfs_bringdown_vaps;
139 	tmp_dfs_to_mlme->mlme_dfs_deliver_event =
140 		mlme_dfs_deliver_event;
141 
142 	tmp_dfs_to_mlme->mlme_acquire_radar_mode_switch_lock =
143 		mlme_acquire_radar_mode_switch_lock;
144 	tmp_dfs_to_mlme->mlme_release_radar_mode_switch_lock =
145 		mlme_release_radar_mode_switch_lock;
146 	/*
147 	 * Register precac auto channel switch feature related callbacks
148 	 */
149 	register_dfs_precac_auto_chan_callbacks_freq(tmp_dfs_to_mlme);
150 	/* Register freq based callbacks */
151 	register_dfs_callbacks_for_freq(tmp_dfs_to_mlme);
152 }
153 #else
154 void register_dfs_callbacks(void)
155 {
156 	struct dfs_to_mlme *tmp_dfs_to_mlme = &global_dfs_to_mlme;
157 
158 	tmp_dfs_to_mlme->pdev_component_obj_attach =
159 		wlan_objmgr_pdev_component_obj_attach;
160 	tmp_dfs_to_mlme->pdev_component_obj_detach =
161 		wlan_objmgr_pdev_component_obj_detach;
162 }
163 #endif
164 
165 /**
166  * dfs_psoc_obj_create_notification() - dfs psoc create notification handler
167  * @psoc: psoc object
168  * @arg_list: Argument list
169  *
170  * Return: QDF_STATUS
171  */
172 static QDF_STATUS dfs_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc,
173 					     void *arg_list)
174 {
175 	QDF_STATUS status;
176 	struct dfs_soc_priv_obj *dfs_soc_obj;
177 
178 	dfs_soc_obj = qdf_mem_malloc(sizeof(*dfs_soc_obj));
179 	if (!dfs_soc_obj)
180 		return QDF_STATUS_E_NOMEM;
181 
182 	dfs_soc_obj->psoc = psoc;
183 
184 	status = wlan_objmgr_psoc_component_obj_attach(psoc,
185 						       WLAN_UMAC_COMP_DFS,
186 						       (void *)dfs_soc_obj,
187 						       QDF_STATUS_SUCCESS);
188 
189 	if (QDF_IS_STATUS_ERROR(status)) {
190 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
191 			"Failed to attach psoc dfs component");
192 		qdf_mem_free(dfs_soc_obj);
193 		return status;
194 	}
195 	/* Initialize precac timer here*/
196 	dfs_zero_cac_timer_init(dfs_soc_obj);
197 
198 	/* Initialize Rolling CAC timer */
199 	dfs_rcac_timer_init(dfs_soc_obj);
200 
201 	/* DFS Rolling CAC SM initialization */
202 	dfs_rcac_sm_create(dfs_soc_obj);
203 
204 	dfs_debug(NULL, WLAN_DEBUG_DFS1,
205 		"DFS obj attach to psoc successfully");
206 
207 	return status;
208 }
209 
210 /**
211  * dfs_psoc_obj_destroy_notification() - dfs psoc destroy notification handler
212  * @psoc: psoc object
213  * @arg_list: Argument list
214  *
215  * Return: QDF_STATUS
216  */
217 static QDF_STATUS dfs_psoc_obj_destroy_notification(struct wlan_objmgr_psoc *psoc,
218 					      void *arg_list)
219 {
220 	QDF_STATUS status;
221 	struct dfs_soc_priv_obj *dfs_soc_obj;
222 
223 	dfs_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
224 						WLAN_UMAC_COMP_DFS);
225 	if (!dfs_soc_obj) {
226 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
227 			"Failed to get dfs obj in psoc");
228 		return QDF_STATUS_E_FAILURE;
229 	}
230 
231 	/* Delete DFS Rolling CAC SM */
232 	dfs_rcac_sm_destroy(dfs_soc_obj);
233 
234 	dfs_rcac_timer_deinit(dfs_soc_obj);
235 	dfs_zero_cac_timer_detach(dfs_soc_obj);
236 
237 	status = wlan_objmgr_psoc_component_obj_detach(psoc,
238 						       WLAN_UMAC_COMP_DFS,
239 						       dfs_soc_obj);
240 
241 	if (QDF_IS_STATUS_ERROR(status))
242 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
243 			"Failed to detach psoc dfs component");
244 
245 	qdf_mem_free(dfs_soc_obj);
246 
247 	return status;
248 }
249 
250 QDF_STATUS dfs_init(void)
251 {
252 	QDF_STATUS status;
253 
254 	status = wlan_objmgr_register_psoc_create_handler(WLAN_UMAC_COMP_DFS,
255 			dfs_psoc_obj_create_notification,
256 			NULL);
257 
258 	if (QDF_IS_STATUS_ERROR(status)) {
259 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
260 			"Failed to register psoc create handler for dfs");
261 		goto err_psoc_create;
262 	}
263 
264 	status = wlan_objmgr_register_psoc_destroy_handler(WLAN_UMAC_COMP_DFS,
265 			dfs_psoc_obj_destroy_notification,
266 			NULL);
267 
268 	if (QDF_IS_STATUS_ERROR(status)) {
269 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
270 			"Failed to register psoc delete handler for dfs");
271 		goto err_psoc_delete;
272 	}
273 
274 	register_dfs_callbacks();
275 
276 	status = wlan_objmgr_register_pdev_create_handler(WLAN_UMAC_COMP_DFS,
277 			wlan_dfs_pdev_obj_create_notification,
278 			NULL);
279 
280 	if (QDF_IS_STATUS_ERROR(status)) {
281 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
282 			"Failed to register pdev create handler for dfs");
283 		goto err_pdev_create;
284 	}
285 
286 	status = wlan_objmgr_register_pdev_destroy_handler(WLAN_UMAC_COMP_DFS,
287 			wlan_dfs_pdev_obj_destroy_notification,
288 			NULL);
289 
290 	if (QDF_IS_STATUS_ERROR(status)) {
291 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
292 			"Failed to register pdev delete handler for dfs");
293 		goto err_pdev_delete;
294 	}
295 
296 	status = qdf_print_set_category_verbose(qdf_get_pidx(),
297 			QDF_MODULE_ID_DFS, QDF_TRACE_LEVEL_INFO, true);
298 
299 	if (QDF_IS_STATUS_ERROR(status)) {
300 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
301 			"Failed to set verbose for category");
302 		goto err_category_verbose;
303 	}
304 
305 	return QDF_STATUS_SUCCESS;
306 
307 err_category_verbose:
308 	wlan_objmgr_unregister_pdev_destroy_handler(WLAN_UMAC_COMP_DFS,
309 			wlan_dfs_pdev_obj_destroy_notification,
310 			NULL);
311 err_pdev_delete:
312 	wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_DFS,
313 			wlan_dfs_pdev_obj_create_notification,
314 			NULL);
315 err_pdev_create:
316 	wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_DFS,
317 			dfs_psoc_obj_destroy_notification,
318 			NULL);
319 err_psoc_delete:
320 	wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_DFS,
321 			dfs_psoc_obj_create_notification,
322 			NULL);
323 err_psoc_create:
324 	return status;
325 }
326 
327 QDF_STATUS dfs_deinit(void)
328 {
329 	QDF_STATUS status;
330 
331 	status = wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_DFS,
332 			dfs_psoc_obj_create_notification,
333 			NULL);
334 
335 	if (QDF_IS_STATUS_ERROR(status))
336 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
337 			"Failed to deregister dfs psoc obj create");
338 
339 	status = wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_DFS,
340 			dfs_psoc_obj_destroy_notification,
341 			NULL);
342 
343 	if (QDF_IS_STATUS_ERROR(status))
344 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
345 			"Failed to deregister dfs psoc obj destroy");
346 
347 	status = wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_DFS,
348 			wlan_dfs_pdev_obj_create_notification,
349 			NULL);
350 
351 	if (QDF_IS_STATUS_ERROR(status))
352 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
353 			"Failed to deregister dfs pdev obj create");
354 
355 	status = wlan_objmgr_unregister_pdev_destroy_handler(WLAN_UMAC_COMP_DFS,
356 			wlan_dfs_pdev_obj_destroy_notification,
357 			NULL);
358 
359 	if (QDF_IS_STATUS_ERROR(status))
360 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
361 			"Failed to deregister dfs pdev obj destroy");
362 
363 	return QDF_STATUS_SUCCESS;
364 }
365 
366 QDF_STATUS wlan_dfs_pdev_obj_create_notification(struct wlan_objmgr_pdev *pdev,
367 		void *arg)
368 {
369 	struct wlan_dfs *dfs = NULL;
370 	struct wlan_objmgr_psoc *psoc;
371 	struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops;
372 	uint8_t pdev_id;
373 	QDF_STATUS status;
374 	bool is_5ghz = false;
375 
376 	if (!pdev) {
377 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null pdev");
378 		return QDF_STATUS_E_FAILURE;
379 	}
380 
381 	psoc = wlan_pdev_get_psoc(pdev);
382 	if (!psoc) {
383 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null psoc");
384 		return QDF_STATUS_E_FAILURE;
385 	}
386 
387 	dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc);
388 	if (!(dfs_tx_ops && dfs_tx_ops->dfs_is_pdev_5ghz)) {
389 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs_tx_ops is null");
390 		return QDF_STATUS_E_FAILURE;
391 	}
392 
393 	status = dfs_tx_ops->dfs_is_pdev_5ghz(pdev, &is_5ghz);
394 	if (QDF_IS_STATUS_ERROR(status)) {
395 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "Failed to get is_5ghz value");
396 		return QDF_STATUS_E_FAILURE;
397 	}
398 
399 	if (!is_5ghz) {
400 		pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
401 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
402 				"Do not allocate DFS object for 2G, pdev_id = %d",
403 				pdev_id);
404 		return QDF_STATUS_SUCCESS;
405 	}
406 
407 	if (dfs_create_object(&dfs) == 1) {
408 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "failed to create object");
409 		return QDF_STATUS_E_FAILURE;
410 	}
411 
412 	status = global_dfs_to_mlme.pdev_component_obj_attach(pdev,
413 		WLAN_UMAC_COMP_DFS, (void *)dfs, QDF_STATUS_SUCCESS);
414 	if (QDF_IS_STATUS_ERROR(status)) {
415 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "obj attach failed");
416 		dfs_destroy_object(dfs);
417 		return QDF_STATUS_E_FAILURE;
418 	}
419 
420 	dfs->dfs_pdev_obj = pdev;
421 
422 	if (!dfs_tx_ops->dfs_is_tgt_offload) {
423 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,
424 			"dfs_is_tgt_offload is null");
425 		dfs_destroy_object(dfs);
426 		return QDF_STATUS_E_FAILURE;
427 	}
428 
429 	dfs->dfs_is_offload_enabled = dfs_tx_ops->dfs_is_tgt_offload(psoc);
430 	dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs_offload %d",
431 		 dfs->dfs_is_offload_enabled);
432 	dfs_agile_soc_obj_init(dfs, psoc);
433 
434 	if (dfs_attach(dfs) == 1) {
435 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs_attch failed");
436 		dfs_destroy_object(dfs);
437 		return QDF_STATUS_E_FAILURE;
438 	}
439 
440 	return QDF_STATUS_SUCCESS;
441 }
442 
443 QDF_STATUS wlan_dfs_pdev_obj_destroy_notification(struct wlan_objmgr_pdev *pdev,
444 		void *arg)
445 {
446 	struct wlan_dfs *dfs = NULL;
447 
448 	if (!pdev) {
449 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "PDEV is NULL");
450 		return QDF_STATUS_E_FAILURE;
451 	}
452 
453 	dfs = wlan_pdev_get_dfs_obj(pdev);
454 
455 	/* DFS is NULL during unload. should we call this function before */
456 	if (dfs) {
457 		global_dfs_to_mlme.pdev_component_obj_detach(pdev,
458 				WLAN_UMAC_COMP_DFS,
459 				(void *)dfs);
460 
461 		dfs_detach(dfs);
462 		dfs->dfs_pdev_obj = NULL;
463 		dfs_destroy_object(dfs);
464 	}
465 
466 	return QDF_STATUS_SUCCESS;
467 }
468 
469 static void dfs_scan_serialization_comp_info_cb(
470 		struct wlan_objmgr_vdev *vdev,
471 		union wlan_serialization_rules_info *comp_info)
472 {
473 	struct wlan_dfs *dfs = NULL;
474 	struct wlan_objmgr_pdev *pdev;
475 
476 	if (!comp_info) {
477 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "comp_info is NULL");
478 		return;
479 	}
480 
481 	if (!vdev) {
482 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "vdev is NULL");
483 		return;
484 	}
485 
486 	pdev = wlan_vdev_get_pdev(vdev);
487 	if (!pdev) {
488 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "pdev is NULL");
489 		return;
490 	}
491 
492 	comp_info->scan_info.is_cac_in_progress = false;
493 
494 	if (!tgt_dfs_is_pdev_5ghz(pdev))
495 		return;
496 
497 	dfs = wlan_pdev_get_dfs_obj(pdev);
498 	if (!dfs) {
499 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs is NULL");
500 		return;
501 	}
502 
503 	if (dfs_is_ap_cac_timer_running(dfs))
504 		comp_info->scan_info.is_cac_in_progress = true;
505 }
506 
507 QDF_STATUS wifi_dfs_psoc_enable(struct wlan_objmgr_psoc *psoc)
508 {
509 	QDF_STATUS status;
510 
511 	status = tgt_dfs_reg_ev_handler(psoc);
512 	if (status != QDF_STATUS_SUCCESS) {
513 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,  "tgt_dfs_reg_ev_handler failed");
514 		return QDF_STATUS_E_FAILURE;
515 	}
516 
517 	status = wlan_serialization_register_comp_info_cb(psoc,
518 			WLAN_UMAC_COMP_DFS,
519 			WLAN_SER_CMD_SCAN,
520 			dfs_scan_serialization_comp_info_cb);
521 	if (status != QDF_STATUS_SUCCESS) {
522 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,  "Serialize scan cmd register failed");
523 		return status;
524 	}
525 
526 	return QDF_STATUS_SUCCESS;
527 }
528 
529 QDF_STATUS wifi_dfs_psoc_disable(struct wlan_objmgr_psoc *psoc)
530 {
531 	QDF_STATUS status;
532 
533 	status = wlan_serialization_deregister_comp_info_cb(psoc,
534 			WLAN_UMAC_COMP_DFS,
535 			WLAN_SER_CMD_SCAN);
536 	if (status != QDF_STATUS_SUCCESS) {
537 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,  "Serialize scan cmd deregister failed");
538 		return status;
539 	}
540 
541 	return QDF_STATUS_SUCCESS;
542 }
543