xref: /freebsd/contrib/wpa/src/ap/acs.c (revision 681ce946f33e75c590e97c53076e86dff1fe8f4a)
1 /*
2  * ACS - Automatic Channel Selection module
3  * Copyright (c) 2011, Atheros Communications
4  * Copyright (c) 2013, Qualcomm Atheros, Inc.
5  *
6  * This software may be distributed under the terms of the BSD license.
7  * See README for more details.
8  */
9 
10 #include "utils/includes.h"
11 #include <math.h>
12 
13 #include "utils/common.h"
14 #include "utils/list.h"
15 #include "common/ieee802_11_defs.h"
16 #include "common/hw_features_common.h"
17 #include "common/wpa_ctrl.h"
18 #include "drivers/driver.h"
19 #include "hostapd.h"
20 #include "ap_drv_ops.h"
21 #include "ap_config.h"
22 #include "hw_features.h"
23 #include "acs.h"
24 
25 /*
26  * Automatic Channel Selection
27  * ===========================
28  *
29  * More info at
30  * ------------
31  * http://wireless.kernel.org/en/users/Documentation/acs
32  *
33  * How to use
34  * ----------
35  * - make sure you have CONFIG_ACS=y in hostapd's .config
36  * - use channel=0 or channel=acs to enable ACS
37  *
38  * How does it work
39  * ----------------
40  * 1. passive scans are used to collect survey data
41  *    (it is assumed that scan trigger collection of survey data in driver)
42  * 2. interference factor is calculated for each channel
43  * 3. ideal channel is picked depending on channel width by using adjacent
44  *    channel interference factors
45  *
46  * Known limitations
47  * -----------------
48  * - Current implementation depends heavily on the amount of time willing to
49  *   spend gathering survey data during hostapd startup. Short traffic bursts
50  *   may be missed and a suboptimal channel may be picked.
51  * - Ideal channel may end up overlapping a channel with 40 MHz intolerant BSS
52  *
53  * Todo / Ideas
54  * ------------
55  * - implement other interference computation methods
56  *   - BSS/RSSI based
57  *   - spectral scan based
58  *   (should be possibly to hook this up with current ACS scans)
59  * - add wpa_supplicant support (for P2P)
60  * - collect a histogram of interference over time allowing more educated
61  *   guess about an ideal channel (perhaps CSA could be used to migrate AP to a
62  *   new "better" channel while running)
63  * - include neighboring BSS scan to avoid conflicts with 40 MHz intolerant BSSs
64  *   when choosing the ideal channel
65  *
66  * Survey interference factor implementation details
67  * -------------------------------------------------
68  * Generic interference_factor in struct hostapd_channel_data is used.
69  *
70  * The survey interference factor is defined as the ratio of the
71  * observed busy time over the time we spent on the channel,
72  * this value is then amplified by the observed noise floor on
73  * the channel in comparison to the lowest noise floor observed
74  * on the entire band.
75  *
76  * This corresponds to:
77  * ---
78  * (busy time - tx time) / (active time - tx time) * 2^(chan_nf + band_min_nf)
79  * ---
80  *
81  * The coefficient of 2 reflects the way power in "far-field"
82  * radiation decreases as the square of distance from the antenna [1].
83  * What this does is it decreases the observed busy time ratio if the
84  * noise observed was low but increases it if the noise was high,
85  * proportionally to the way "far field" radiation changes over
86  * distance.
87  *
88  * If channel busy time is not available the fallback is to use channel RX time.
89  *
90  * Since noise floor is in dBm it is necessary to convert it into Watts so that
91  * combined channel interference (e.g., HT40, which uses two channels) can be
92  * calculated easily.
93  * ---
94  * (busy time - tx time) / (active time - tx time) *
95  *    2^(10^(chan_nf/10) + 10^(band_min_nf/10))
96  * ---
97  *
98  * However to account for cases where busy/rx time is 0 (channel load is then
99  * 0%) channel noise floor signal power is combined into the equation so a
100  * channel with lower noise floor is preferred. The equation becomes:
101  * ---
102  * 10^(chan_nf/5) + (busy time - tx time) / (active time - tx time) *
103  *    2^(10^(chan_nf/10) + 10^(band_min_nf/10))
104  * ---
105  *
106  * All this "interference factor" is purely subjective and only time
107  * will tell how usable this is. By using the minimum noise floor we
108  * remove any possible issues due to card calibration. The computation
109  * of the interference factor then is dependent on what the card itself
110  * picks up as the minimum noise, not an actual real possible card
111  * noise value.
112  *
113  * Total interference computation details
114  * --------------------------------------
115  * The above channel interference factor is calculated with no respect to
116  * target operational bandwidth.
117  *
118  * To find an ideal channel the above data is combined by taking into account
119  * the target operational bandwidth and selected band. E.g., on 2.4 GHz channels
120  * overlap with 20 MHz bandwidth, but there is no overlap for 20 MHz bandwidth
121  * on 5 GHz.
122  *
123  * Each valid and possible channel spec (i.e., channel + width) is taken and its
124  * interference factor is computed by summing up interferences of each channel
125  * it overlaps. The one with least total interference is picked up.
126  *
127  * Note: This implies base channel interference factor must be non-negative
128  * allowing easy summing up.
129  *
130  * Example ACS analysis printout
131  * -----------------------------
132  *
133  * ACS: Trying survey-based ACS
134  * ACS: Survey analysis for channel 1 (2412 MHz)
135  * ACS:  1: min_nf=-113 interference_factor=0.0802469 nf=-113 time=162 busy=0 rx=13
136  * ACS:  2: min_nf=-113 interference_factor=0.0745342 nf=-113 time=161 busy=0 rx=12
137  * ACS:  3: min_nf=-113 interference_factor=0.0679012 nf=-113 time=162 busy=0 rx=11
138  * ACS:  4: min_nf=-113 interference_factor=0.0310559 nf=-113 time=161 busy=0 rx=5
139  * ACS:  5: min_nf=-113 interference_factor=0.0248447 nf=-113 time=161 busy=0 rx=4
140  * ACS:  * interference factor average: 0.0557166
141  * ACS: Survey analysis for channel 2 (2417 MHz)
142  * ACS:  1: min_nf=-113 interference_factor=0.0185185 nf=-113 time=162 busy=0 rx=3
143  * ACS:  2: min_nf=-113 interference_factor=0.0246914 nf=-113 time=162 busy=0 rx=4
144  * ACS:  3: min_nf=-113 interference_factor=0.037037 nf=-113 time=162 busy=0 rx=6
145  * ACS:  4: min_nf=-113 interference_factor=0.149068 nf=-113 time=161 busy=0 rx=24
146  * ACS:  5: min_nf=-113 interference_factor=0.0248447 nf=-113 time=161 busy=0 rx=4
147  * ACS:  * interference factor average: 0.050832
148  * ACS: Survey analysis for channel 3 (2422 MHz)
149  * ACS:  1: min_nf=-113 interference_factor=2.51189e-23 nf=-113 time=162 busy=0 rx=0
150  * ACS:  2: min_nf=-113 interference_factor=0.0185185 nf=-113 time=162 busy=0 rx=3
151  * ACS:  3: min_nf=-113 interference_factor=0.0186335 nf=-113 time=161 busy=0 rx=3
152  * ACS:  4: min_nf=-113 interference_factor=0.0186335 nf=-113 time=161 busy=0 rx=3
153  * ACS:  5: min_nf=-113 interference_factor=0.0186335 nf=-113 time=161 busy=0 rx=3
154  * ACS:  * interference factor average: 0.0148838
155  * ACS: Survey analysis for channel 4 (2427 MHz)
156  * ACS:  1: min_nf=-114 interference_factor=1.58489e-23 nf=-114 time=162 busy=0 rx=0
157  * ACS:  2: min_nf=-114 interference_factor=0.0555556 nf=-114 time=162 busy=0 rx=9
158  * ACS:  3: min_nf=-114 interference_factor=1.58489e-23 nf=-114 time=161 busy=0 rx=0
159  * ACS:  4: min_nf=-114 interference_factor=0.0186335 nf=-114 time=161 busy=0 rx=3
160  * ACS:  5: min_nf=-114 interference_factor=0.00621118 nf=-114 time=161 busy=0 rx=1
161  * ACS:  * interference factor average: 0.0160801
162  * ACS: Survey analysis for channel 5 (2432 MHz)
163  * ACS:  1: min_nf=-114 interference_factor=0.409938 nf=-113 time=161 busy=0 rx=66
164  * ACS:  2: min_nf=-114 interference_factor=0.0432099 nf=-113 time=162 busy=0 rx=7
165  * ACS:  3: min_nf=-114 interference_factor=0.0124224 nf=-113 time=161 busy=0 rx=2
166  * ACS:  4: min_nf=-114 interference_factor=0.677019 nf=-113 time=161 busy=0 rx=109
167  * ACS:  5: min_nf=-114 interference_factor=0.0186335 nf=-114 time=161 busy=0 rx=3
168  * ACS:  * interference factor average: 0.232244
169  * ACS: Survey analysis for channel 6 (2437 MHz)
170  * ACS:  1: min_nf=-113 interference_factor=0.552795 nf=-113 time=161 busy=0 rx=89
171  * ACS:  2: min_nf=-113 interference_factor=0.0807453 nf=-112 time=161 busy=0 rx=13
172  * ACS:  3: min_nf=-113 interference_factor=0.0310559 nf=-113 time=161 busy=0 rx=5
173  * ACS:  4: min_nf=-113 interference_factor=0.434783 nf=-112 time=161 busy=0 rx=70
174  * ACS:  5: min_nf=-113 interference_factor=0.0621118 nf=-113 time=161 busy=0 rx=10
175  * ACS:  * interference factor average: 0.232298
176  * ACS: Survey analysis for channel 7 (2442 MHz)
177  * ACS:  1: min_nf=-113 interference_factor=0.440994 nf=-112 time=161 busy=0 rx=71
178  * ACS:  2: min_nf=-113 interference_factor=0.385093 nf=-113 time=161 busy=0 rx=62
179  * ACS:  3: min_nf=-113 interference_factor=0.0372671 nf=-113 time=161 busy=0 rx=6
180  * ACS:  4: min_nf=-113 interference_factor=0.0372671 nf=-113 time=161 busy=0 rx=6
181  * ACS:  5: min_nf=-113 interference_factor=0.0745342 nf=-113 time=161 busy=0 rx=12
182  * ACS:  * interference factor average: 0.195031
183  * ACS: Survey analysis for channel 8 (2447 MHz)
184  * ACS:  1: min_nf=-114 interference_factor=0.0496894 nf=-112 time=161 busy=0 rx=8
185  * ACS:  2: min_nf=-114 interference_factor=0.0496894 nf=-114 time=161 busy=0 rx=8
186  * ACS:  3: min_nf=-114 interference_factor=0.0372671 nf=-113 time=161 busy=0 rx=6
187  * ACS:  4: min_nf=-114 interference_factor=0.12963 nf=-113 time=162 busy=0 rx=21
188  * ACS:  5: min_nf=-114 interference_factor=0.166667 nf=-114 time=162 busy=0 rx=27
189  * ACS:  * interference factor average: 0.0865885
190  * ACS: Survey analysis for channel 9 (2452 MHz)
191  * ACS:  1: min_nf=-114 interference_factor=0.0124224 nf=-114 time=161 busy=0 rx=2
192  * ACS:  2: min_nf=-114 interference_factor=0.0310559 nf=-114 time=161 busy=0 rx=5
193  * ACS:  3: min_nf=-114 interference_factor=1.58489e-23 nf=-114 time=161 busy=0 rx=0
194  * ACS:  4: min_nf=-114 interference_factor=0.00617284 nf=-114 time=162 busy=0 rx=1
195  * ACS:  5: min_nf=-114 interference_factor=1.58489e-23 nf=-114 time=162 busy=0 rx=0
196  * ACS:  * interference factor average: 0.00993022
197  * ACS: Survey analysis for channel 10 (2457 MHz)
198  * ACS:  1: min_nf=-114 interference_factor=0.00621118 nf=-114 time=161 busy=0 rx=1
199  * ACS:  2: min_nf=-114 interference_factor=0.00621118 nf=-114 time=161 busy=0 rx=1
200  * ACS:  3: min_nf=-114 interference_factor=0.00621118 nf=-114 time=161 busy=0 rx=1
201  * ACS:  4: min_nf=-114 interference_factor=0.0493827 nf=-114 time=162 busy=0 rx=8
202  * ACS:  5: min_nf=-114 interference_factor=1.58489e-23 nf=-114 time=162 busy=0 rx=0
203  * ACS:  * interference factor average: 0.0136033
204  * ACS: Survey analysis for channel 11 (2462 MHz)
205  * ACS:  1: min_nf=-114 interference_factor=1.58489e-23 nf=-114 time=161 busy=0 rx=0
206  * ACS:  2: min_nf=-114 interference_factor=2.51189e-23 nf=-113 time=161 busy=0 rx=0
207  * ACS:  3: min_nf=-114 interference_factor=2.51189e-23 nf=-113 time=161 busy=0 rx=0
208  * ACS:  4: min_nf=-114 interference_factor=0.0432099 nf=-114 time=162 busy=0 rx=7
209  * ACS:  5: min_nf=-114 interference_factor=0.0925926 nf=-114 time=162 busy=0 rx=15
210  * ACS:  * interference factor average: 0.0271605
211  * ACS: Survey analysis for channel 12 (2467 MHz)
212  * ACS:  1: min_nf=-114 interference_factor=0.0621118 nf=-113 time=161 busy=0 rx=10
213  * ACS:  2: min_nf=-114 interference_factor=0.00621118 nf=-114 time=161 busy=0 rx=1
214  * ACS:  3: min_nf=-114 interference_factor=2.51189e-23 nf=-113 time=162 busy=0 rx=0
215  * ACS:  4: min_nf=-114 interference_factor=2.51189e-23 nf=-113 time=162 busy=0 rx=0
216  * ACS:  5: min_nf=-114 interference_factor=0.00617284 nf=-113 time=162 busy=0 rx=1
217  * ACS:  * interference factor average: 0.0148992
218  * ACS: Survey analysis for channel 13 (2472 MHz)
219  * ACS:  1: min_nf=-114 interference_factor=0.0745342 nf=-114 time=161 busy=0 rx=12
220  * ACS:  2: min_nf=-114 interference_factor=0.0555556 nf=-114 time=162 busy=0 rx=9
221  * ACS:  3: min_nf=-114 interference_factor=1.58489e-23 nf=-114 time=162 busy=0 rx=0
222  * ACS:  4: min_nf=-114 interference_factor=1.58489e-23 nf=-114 time=162 busy=0 rx=0
223  * ACS:  5: min_nf=-114 interference_factor=1.58489e-23 nf=-114 time=162 busy=0 rx=0
224  * ACS:  * interference factor average: 0.0260179
225  * ACS: Survey analysis for selected bandwidth 20MHz
226  * ACS:  * channel 1: total interference = 0.121432
227  * ACS:  * channel 2: total interference = 0.137512
228  * ACS:  * channel 3: total interference = 0.369757
229  * ACS:  * channel 4: total interference = 0.546338
230  * ACS:  * channel 5: total interference = 0.690538
231  * ACS:  * channel 6: total interference = 0.762242
232  * ACS:  * channel 7: total interference = 0.756092
233  * ACS:  * channel 8: total interference = 0.537451
234  * ACS:  * channel 9: total interference = 0.332313
235  * ACS:  * channel 10: total interference = 0.152182
236  * ACS:  * channel 11: total interference = 0.0916111
237  * ACS:  * channel 12: total interference = 0.0816809
238  * ACS:  * channel 13: total interference = 0.0680776
239  * ACS: Ideal channel is 13 (2472 MHz) with total interference factor of 0.0680776
240  *
241  * [1] http://en.wikipedia.org/wiki/Near_and_far_field
242  */
243 
244 
245 static int acs_request_scan(struct hostapd_iface *iface);
246 static int acs_survey_is_sufficient(struct freq_survey *survey);
247 
248 
249 static void acs_clean_chan_surveys(struct hostapd_channel_data *chan)
250 {
251 	struct freq_survey *survey, *tmp;
252 
253 	if (dl_list_empty(&chan->survey_list))
254 		return;
255 
256 	dl_list_for_each_safe(survey, tmp, &chan->survey_list,
257 			      struct freq_survey, list) {
258 		dl_list_del(&survey->list);
259 		os_free(survey);
260 	}
261 }
262 
263 
264 static void acs_cleanup_mode(struct hostapd_hw_modes *mode)
265 {
266 	int i;
267 	struct hostapd_channel_data *chan;
268 
269 	for (i = 0; i < mode->num_channels; i++) {
270 		chan = &mode->channels[i];
271 
272 		if (chan->flag & HOSTAPD_CHAN_SURVEY_LIST_INITIALIZED)
273 			acs_clean_chan_surveys(chan);
274 
275 		dl_list_init(&chan->survey_list);
276 		chan->flag |= HOSTAPD_CHAN_SURVEY_LIST_INITIALIZED;
277 		chan->min_nf = 0;
278 	}
279 }
280 
281 
282 void acs_cleanup(struct hostapd_iface *iface)
283 {
284 	int i;
285 
286 	for (i = 0; i < iface->num_hw_features; i++)
287 		acs_cleanup_mode(&iface->hw_features[i]);
288 
289 	iface->chans_surveyed = 0;
290 	iface->acs_num_completed_scans = 0;
291 }
292 
293 
294 static void acs_fail(struct hostapd_iface *iface)
295 {
296 	wpa_printf(MSG_ERROR, "ACS: Failed to start");
297 	acs_cleanup(iface);
298 	hostapd_disable_iface(iface);
299 }
300 
301 
302 static long double
303 acs_survey_interference_factor(struct freq_survey *survey, s8 min_nf)
304 {
305 	long double factor, busy, total;
306 
307 	if (survey->filled & SURVEY_HAS_CHAN_TIME_BUSY)
308 		busy = survey->channel_time_busy;
309 	else if (survey->filled & SURVEY_HAS_CHAN_TIME_RX)
310 		busy = survey->channel_time_rx;
311 	else {
312 		wpa_printf(MSG_ERROR, "ACS: Survey data missing");
313 		return 0;
314 	}
315 
316 	total = survey->channel_time;
317 
318 	if (survey->filled & SURVEY_HAS_CHAN_TIME_TX) {
319 		busy -= survey->channel_time_tx;
320 		total -= survey->channel_time_tx;
321 	}
322 
323 	/* TODO: figure out the best multiplier for noise floor base */
324 	factor = pow(10, survey->nf / 5.0L) +
325 		(total ? (busy / total) : 0) *
326 		pow(2, pow(10, (long double) survey->nf / 10.0L) -
327 		    pow(10, (long double) min_nf / 10.0L));
328 
329 	return factor;
330 }
331 
332 
333 static void
334 acs_survey_chan_interference_factor(struct hostapd_iface *iface,
335 				    struct hostapd_channel_data *chan)
336 {
337 	struct freq_survey *survey;
338 	unsigned int i = 0;
339 	long double int_factor = 0;
340 	unsigned count = 0;
341 
342 	if (dl_list_empty(&chan->survey_list) ||
343 	    (chan->flag & HOSTAPD_CHAN_DISABLED))
344 		return;
345 
346 	chan->interference_factor = 0;
347 
348 	dl_list_for_each(survey, &chan->survey_list, struct freq_survey, list)
349 	{
350 		i++;
351 
352 		if (!acs_survey_is_sufficient(survey)) {
353 			wpa_printf(MSG_DEBUG, "ACS: %d: insufficient data", i);
354 			continue;
355 		}
356 
357 		count++;
358 		int_factor = acs_survey_interference_factor(survey,
359 							    iface->lowest_nf);
360 		chan->interference_factor += int_factor;
361 		wpa_printf(MSG_DEBUG, "ACS: %d: min_nf=%d interference_factor=%Lg nf=%d time=%lu busy=%lu rx=%lu",
362 			   i, chan->min_nf, int_factor,
363 			   survey->nf, (unsigned long) survey->channel_time,
364 			   (unsigned long) survey->channel_time_busy,
365 			   (unsigned long) survey->channel_time_rx);
366 	}
367 
368 	if (count)
369 		chan->interference_factor /= count;
370 }
371 
372 
373 static int acs_usable_bw40_chan(const struct hostapd_channel_data *chan)
374 {
375 	const int allowed[] = { 5180, 5220, 5260, 5300, 5500, 5540, 5580, 5620,
376 				5660, 5745, 5785, 4920, 4960, 5955, 5995, 6035,
377 				6075, 6115, 6155, 6195, 6235, 6275, 6315, 6355,
378 				6395, 6435, 6475, 6515, 6555, 6595, 6635, 6675,
379 				6715, 6755, 6795, 6835, 6875, 6915, 6955, 6995,
380 				7035, 7075 };
381 	unsigned int i;
382 
383 	for (i = 0; i < ARRAY_SIZE(allowed); i++)
384 		if (chan->freq == allowed[i])
385 			return 1;
386 
387 	return 0;
388 }
389 
390 
391 static int acs_usable_bw80_chan(const struct hostapd_channel_data *chan)
392 {
393 	const int allowed[] = { 5180, 5260, 5500, 5580, 5660, 5745, 5955, 6035,
394 				6115, 6195, 6275, 6355, 6435, 6515, 6595, 6675,
395 				6755, 6835, 6915, 6995 };
396 	unsigned int i;
397 
398 	for (i = 0; i < ARRAY_SIZE(allowed); i++)
399 		if (chan->freq == allowed[i])
400 			return 1;
401 
402 	return 0;
403 }
404 
405 
406 static int acs_usable_bw160_chan(const struct hostapd_channel_data *chan)
407 {
408 	const int allowed[] = { 5180, 5500, 5955, 6115, 6275, 6435, 6595, 6755,
409 				6915 };
410 	unsigned int i;
411 
412 	for (i = 0; i < ARRAY_SIZE(allowed); i++)
413 		if (chan->freq == allowed[i])
414 			return 1;
415 
416 	return 0;
417 }
418 
419 
420 static int acs_survey_is_sufficient(struct freq_survey *survey)
421 {
422 	if (!(survey->filled & SURVEY_HAS_NF)) {
423 		wpa_printf(MSG_INFO, "ACS: Survey is missing noise floor");
424 		return 0;
425 	}
426 
427 	if (!(survey->filled & SURVEY_HAS_CHAN_TIME)) {
428 		wpa_printf(MSG_INFO, "ACS: Survey is missing channel time");
429 		return 0;
430 	}
431 
432 	if (!(survey->filled & SURVEY_HAS_CHAN_TIME_BUSY) &&
433 	    !(survey->filled & SURVEY_HAS_CHAN_TIME_RX)) {
434 		wpa_printf(MSG_INFO,
435 			   "ACS: Survey is missing RX and busy time (at least one is required)");
436 		return 0;
437 	}
438 
439 	return 1;
440 }
441 
442 
443 static int acs_survey_list_is_sufficient(struct hostapd_channel_data *chan)
444 {
445 	struct freq_survey *survey;
446 	int ret = -1;
447 
448 	dl_list_for_each(survey, &chan->survey_list, struct freq_survey, list)
449 	{
450 		if (acs_survey_is_sufficient(survey)) {
451 			ret = 1;
452 			break;
453 		}
454 		ret = 0;
455 	}
456 
457 	if (ret == -1)
458 		ret = 1; /* no survey list entries */
459 
460 	if (!ret) {
461 		wpa_printf(MSG_INFO,
462 			   "ACS: Channel %d has insufficient survey data",
463 			   chan->chan);
464 	}
465 
466 	return ret;
467 }
468 
469 
470 static int acs_surveys_are_sufficient_mode(struct hostapd_hw_modes *mode)
471 {
472 	int i;
473 	struct hostapd_channel_data *chan;
474 
475 	for (i = 0; i < mode->num_channels; i++) {
476 		chan = &mode->channels[i];
477 		if (!(chan->flag & HOSTAPD_CHAN_DISABLED) &&
478 		    acs_survey_list_is_sufficient(chan))
479 			return 1;
480 	}
481 
482 	return 0;
483 }
484 
485 
486 static int acs_surveys_are_sufficient(struct hostapd_iface *iface)
487 {
488 	int i;
489 	struct hostapd_hw_modes *mode;
490 
491 	for (i = 0; i < iface->num_hw_features; i++) {
492 		mode = &iface->hw_features[i];
493 		if (!hostapd_hw_skip_mode(iface, mode) &&
494 		    acs_surveys_are_sufficient_mode(mode))
495 			return 1;
496 	}
497 
498 	return 0;
499 }
500 
501 
502 static int acs_usable_chan(struct hostapd_channel_data *chan)
503 {
504 	return !dl_list_empty(&chan->survey_list) &&
505 		!(chan->flag & HOSTAPD_CHAN_DISABLED) &&
506 		acs_survey_list_is_sufficient(chan);
507 }
508 
509 
510 static int is_in_chanlist(struct hostapd_iface *iface,
511 			  struct hostapd_channel_data *chan)
512 {
513 	if (!iface->conf->acs_ch_list.num)
514 		return 1;
515 
516 	return freq_range_list_includes(&iface->conf->acs_ch_list, chan->chan);
517 }
518 
519 
520 static int is_in_freqlist(struct hostapd_iface *iface,
521 			  struct hostapd_channel_data *chan)
522 {
523 	if (!iface->conf->acs_freq_list.num)
524 		return 1;
525 
526 	return freq_range_list_includes(&iface->conf->acs_freq_list,
527 					chan->freq);
528 }
529 
530 
531 static void acs_survey_mode_interference_factor(
532 	struct hostapd_iface *iface, struct hostapd_hw_modes *mode)
533 {
534 	int i;
535 	struct hostapd_channel_data *chan;
536 
537 	for (i = 0; i < mode->num_channels; i++) {
538 		chan = &mode->channels[i];
539 
540 		if (!acs_usable_chan(chan))
541 			continue;
542 
543 		if (!is_in_chanlist(iface, chan))
544 			continue;
545 
546 		if (!is_in_freqlist(iface, chan))
547 			continue;
548 
549 		wpa_printf(MSG_DEBUG, "ACS: Survey analysis for channel %d (%d MHz)",
550 			   chan->chan, chan->freq);
551 
552 		acs_survey_chan_interference_factor(iface, chan);
553 
554 		wpa_printf(MSG_DEBUG, "ACS:  * interference factor average: %Lg",
555 			   chan->interference_factor);
556 	}
557 }
558 
559 
560 static void acs_survey_all_chans_interference_factor(
561 	struct hostapd_iface *iface)
562 {
563 	int i;
564 	struct hostapd_hw_modes *mode;
565 
566 	for (i = 0; i < iface->num_hw_features; i++) {
567 		mode = &iface->hw_features[i];
568 		if (!hostapd_hw_skip_mode(iface, mode))
569 			acs_survey_mode_interference_factor(iface, mode);
570 	}
571 }
572 
573 
574 static struct hostapd_channel_data *
575 acs_find_chan_mode(struct hostapd_hw_modes *mode, int freq)
576 {
577 	struct hostapd_channel_data *chan;
578 	int i;
579 
580 	for (i = 0; i < mode->num_channels; i++) {
581 		chan = &mode->channels[i];
582 
583 		if (chan->flag & HOSTAPD_CHAN_DISABLED)
584 			continue;
585 
586 		if (chan->freq == freq)
587 			return chan;
588 	}
589 
590 	return NULL;
591 }
592 
593 
594 static struct hostapd_channel_data *
595 acs_find_chan(struct hostapd_iface *iface, int freq)
596 {
597 	int i;
598 	struct hostapd_hw_modes *mode;
599 	struct hostapd_channel_data *chan;
600 
601 	for (i = 0; i < iface->num_hw_features; i++) {
602 		mode = &iface->hw_features[i];
603 		if (!hostapd_hw_skip_mode(iface, mode)) {
604 			chan = acs_find_chan_mode(mode, freq);
605 			if (chan)
606 				return chan;
607 		}
608 	}
609 
610 	return NULL;
611 }
612 
613 
614 static int is_24ghz_mode(enum hostapd_hw_mode mode)
615 {
616 	return mode == HOSTAPD_MODE_IEEE80211B ||
617 		mode == HOSTAPD_MODE_IEEE80211G;
618 }
619 
620 
621 static int is_common_24ghz_chan(int chan)
622 {
623 	return chan == 1 || chan == 6 || chan == 11;
624 }
625 
626 
627 #ifndef ACS_ADJ_WEIGHT
628 #define ACS_ADJ_WEIGHT 0.85
629 #endif /* ACS_ADJ_WEIGHT */
630 
631 #ifndef ACS_NEXT_ADJ_WEIGHT
632 #define ACS_NEXT_ADJ_WEIGHT 0.55
633 #endif /* ACS_NEXT_ADJ_WEIGHT */
634 
635 #ifndef ACS_24GHZ_PREFER_1_6_11
636 /*
637  * Select commonly used channels 1, 6, 11 by default even if a neighboring
638  * channel has a smaller interference factor as long as it is not better by more
639  * than this multiplier.
640  */
641 #define ACS_24GHZ_PREFER_1_6_11 0.8
642 #endif /* ACS_24GHZ_PREFER_1_6_11 */
643 
644 static void
645 acs_find_ideal_chan_mode(struct hostapd_iface *iface,
646 			 struct hostapd_hw_modes *mode,
647 			 int n_chans, u32 bw,
648 			 struct hostapd_channel_data **rand_chan,
649 			 struct hostapd_channel_data **ideal_chan,
650 			 long double *ideal_factor)
651 {
652 	struct hostapd_channel_data *chan, *adj_chan = NULL;
653 	long double factor;
654 	int i, j;
655 	unsigned int k;
656 
657 	for (i = 0; i < mode->num_channels; i++) {
658 		double total_weight;
659 		struct acs_bias *bias, tmp_bias;
660 
661 		chan = &mode->channels[i];
662 
663 		/* Since in the current ACS implementation the first channel is
664 		 * always a primary channel, skip channels not available as
665 		 * primary until more sophisticated channel selection is
666 		 * implemented. */
667 		if (!chan_pri_allowed(chan))
668 			continue;
669 
670 		if (!is_in_chanlist(iface, chan))
671 			continue;
672 
673 		if (!is_in_freqlist(iface, chan))
674 			continue;
675 
676 		if (!chan_bw_allowed(chan, bw, 1, 1)) {
677 			wpa_printf(MSG_DEBUG,
678 				   "ACS: Channel %d: BW %u is not supported",
679 				   chan->chan, bw);
680 			continue;
681 		}
682 
683 		/* HT40 on 5 GHz has a limited set of primary channels as per
684 		 * 11n Annex J */
685 		if (mode->mode == HOSTAPD_MODE_IEEE80211A &&
686 		    ((iface->conf->ieee80211n &&
687 		      iface->conf->secondary_channel) ||
688 		     is_6ghz_freq(chan->freq)) &&
689 		    !acs_usable_bw40_chan(chan)) {
690 			wpa_printf(MSG_DEBUG,
691 				   "ACS: Channel %d: not allowed as primary channel for 40 MHz bandwidth",
692 				   chan->chan);
693 			continue;
694 		}
695 
696 		if (mode->mode == HOSTAPD_MODE_IEEE80211A &&
697 		    (iface->conf->ieee80211ac || iface->conf->ieee80211ax)) {
698 			if (hostapd_get_oper_chwidth(iface->conf) ==
699 			    CHANWIDTH_80MHZ &&
700 			    !acs_usable_bw80_chan(chan)) {
701 				wpa_printf(MSG_DEBUG,
702 					   "ACS: Channel %d: not allowed as primary channel for 80 MHz bandwidth",
703 					   chan->chan);
704 				continue;
705 			}
706 
707 			if (hostapd_get_oper_chwidth(iface->conf) ==
708 			    CHANWIDTH_160MHZ &&
709 			    !acs_usable_bw160_chan(chan)) {
710 				wpa_printf(MSG_DEBUG,
711 					   "ACS: Channel %d: not allowed as primary channel for 160 MHz bandwidth",
712 					   chan->chan);
713 				continue;
714 			}
715 		}
716 
717 		factor = 0;
718 		if (acs_usable_chan(chan))
719 			factor = chan->interference_factor;
720 		total_weight = 1;
721 
722 		for (j = 1; j < n_chans; j++) {
723 			adj_chan = acs_find_chan(iface, chan->freq + (j * 20));
724 			if (!adj_chan)
725 				break;
726 
727 			if (!chan_bw_allowed(adj_chan, bw, 1, 0)) {
728 				wpa_printf(MSG_DEBUG,
729 					   "ACS: PRI Channel %d: secondary channel %d BW %u is not supported",
730 					   chan->chan, adj_chan->chan, bw);
731 				break;
732 			}
733 
734 			if (acs_usable_chan(adj_chan)) {
735 				factor += adj_chan->interference_factor;
736 				total_weight += 1;
737 			}
738 		}
739 
740 		if (j != n_chans) {
741 			wpa_printf(MSG_DEBUG, "ACS: Channel %d: not enough bandwidth",
742 				   chan->chan);
743 			continue;
744 		}
745 
746 		/* 2.4 GHz has overlapping 20 MHz channels. Include adjacent
747 		 * channel interference factor. */
748 		if (is_24ghz_mode(mode->mode)) {
749 			for (j = 0; j < n_chans; j++) {
750 				adj_chan = acs_find_chan(iface, chan->freq +
751 							 (j * 20) - 5);
752 				if (adj_chan && acs_usable_chan(adj_chan)) {
753 					factor += ACS_ADJ_WEIGHT *
754 						adj_chan->interference_factor;
755 					total_weight += ACS_ADJ_WEIGHT;
756 				}
757 
758 				adj_chan = acs_find_chan(iface, chan->freq +
759 							 (j * 20) - 10);
760 				if (adj_chan && acs_usable_chan(adj_chan)) {
761 					factor += ACS_NEXT_ADJ_WEIGHT *
762 						adj_chan->interference_factor;
763 					total_weight += ACS_NEXT_ADJ_WEIGHT;
764 				}
765 
766 				adj_chan = acs_find_chan(iface, chan->freq +
767 							 (j * 20) + 5);
768 				if (adj_chan && acs_usable_chan(adj_chan)) {
769 					factor += ACS_ADJ_WEIGHT *
770 						adj_chan->interference_factor;
771 					total_weight += ACS_ADJ_WEIGHT;
772 				}
773 
774 				adj_chan = acs_find_chan(iface, chan->freq +
775 							 (j * 20) + 10);
776 				if (adj_chan && acs_usable_chan(adj_chan)) {
777 					factor += ACS_NEXT_ADJ_WEIGHT *
778 						adj_chan->interference_factor;
779 					total_weight += ACS_NEXT_ADJ_WEIGHT;
780 				}
781 			}
782 		}
783 
784 		factor /= total_weight;
785 
786 		bias = NULL;
787 		if (iface->conf->acs_chan_bias) {
788 			for (k = 0; k < iface->conf->num_acs_chan_bias; k++) {
789 				bias = &iface->conf->acs_chan_bias[k];
790 				if (bias->channel == chan->chan)
791 					break;
792 				bias = NULL;
793 			}
794 		} else if (is_24ghz_mode(mode->mode) &&
795 			   is_common_24ghz_chan(chan->chan)) {
796 			tmp_bias.channel = chan->chan;
797 			tmp_bias.bias = ACS_24GHZ_PREFER_1_6_11;
798 			bias = &tmp_bias;
799 		}
800 
801 		if (bias) {
802 			factor *= bias->bias;
803 			wpa_printf(MSG_DEBUG,
804 				   "ACS:  * channel %d: total interference = %Lg (%f bias)",
805 				   chan->chan, factor, bias->bias);
806 		} else {
807 			wpa_printf(MSG_DEBUG,
808 				   "ACS:  * channel %d: total interference = %Lg",
809 				   chan->chan, factor);
810 		}
811 
812 		if (acs_usable_chan(chan) &&
813 		    (!*ideal_chan || factor < *ideal_factor)) {
814 			*ideal_factor = factor;
815 			*ideal_chan = chan;
816 		}
817 
818 		/* This channel would at least be usable */
819 		if (!(*rand_chan))
820 			*rand_chan = chan;
821 	}
822 }
823 
824 
825 /*
826  * At this point it's assumed chan->interference_factor has been computed.
827  * This function should be reusable regardless of interference computation
828  * option (survey, BSS, spectral, ...). chan->interference factor must be
829  * summable (i.e., must be always greater than zero).
830  */
831 static struct hostapd_channel_data *
832 acs_find_ideal_chan(struct hostapd_iface *iface)
833 {
834 	struct hostapd_channel_data *ideal_chan = NULL,
835 		*rand_chan = NULL;
836 	long double ideal_factor = 0;
837 	int i;
838 	int n_chans = 1;
839 	u32 bw;
840 	struct hostapd_hw_modes *mode;
841 
842 	if (is_6ghz_op_class(iface->conf->op_class)) {
843 		bw = op_class_to_bandwidth(iface->conf->op_class);
844 		n_chans = bw / 20;
845 		goto bw_selected;
846 	}
847 
848 	/* TODO: HT40- support */
849 
850 	if (iface->conf->ieee80211n &&
851 	    iface->conf->secondary_channel == -1) {
852 		wpa_printf(MSG_ERROR, "ACS: HT40- is not supported yet. Please try HT40+");
853 		return NULL;
854 	}
855 
856 	if (iface->conf->ieee80211n &&
857 	    iface->conf->secondary_channel)
858 		n_chans = 2;
859 
860 	if (iface->conf->ieee80211ac || iface->conf->ieee80211ax) {
861 		switch (hostapd_get_oper_chwidth(iface->conf)) {
862 		case CHANWIDTH_80MHZ:
863 			n_chans = 4;
864 			break;
865 		case CHANWIDTH_160MHZ:
866 			n_chans = 8;
867 			break;
868 		}
869 	}
870 
871 	bw = num_chan_to_bw(n_chans);
872 
873 bw_selected:
874 	/* TODO: VHT/HE80+80. Update acs_adjust_center_freq() too. */
875 
876 	wpa_printf(MSG_DEBUG,
877 		   "ACS: Survey analysis for selected bandwidth %d MHz", bw);
878 
879 	for (i = 0; i < iface->num_hw_features; i++) {
880 		mode = &iface->hw_features[i];
881 		if (!hostapd_hw_skip_mode(iface, mode))
882 			acs_find_ideal_chan_mode(iface, mode, n_chans, bw,
883 						 &rand_chan, &ideal_chan,
884 						 &ideal_factor);
885 	}
886 
887 	if (ideal_chan) {
888 		wpa_printf(MSG_DEBUG, "ACS: Ideal channel is %d (%d MHz) with total interference factor of %Lg",
889 			   ideal_chan->chan, ideal_chan->freq, ideal_factor);
890 		return ideal_chan;
891 	}
892 
893 	return rand_chan;
894 }
895 
896 
897 static void acs_adjust_center_freq(struct hostapd_iface *iface)
898 {
899 	int offset;
900 
901 	wpa_printf(MSG_DEBUG, "ACS: Adjusting VHT center frequency");
902 
903 	switch (hostapd_get_oper_chwidth(iface->conf)) {
904 	case CHANWIDTH_USE_HT:
905 		offset = 2 * iface->conf->secondary_channel;
906 		break;
907 	case CHANWIDTH_80MHZ:
908 		offset = 6;
909 		break;
910 	case CHANWIDTH_160MHZ:
911 		offset = 14;
912 		break;
913 	default:
914 		/* TODO: How can this be calculated? Adjust
915 		 * acs_find_ideal_chan() */
916 		wpa_printf(MSG_INFO,
917 			   "ACS: Only VHT20/40/80/160 is supported now");
918 		return;
919 	}
920 
921 	hostapd_set_oper_centr_freq_seg0_idx(iface->conf,
922 					     iface->conf->channel + offset);
923 }
924 
925 
926 static int acs_study_survey_based(struct hostapd_iface *iface)
927 {
928 	wpa_printf(MSG_DEBUG, "ACS: Trying survey-based ACS");
929 
930 	if (!iface->chans_surveyed) {
931 		wpa_printf(MSG_ERROR, "ACS: Unable to collect survey data");
932 		return -1;
933 	}
934 
935 	if (!acs_surveys_are_sufficient(iface)) {
936 		wpa_printf(MSG_ERROR, "ACS: Surveys have insufficient data");
937 		return -1;
938 	}
939 
940 	acs_survey_all_chans_interference_factor(iface);
941 	return 0;
942 }
943 
944 
945 static int acs_study_options(struct hostapd_iface *iface)
946 {
947 	if (acs_study_survey_based(iface) == 0)
948 		return 0;
949 
950 	/* TODO: If no surveys are available/sufficient this is a good
951 	 * place to fallback to BSS-based ACS */
952 
953 	return -1;
954 }
955 
956 
957 static void acs_study(struct hostapd_iface *iface)
958 {
959 	struct hostapd_channel_data *ideal_chan;
960 	int err;
961 
962 	err = acs_study_options(iface);
963 	if (err < 0) {
964 		wpa_printf(MSG_ERROR, "ACS: All study options have failed");
965 		goto fail;
966 	}
967 
968 	ideal_chan = acs_find_ideal_chan(iface);
969 	if (!ideal_chan) {
970 		wpa_printf(MSG_ERROR, "ACS: Failed to compute ideal channel");
971 		err = -1;
972 		goto fail;
973 	}
974 
975 	iface->conf->channel = ideal_chan->chan;
976 	iface->freq = ideal_chan->freq;
977 
978 	if (iface->conf->ieee80211ac || iface->conf->ieee80211ax)
979 		acs_adjust_center_freq(iface);
980 
981 	err = 0;
982 fail:
983 	/*
984 	 * hostapd_setup_interface_complete() will return -1 on failure,
985 	 * 0 on success and 0 is HOSTAPD_CHAN_VALID :)
986 	 */
987 	if (hostapd_acs_completed(iface, err) == HOSTAPD_CHAN_VALID) {
988 		acs_cleanup(iface);
989 		return;
990 	}
991 
992 	/* This can possibly happen if channel parameters (secondary
993 	 * channel, center frequencies) are misconfigured */
994 	wpa_printf(MSG_ERROR, "ACS: Possibly channel configuration is invalid, please report this along with your config file.");
995 	acs_fail(iface);
996 }
997 
998 
999 static void acs_scan_complete(struct hostapd_iface *iface)
1000 {
1001 	int err;
1002 
1003 	iface->scan_cb = NULL;
1004 
1005 	wpa_printf(MSG_DEBUG, "ACS: Using survey based algorithm (acs_num_scans=%d)",
1006 		   iface->conf->acs_num_scans);
1007 
1008 	err = hostapd_drv_get_survey(iface->bss[0], 0);
1009 	if (err) {
1010 		wpa_printf(MSG_ERROR, "ACS: Failed to get survey data");
1011 		goto fail;
1012 	}
1013 
1014 	if (++iface->acs_num_completed_scans < iface->conf->acs_num_scans) {
1015 		err = acs_request_scan(iface);
1016 		if (err) {
1017 			wpa_printf(MSG_ERROR, "ACS: Failed to request scan");
1018 			goto fail;
1019 		}
1020 
1021 		return;
1022 	}
1023 
1024 	acs_study(iface);
1025 	return;
1026 fail:
1027 	hostapd_acs_completed(iface, 1);
1028 	acs_fail(iface);
1029 }
1030 
1031 
1032 static int * acs_request_scan_add_freqs(struct hostapd_iface *iface,
1033 					struct hostapd_hw_modes *mode,
1034 					int *freq)
1035 {
1036 	struct hostapd_channel_data *chan;
1037 	int i;
1038 
1039 	for (i = 0; i < mode->num_channels; i++) {
1040 		chan = &mode->channels[i];
1041 		if (chan->flag & HOSTAPD_CHAN_DISABLED)
1042 			continue;
1043 
1044 		if (!is_in_chanlist(iface, chan))
1045 			continue;
1046 
1047 		if (!is_in_freqlist(iface, chan))
1048 			continue;
1049 
1050 		*freq++ = chan->freq;
1051 	}
1052 
1053 	return freq;
1054 }
1055 
1056 
1057 static int acs_request_scan(struct hostapd_iface *iface)
1058 {
1059 	struct wpa_driver_scan_params params;
1060 	int i, *freq;
1061 	int num_channels;
1062 	struct hostapd_hw_modes *mode;
1063 
1064 	os_memset(&params, 0, sizeof(params));
1065 
1066 	num_channels = 0;
1067 	for (i = 0; i < iface->num_hw_features; i++) {
1068 		mode = &iface->hw_features[i];
1069 		if (!hostapd_hw_skip_mode(iface, mode))
1070 			num_channels += mode->num_channels;
1071 	}
1072 
1073 	params.freqs = os_calloc(num_channels + 1, sizeof(params.freqs[0]));
1074 	if (params.freqs == NULL)
1075 		return -1;
1076 
1077 	freq = params.freqs;
1078 
1079 	for (i = 0; i < iface->num_hw_features; i++) {
1080 		mode = &iface->hw_features[i];
1081 		if (!hostapd_hw_skip_mode(iface, mode))
1082 			freq = acs_request_scan_add_freqs(iface, mode, freq);
1083 	}
1084 
1085 	*freq = 0;
1086 
1087 	if (params.freqs == freq) {
1088 		wpa_printf(MSG_ERROR, "ACS: No available channels found");
1089 		os_free(params.freqs);
1090 		return -1;
1091 	}
1092 
1093 	iface->scan_cb = acs_scan_complete;
1094 
1095 	wpa_printf(MSG_DEBUG, "ACS: Scanning %d / %d",
1096 		   iface->acs_num_completed_scans + 1,
1097 		   iface->conf->acs_num_scans);
1098 
1099 	if (hostapd_driver_scan(iface->bss[0], &params) < 0) {
1100 		wpa_printf(MSG_ERROR, "ACS: Failed to request initial scan");
1101 		acs_cleanup(iface);
1102 		os_free(params.freqs);
1103 		return -1;
1104 	}
1105 
1106 	os_free(params.freqs);
1107 	return 0;
1108 }
1109 
1110 
1111 enum hostapd_chan_status acs_init(struct hostapd_iface *iface)
1112 {
1113 	wpa_printf(MSG_INFO, "ACS: Automatic channel selection started, this may take a bit");
1114 
1115 	if (iface->drv_flags & WPA_DRIVER_FLAGS_ACS_OFFLOAD) {
1116 		wpa_printf(MSG_INFO, "ACS: Offloading to driver");
1117 		if (hostapd_drv_do_acs(iface->bss[0]))
1118 			return HOSTAPD_CHAN_INVALID;
1119 		return HOSTAPD_CHAN_ACS;
1120 	}
1121 
1122 	if (!iface->current_mode &&
1123 	    iface->conf->hw_mode != HOSTAPD_MODE_IEEE80211ANY)
1124 		return HOSTAPD_CHAN_INVALID;
1125 
1126 	acs_cleanup(iface);
1127 
1128 	if (acs_request_scan(iface) < 0)
1129 		return HOSTAPD_CHAN_INVALID;
1130 
1131 	hostapd_set_state(iface, HAPD_IFACE_ACS);
1132 	wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, ACS_EVENT_STARTED);
1133 
1134 	return HOSTAPD_CHAN_ACS;
1135 }
1136