xref: /wlan-dirver/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_ucfg_api.c (revision 11f5a63a6cbdda84849a730de22f0a71e635d58c)
1 /*
2  * Copyright (c) 2016-2019 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 has the DFS dispatcher API implementation which is exposed
22  * to outside of DFS component.
23  */
24 
25 #include "wlan_dfs_ucfg_api.h"
26 #include "wlan_dfs_init_deinit_api.h"
27 #include "../../core/src/dfs.h"
28 #include "../../core/src/dfs_zero_cac.h"
29 #include "../../core/src/dfs_partial_offload_radar.h"
30 #include "../../core/src/dfs_process_radar_found_ind.h"
31 #include <qdf_module.h>
32 
33 QDF_STATUS ucfg_dfs_is_ap_cac_timer_running(struct wlan_objmgr_pdev *pdev,
34 		int *is_ap_cac_timer_running)
35 {
36 	struct wlan_dfs *dfs;
37 
38 	dfs = wlan_pdev_get_dfs_obj(pdev);
39 	if (!dfs)
40 		return  QDF_STATUS_E_FAILURE;
41 
42 	*is_ap_cac_timer_running = dfs_is_ap_cac_timer_running(dfs);
43 
44 	return QDF_STATUS_SUCCESS;
45 }
46 qdf_export_symbol(ucfg_dfs_is_ap_cac_timer_running);
47 
48 QDF_STATUS ucfg_dfs_getnol(struct wlan_objmgr_pdev *pdev,
49 		void *dfs_nolinfo)
50 {
51 	struct wlan_dfs *dfs;
52 
53 	dfs = wlan_pdev_get_dfs_obj(pdev);
54 	if (!dfs)
55 		return  QDF_STATUS_E_FAILURE;
56 
57 	dfs_getnol(dfs, dfs_nolinfo);
58 
59 	return QDF_STATUS_SUCCESS;
60 }
61 qdf_export_symbol(ucfg_dfs_getnol);
62 
63 QDF_STATUS ucfg_dfs_override_cac_timeout(struct wlan_objmgr_pdev *pdev,
64 		int cac_timeout,
65 		int *status)
66 {
67 	struct wlan_dfs *dfs;
68 
69 	dfs = wlan_pdev_get_dfs_obj(pdev);
70 	if (!dfs)
71 		return  QDF_STATUS_E_FAILURE;
72 
73 	*status = dfs_override_cac_timeout(dfs, cac_timeout);
74 
75 	return QDF_STATUS_SUCCESS;
76 }
77 qdf_export_symbol(ucfg_dfs_override_cac_timeout);
78 
79 QDF_STATUS ucfg_dfs_get_override_cac_timeout(struct wlan_objmgr_pdev *pdev,
80 		int *cac_timeout,
81 		int *status)
82 {
83 	struct wlan_dfs *dfs;
84 
85 	dfs = wlan_pdev_get_dfs_obj(pdev);
86 	if (!dfs)
87 		return  QDF_STATUS_E_FAILURE;
88 
89 	*status = dfs_get_override_cac_timeout(dfs, cac_timeout);
90 
91 	return QDF_STATUS_SUCCESS;
92 }
93 qdf_export_symbol(ucfg_dfs_get_override_cac_timeout);
94 
95 QDF_STATUS ucfg_dfs_get_override_precac_timeout(struct wlan_objmgr_pdev *pdev,
96 		int *precac_timeout)
97 {
98 	struct wlan_dfs *dfs;
99 
100 	dfs = wlan_pdev_get_dfs_obj(pdev);
101 	if (!dfs)
102 		return  QDF_STATUS_E_FAILURE;
103 
104 	dfs_get_override_precac_timeout(dfs, precac_timeout);
105 
106 	return QDF_STATUS_SUCCESS;
107 }
108 qdf_export_symbol(ucfg_dfs_get_override_precac_timeout);
109 
110 QDF_STATUS ucfg_dfs_override_precac_timeout(struct wlan_objmgr_pdev *pdev,
111 		int precac_timeout)
112 {
113 	struct wlan_dfs *dfs;
114 
115 	dfs = wlan_pdev_get_dfs_obj(pdev);
116 	if (!dfs)
117 		return  QDF_STATUS_E_FAILURE;
118 
119 	dfs_override_precac_timeout(dfs, precac_timeout);
120 
121 	return QDF_STATUS_SUCCESS;
122 }
123 qdf_export_symbol(ucfg_dfs_override_precac_timeout);
124 
125 QDF_STATUS ucfg_dfs_set_precac_enable(struct wlan_objmgr_pdev *pdev,
126 		uint32_t value)
127 {
128 	struct wlan_dfs *dfs;
129 
130 	dfs = wlan_pdev_get_dfs_obj(pdev);
131 	if (!dfs) {
132 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
133 		return  QDF_STATUS_E_FAILURE;
134 	}
135 
136 	dfs_set_precac_enable(dfs, value);
137 
138 	return QDF_STATUS_SUCCESS;
139 }
140 qdf_export_symbol(ucfg_dfs_set_precac_enable);
141 
142 QDF_STATUS ucfg_dfs_get_legacy_precac_enable(struct wlan_objmgr_pdev *pdev,
143 					     bool *buff)
144 {
145 	struct wlan_dfs *dfs;
146 
147 	if (!tgt_dfs_is_pdev_5ghz(pdev))
148 		return QDF_STATUS_SUCCESS;
149 
150 	dfs = wlan_pdev_get_dfs_obj(pdev);
151 	if (!dfs) {
152 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
153 		return  QDF_STATUS_E_FAILURE;
154 	}
155 
156 	*buff = dfs_is_legacy_precac_enabled(dfs);
157 
158 	return QDF_STATUS_SUCCESS;
159 }
160 
161 qdf_export_symbol(ucfg_dfs_get_legacy_precac_enable);
162 
163 QDF_STATUS ucfg_dfs_get_agile_precac_enable(struct wlan_objmgr_pdev *pdev,
164 					    bool *buff)
165 {
166 	struct wlan_dfs *dfs;
167 
168 	if (!pdev || !buff)
169 		return QDF_STATUS_E_FAILURE;
170 
171 	if (!tgt_dfs_is_pdev_5ghz(pdev)) {
172 		*buff = false;
173 		return QDF_STATUS_SUCCESS;
174 	}
175 
176 	dfs = wlan_pdev_get_dfs_obj(pdev);
177 	if (!dfs) {
178 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
179 		return QDF_STATUS_E_FAILURE;
180 	}
181 
182 	*buff = dfs_is_agile_precac_enabled(dfs);
183 
184 	return QDF_STATUS_SUCCESS;
185 }
186 
187 qdf_export_symbol(ucfg_dfs_get_agile_precac_enable);
188 
189 QDF_STATUS
190 ucfg_dfs_set_nol_subchannel_marking(struct wlan_objmgr_pdev *pdev,
191 				    bool nol_subchannel_marking)
192 {
193 	struct wlan_dfs *dfs;
194 
195 	dfs = wlan_pdev_get_dfs_obj(pdev);
196 	if (!dfs)
197 		return  QDF_STATUS_E_FAILURE;
198 
199 	dfs_set_nol_subchannel_marking(dfs, nol_subchannel_marking);
200 
201 	return QDF_STATUS_SUCCESS;
202 }
203 qdf_export_symbol(ucfg_dfs_set_nol_subchannel_marking);
204 
205 QDF_STATUS ucfg_dfs_get_nol_subchannel_marking(struct wlan_objmgr_pdev *pdev,
206 					       bool *nol_subchannel_marking)
207 {
208 	struct wlan_dfs *dfs;
209 
210 	dfs = wlan_pdev_get_dfs_obj(pdev);
211 	if (!dfs)
212 		return  QDF_STATUS_E_FAILURE;
213 
214 	dfs_get_nol_subchannel_marking(dfs, nol_subchannel_marking);
215 
216 	return QDF_STATUS_SUCCESS;
217 }
218 qdf_export_symbol(ucfg_dfs_get_nol_subchannel_marking);
219 #ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT
220 QDF_STATUS ucfg_dfs_set_precac_intermediate_chan(struct wlan_objmgr_pdev *pdev,
221 						 uint32_t value)
222 {
223 	struct wlan_dfs *dfs;
224 
225 	dfs = wlan_pdev_get_dfs_obj(pdev);
226 	if (!dfs) {
227 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
228 		return  QDF_STATUS_E_FAILURE;
229 	}
230 
231 	dfs_set_precac_intermediate_chan(dfs, value);
232 
233 	return QDF_STATUS_SUCCESS;
234 }
235 
236 QDF_STATUS ucfg_dfs_get_precac_intermediate_chan(struct wlan_objmgr_pdev *pdev,
237 						 int *buff)
238 {
239 	struct wlan_dfs *dfs;
240 
241 	dfs = wlan_pdev_get_dfs_obj(pdev);
242 	if (!dfs) {
243 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
244 		return  QDF_STATUS_E_FAILURE;
245 	}
246 
247 	*buff = dfs_get_precac_intermediate_chan(dfs);
248 
249 	return QDF_STATUS_SUCCESS;
250 }
251 
252 #ifdef CONFIG_CHAN_NUM_API
253 enum precac_chan_state
254 ucfg_dfs_get_precac_chan_state(struct wlan_objmgr_pdev *pdev,
255 			       uint8_t precac_chan)
256 {
257 	struct wlan_dfs *dfs;
258 	enum precac_chan_state retval = PRECAC_ERR;
259 
260 	dfs = wlan_pdev_get_dfs_obj(pdev);
261 	if (!dfs) {
262 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
263 		return PRECAC_ERR;
264 	}
265 
266 	retval = dfs_get_precac_chan_state(dfs, precac_chan);
267 	if (retval == PRECAC_ERR) {
268 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,
269 			"Could not find precac channel state");
270 	}
271 
272 	return retval;
273 }
274 #endif
275 
276 #ifdef CONFIG_CHAN_FREQ_API
277 enum precac_chan_state
278 ucfg_dfs_get_precac_chan_state_for_freq(struct wlan_objmgr_pdev *pdev,
279 					uint16_t precac_chan_freq)
280 {
281 	/* To be implemented when component dev changes are ready */
282 	return PRECAC_ERR;
283 }
284 #endif
285 #endif
286 
287 #ifdef QCA_MCL_DFS_SUPPORT
288 QDF_STATUS ucfg_dfs_update_config(struct wlan_objmgr_psoc *psoc,
289 		struct dfs_user_config *req)
290 {
291 	struct dfs_soc_priv_obj *soc_obj;
292 
293 	if (!psoc || !req) {
294 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
295 			"psoc: 0x%pK, req: 0x%pK", psoc, req);
296 		return QDF_STATUS_E_FAILURE;
297 	}
298 
299 	soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
300 							WLAN_UMAC_COMP_DFS);
301 	if (!soc_obj) {
302 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
303 			"Failed to get dfs psoc component");
304 		return QDF_STATUS_E_FAILURE;
305 	}
306 
307 	soc_obj->dfs_is_phyerr_filter_offload =
308 			req->dfs_is_phyerr_filter_offload;
309 
310 	return QDF_STATUS_SUCCESS;
311 }
312 qdf_export_symbol(ucfg_dfs_update_config);
313 #endif
314 
315 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST)
316 QDF_STATUS ucfg_dfs_set_override_status_timeout(struct wlan_objmgr_pdev *pdev,
317 					    int status_timeout)
318 {
319 	struct wlan_dfs *dfs;
320 
321 	dfs = wlan_pdev_get_dfs_obj(pdev);
322 	if (!dfs) {
323 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
324 		return  QDF_STATUS_E_FAILURE;
325 	}
326 
327 	dfs_set_override_status_timeout(dfs, status_timeout);
328 
329 	return QDF_STATUS_SUCCESS;
330 }
331 
332 qdf_export_symbol(ucfg_dfs_set_override_status_timeout);
333 
334 QDF_STATUS ucfg_dfs_get_override_status_timeout(struct wlan_objmgr_pdev *pdev,
335 						int *status_timeout)
336 {
337 	struct wlan_dfs *dfs;
338 
339 	dfs = wlan_pdev_get_dfs_obj(pdev);
340 	if (!dfs) {
341 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "null dfs");
342 		return  QDF_STATUS_E_FAILURE;
343 	}
344 
345 	dfs_get_override_status_timeout(dfs, status_timeout);
346 
347 	return QDF_STATUS_SUCCESS;
348 }
349 
350 qdf_export_symbol(ucfg_dfs_get_override_status_timeout);
351 #endif
352 
353 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(WLAN_DFS_SYNTHETIC_RADAR)
354 void ucfg_dfs_allow_hw_pulses(struct wlan_objmgr_pdev *pdev,
355 			      bool allow_hw_pulses)
356 {
357 	struct wlan_dfs *dfs;
358 
359 	if (!tgt_dfs_is_pdev_5ghz(pdev))
360 		return;
361 
362 	dfs = wlan_pdev_get_dfs_obj(pdev);
363 	if (!dfs) {
364 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
365 		return;
366 	}
367 
368 	dfs_allow_hw_pulses(dfs, allow_hw_pulses);
369 }
370 
371 qdf_export_symbol(ucfg_dfs_allow_hw_pulses);
372 
373 bool ucfg_dfs_is_hw_pulses_allowed(struct wlan_objmgr_pdev *pdev)
374 {
375 	struct wlan_dfs *dfs;
376 
377 	if (!tgt_dfs_is_pdev_5ghz(pdev))
378 		return false;
379 
380 	dfs = wlan_pdev_get_dfs_obj(pdev);
381 	if (!dfs) {
382 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
383 		return;
384 	}
385 
386 	return dfs_is_hw_pulses_allowed(dfs);
387 }
388 
389 qdf_export_symbol(ucfg_dfs_is_hw_pulses_allowed);
390 #endif
391 
392 #ifdef QCA_SUPPORT_AGILE_DFS
393 QDF_STATUS ucfg_dfs_reset_agile_config(struct wlan_objmgr_psoc *psoc)
394 {
395 	struct dfs_soc_priv_obj *soc_obj;
396 
397 	if (!psoc) {
398 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,  "psoc is null");
399 		return QDF_STATUS_E_FAILURE;
400 	}
401 
402 	soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
403 							WLAN_UMAC_COMP_DFS);
404 	if (!soc_obj) {
405 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
406 			"Failed to get dfs psoc component");
407 		return QDF_STATUS_E_FAILURE;
408 	}
409 
410 	dfs_reset_agile_config(soc_obj);
411 
412 	return QDF_STATUS_SUCCESS;
413 }
414 
415 qdf_export_symbol(ucfg_dfs_reset_agile_config);
416 #endif
417 
418 QDF_STATUS ucfg_dfs_reinit_timers(struct wlan_objmgr_pdev *pdev)
419 {
420 	struct wlan_dfs *dfs;
421 
422 	if (!tgt_dfs_is_pdev_5ghz(pdev))
423 		return QDF_STATUS_SUCCESS;
424 
425 	dfs = wlan_pdev_get_dfs_obj(pdev);
426 	if (!dfs) {
427 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
428 		return QDF_STATUS_E_FAILURE;
429 	}
430 
431 	dfs_reinit_timers(dfs);
432 
433 	return QDF_STATUS_SUCCESS;
434 }
435 
436 qdf_export_symbol(ucfg_dfs_reinit_timers);
437