xref: /wlan-dirver/qca-wifi-host-cmn/umac/dfs/core/src/misc/dfs_filter_init.c (revision 1b9674e21e24478fba4530f5ae7396b9555e9c6a)
1 /*
2  * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2002-2006, Atheros Communications Inc.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 /**
19  * DOC: This file contains the dfs_attach() and dfs_detach() functions as well
20  * as the dfs_control() function which is used to process ioctls related to DFS.
21  * For Linux/Mac,  "radartool" is the command line tool that can be used to call
22  * various ioctls to set and get radar detection thresholds.
23  */
24 
25 #include "../dfs_zero_cac.h"
26 #include "wlan_dfs_lmac_api.h"
27 #include "wlan_dfs_mlme_api.h"
28 #include "wlan_dfs_tgt_api.h"
29 #include "../dfs_internal.h"
30 #include "../dfs_filter_init.h"
31 #include "../dfs_partial_offload_radar.h"
32 
33 /*
34  * Channel switch announcement (CSA)
35  * usenol=1 (default) make CSA and switch to a new channel on radar detect
36  * usenol=0, make CSA with next channel same as current on radar detect
37  * usenol=2, no CSA and stay on the same channel on radar detect
38  */
39 
40 /**
41  * dfs_task() - The timer function to process the radar pulses.
42  */
43 static os_timer_func(dfs_task)
44 {
45 	struct wlan_dfs *dfs = NULL;
46 
47 	OS_GET_TIMER_ARG(dfs, struct wlan_dfs *);
48 
49 	if (!dfs) {
50 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs is NULL");
51 		return;
52 	}
53 
54 	dfs_process_radarevent(dfs, dfs->dfs_curchan);
55 
56 	dfs->wlan_radar_tasksched = 0;
57 }
58 
59 /**
60  * dfs_main_task_timer_init() - Initialize dfs task timer.
61  * @dfs: Pointer to wlan_dfs structure.
62  */
63 static void dfs_main_task_timer_init(struct wlan_dfs *dfs)
64 {
65 	qdf_timer_init(NULL,
66 			&(dfs->wlan_dfs_task_timer),
67 			dfs_task,
68 			(void *)(dfs),
69 			QDF_TIMER_TYPE_WAKE_APPS);
70 }
71 
72 int dfs_main_attach(struct wlan_dfs *dfs)
73 {
74 	int i, n;
75 	struct wlan_dfs_radar_tab_info radar_info;
76 
77 	if (!dfs) {
78 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs is NULL");
79 		return 0;
80 	}
81 
82 	/* If ignore_dfs is set to 1 then Radar detection is disabled. */
83 	if (dfs->dfs_ignore_dfs) {
84 		dfs_debug(dfs, WLAN_DEBUG_DFS1, "ignoring dfs");
85 		return 0;
86 	}
87 
88 	/*
89 	 * Zero out radar_info. It's possible that the attach function
90 	 * won't fetch an initial regulatory configuration; you really
91 	 * do want to ensure that the contents indicates there aren't
92 	 * any filters.
93 	 */
94 	qdf_mem_zero(&radar_info, sizeof(radar_info));
95 
96 	lmac_get_caps(dfs->dfs_pdev_obj, &(dfs->dfs_caps));
97 
98 	dfs_clear_stats(dfs);
99 	dfs->dfs_event_log_on = 1;
100 	dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "event log enabled by default");
101 
102 	dfs->dfs_enable = 1;
103 
104 	/*Verify : Passing NULL to qdf_timer_init().*/
105 	dfs_main_task_timer_init(dfs);
106 
107 	dfs_host_wait_timer_init(dfs);
108 
109 	WLAN_DFSQ_LOCK_CREATE(dfs);
110 	STAILQ_INIT(&dfs->dfs_radarq);
111 	WLAN_ARQ_LOCK_CREATE(dfs);
112 	STAILQ_INIT(&dfs->dfs_arq);
113 	STAILQ_INIT(&(dfs->dfs_eventq));
114 	WLAN_DFSEVENTQ_LOCK_CREATE(dfs);
115 
116 	dfs->events = (struct dfs_event *)qdf_mem_malloc(
117 			sizeof(struct dfs_event)*DFS_MAX_EVENTS);
118 	if (!(dfs->events)) {
119 		dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS, "events allocation failed");
120 		return 1;
121 	}
122 	for (i = 0; i < DFS_MAX_EVENTS; i++)
123 		STAILQ_INSERT_TAIL(&(dfs->dfs_eventq), &dfs->events[i],
124 				re_list);
125 
126 	dfs->pulses = (struct dfs_pulseline *)qdf_mem_malloc(
127 			sizeof(struct dfs_pulseline));
128 	if (!(dfs->pulses)) {
129 		qdf_mem_free(dfs->events);
130 		dfs->events = NULL;
131 		dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS, "Pulse buffer allocation failed");
132 		return 1;
133 	}
134 
135 	dfs->pulses->pl_lastelem = DFS_MAX_PULSE_BUFFER_MASK;
136 
137 	/* Allocate memory for radar filters. */
138 	for (n = 0; n < DFS_MAX_RADAR_TYPES; n++) {
139 		dfs->dfs_radarf[n] = (struct dfs_filtertype *)
140 			qdf_mem_malloc(sizeof(struct dfs_filtertype));
141 		if (!(dfs->dfs_radarf[n])) {
142 			dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS,
143 					"cannot allocate memory for radar filter types");
144 			goto bad1;
145 		}
146 		qdf_mem_zero(dfs->dfs_radarf[n], sizeof(struct dfs_filtertype));
147 	}
148 
149 	/* Allocate memory for radar table. */
150 	dfs->dfs_ftindextable = (int8_t **)qdf_mem_malloc(
151 			DFS_NUM_FT_IDX_TBL_ROWS*sizeof(int8_t *));
152 	if (!(dfs->dfs_ftindextable)) {
153 		dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS, "Cannot allocate memory for radar table");
154 		goto bad1;
155 	}
156 	for (n = 0; n < DFS_NUM_FT_IDX_TBL_ROWS; n++) {
157 		dfs->dfs_ftindextable[n] = qdf_mem_malloc(
158 				DFS_MAX_RADAR_OVERLAP*sizeof(int8_t));
159 		if (!(dfs->dfs_ftindextable[n])) {
160 			dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS,
161 					"cannot allocate memory for radar table entry");
162 			goto bad2;
163 		}
164 	}
165 
166 	dfs->dfs_use_nol = 1;
167 
168 	/* Init the cached extension channel busy for false alarm reduction */
169 	dfs->dfs_rinfo.ext_chan_busy_ts = lmac_get_tsf64(dfs->dfs_pdev_obj);
170 	dfs->dfs_rinfo.dfs_ext_chan_busy = 0;
171 	/* Init the Bin5 chirping related data */
172 	dfs->dfs_rinfo.dfs_bin5_chirp_ts = dfs->dfs_rinfo.ext_chan_busy_ts;
173 	dfs->dfs_rinfo.dfs_last_bin5_dur = MAX_BIN5_DUR;
174 	dfs->dfs_b5radars = NULL;
175 
176 	/*
177 	 * If dfs_init_radar_filters() fails, we can abort here and
178 	 * reconfigure when the first valid channel + radar config
179 	 * is available.
180 	 */
181 	if (dfs_init_radar_filters(dfs, &radar_info)) {
182 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "Radar Filter Intialization Failed");
183 		return 1;
184 	}
185 
186 	dfs->wlan_dfs_false_rssi_thres = RSSI_POSSIBLY_FALSE;
187 	dfs->wlan_dfs_peak_mag = SEARCH_FFT_REPORT_PEAK_MAG_THRSH;
188 	dfs->dfs_phyerr_freq_min     = 0x7fffffff;
189 	dfs->dfs_phyerr_freq_max     = 0;
190 	dfs->dfs_phyerr_queued_count = 0;
191 	dfs->dfs_phyerr_w53_counter  = 0;
192 	dfs->dfs_pri_multiplier      = 2;
193 	dfs_get_radars(dfs);
194 
195 	return 0;
196 
197 bad2:
198 	qdf_mem_free(dfs->dfs_ftindextable);
199 	dfs->dfs_ftindextable = NULL;
200 bad1:
201 	for (n = 0; n < DFS_MAX_RADAR_TYPES; n++) {
202 		if (dfs->dfs_radarf[n] != NULL) {
203 			qdf_mem_free(dfs->dfs_radarf[n]);
204 			dfs->dfs_radarf[n] = NULL;
205 		}
206 	}
207 	if (dfs->pulses) {
208 		qdf_mem_free(dfs->pulses);
209 		dfs->pulses = NULL;
210 	}
211 	if (dfs->events) {
212 		qdf_mem_free(dfs->events);
213 		dfs->events = NULL;
214 	}
215 
216 	return 1;
217 }
218 
219 void dfs_main_timer_reset(struct wlan_dfs *dfs)
220 {
221 	if (dfs->wlan_radar_tasksched) {
222 		qdf_timer_sync_cancel(&dfs->wlan_dfs_task_timer);
223 		dfs->wlan_radar_tasksched = 0;
224 	}
225 }
226 
227 void dfs_main_timer_free(struct wlan_dfs *dfs)
228 {
229 	qdf_timer_free(&dfs->wlan_dfs_task_timer);
230 	dfs->wlan_radar_tasksched = 0;
231 }
232 
233 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST)
234 void dfs_host_wait_timer_free(struct wlan_dfs *dfs)
235 {
236 	qdf_timer_free(&dfs->dfs_host_wait_timer);
237 }
238 #endif
239 
240 void dfs_main_detach(struct wlan_dfs *dfs)
241 {
242 	int n, empty;
243 
244 	if (!dfs->dfs_enable) {
245 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "Already detached");
246 		return;
247 	}
248 
249 	dfs->dfs_enable = 0;
250 
251 	if (dfs->dfs_curchan != NULL) {
252 		qdf_mem_free(dfs->dfs_curchan);
253 		dfs->dfs_curchan = NULL;
254 	}
255 
256 	dfs_reset_radarq(dfs);
257 	dfs_reset_alldelaylines(dfs);
258 
259 	if (dfs->pulses != NULL) {
260 		qdf_mem_free(dfs->pulses);
261 		dfs->pulses = NULL;
262 	}
263 
264 	for (n = 0; n < DFS_MAX_RADAR_TYPES; n++) {
265 		if (dfs->dfs_radarf[n] != NULL) {
266 			qdf_mem_free(dfs->dfs_radarf[n]);
267 			dfs->dfs_radarf[n] = NULL;
268 		}
269 	}
270 
271 	if (dfs->dfs_ftindextable != NULL) {
272 		for (n = 0; n < DFS_NUM_FT_IDX_TBL_ROWS; n++) {
273 			if (dfs->dfs_ftindextable[n] != NULL) {
274 				qdf_mem_free(dfs->dfs_ftindextable[n]);
275 				dfs->dfs_ftindextable[n] = NULL;
276 			}
277 		}
278 		qdf_mem_free(dfs->dfs_ftindextable);
279 		dfs->dfs_ftindextable = NULL;
280 		dfs->wlan_dfs_isdfsregdomain = 0;
281 	}
282 
283 	if (dfs->dfs_b5radars != NULL) {
284 		qdf_mem_free(dfs->dfs_b5radars);
285 		dfs->dfs_b5radars = NULL;
286 	}
287 
288 	dfs_reset_ar(dfs);
289 
290 	WLAN_ARQ_LOCK(dfs);
291 	empty = STAILQ_EMPTY(&(dfs->dfs_arq));
292 	WLAN_ARQ_UNLOCK(dfs);
293 	if (!empty)
294 		dfs_reset_arq(dfs);
295 
296 	if (dfs->events != NULL) {
297 		qdf_mem_free(dfs->events);
298 		dfs->events = NULL;
299 	}
300 
301 	WLAN_DFSQ_LOCK_DESTROY(dfs);
302 	WLAN_ARQ_LOCK_DESTROY(dfs);
303 	WLAN_DFSEVENTQ_LOCK_DESTROY(dfs);
304 }
305 
306 int dfs_start_host_based_bangradar(struct wlan_dfs *dfs)
307 {
308 	dfs->wlan_radar_tasksched = 1;
309 	qdf_timer_mod(&dfs->wlan_dfs_task_timer, 0);
310 
311 	return 0;
312 }
313