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  *
6  * Permission to use, copy, modify, and/or distribute this software for
7  * any purpose with or without fee is hereby granted, provided that the
8  * above copyright notice and this permission notice appear in all
9  * copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
12  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
13  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
14  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
15  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
16  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
17  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
18  * PERFORMANCE OF THIS SOFTWARE.
19  */
20 
21 /**
22  * DOC: This file has the DFS dispatcher API implementation which is exposed
23  * to outside of DFS component.
24  */
25 
26 #include "wlan_dfs_ucfg_api.h"
27 #include "wlan_dfs_init_deinit_api.h"
28 #include "../../core/src/dfs.h"
29 #include "../../core/src/dfs_zero_cac.h"
30 #include "../../core/src/dfs_partial_offload_radar.h"
31 #include "../../core/src/dfs_process_radar_found_ind.h"
32 #include <qdf_module.h>
33 
ucfg_dfs_is_ap_cac_timer_running(struct wlan_objmgr_pdev * pdev,int * is_ap_cac_timer_running)34 QDF_STATUS ucfg_dfs_is_ap_cac_timer_running(struct wlan_objmgr_pdev *pdev,
35 		int *is_ap_cac_timer_running)
36 {
37 	struct wlan_dfs *dfs;
38 
39 	dfs = wlan_pdev_get_dfs_obj(pdev);
40 	if (!dfs)
41 		return  QDF_STATUS_E_FAILURE;
42 
43 	*is_ap_cac_timer_running = dfs_is_ap_cac_timer_running(dfs);
44 
45 	return QDF_STATUS_SUCCESS;
46 }
47 qdf_export_symbol(ucfg_dfs_is_ap_cac_timer_running);
48 
ucfg_dfs_getnol(struct wlan_objmgr_pdev * pdev,void * dfs_nolinfo)49 QDF_STATUS ucfg_dfs_getnol(struct wlan_objmgr_pdev *pdev,
50 		void *dfs_nolinfo)
51 {
52 	struct wlan_dfs *dfs;
53 
54 	dfs = wlan_pdev_get_dfs_obj(pdev);
55 	if (!dfs)
56 		return  QDF_STATUS_E_FAILURE;
57 
58 	dfs_getnol(dfs, dfs_nolinfo);
59 
60 	return QDF_STATUS_SUCCESS;
61 }
62 qdf_export_symbol(ucfg_dfs_getnol);
63 
ucfg_dfs_override_cac_timeout(struct wlan_objmgr_pdev * pdev,int cac_timeout,int * status)64 QDF_STATUS ucfg_dfs_override_cac_timeout(struct wlan_objmgr_pdev *pdev,
65 		int cac_timeout,
66 		int *status)
67 {
68 	struct wlan_dfs *dfs;
69 
70 	dfs = wlan_pdev_get_dfs_obj(pdev);
71 	if (!dfs)
72 		return  QDF_STATUS_E_FAILURE;
73 
74 	*status = dfs_override_cac_timeout(dfs, cac_timeout);
75 
76 	return QDF_STATUS_SUCCESS;
77 }
78 qdf_export_symbol(ucfg_dfs_override_cac_timeout);
79 
ucfg_dfs_get_override_cac_timeout(struct wlan_objmgr_pdev * pdev,int * cac_timeout,int * status)80 QDF_STATUS ucfg_dfs_get_override_cac_timeout(struct wlan_objmgr_pdev *pdev,
81 		int *cac_timeout,
82 		int *status)
83 {
84 	struct wlan_dfs *dfs;
85 
86 	dfs = wlan_pdev_get_dfs_obj(pdev);
87 	if (!dfs)
88 		return  QDF_STATUS_E_FAILURE;
89 
90 	*status = dfs_get_override_cac_timeout(dfs, cac_timeout);
91 
92 	return QDF_STATUS_SUCCESS;
93 }
94 qdf_export_symbol(ucfg_dfs_get_override_cac_timeout);
95 
ucfg_dfs_get_override_precac_timeout(struct wlan_objmgr_pdev * pdev,int * precac_timeout)96 QDF_STATUS ucfg_dfs_get_override_precac_timeout(struct wlan_objmgr_pdev *pdev,
97 		int *precac_timeout)
98 {
99 	struct wlan_dfs *dfs;
100 
101 	dfs = wlan_pdev_get_dfs_obj(pdev);
102 	if (!dfs)
103 		return  QDF_STATUS_E_FAILURE;
104 
105 	dfs_get_override_precac_timeout(dfs, precac_timeout);
106 
107 	return QDF_STATUS_SUCCESS;
108 }
109 qdf_export_symbol(ucfg_dfs_get_override_precac_timeout);
110 
ucfg_dfs_override_precac_timeout(struct wlan_objmgr_pdev * pdev,int precac_timeout)111 QDF_STATUS ucfg_dfs_override_precac_timeout(struct wlan_objmgr_pdev *pdev,
112 		int precac_timeout)
113 {
114 	struct wlan_dfs *dfs;
115 
116 	dfs = wlan_pdev_get_dfs_obj(pdev);
117 	if (!dfs)
118 		return  QDF_STATUS_E_FAILURE;
119 
120 	dfs_override_precac_timeout(dfs, precac_timeout);
121 
122 	return QDF_STATUS_SUCCESS;
123 }
124 qdf_export_symbol(ucfg_dfs_override_precac_timeout);
125 
ucfg_dfs_set_precac_enable(struct wlan_objmgr_pdev * pdev,uint32_t value)126 QDF_STATUS ucfg_dfs_set_precac_enable(struct wlan_objmgr_pdev *pdev,
127 		uint32_t value)
128 {
129 	struct wlan_dfs *dfs;
130 
131 	dfs = wlan_pdev_get_dfs_obj(pdev);
132 	if (!dfs) {
133 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
134 		return  QDF_STATUS_E_FAILURE;
135 	}
136 
137 	dfs_set_precac_enable(dfs, value);
138 
139 	return QDF_STATUS_SUCCESS;
140 }
141 qdf_export_symbol(ucfg_dfs_set_precac_enable);
142 
ucfg_dfs_get_agile_precac_enable(struct wlan_objmgr_pdev * pdev,bool * buff)143 QDF_STATUS ucfg_dfs_get_agile_precac_enable(struct wlan_objmgr_pdev *pdev,
144 					    bool *buff)
145 {
146 	struct wlan_dfs *dfs;
147 
148 	if (!pdev || !buff)
149 		return QDF_STATUS_E_FAILURE;
150 
151 	if (!tgt_dfs_is_5ghz_supported_in_pdev(pdev)) {
152 		*buff = false;
153 		return QDF_STATUS_SUCCESS;
154 	}
155 
156 	dfs = wlan_pdev_get_dfs_obj(pdev);
157 	if (!dfs) {
158 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
159 		*buff = false;
160 		return QDF_STATUS_SUCCESS;
161 	}
162 
163 	*buff = dfs_is_agile_precac_enabled(dfs);
164 
165 	return QDF_STATUS_SUCCESS;
166 }
167 
168 qdf_export_symbol(ucfg_dfs_get_agile_precac_enable);
169 
170 QDF_STATUS
ucfg_dfs_set_nol_subchannel_marking(struct wlan_objmgr_pdev * pdev,bool nol_subchannel_marking)171 ucfg_dfs_set_nol_subchannel_marking(struct wlan_objmgr_pdev *pdev,
172 				    bool nol_subchannel_marking)
173 {
174 	struct wlan_dfs *dfs;
175 
176 	dfs = wlan_pdev_get_dfs_obj(pdev);
177 	if (!dfs)
178 		return  QDF_STATUS_E_FAILURE;
179 
180 	dfs_set_nol_subchannel_marking(dfs, nol_subchannel_marking);
181 
182 	return QDF_STATUS_SUCCESS;
183 }
184 qdf_export_symbol(ucfg_dfs_set_nol_subchannel_marking);
185 
ucfg_dfs_get_nol_subchannel_marking(struct wlan_objmgr_pdev * pdev,bool * nol_subchannel_marking)186 QDF_STATUS ucfg_dfs_get_nol_subchannel_marking(struct wlan_objmgr_pdev *pdev,
187 					       bool *nol_subchannel_marking)
188 {
189 	struct wlan_dfs *dfs;
190 
191 	dfs = wlan_pdev_get_dfs_obj(pdev);
192 	if (!dfs)
193 		return  QDF_STATUS_E_FAILURE;
194 
195 	dfs_get_nol_subchannel_marking(dfs, nol_subchannel_marking);
196 
197 	return QDF_STATUS_SUCCESS;
198 }
199 qdf_export_symbol(ucfg_dfs_get_nol_subchannel_marking);
200 #ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT
ucfg_dfs_set_precac_intermediate_chan(struct wlan_objmgr_pdev * pdev,uint32_t value)201 QDF_STATUS ucfg_dfs_set_precac_intermediate_chan(struct wlan_objmgr_pdev *pdev,
202 						 uint32_t value)
203 {
204 	struct wlan_dfs *dfs;
205 
206 	dfs = wlan_pdev_get_dfs_obj(pdev);
207 	if (!dfs) {
208 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
209 		return  QDF_STATUS_E_FAILURE;
210 	}
211 
212 	dfs_set_precac_intermediate_chan(dfs, value);
213 
214 	return QDF_STATUS_SUCCESS;
215 }
216 
ucfg_dfs_get_precac_intermediate_chan(struct wlan_objmgr_pdev * pdev,int * buff)217 QDF_STATUS ucfg_dfs_get_precac_intermediate_chan(struct wlan_objmgr_pdev *pdev,
218 						 int *buff)
219 {
220 	struct wlan_dfs *dfs;
221 
222 	dfs = wlan_pdev_get_dfs_obj(pdev);
223 	if (!dfs) {
224 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
225 		return  QDF_STATUS_E_FAILURE;
226 	}
227 
228 	*buff = dfs_get_precac_intermediate_chan(dfs);
229 
230 	return QDF_STATUS_SUCCESS;
231 }
232 
233 #ifdef CONFIG_CHAN_FREQ_API
234 enum precac_chan_state
ucfg_dfs_get_precac_chan_state_for_freq(struct wlan_objmgr_pdev * pdev,uint16_t precac_chan_freq)235 ucfg_dfs_get_precac_chan_state_for_freq(struct wlan_objmgr_pdev *pdev,
236 					uint16_t precac_chan_freq)
237 {
238 	struct wlan_dfs *dfs;
239 	enum precac_chan_state retval = PRECAC_ERR;
240 
241 	dfs = wlan_pdev_get_dfs_obj(pdev);
242 	if (!dfs) {
243 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
244 		return PRECAC_ERR;
245 	}
246 
247 	retval = dfs_get_precac_chan_state_for_freq(dfs, precac_chan_freq);
248 	if (retval == PRECAC_ERR) {
249 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,
250 			"Could not find precac channel state");
251 	}
252 
253 	return retval;
254 }
255 #endif
256 #endif
257 
258 #ifdef MOBILE_DFS_SUPPORT
ucfg_dfs_update_config(struct wlan_objmgr_psoc * psoc,struct dfs_user_config * req)259 QDF_STATUS ucfg_dfs_update_config(struct wlan_objmgr_psoc *psoc,
260 		struct dfs_user_config *req)
261 {
262 	struct dfs_soc_priv_obj *soc_obj;
263 
264 	if (!psoc || !req) {
265 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
266 			"psoc: 0x%pK, req: 0x%pK", psoc, req);
267 		return QDF_STATUS_E_FAILURE;
268 	}
269 
270 	soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
271 							WLAN_UMAC_COMP_DFS);
272 	if (!soc_obj) {
273 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
274 			"Failed to get dfs psoc component");
275 		return QDF_STATUS_E_FAILURE;
276 	}
277 
278 	soc_obj->dfs_is_phyerr_filter_offload =
279 			req->dfs_is_phyerr_filter_offload;
280 
281 	return QDF_STATUS_SUCCESS;
282 }
283 qdf_export_symbol(ucfg_dfs_update_config);
284 #endif
285 
286 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST)
ucfg_dfs_set_override_status_timeout(struct wlan_objmgr_pdev * pdev,int status_timeout)287 QDF_STATUS ucfg_dfs_set_override_status_timeout(struct wlan_objmgr_pdev *pdev,
288 					    int status_timeout)
289 {
290 	struct wlan_dfs *dfs;
291 
292 	dfs = wlan_pdev_get_dfs_obj(pdev);
293 	if (!dfs) {
294 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
295 		return  QDF_STATUS_E_FAILURE;
296 	}
297 
298 	dfs_set_override_status_timeout(dfs, status_timeout);
299 
300 	return QDF_STATUS_SUCCESS;
301 }
302 
303 qdf_export_symbol(ucfg_dfs_set_override_status_timeout);
304 
ucfg_dfs_get_override_status_timeout(struct wlan_objmgr_pdev * pdev,int * status_timeout)305 QDF_STATUS ucfg_dfs_get_override_status_timeout(struct wlan_objmgr_pdev *pdev,
306 						int *status_timeout)
307 {
308 	struct wlan_dfs *dfs;
309 
310 	dfs = wlan_pdev_get_dfs_obj(pdev);
311 	if (!dfs) {
312 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
313 		return  QDF_STATUS_E_FAILURE;
314 	}
315 
316 	dfs_get_override_status_timeout(dfs, status_timeout);
317 
318 	return QDF_STATUS_SUCCESS;
319 }
320 
321 qdf_export_symbol(ucfg_dfs_get_override_status_timeout);
322 #endif
323 
324 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(WLAN_DFS_SYNTHETIC_RADAR)
ucfg_dfs_allow_hw_pulses(struct wlan_objmgr_pdev * pdev,bool allow_hw_pulses)325 void ucfg_dfs_allow_hw_pulses(struct wlan_objmgr_pdev *pdev,
326 			      bool allow_hw_pulses)
327 {
328 	struct wlan_dfs *dfs;
329 
330 	if (!tgt_dfs_is_5ghz_supported_in_pdev(pdev))
331 		return;
332 
333 	dfs = wlan_pdev_get_dfs_obj(pdev);
334 	if (!dfs) {
335 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
336 		return;
337 	}
338 
339 	dfs_allow_hw_pulses(dfs, allow_hw_pulses);
340 }
341 
342 qdf_export_symbol(ucfg_dfs_allow_hw_pulses);
343 
ucfg_dfs_is_hw_pulses_allowed(struct wlan_objmgr_pdev * pdev)344 bool ucfg_dfs_is_hw_pulses_allowed(struct wlan_objmgr_pdev *pdev)
345 {
346 	struct wlan_dfs *dfs;
347 
348 	if (!tgt_dfs_is_5ghz_supported_in_pdev(pdev))
349 		return false;
350 
351 	dfs = wlan_pdev_get_dfs_obj(pdev);
352 	if (!dfs) {
353 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
354 		return false;
355 	}
356 
357 	return dfs_is_hw_pulses_allowed(dfs);
358 }
359 
360 qdf_export_symbol(ucfg_dfs_is_hw_pulses_allowed);
361 #endif
362 
363 #ifdef QCA_SUPPORT_AGILE_DFS
ucfg_dfs_reset_agile_config(struct wlan_objmgr_psoc * psoc)364 QDF_STATUS ucfg_dfs_reset_agile_config(struct wlan_objmgr_psoc *psoc)
365 {
366 	struct dfs_soc_priv_obj *soc_obj;
367 
368 	if (!psoc) {
369 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,  "psoc is null");
370 		return QDF_STATUS_E_FAILURE;
371 	}
372 
373 	soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
374 							WLAN_UMAC_COMP_DFS);
375 	if (!soc_obj) {
376 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
377 			"Failed to get dfs psoc component");
378 		return QDF_STATUS_E_FAILURE;
379 	}
380 
381 	dfs_reset_agile_config(soc_obj);
382 
383 	return QDF_STATUS_SUCCESS;
384 }
385 
386 qdf_export_symbol(ucfg_dfs_reset_agile_config);
387 #endif
388 
ucfg_dfs_reinit_timers(struct wlan_objmgr_pdev * pdev)389 QDF_STATUS ucfg_dfs_reinit_timers(struct wlan_objmgr_pdev *pdev)
390 {
391 	struct wlan_dfs *dfs;
392 
393 	if (!tgt_dfs_is_5ghz_supported_in_pdev(pdev))
394 		return QDF_STATUS_SUCCESS;
395 
396 	dfs = wlan_pdev_get_dfs_obj(pdev);
397 	if (!dfs) {
398 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
399 		return QDF_STATUS_E_FAILURE;
400 	}
401 
402 	dfs_reinit_timers(dfs);
403 
404 	return QDF_STATUS_SUCCESS;
405 }
406 
407 qdf_export_symbol(ucfg_dfs_reinit_timers);
408 
409 #ifdef QCA_SUPPORT_ADFS_RCAC
ucfg_dfs_set_rcac_enable(struct wlan_objmgr_pdev * pdev,bool rcac_en)410 QDF_STATUS ucfg_dfs_set_rcac_enable(struct wlan_objmgr_pdev *pdev,
411 				    bool rcac_en)
412 {
413 	struct wlan_dfs *dfs;
414 
415 	dfs = wlan_pdev_get_dfs_obj(pdev);
416 	if (!dfs) {
417 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
418 		return QDF_STATUS_E_FAILURE;
419 	}
420 
421 	dfs_set_rcac_enable(dfs, rcac_en);
422 
423 	return QDF_STATUS_SUCCESS;
424 }
425 
426 qdf_export_symbol(ucfg_dfs_set_rcac_enable);
427 
ucfg_dfs_get_rcac_enable(struct wlan_objmgr_pdev * pdev,bool * rcac_en)428 QDF_STATUS ucfg_dfs_get_rcac_enable(struct wlan_objmgr_pdev *pdev,
429 				    bool *rcac_en)
430 {
431 	struct wlan_dfs *dfs;
432 
433 	if (!tgt_dfs_is_5ghz_supported_in_pdev(pdev)) {
434 		*rcac_en = false;
435 		return QDF_STATUS_SUCCESS;
436 	}
437 
438 	dfs = wlan_pdev_get_dfs_obj(pdev);
439 	if (!dfs) {
440 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
441 		return QDF_STATUS_E_FAILURE;
442 	}
443 
444 	dfs_get_rcac_enable(dfs, rcac_en);
445 
446 	return QDF_STATUS_SUCCESS;
447 }
448 
449 qdf_export_symbol(ucfg_dfs_get_rcac_enable);
450 
ucfg_dfs_set_rcac_freq(struct wlan_objmgr_pdev * pdev,qdf_freq_t rcac_freq)451 QDF_STATUS ucfg_dfs_set_rcac_freq(struct wlan_objmgr_pdev *pdev,
452 				  qdf_freq_t rcac_freq)
453 {
454 	struct wlan_dfs *dfs;
455 
456 	dfs = wlan_pdev_get_dfs_obj(pdev);
457 	if (!dfs) {
458 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
459 		return QDF_STATUS_E_FAILURE;
460 	}
461 
462 	dfs_set_rcac_freq(dfs, rcac_freq);
463 
464 	return QDF_STATUS_SUCCESS;
465 }
466 
467 qdf_export_symbol(ucfg_dfs_set_rcac_freq);
468 
ucfg_dfs_get_rcac_freq(struct wlan_objmgr_pdev * pdev,qdf_freq_t * rcac_freq)469 QDF_STATUS ucfg_dfs_get_rcac_freq(struct wlan_objmgr_pdev *pdev,
470 				  qdf_freq_t *rcac_freq)
471 {
472 	struct wlan_dfs *dfs;
473 
474 	dfs = wlan_pdev_get_dfs_obj(pdev);
475 	if (!dfs) {
476 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
477 		return QDF_STATUS_E_FAILURE;
478 	}
479 
480 	dfs_get_rcac_freq(dfs, rcac_freq);
481 
482 	return QDF_STATUS_SUCCESS;
483 }
484 
485 qdf_export_symbol(ucfg_dfs_get_rcac_freq);
486 
ucfg_dfs_is_agile_rcac_enabled(struct wlan_objmgr_pdev * pdev)487 bool ucfg_dfs_is_agile_rcac_enabled(struct wlan_objmgr_pdev *pdev)
488 {
489 	struct wlan_dfs *dfs;
490 
491 	dfs = wlan_pdev_get_dfs_obj(pdev);
492 	if (!dfs) {
493 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
494 		return false;
495 	}
496 
497 	return dfs_is_agile_rcac_enabled(dfs);
498 }
499 
500 qdf_export_symbol(ucfg_dfs_is_agile_rcac_enabled);
501 #endif
502 
503