xref: /freebsd/contrib/wpa/src/ap/acs.c (revision 71e72c9e91c4b8007a4292e09669e8b549c29e97)
1 /*
2  * ACS - Automatic Channel Selection module
3  * Copyright (c) 2011, Atheros Communications
4  * Copyright (c) 2013, Qualcomm Atheros, Inc.
5  * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
6  *
7  * This software may be distributed under the terms of the BSD license.
8  * See README for more details.
9  */
10 
11 #include "utils/includes.h"
12 #include <math.h>
13 
14 #include "utils/common.h"
15 #include "utils/list.h"
16 #include "utils/eloop.h"
17 #include "common/ieee802_11_defs.h"
18 #include "common/hw_features_common.h"
19 #include "common/wpa_ctrl.h"
20 #include "drivers/driver.h"
21 #include "hostapd.h"
22 #include "ap_drv_ops.h"
23 #include "ap_config.h"
24 #include "hw_features.h"
25 #include "acs.h"
26 
27 /*
28  * Automatic Channel Selection
29  * ===========================
30  *
31  * More info at
32  * ------------
33  * http://wireless.kernel.org/en/users/Documentation/acs
34  *
35  * How to use
36  * ----------
37  * - make sure you have CONFIG_ACS=y in hostapd's .config
38  * - use channel=0 or channel=acs to enable ACS
39  *
40  * How does it work
41  * ----------------
42  * 1. passive scans are used to collect survey data
43  *    (it is assumed that scan trigger collection of survey data in driver)
44  * 2. interference factor is calculated for each channel
45  * 3. ideal channel is picked depending on channel width by using adjacent
46  *    channel interference factors
47  *
48  * Known limitations
49  * -----------------
50  * - Current implementation depends heavily on the amount of time willing to
51  *   spend gathering survey data during hostapd startup. Short traffic bursts
52  *   may be missed and a suboptimal channel may be picked.
53  * - Ideal channel may end up overlapping a channel with 40 MHz intolerant BSS
54  *
55  * Todo / Ideas
56  * ------------
57  * - implement other interference computation methods
58  *   - RSSI based
59  *   - spectral scan based
60  *   (should be possibly to hook this up with current ACS scans)
61  * - add wpa_supplicant support (for P2P)
62  * - collect a histogram of interference over time allowing more educated
63  *   guess about an ideal channel (perhaps CSA could be used to migrate AP to a
64  *   new "better" channel while running)
65  * - include neighboring BSS scan to avoid conflicts with 40 MHz intolerant BSSs
66  *   when choosing the ideal channel
67  *
68  * Survey interference factor implementation details
69  * -------------------------------------------------
70  * Generic interference_factor in struct hostapd_channel_data is used.
71  *
72  * The survey interference factor is defined as the ratio of the
73  * observed busy time over the time we spent on the channel,
74  * this value is then amplified by the observed noise floor on
75  * the channel in comparison to the lowest noise floor observed
76  * on the entire band.
77  *
78  * This corresponds to:
79  * ---
80  * (busy time - tx time) / (active time - tx time) * 2^(chan_nf - band_min_nf)
81  * ---
82  *
83  * The coefficient of 2 reflects the way power in "far-field"
84  * radiation decreases as the square of distance from the antenna [1].
85  * What this does is it decreases the observed busy time ratio if the
86  * noise observed was low but increases it if the noise was high,
87  * proportionally to the way "far field" radiation changes over
88  * distance.
89  *
90  * If channel busy time is not available the fallback is to use channel RX time.
91  *
92  * Since noise floor is in dBm it is necessary to convert it into Watts so that
93  * combined channel interference (e.g., HT40, which uses two channels) can be
94  * calculated easily.
95  * ---
96  * (busy time - tx time) / (active time - tx time) *
97  *    2^(10^(chan_nf/10) - 10^(band_min_nf/10))
98  * ---
99  *
100  * However to account for cases where busy/rx time is 0 (channel load is then
101  * 0%) channel noise floor signal power is combined into the equation so a
102  * channel with lower noise floor is preferred. The equation becomes:
103  * ---
104  * 10^(chan_nf/5) + (busy time - tx time) / (active time - tx time) *
105  *    2^(10^(chan_nf/10) - 10^(band_min_nf/10))
106  * ---
107  *
108  * All this "interference factor" is purely subjective and only time
109  * will tell how usable this is. By using the minimum noise floor we
110  * remove any possible issues due to card calibration. The computation
111  * of the interference factor then is dependent on what the card itself
112  * picks up as the minimum noise, not an actual real possible card
113  * noise value.
114  *
115  * Total interference computation details
116  * --------------------------------------
117  * The above channel interference factor is calculated with no respect to
118  * target operational bandwidth.
119  *
120  * To find an ideal channel the above data is combined by taking into account
121  * the target operational bandwidth and selected band. E.g., on 2.4 GHz channels
122  * overlap with 20 MHz bandwidth, but there is no overlap for 20 MHz bandwidth
123  * on 5 GHz.
124  *
125  * Each valid and possible channel spec (i.e., channel + width) is taken and its
126  * interference factor is computed by summing up interferences of each channel
127  * it overlaps. The one with least total interference is picked up.
128  *
129  * Note: This implies base channel interference factor must be non-negative
130  * allowing easy summing up.
131  *
132  * Example ACS analysis printout
133  * -----------------------------
134  *
135  * ACS: Trying survey-based ACS
136  * ACS: Survey analysis for channel 1 (2412 MHz)
137  * ACS:  1: min_nf=-113 interference_factor=0.0802469 nf=-113 time=162 busy=0 rx=13
138  * ACS:  2: min_nf=-113 interference_factor=0.0745342 nf=-113 time=161 busy=0 rx=12
139  * ACS:  3: min_nf=-113 interference_factor=0.0679012 nf=-113 time=162 busy=0 rx=11
140  * ACS:  4: min_nf=-113 interference_factor=0.0310559 nf=-113 time=161 busy=0 rx=5
141  * ACS:  5: min_nf=-113 interference_factor=0.0248447 nf=-113 time=161 busy=0 rx=4
142  * ACS:  * interference factor average: 0.0557166
143  * ACS: Survey analysis for channel 2 (2417 MHz)
144  * ACS:  1: min_nf=-113 interference_factor=0.0185185 nf=-113 time=162 busy=0 rx=3
145  * ACS:  2: min_nf=-113 interference_factor=0.0246914 nf=-113 time=162 busy=0 rx=4
146  * ACS:  3: min_nf=-113 interference_factor=0.037037 nf=-113 time=162 busy=0 rx=6
147  * ACS:  4: min_nf=-113 interference_factor=0.149068 nf=-113 time=161 busy=0 rx=24
148  * ACS:  5: min_nf=-113 interference_factor=0.0248447 nf=-113 time=161 busy=0 rx=4
149  * ACS:  * interference factor average: 0.050832
150  * ACS: Survey analysis for channel 3 (2422 MHz)
151  * ACS:  1: min_nf=-113 interference_factor=2.51189e-23 nf=-113 time=162 busy=0 rx=0
152  * ACS:  2: min_nf=-113 interference_factor=0.0185185 nf=-113 time=162 busy=0 rx=3
153  * ACS:  3: min_nf=-113 interference_factor=0.0186335 nf=-113 time=161 busy=0 rx=3
154  * ACS:  4: min_nf=-113 interference_factor=0.0186335 nf=-113 time=161 busy=0 rx=3
155  * ACS:  5: min_nf=-113 interference_factor=0.0186335 nf=-113 time=161 busy=0 rx=3
156  * ACS:  * interference factor average: 0.0148838
157  * ACS: Survey analysis for channel 4 (2427 MHz)
158  * ACS:  1: min_nf=-114 interference_factor=1.58489e-23 nf=-114 time=162 busy=0 rx=0
159  * ACS:  2: min_nf=-114 interference_factor=0.0555556 nf=-114 time=162 busy=0 rx=9
160  * ACS:  3: min_nf=-114 interference_factor=1.58489e-23 nf=-114 time=161 busy=0 rx=0
161  * ACS:  4: min_nf=-114 interference_factor=0.0186335 nf=-114 time=161 busy=0 rx=3
162  * ACS:  5: min_nf=-114 interference_factor=0.00621118 nf=-114 time=161 busy=0 rx=1
163  * ACS:  * interference factor average: 0.0160801
164  * ACS: Survey analysis for channel 5 (2432 MHz)
165  * ACS:  1: min_nf=-114 interference_factor=0.409938 nf=-113 time=161 busy=0 rx=66
166  * ACS:  2: min_nf=-114 interference_factor=0.0432099 nf=-113 time=162 busy=0 rx=7
167  * ACS:  3: min_nf=-114 interference_factor=0.0124224 nf=-113 time=161 busy=0 rx=2
168  * ACS:  4: min_nf=-114 interference_factor=0.677019 nf=-113 time=161 busy=0 rx=109
169  * ACS:  5: min_nf=-114 interference_factor=0.0186335 nf=-114 time=161 busy=0 rx=3
170  * ACS:  * interference factor average: 0.232244
171  * ACS: Survey analysis for channel 6 (2437 MHz)
172  * ACS:  1: min_nf=-113 interference_factor=0.552795 nf=-113 time=161 busy=0 rx=89
173  * ACS:  2: min_nf=-113 interference_factor=0.0807453 nf=-112 time=161 busy=0 rx=13
174  * ACS:  3: min_nf=-113 interference_factor=0.0310559 nf=-113 time=161 busy=0 rx=5
175  * ACS:  4: min_nf=-113 interference_factor=0.434783 nf=-112 time=161 busy=0 rx=70
176  * ACS:  5: min_nf=-113 interference_factor=0.0621118 nf=-113 time=161 busy=0 rx=10
177  * ACS:  * interference factor average: 0.232298
178  * ACS: Survey analysis for channel 7 (2442 MHz)
179  * ACS:  1: min_nf=-113 interference_factor=0.440994 nf=-112 time=161 busy=0 rx=71
180  * ACS:  2: min_nf=-113 interference_factor=0.385093 nf=-113 time=161 busy=0 rx=62
181  * ACS:  3: min_nf=-113 interference_factor=0.0372671 nf=-113 time=161 busy=0 rx=6
182  * ACS:  4: min_nf=-113 interference_factor=0.0372671 nf=-113 time=161 busy=0 rx=6
183  * ACS:  5: min_nf=-113 interference_factor=0.0745342 nf=-113 time=161 busy=0 rx=12
184  * ACS:  * interference factor average: 0.195031
185  * ACS: Survey analysis for channel 8 (2447 MHz)
186  * ACS:  1: min_nf=-114 interference_factor=0.0496894 nf=-112 time=161 busy=0 rx=8
187  * ACS:  2: min_nf=-114 interference_factor=0.0496894 nf=-114 time=161 busy=0 rx=8
188  * ACS:  3: min_nf=-114 interference_factor=0.0372671 nf=-113 time=161 busy=0 rx=6
189  * ACS:  4: min_nf=-114 interference_factor=0.12963 nf=-113 time=162 busy=0 rx=21
190  * ACS:  5: min_nf=-114 interference_factor=0.166667 nf=-114 time=162 busy=0 rx=27
191  * ACS:  * interference factor average: 0.0865885
192  * ACS: Survey analysis for channel 9 (2452 MHz)
193  * ACS:  1: min_nf=-114 interference_factor=0.0124224 nf=-114 time=161 busy=0 rx=2
194  * ACS:  2: min_nf=-114 interference_factor=0.0310559 nf=-114 time=161 busy=0 rx=5
195  * ACS:  3: min_nf=-114 interference_factor=1.58489e-23 nf=-114 time=161 busy=0 rx=0
196  * ACS:  4: min_nf=-114 interference_factor=0.00617284 nf=-114 time=162 busy=0 rx=1
197  * ACS:  5: min_nf=-114 interference_factor=1.58489e-23 nf=-114 time=162 busy=0 rx=0
198  * ACS:  * interference factor average: 0.00993022
199  * ACS: Survey analysis for channel 10 (2457 MHz)
200  * ACS:  1: min_nf=-114 interference_factor=0.00621118 nf=-114 time=161 busy=0 rx=1
201  * ACS:  2: min_nf=-114 interference_factor=0.00621118 nf=-114 time=161 busy=0 rx=1
202  * ACS:  3: min_nf=-114 interference_factor=0.00621118 nf=-114 time=161 busy=0 rx=1
203  * ACS:  4: min_nf=-114 interference_factor=0.0493827 nf=-114 time=162 busy=0 rx=8
204  * ACS:  5: min_nf=-114 interference_factor=1.58489e-23 nf=-114 time=162 busy=0 rx=0
205  * ACS:  * interference factor average: 0.0136033
206  * ACS: Survey analysis for channel 11 (2462 MHz)
207  * ACS:  1: min_nf=-114 interference_factor=1.58489e-23 nf=-114 time=161 busy=0 rx=0
208  * ACS:  2: min_nf=-114 interference_factor=2.51189e-23 nf=-113 time=161 busy=0 rx=0
209  * ACS:  3: min_nf=-114 interference_factor=2.51189e-23 nf=-113 time=161 busy=0 rx=0
210  * ACS:  4: min_nf=-114 interference_factor=0.0432099 nf=-114 time=162 busy=0 rx=7
211  * ACS:  5: min_nf=-114 interference_factor=0.0925926 nf=-114 time=162 busy=0 rx=15
212  * ACS:  * interference factor average: 0.0271605
213  * ACS: Survey analysis for channel 12 (2467 MHz)
214  * ACS:  1: min_nf=-114 interference_factor=0.0621118 nf=-113 time=161 busy=0 rx=10
215  * ACS:  2: min_nf=-114 interference_factor=0.00621118 nf=-114 time=161 busy=0 rx=1
216  * ACS:  3: min_nf=-114 interference_factor=2.51189e-23 nf=-113 time=162 busy=0 rx=0
217  * ACS:  4: min_nf=-114 interference_factor=2.51189e-23 nf=-113 time=162 busy=0 rx=0
218  * ACS:  5: min_nf=-114 interference_factor=0.00617284 nf=-113 time=162 busy=0 rx=1
219  * ACS:  * interference factor average: 0.0148992
220  * ACS: Survey analysis for channel 13 (2472 MHz)
221  * ACS:  1: min_nf=-114 interference_factor=0.0745342 nf=-114 time=161 busy=0 rx=12
222  * ACS:  2: min_nf=-114 interference_factor=0.0555556 nf=-114 time=162 busy=0 rx=9
223  * ACS:  3: min_nf=-114 interference_factor=1.58489e-23 nf=-114 time=162 busy=0 rx=0
224  * ACS:  4: min_nf=-114 interference_factor=1.58489e-23 nf=-114 time=162 busy=0 rx=0
225  * ACS:  5: min_nf=-114 interference_factor=1.58489e-23 nf=-114 time=162 busy=0 rx=0
226  * ACS:  * interference factor average: 0.0260179
227  * ACS: Survey analysis for selected bandwidth 20MHz
228  * ACS:  * channel 1: total interference = 0.121432
229  * ACS:  * channel 2: total interference = 0.137512
230  * ACS:  * channel 3: total interference = 0.369757
231  * ACS:  * channel 4: total interference = 0.546338
232  * ACS:  * channel 5: total interference = 0.690538
233  * ACS:  * channel 6: total interference = 0.762242
234  * ACS:  * channel 7: total interference = 0.756092
235  * ACS:  * channel 8: total interference = 0.537451
236  * ACS:  * channel 9: total interference = 0.332313
237  * ACS:  * channel 10: total interference = 0.152182
238  * ACS:  * channel 11: total interference = 0.0916111
239  * ACS:  * channel 12: total interference = 0.0816809
240  * ACS:  * channel 13: total interference = 0.0680776
241  * ACS: Ideal channel is 13 (2472 MHz) with total interference factor of 0.0680776
242  *
243  * [1] http://en.wikipedia.org/wiki/Near_and_far_field
244  */
245 
246 enum bw_type {
247 	ACS_BW40,
248 	ACS_BW80,
249 	ACS_BW160,
250 	ACS_BW320_1,
251 	ACS_BW320_2,
252 };
253 
254 struct bw_item {
255 	int first;
256 	int last;
257 	int center_chan;
258 };
259 
260 static const struct bw_item bw_40[] = {
261 	{ 5180, 5200, 38 }, { 5220, 5240, 46 }, { 5260, 5280, 54 },
262 	{ 5300, 5320, 62 }, { 5500, 5520, 102 }, { 5540, 5560, 110 },
263 	{ 5580, 5600, 118 }, { 5620, 5640, 126 }, { 5660, 5680, 134 },
264 	{ 5700, 5720, 142 }, { 5745, 5765, 151 }, { 5785, 5805, 159 },
265 	{ 5825, 5845, 167 }, { 5865, 5885, 175 },
266 	{ 5955, 5975, 3 }, { 5995, 6015, 11 }, { 6035, 6055, 19 },
267 	{ 6075, 6095, 27 }, { 6115, 6135, 35 }, { 6155, 6175, 43 },
268 	{ 6195, 6215, 51 }, { 6235, 6255, 59 }, { 6275, 6295, 67 },
269 	{ 6315, 6335, 75 }, { 6355, 6375, 83 }, { 6395, 6415, 91 },
270 	{ 6435, 6455, 99 }, { 6475, 6495, 107 }, { 6515, 6535, 115 },
271 	{ 6555, 6575, 123 }, { 6595, 6615, 131 }, { 6635, 6655, 139 },
272 	{ 6675, 6695, 147 }, { 6715, 6735, 155 }, { 6755, 6775, 163 },
273 	{ 6795, 6815, 171 }, { 6835, 6855, 179 }, { 6875, 6895, 187 },
274 	{ 6915, 6935, 195 }, { 6955, 6975, 203 }, { 6995, 7015, 211 },
275 	{ 7035, 7055, 219 }, { 7075, 7095, 227}, { -1, -1, -1 }
276 };
277 static const struct bw_item bw_80[] = {
278 	{ 5180, 5240, 42 }, { 5260, 5320, 58 }, { 5500, 5560, 106 },
279 	{ 5580, 5640, 122 }, { 5660, 5720, 138 }, { 5745, 5805, 155 },
280 	{ 5825, 5885, 171},
281 	{ 5955, 6015, 7 }, { 6035, 6095, 23 }, { 6115, 6175, 39 },
282 	{ 6195, 6255, 55 }, { 6275, 6335, 71 }, { 6355, 6415, 87 },
283 	{ 6435, 6495, 103 }, { 6515, 6575, 119 }, { 6595, 6655, 135 },
284 	{ 6675, 6735, 151 }, { 6755, 6815, 167 }, { 6835, 6895, 183 },
285 	{ 6915, 6975, 199 }, { 6995, 7055, 215 }, { -1, -1, -1 }
286 };
287 static const struct bw_item bw_160[] = {
288 	{ 5180, 5320, 50 }, { 5500, 5640, 114 }, { 5745, 5885, 163 },
289 	{ 5955, 6095, 15 }, { 6115, 6255, 47 }, { 6275, 6415, 79 },
290 	{ 6435, 6575, 111 }, { 6595, 6735, 143 },
291 	{ 6755, 6895, 175 }, { 6915, 7055, 207 }, { -1, -1, -1 }
292 };
293 static const struct bw_item bw_320_1[] = {
294 	{ 5955, 6255, 31 }, { 6275, 6575, 95 }, { 6595, 6895, 159 },
295 	{ -1, -1, -1 }
296 };
297 static const struct bw_item bw_320_2[] = {
298 	{ 6115, 6415, 63 }, { 6435, 6735, 127 }, { 6755, 7055, 191 },
299 	{ -1, -1, -1 }
300 };
301 static const struct bw_item *bw_desc[] = {
302 	[ACS_BW40] = bw_40,
303 	[ACS_BW80] = bw_80,
304 	[ACS_BW160] = bw_160,
305 	[ACS_BW320_1] = bw_320_1,
306 	[ACS_BW320_2] = bw_320_2,
307 };
308 
309 
310 static int acs_request_scan(struct hostapd_iface *iface);
311 static int acs_survey_is_sufficient(struct freq_survey *survey);
312 static void acs_scan_retry(void *eloop_data, void *user_data);
313 
314 
acs_clean_chan_surveys(struct hostapd_channel_data * chan)315 static void acs_clean_chan_surveys(struct hostapd_channel_data *chan)
316 {
317 	struct freq_survey *survey, *tmp;
318 
319 	if (dl_list_empty(&chan->survey_list))
320 		return;
321 
322 	dl_list_for_each_safe(survey, tmp, &chan->survey_list,
323 			      struct freq_survey, list) {
324 		dl_list_del(&survey->list);
325 		os_free(survey);
326 	}
327 }
328 
329 
acs_cleanup_mode(struct hostapd_hw_modes * mode)330 static void acs_cleanup_mode(struct hostapd_hw_modes *mode)
331 {
332 	int i;
333 	struct hostapd_channel_data *chan;
334 
335 	for (i = 0; i < mode->num_channels; i++) {
336 		chan = &mode->channels[i];
337 
338 		if (chan->flag & HOSTAPD_CHAN_SURVEY_LIST_INITIALIZED)
339 			acs_clean_chan_surveys(chan);
340 
341 		dl_list_init(&chan->survey_list);
342 		chan->flag |= HOSTAPD_CHAN_SURVEY_LIST_INITIALIZED;
343 		chan->min_nf = 0;
344 		chan->punct_bitmap = 0;
345 	}
346 }
347 
348 
acs_cleanup(struct hostapd_iface * iface)349 void acs_cleanup(struct hostapd_iface *iface)
350 {
351 	int i;
352 
353 	for (i = 0; i < iface->num_hw_features; i++)
354 		acs_cleanup_mode(&iface->hw_features[i]);
355 
356 	iface->chans_surveyed = 0;
357 	iface->acs_num_completed_scans = 0;
358 	iface->acs_num_retries = 0;
359 	eloop_cancel_timeout(acs_scan_retry, iface, NULL);
360 }
361 
362 
acs_fail(struct hostapd_iface * iface)363 static void acs_fail(struct hostapd_iface *iface)
364 {
365 	wpa_printf(MSG_ERROR, "ACS: Failed to start");
366 	acs_cleanup(iface);
367 	hostapd_disable_iface(iface);
368 }
369 
370 
371 static long double
acs_survey_interference_factor(struct freq_survey * survey,s8 min_nf)372 acs_survey_interference_factor(struct freq_survey *survey, s8 min_nf)
373 {
374 	long double factor, busy, total;
375 
376 	if (survey->filled & SURVEY_HAS_CHAN_TIME_BUSY)
377 		busy = survey->channel_time_busy;
378 	else if (survey->filled & SURVEY_HAS_CHAN_TIME_RX)
379 		busy = survey->channel_time_rx;
380 	else {
381 		wpa_printf(MSG_ERROR, "ACS: Survey data missing");
382 		return 0;
383 	}
384 
385 	total = survey->channel_time;
386 
387 	if (survey->filled & SURVEY_HAS_CHAN_TIME_TX) {
388 		busy -= survey->channel_time_tx;
389 		total -= survey->channel_time_tx;
390 	}
391 
392 	/* TODO: figure out the best multiplier for noise floor base */
393 	factor = pow(10, survey->nf / 5.0L) +
394 		(total ? (busy / total) : 0) *
395 		pow(2, pow(10, (long double) survey->nf / 10.0L) -
396 		    pow(10, (long double) min_nf / 10.0L));
397 
398 	return factor;
399 }
400 
401 
402 static void
acs_survey_chan_interference_factor(struct hostapd_iface * iface,struct hostapd_channel_data * chan)403 acs_survey_chan_interference_factor(struct hostapd_iface *iface,
404 				    struct hostapd_channel_data *chan)
405 {
406 	struct freq_survey *survey;
407 	unsigned int i = 0;
408 	long double int_factor = 0;
409 	unsigned count = 0;
410 
411 	if (dl_list_empty(&chan->survey_list) ||
412 	    (chan->flag & HOSTAPD_CHAN_DISABLED))
413 		return;
414 
415 	chan->interference_factor = 0;
416 
417 	dl_list_for_each(survey, &chan->survey_list, struct freq_survey, list)
418 	{
419 		i++;
420 
421 		if (!acs_survey_is_sufficient(survey)) {
422 			wpa_printf(MSG_DEBUG, "ACS: %d: insufficient data", i);
423 			continue;
424 		}
425 
426 		count++;
427 		int_factor = acs_survey_interference_factor(survey,
428 							    iface->lowest_nf);
429 		chan->interference_factor += int_factor;
430 		wpa_printf(MSG_DEBUG, "ACS: %d: min_nf=%d interference_factor=%Lg nf=%d time=%lu busy=%lu rx=%lu",
431 			   i, chan->min_nf, int_factor,
432 			   survey->nf, (unsigned long) survey->channel_time,
433 			   (unsigned long) survey->channel_time_busy,
434 			   (unsigned long) survey->channel_time_rx);
435 	}
436 
437 	if (count)
438 		chan->interference_factor /= count;
439 }
440 
441 
acs_usable_bw_chan(const struct hostapd_channel_data * chan,enum bw_type bw)442 static bool acs_usable_bw_chan(const struct hostapd_channel_data *chan,
443 			       enum bw_type bw)
444 {
445 	unsigned int i = 0;
446 
447 	while (bw_desc[bw][i].first != -1) {
448 		if (chan->freq == bw_desc[bw][i].first)
449 			return true;
450 		i++;
451 	}
452 
453 	return false;
454 }
455 
456 
acs_get_bw_center_chan(int freq,enum bw_type bw)457 static int acs_get_bw_center_chan(int freq, enum bw_type bw)
458 {
459 	unsigned int i = 0;
460 
461 	while (bw_desc[bw][i].first != -1) {
462 		if (freq >= bw_desc[bw][i].first &&
463 		    freq <= bw_desc[bw][i].last)
464 			return bw_desc[bw][i].center_chan;
465 		i++;
466 	}
467 
468 	return 0;
469 }
470 
471 
acs_survey_is_sufficient(struct freq_survey * survey)472 static int acs_survey_is_sufficient(struct freq_survey *survey)
473 {
474 	if (!(survey->filled & SURVEY_HAS_NF)) {
475 		wpa_printf(MSG_INFO,
476 			   "ACS: Survey for freq %d is missing noise floor",
477 			   survey->freq);
478 		return 0;
479 	}
480 
481 	if (!(survey->filled & SURVEY_HAS_CHAN_TIME)) {
482 		wpa_printf(MSG_INFO,
483 			   "ACS: Survey for freq %d is missing channel time",
484 			   survey->freq);
485 		return 0;
486 	}
487 
488 	if (!(survey->filled & SURVEY_HAS_CHAN_TIME_BUSY) &&
489 	    !(survey->filled & SURVEY_HAS_CHAN_TIME_RX)) {
490 		wpa_printf(MSG_INFO,
491 			   "ACS: Survey for freq %d is missing RX and busy time (at least one is required)",
492 			   survey->freq);
493 		return 0;
494 	}
495 
496 	return 1;
497 }
498 
499 
acs_survey_list_is_sufficient(struct hostapd_channel_data * chan)500 static int acs_survey_list_is_sufficient(struct hostapd_channel_data *chan)
501 {
502 	struct freq_survey *survey;
503 	int ret = -1;
504 
505 	dl_list_for_each(survey, &chan->survey_list, struct freq_survey, list)
506 	{
507 		if (acs_survey_is_sufficient(survey)) {
508 			ret = 1;
509 			break;
510 		}
511 		ret = 0;
512 	}
513 
514 	if (ret == -1)
515 		ret = 0; /* no survey list entries */
516 
517 	if (!ret) {
518 		wpa_printf(MSG_INFO,
519 			   "ACS: Channel %d has insufficient survey data",
520 			   chan->chan);
521 	}
522 
523 	return ret;
524 }
525 
526 
acs_surveys_are_sufficient_mode(struct hostapd_hw_modes * mode)527 static int acs_surveys_are_sufficient_mode(struct hostapd_hw_modes *mode)
528 {
529 	int i;
530 	struct hostapd_channel_data *chan;
531 
532 	for (i = 0; i < mode->num_channels; i++) {
533 		chan = &mode->channels[i];
534 		if (!(chan->flag & HOSTAPD_CHAN_DISABLED) &&
535 		    acs_survey_list_is_sufficient(chan))
536 			return 1;
537 	}
538 
539 	return 0;
540 }
541 
542 
acs_surveys_are_sufficient(struct hostapd_iface * iface)543 static int acs_surveys_are_sufficient(struct hostapd_iface *iface)
544 {
545 	int i;
546 	struct hostapd_hw_modes *mode;
547 
548 	for (i = 0; i < iface->num_hw_features; i++) {
549 		mode = &iface->hw_features[i];
550 		if (!hostapd_hw_skip_mode(iface, mode) &&
551 		    acs_surveys_are_sufficient_mode(mode))
552 			return 1;
553 	}
554 
555 	return 0;
556 }
557 
558 
acs_usable_chan(struct hostapd_channel_data * chan)559 static int acs_usable_chan(struct hostapd_channel_data *chan)
560 {
561 	if (chan->interference_bss_based)
562 		return 1;
563 
564 	return !dl_list_empty(&chan->survey_list) &&
565 		!(chan->flag & HOSTAPD_CHAN_DISABLED) &&
566 		acs_survey_list_is_sufficient(chan);
567 }
568 
569 
is_in_chanlist(struct hostapd_iface * iface,struct hostapd_channel_data * chan)570 static int is_in_chanlist(struct hostapd_iface *iface,
571 			  struct hostapd_channel_data *chan)
572 {
573 	if (!iface->conf->acs_ch_list.num)
574 		return 1;
575 
576 	return freq_range_list_includes(&iface->conf->acs_ch_list, chan->chan);
577 }
578 
579 
is_in_freqlist(struct hostapd_iface * iface,struct hostapd_channel_data * chan)580 static int is_in_freqlist(struct hostapd_iface *iface,
581 			  struct hostapd_channel_data *chan)
582 {
583 	if (!iface->conf->acs_freq_list.num)
584 		return 1;
585 
586 	return freq_range_list_includes(&iface->conf->acs_freq_list,
587 					chan->freq);
588 }
589 
590 
acs_survey_mode_interference_factor(struct hostapd_iface * iface,struct hostapd_hw_modes * mode)591 static void acs_survey_mode_interference_factor(
592 	struct hostapd_iface *iface, struct hostapd_hw_modes *mode)
593 {
594 	int i;
595 	struct hostapd_channel_data *chan;
596 
597 	for (i = 0; i < mode->num_channels; i++) {
598 		chan = &mode->channels[i];
599 
600 		if (!acs_usable_chan(chan))
601 			continue;
602 
603 		if ((chan->flag & HOSTAPD_CHAN_RADAR) &&
604 		    iface->conf->acs_exclude_dfs)
605 			continue;
606 
607 		if (!is_in_chanlist(iface, chan))
608 			continue;
609 
610 		if (!is_in_freqlist(iface, chan))
611 			continue;
612 
613 		if (chan->max_tx_power < iface->conf->min_tx_power)
614 			continue;
615 
616 		if ((chan->flag & HOSTAPD_CHAN_INDOOR_ONLY) &&
617 		    iface->conf->country[2] == 0x4f)
618 			continue;
619 
620 		wpa_printf(MSG_DEBUG, "ACS: Survey analysis for channel %d (%d MHz)",
621 			   chan->chan, chan->freq);
622 
623 		acs_survey_chan_interference_factor(iface, chan);
624 
625 		wpa_printf(MSG_DEBUG, "ACS:  * interference factor average: %Lg",
626 			   chan->interference_factor);
627 	}
628 }
629 
630 
acs_survey_all_chans_interference_factor(struct hostapd_iface * iface)631 static void acs_survey_all_chans_interference_factor(
632 	struct hostapd_iface *iface)
633 {
634 	int i;
635 	struct hostapd_hw_modes *mode;
636 
637 	for (i = 0; i < iface->num_hw_features; i++) {
638 		mode = &iface->hw_features[i];
639 		if (!hostapd_hw_skip_mode(iface, mode))
640 			acs_survey_mode_interference_factor(iface, mode);
641 	}
642 }
643 
644 
645 static struct hostapd_channel_data *
acs_find_chan_mode(struct hostapd_hw_modes * mode,int freq)646 acs_find_chan_mode(struct hostapd_hw_modes *mode, int freq)
647 {
648 	struct hostapd_channel_data *chan;
649 	int i;
650 
651 	for (i = 0; i < mode->num_channels; i++) {
652 		chan = &mode->channels[i];
653 
654 		if (chan->flag & HOSTAPD_CHAN_DISABLED)
655 			continue;
656 
657 		if (chan->freq == freq)
658 			return chan;
659 	}
660 
661 	return NULL;
662 }
663 
664 
665 static enum hostapd_hw_mode
acs_find_mode(struct hostapd_iface * iface,int freq)666 acs_find_mode(struct hostapd_iface *iface, int freq)
667 {
668 	int i;
669 	struct hostapd_hw_modes *mode;
670 	struct hostapd_channel_data *chan;
671 
672 	for (i = 0; i < iface->num_hw_features; i++) {
673 		mode = &iface->hw_features[i];
674 		if (!hostapd_hw_skip_mode(iface, mode)) {
675 			chan = acs_find_chan_mode(mode, freq);
676 			if (chan)
677 				return mode->mode;
678 		}
679 	}
680 
681 	return HOSTAPD_MODE_IEEE80211ANY;
682 }
683 
684 
685 static struct hostapd_channel_data *
acs_find_chan(struct hostapd_iface * iface,int freq)686 acs_find_chan(struct hostapd_iface *iface, int freq)
687 {
688 	int i;
689 	struct hostapd_hw_modes *mode;
690 	struct hostapd_channel_data *chan;
691 
692 	for (i = 0; i < iface->num_hw_features; i++) {
693 		mode = &iface->hw_features[i];
694 		if (!hostapd_hw_skip_mode(iface, mode)) {
695 			chan = acs_find_chan_mode(mode, freq);
696 			if (chan)
697 				return chan;
698 		}
699 	}
700 
701 	return NULL;
702 }
703 
704 
is_24ghz_mode(enum hostapd_hw_mode mode)705 static int is_24ghz_mode(enum hostapd_hw_mode mode)
706 {
707 	return mode == HOSTAPD_MODE_IEEE80211B ||
708 		mode == HOSTAPD_MODE_IEEE80211G;
709 }
710 
711 
is_common_24ghz_chan(int chan)712 static int is_common_24ghz_chan(int chan)
713 {
714 	return chan == 1 || chan == 6 || chan == 11;
715 }
716 
717 
718 #ifndef ACS_ADJ_WEIGHT
719 #define ACS_ADJ_WEIGHT 0.85
720 #endif /* ACS_ADJ_WEIGHT */
721 
722 #ifndef ACS_NEXT_ADJ_WEIGHT
723 #define ACS_NEXT_ADJ_WEIGHT 0.55
724 #endif /* ACS_NEXT_ADJ_WEIGHT */
725 
726 #ifndef ACS_24GHZ_PREFER_1_6_11
727 /*
728  * Select commonly used channels 1, 6, 11 by default even if a neighboring
729  * channel has a smaller interference factor as long as it is not better by more
730  * than this multiplier.
731  */
732 #define ACS_24GHZ_PREFER_1_6_11 0.8
733 #endif /* ACS_24GHZ_PREFER_1_6_11 */
734 
735 
736 #ifdef CONFIG_IEEE80211BE
acs_update_puncturing_bitmap(struct hostapd_iface * iface,struct hostapd_hw_modes * mode,u32 bw,int n_chans,struct hostapd_channel_data * chan,long double factor,int index_primary)737 static void acs_update_puncturing_bitmap(struct hostapd_iface *iface,
738 					 struct hostapd_hw_modes *mode, u32 bw,
739 					 int n_chans,
740 					 struct hostapd_channel_data *chan,
741 					 long double factor,
742 					 int index_primary)
743 {
744 	struct hostapd_config *conf = iface->conf;
745 	struct hostapd_channel_data *adj_chan = NULL, *first_chan = chan;
746 	int i;
747 	long double threshold;
748 
749 	/*
750 	 * If threshold is 0 or user configured puncturing pattern is
751 	 * available then don't add additional puncturing.
752 	 */
753 	if (!conf->punct_acs_threshold || conf->punct_bitmap)
754 		return;
755 
756 	if (is_24ghz_mode(mode->mode) || bw < 80)
757 		return;
758 
759 	threshold = factor * conf->punct_acs_threshold / 100;
760 	for (i = 0; i < n_chans; i++) {
761 		int adj_freq;
762 
763 		if (i == index_primary)
764 			continue; /* Cannot puncture primary channel */
765 
766 		if (i > index_primary)
767 			adj_freq = chan->freq + (i - index_primary) * 20;
768 		else
769 			adj_freq = chan->freq - (index_primary - i) * 20;
770 
771 		adj_chan = acs_find_chan(iface, adj_freq);
772 		if (!adj_chan) {
773 			chan->punct_bitmap = 0;
774 			return;
775 		}
776 
777 		if (i == 0)
778 			first_chan = adj_chan;
779 
780 		if (adj_chan->interference_factor > threshold)
781 			chan->punct_bitmap |= BIT(i);
782 	}
783 
784 	if (!is_punct_bitmap_valid(bw, (chan->freq - first_chan->freq) / 20,
785 				   chan->punct_bitmap))
786 		chan->punct_bitmap = 0;
787 }
788 #endif /* CONFIG_IEEE80211BE */
789 
790 
791 static bool
acs_usable_bw320_chan(struct hostapd_iface * iface,struct hostapd_channel_data * chan,int * bw320_offset)792 acs_usable_bw320_chan(struct hostapd_iface *iface,
793 		      struct hostapd_channel_data *chan, int *bw320_offset)
794 {
795 	const char *bw320_str[] = { "320 MHz", "320 MHz-1", "320 MHz-2" };
796 	int conf_bw320_offset = hostapd_get_bw320_offset(iface->conf);
797 
798 	*bw320_offset = 0;
799 	switch (conf_bw320_offset) {
800 	case 1:
801 		if (acs_usable_bw_chan(chan, ACS_BW320_1))
802 			*bw320_offset = 1;
803 		break;
804 	case 2:
805 		if (acs_usable_bw_chan(chan, ACS_BW320_2))
806 			*bw320_offset = 2;
807 		break;
808 	case 0:
809 	default:
810 		conf_bw320_offset = 0;
811 		if (acs_usable_bw_chan(chan, ACS_BW320_1))
812 			*bw320_offset = 1;
813 		else if (acs_usable_bw_chan(chan, ACS_BW320_2))
814 			*bw320_offset = 2;
815 		break;
816 	}
817 
818 	if (!*bw320_offset)
819 		wpa_printf(MSG_DEBUG,
820 			   "ACS: Channel %d: not allowed as primary channel for %s bandwidth",
821 			   chan->chan, bw320_str[conf_bw320_offset]);
822 
823 	return *bw320_offset != 0;
824 }
825 
826 
827 static void
acs_find_ideal_chan_mode(struct hostapd_iface * iface,struct hostapd_hw_modes * mode,int n_chans,u32 bw,struct hostapd_channel_data ** rand_chan,struct hostapd_channel_data ** ideal_chan,long double * ideal_factor)828 acs_find_ideal_chan_mode(struct hostapd_iface *iface,
829 			 struct hostapd_hw_modes *mode,
830 			 int n_chans, u32 bw,
831 			 struct hostapd_channel_data **rand_chan,
832 			 struct hostapd_channel_data **ideal_chan,
833 			 long double *ideal_factor)
834 {
835 	struct hostapd_channel_data *chan, *adj_chan = NULL,
836 		*chan2 = NULL, *best;
837 	long double factor;
838 	int i, j;
839 	int bw320_offset = 0, ideal_bw320_offset = 0;
840 	unsigned int k;
841 	int secondary_channel = 1, freq_offset;
842 #ifdef CONFIG_IEEE80211BE
843 	int index_primary = 0;
844 #endif /* CONFIG_IEEE80211BE */
845 
846 	if (is_24ghz_mode(mode->mode))
847 		secondary_channel = iface->conf->secondary_channel;
848 
849 	for (i = 0; i < mode->num_channels; i++) {
850 		double total_weight = 0;
851 		struct acs_bias *bias, tmp_bias;
852 
853 		chan = &mode->channels[i];
854 
855 		/* HT40 on 5 GHz has a limited set of primary channels as per
856 		 * 11n Annex J */
857 		if (bw == 40 &&
858 		    mode->mode == HOSTAPD_MODE_IEEE80211A &&
859 		    iface->conf->ieee80211n &&
860 		    !acs_usable_bw_chan(chan, ACS_BW40)) {
861 			wpa_printf(MSG_DEBUG,
862 				   "ACS: Channel %d: not allowed as primary channel for 40 MHz bandwidth",
863 				   chan->chan);
864 			continue;
865 		}
866 
867 		if (mode->mode == HOSTAPD_MODE_IEEE80211A &&
868 		    (iface->conf->ieee80211ac || iface->conf->ieee80211ax ||
869 		     iface->conf->ieee80211be)) {
870 			if (bw == 80 && !acs_usable_bw_chan(chan, ACS_BW80)) {
871 				wpa_printf(MSG_DEBUG,
872 					   "ACS: Channel %d: not allowed as primary channel for 80 MHz bandwidth",
873 					   chan->chan);
874 				continue;
875 			}
876 
877 			if (bw == 160 && !acs_usable_bw_chan(chan, ACS_BW160)) {
878 				wpa_printf(MSG_DEBUG,
879 					   "ACS: Channel %d: not allowed as primary channel for 160 MHz bandwidth",
880 					   chan->chan);
881 				continue;
882 			}
883 		}
884 
885 		if (mode->mode == HOSTAPD_MODE_IEEE80211A &&
886 		    iface->conf->ieee80211be) {
887 			if (bw == 320 &&
888 			    !acs_usable_bw320_chan(iface, chan,
889 						   &bw320_offset)) {
890 				wpa_printf(MSG_DEBUG,
891 					   "ACS: Channel %d: not allowed as primary channel for 320 MHz bandwidth",
892 					   chan->chan);
893 				continue;
894 			}
895 		}
896 
897 		factor = 0;
898 		best = NULL;
899 
900 		for (j = 0; j < n_chans; j++) {
901 			chan2 = acs_find_chan(iface, chan->freq +
902 					      j * secondary_channel * 20);
903 			if (!chan2)
904 				break;
905 
906 			if (!chan_bw_allowed(chan2, bw, secondary_channel != -1,
907 					     j == 0)) {
908 				wpa_printf(MSG_DEBUG,
909 					   "ACS: Channel %d: BW %u is not supported",
910 					   chan2->chan, bw);
911 				break;
912 			}
913 
914 			if ((chan2->flag & HOSTAPD_CHAN_RADAR) &&
915 			    iface->conf->acs_exclude_dfs)
916 				break;
917 
918 			if (chan2->max_tx_power < iface->conf->min_tx_power)
919 				break;
920 
921 			if ((chan2->flag & HOSTAPD_CHAN_INDOOR_ONLY) &&
922 			    iface->conf->country[2] == 0x4f)
923 				break;
924 
925 			if (!acs_usable_chan(chan2))
926 				continue;
927 
928 			factor += chan2->interference_factor;
929 			total_weight += 1;
930 
931 			if (!chan_pri_allowed(chan2))
932 				continue;
933 
934 			if (!is_in_chanlist(iface, chan2))
935 				continue;
936 
937 			if (!is_in_freqlist(iface, chan2))
938 				continue;
939 
940 			if (iface->conf->acs_exclude_6ghz_non_psc &&
941 			    !is_6ghz_psc_frequency(chan2->freq))
942 				continue;
943 
944 			/* find the best channel in this segment */
945 			if (!best || chan2->interference_factor <
946 			    best->interference_factor)
947 				best = chan2;
948 		}
949 
950 		if (j != n_chans) {
951 			wpa_printf(MSG_DEBUG, "ACS: Channel %d: not enough bandwidth",
952 				   chan->chan);
953 			continue;
954 		}
955 
956 		if (!best) {
957 			wpa_printf(MSG_DEBUG,
958 				   "ACS: No valid channel found in the segment starting with channel %d",
959 				   chan->chan);
960 			continue;
961 		}
962 
963 		/* If the AP is in the 5 GHz or 6 GHz band, lets prefer a less
964 		 * crowded primary channel if one was found in the segment */
965 		if (iface->current_mode &&
966 		    iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A &&
967 		    chan != best) {
968 			wpa_printf(MSG_DEBUG,
969 				   "ACS: promoting channel %d over %d (less interference %Lg/%Lg)",
970 				   best->chan, chan->chan,
971 				   chan->interference_factor,
972 				   best->interference_factor);
973 #ifdef CONFIG_IEEE80211BE
974 			index_primary = (best->freq - chan->freq) / 20;
975 #endif /* CONFIG_IEEE80211BE */
976 			chan = best;
977 		}
978 
979 		/* 2.4 GHz has overlapping 20 MHz channels. Include adjacent
980 		 * channel interference factor. */
981 		if (is_24ghz_mode(mode->mode)) {
982 			for (j = 0; j < n_chans; j++) {
983 				freq_offset = j * 20 * secondary_channel;
984 				adj_chan = acs_find_chan(iface, chan->freq +
985 							 freq_offset - 5);
986 				if (adj_chan && acs_usable_chan(adj_chan)) {
987 					factor += ACS_ADJ_WEIGHT *
988 						adj_chan->interference_factor;
989 					total_weight += ACS_ADJ_WEIGHT;
990 				}
991 
992 				adj_chan = acs_find_chan(iface, chan->freq +
993 							 freq_offset - 10);
994 				if (adj_chan && acs_usable_chan(adj_chan)) {
995 					factor += ACS_NEXT_ADJ_WEIGHT *
996 						adj_chan->interference_factor;
997 					total_weight += ACS_NEXT_ADJ_WEIGHT;
998 				}
999 
1000 				adj_chan = acs_find_chan(iface, chan->freq +
1001 							 freq_offset + 5);
1002 				if (adj_chan && acs_usable_chan(adj_chan)) {
1003 					factor += ACS_ADJ_WEIGHT *
1004 						adj_chan->interference_factor;
1005 					total_weight += ACS_ADJ_WEIGHT;
1006 				}
1007 
1008 				adj_chan = acs_find_chan(iface, chan->freq +
1009 							 freq_offset + 10);
1010 				if (adj_chan && acs_usable_chan(adj_chan)) {
1011 					factor += ACS_NEXT_ADJ_WEIGHT *
1012 						adj_chan->interference_factor;
1013 					total_weight += ACS_NEXT_ADJ_WEIGHT;
1014 				}
1015 			}
1016 		}
1017 
1018 		if (total_weight == 0)
1019 			continue;
1020 
1021 		factor /= total_weight;
1022 
1023 		bias = NULL;
1024 		if (iface->conf->acs_chan_bias) {
1025 			for (k = 0; k < iface->conf->num_acs_chan_bias; k++) {
1026 				bias = &iface->conf->acs_chan_bias[k];
1027 				if (bias->channel == chan->chan)
1028 					break;
1029 				bias = NULL;
1030 			}
1031 		} else if (is_24ghz_mode(mode->mode) &&
1032 			   is_common_24ghz_chan(chan->chan)) {
1033 			tmp_bias.channel = chan->chan;
1034 			tmp_bias.bias = ACS_24GHZ_PREFER_1_6_11;
1035 			bias = &tmp_bias;
1036 		}
1037 
1038 		if (bias) {
1039 			factor *= bias->bias;
1040 			wpa_printf(MSG_DEBUG,
1041 				   "ACS:  * channel %d: total interference = %Lg (%f bias)",
1042 				   chan->chan, factor, bias->bias);
1043 		} else {
1044 			wpa_printf(MSG_DEBUG,
1045 				   "ACS:  * channel %d: total interference = %Lg",
1046 				   chan->chan, factor);
1047 		}
1048 
1049 		if (acs_usable_chan(chan) &&
1050 		    (!*ideal_chan || factor < *ideal_factor)) {
1051 			/* Reset puncturing bitmap for the previous ideal
1052 			 * channel */
1053 			if (*ideal_chan)
1054 				(*ideal_chan)->punct_bitmap = 0;
1055 
1056 			*ideal_factor = factor;
1057 			*ideal_chan = chan;
1058 			ideal_bw320_offset = bw320_offset;
1059 
1060 #ifdef CONFIG_IEEE80211BE
1061 			if (iface->conf->ieee80211be)
1062 				acs_update_puncturing_bitmap(iface, mode, bw,
1063 							     n_chans, chan,
1064 							     factor,
1065 							     index_primary);
1066 #endif /* CONFIG_IEEE80211BE */
1067 		}
1068 
1069 		/* This channel would at least be usable */
1070 		if (!(*rand_chan)) {
1071 			*rand_chan = chan;
1072 			ideal_bw320_offset = bw320_offset;
1073 		}
1074 	}
1075 
1076 	hostapd_set_and_check_bw320_offset(iface->conf, ideal_bw320_offset);
1077 }
1078 
1079 
1080 /*
1081  * At this point it's assumed chan->interference_factor has been computed.
1082  * This function should be reusable regardless of interference computation
1083  * option (survey, BSS, spectral, ...). chan->interference factor must be
1084  * summable (i.e., must be always greater than zero).
1085  */
1086 static struct hostapd_channel_data *
acs_find_ideal_chan(struct hostapd_iface * iface)1087 acs_find_ideal_chan(struct hostapd_iface *iface)
1088 {
1089 	struct hostapd_channel_data *ideal_chan = NULL,
1090 		*rand_chan = NULL;
1091 	long double ideal_factor = 0;
1092 	int i;
1093 	int n_chans = 1;
1094 	u32 bw;
1095 	struct hostapd_hw_modes *mode;
1096 
1097 	if (is_6ghz_op_class(iface->conf->op_class)) {
1098 		bw = op_class_to_bandwidth(iface->conf->op_class);
1099 		n_chans = bw / 20;
1100 		goto bw_selected;
1101 	}
1102 
1103 	if (iface->conf->ieee80211n &&
1104 	    iface->conf->secondary_channel)
1105 		n_chans = 2;
1106 
1107 	if (iface->conf->ieee80211ac || iface->conf->ieee80211ax ||
1108 	    iface->conf->ieee80211be) {
1109 		switch (hostapd_get_oper_chwidth(iface->conf)) {
1110 		case CONF_OPER_CHWIDTH_80MHZ:
1111 			n_chans = 4;
1112 			break;
1113 		case CONF_OPER_CHWIDTH_160MHZ:
1114 			n_chans = 8;
1115 			break;
1116 		case CONF_OPER_CHWIDTH_320MHZ:
1117 			n_chans = 16;
1118 			break;
1119 		default:
1120 			break;
1121 		}
1122 	}
1123 
1124 	bw = num_chan_to_bw(n_chans);
1125 
1126 bw_selected:
1127 	/* TODO: VHT/HE80+80. Update acs_adjust_center_freq() too. */
1128 
1129 	wpa_printf(MSG_DEBUG,
1130 		   "ACS: Survey analysis for selected bandwidth %d MHz", bw);
1131 
1132 	for (i = 0; i < iface->num_hw_features; i++) {
1133 		mode = &iface->hw_features[i];
1134 		if (!hostapd_hw_skip_mode(iface, mode))
1135 			acs_find_ideal_chan_mode(iface, mode, n_chans, bw,
1136 						 &rand_chan, &ideal_chan,
1137 						 &ideal_factor);
1138 	}
1139 
1140 	if (ideal_chan) {
1141 		wpa_printf(MSG_DEBUG, "ACS: Ideal channel is %d (%d MHz) with total interference factor of %Lg",
1142 			   ideal_chan->chan, ideal_chan->freq, ideal_factor);
1143 
1144 #ifdef CONFIG_IEEE80211BE
1145 		if (iface->conf->punct_acs_threshold)
1146 			wpa_printf(MSG_DEBUG, "ACS: RU puncturing bitmap 0x%x",
1147 				   ideal_chan->punct_bitmap);
1148 #endif /* CONFIG_IEEE80211BE */
1149 
1150 		return ideal_chan;
1151 	}
1152 
1153 	return rand_chan;
1154 }
1155 
1156 
acs_adjust_secondary(struct hostapd_iface * iface)1157 static void acs_adjust_secondary(struct hostapd_iface *iface)
1158 {
1159 	unsigned int i;
1160 
1161 	/* When working with bandwidth over 20 MHz on the 5 GHz or 6 GHz band,
1162 	 * ACS can return a secondary channel which is not the first channel of
1163 	 * the segment and we need to adjust. */
1164 	if (!iface->conf->secondary_channel ||
1165 	    acs_find_mode(iface, iface->freq) != HOSTAPD_MODE_IEEE80211A)
1166 		return;
1167 
1168 	wpa_printf(MSG_DEBUG,
1169 		   "ACS: Adjusting HT/VHT/HE/EHT secondary frequency");
1170 
1171 	for (i = 0; bw_desc[ACS_BW40][i].first != -1; i++) {
1172 		if (iface->freq == bw_desc[ACS_BW40][i].first)
1173 			iface->conf->secondary_channel = 1;
1174 		else if (iface->freq == bw_desc[ACS_BW40][i].last)
1175 			iface->conf->secondary_channel = -1;
1176 	}
1177 }
1178 
1179 
acs_adjust_center_freq(struct hostapd_iface * iface)1180 static void acs_adjust_center_freq(struct hostapd_iface *iface)
1181 {
1182 	int center;
1183 
1184 	wpa_printf(MSG_DEBUG, "ACS: Adjusting center frequency");
1185 
1186 	switch (hostapd_get_oper_chwidth(iface->conf)) {
1187 	case CONF_OPER_CHWIDTH_USE_HT:
1188 		if (iface->conf->secondary_channel &&
1189 		    iface->freq >= 2400 && iface->freq < 2500)
1190 			center = iface->conf->channel +
1191 				2 * iface->conf->secondary_channel;
1192 		else if (iface->conf->secondary_channel)
1193 			center = acs_get_bw_center_chan(iface->freq, ACS_BW40);
1194 		else
1195 			center = iface->conf->channel;
1196 		break;
1197 	case CONF_OPER_CHWIDTH_80MHZ:
1198 		center = acs_get_bw_center_chan(iface->freq, ACS_BW80);
1199 		break;
1200 	case CONF_OPER_CHWIDTH_160MHZ:
1201 		center = acs_get_bw_center_chan(iface->freq, ACS_BW160);
1202 		break;
1203 	case CONF_OPER_CHWIDTH_320MHZ:
1204 		switch (hostapd_get_bw320_offset(iface->conf)) {
1205 		case 1:
1206 			center = acs_get_bw_center_chan(iface->freq,
1207 							ACS_BW320_1);
1208 			break;
1209 		case 2:
1210 			center = acs_get_bw_center_chan(iface->freq,
1211 							ACS_BW320_2);
1212 			break;
1213 		default:
1214 			wpa_printf(MSG_INFO,
1215 				   "ACS: BW320 offset is not selected");
1216 			return;
1217 		}
1218 
1219 		break;
1220 	default:
1221 		/* TODO: How can this be calculated? Adjust
1222 		 * acs_find_ideal_chan() */
1223 		wpa_printf(MSG_INFO,
1224 			   "ACS: Only VHT20/40/80/160/320 is supported now");
1225 		return;
1226 	}
1227 
1228 	hostapd_set_oper_centr_freq_seg0_idx(iface->conf, center);
1229 }
1230 
1231 
acs_study_survey_based(struct hostapd_iface * iface)1232 static int acs_study_survey_based(struct hostapd_iface *iface)
1233 {
1234 	wpa_printf(MSG_DEBUG, "ACS: Trying survey-based ACS");
1235 
1236 	if (!iface->chans_surveyed) {
1237 		wpa_printf(MSG_ERROR, "ACS: Unable to collect survey data");
1238 		return -1;
1239 	}
1240 
1241 	if (!acs_surveys_are_sufficient(iface)) {
1242 		wpa_printf(MSG_ERROR, "ACS: Surveys have insufficient data");
1243 		return -1;
1244 	}
1245 
1246 	acs_survey_all_chans_interference_factor(iface);
1247 	return 0;
1248 }
1249 
1250 
acs_study_bss_based(struct hostapd_iface * iface)1251 static int acs_study_bss_based(struct hostapd_iface *iface)
1252 {
1253 	struct wpa_scan_results *scan_res;
1254 	int j;
1255 
1256 	wpa_printf(MSG_DEBUG, "ACS: Trying BSS-based ACS");
1257 
1258 	scan_res = hostapd_driver_get_scan_results(iface->bss[0]);
1259 	if (!scan_res) {
1260 		wpa_printf(MSG_INFO, "ACS: Scan request failed");
1261 		hostapd_setup_interface_complete(iface, 1);
1262 		return -1;
1263 	}
1264 
1265 	for (j = 0; j < iface->current_mode->num_channels; j++) {
1266 		struct hostapd_channel_data *chan;
1267 		unsigned int bss_on_ch = 0;
1268 		size_t i;
1269 
1270 		chan = &iface->current_mode->channels[j];
1271 		for (i = 0; i < scan_res->num; i++) {
1272 			struct wpa_scan_res *bss = scan_res->res[i];
1273 
1274 			if (bss->freq == chan->freq)
1275 				bss_on_ch++;
1276 		}
1277 
1278 		wpa_printf(MSG_MSGDUMP,
1279 			   "ACS: Interference on ch %d (%d MHz): %d",
1280 			   chan->chan, chan->freq, bss_on_ch);
1281 		chan->interference_factor = bss_on_ch;
1282 		chan->interference_bss_based = true;
1283 	}
1284 
1285 	wpa_scan_results_free(scan_res);
1286 	return 0;
1287 }
1288 
1289 
acs_study_options(struct hostapd_iface * iface)1290 static int acs_study_options(struct hostapd_iface *iface)
1291 {
1292 	if (acs_study_survey_based(iface) == 0)
1293 		return 0;
1294 
1295 	wpa_printf(MSG_INFO, "ACS: Survey based ACS failed");
1296 	if (acs_study_bss_based(iface) == 0)
1297 		return 0;
1298 
1299 	return -1;
1300 }
1301 
1302 
acs_study(struct hostapd_iface * iface)1303 static void acs_study(struct hostapd_iface *iface)
1304 {
1305 	struct hostapd_channel_data *ideal_chan;
1306 	int err;
1307 
1308 	err = acs_study_options(iface);
1309 	if (err < 0) {
1310 		wpa_printf(MSG_ERROR, "ACS: All study options have failed");
1311 		goto fail;
1312 	}
1313 
1314 	ideal_chan = acs_find_ideal_chan(iface);
1315 	if (!ideal_chan) {
1316 		wpa_printf(MSG_ERROR, "ACS: Failed to compute ideal channel");
1317 		err = -1;
1318 		goto fail;
1319 	}
1320 
1321 	iface->conf->channel = ideal_chan->chan;
1322 	iface->freq = ideal_chan->freq;
1323 #ifdef CONFIG_IEEE80211BE
1324 	iface->conf->punct_bitmap = ideal_chan->punct_bitmap;
1325 #endif /* CONFIG_IEEE80211BE */
1326 
1327 	if (iface->conf->ieee80211ac || iface->conf->ieee80211ax ||
1328 	    iface->conf->ieee80211be) {
1329 		acs_adjust_secondary(iface);
1330 		acs_adjust_center_freq(iface);
1331 	}
1332 
1333 	err = hostapd_select_hw_mode(iface);
1334 	if (err) {
1335 		wpa_printf(MSG_ERROR,
1336 			   "ACS: Could not (err: %d) select hw_mode for freq=%d channel=%d",
1337 			err, iface->freq, iface->conf->channel);
1338 		err = -1;
1339 		goto fail;
1340 	}
1341 
1342 	err = 0;
1343 fail:
1344 	/*
1345 	 * hostapd_setup_interface_complete() will return -1 on failure,
1346 	 * 0 on success and 0 is HOSTAPD_CHAN_VALID :)
1347 	 */
1348 	if (hostapd_acs_completed(iface, err) == HOSTAPD_CHAN_VALID) {
1349 		acs_cleanup(iface);
1350 		return;
1351 	}
1352 
1353 	/* This can possibly happen if channel parameters (secondary
1354 	 * channel, center frequencies) are misconfigured */
1355 	wpa_printf(MSG_ERROR, "ACS: Possibly channel configuration is invalid, please report this along with your config file.");
1356 	acs_fail(iface);
1357 }
1358 
1359 
acs_scan_complete(struct hostapd_iface * iface)1360 static void acs_scan_complete(struct hostapd_iface *iface)
1361 {
1362 	int err;
1363 
1364 	iface->scan_cb = NULL;
1365 	iface->acs_num_retries = 0;
1366 
1367 	wpa_printf(MSG_DEBUG, "ACS: Using survey based algorithm (acs_num_scans=%d)",
1368 		   iface->conf->acs_num_scans);
1369 
1370 	err = hostapd_drv_get_survey(iface->bss[0], 0);
1371 	if (err) {
1372 		wpa_printf(MSG_ERROR, "ACS: Failed to get survey data");
1373 		goto fail;
1374 	}
1375 
1376 	if (++iface->acs_num_completed_scans < iface->conf->acs_num_scans) {
1377 		err = acs_request_scan(iface);
1378 		if (err && err != -EBUSY) {
1379 			wpa_printf(MSG_ERROR, "ACS: Failed to request scan");
1380 			goto fail;
1381 		}
1382 
1383 		return;
1384 	}
1385 
1386 	acs_study(iface);
1387 	return;
1388 fail:
1389 	hostapd_acs_completed(iface, 1);
1390 	acs_fail(iface);
1391 }
1392 
1393 
acs_request_scan_add_freqs(struct hostapd_iface * iface,struct hostapd_hw_modes * mode,int * freq)1394 static int * acs_request_scan_add_freqs(struct hostapd_iface *iface,
1395 					struct hostapd_hw_modes *mode,
1396 					int *freq)
1397 {
1398 	struct hostapd_channel_data *chan;
1399 	int i;
1400 
1401 	for (i = 0; i < mode->num_channels; i++) {
1402 		chan = &mode->channels[i];
1403 		if ((chan->flag & HOSTAPD_CHAN_DISABLED) ||
1404 		    ((chan->flag & HOSTAPD_CHAN_RADAR) &&
1405 		     iface->conf->acs_exclude_dfs))
1406 			continue;
1407 
1408 		if (!is_in_chanlist(iface, chan))
1409 			continue;
1410 
1411 		if (!is_in_freqlist(iface, chan))
1412 			continue;
1413 
1414 		if (chan->max_tx_power < iface->conf->min_tx_power)
1415 			continue;
1416 
1417 		if ((chan->flag & HOSTAPD_CHAN_INDOOR_ONLY) &&
1418 		    iface->conf->country[2] == 0x4f)
1419 			continue;
1420 
1421 		*freq++ = chan->freq;
1422 	}
1423 
1424 	return freq;
1425 }
1426 
1427 
acs_request_scan(struct hostapd_iface * iface)1428 static int acs_request_scan(struct hostapd_iface *iface)
1429 {
1430 	struct wpa_driver_scan_params params;
1431 	int i, *freq, ret;
1432 	int num_channels;
1433 	struct hostapd_hw_modes *mode;
1434 
1435 	os_memset(&params, 0, sizeof(params));
1436 
1437 	num_channels = 0;
1438 	for (i = 0; i < iface->num_hw_features; i++) {
1439 		mode = &iface->hw_features[i];
1440 		if (!hostapd_hw_skip_mode(iface, mode))
1441 			num_channels += mode->num_channels;
1442 	}
1443 
1444 	params.freqs = os_calloc(num_channels + 1, sizeof(params.freqs[0]));
1445 	if (params.freqs == NULL)
1446 		return -1;
1447 
1448 	freq = params.freqs;
1449 
1450 	for (i = 0; i < iface->num_hw_features; i++) {
1451 		mode = &iface->hw_features[i];
1452 		if (!hostapd_hw_skip_mode(iface, mode))
1453 			freq = acs_request_scan_add_freqs(iface, mode, freq);
1454 	}
1455 
1456 	*freq = 0;
1457 
1458 	if (params.freqs == freq) {
1459 		wpa_printf(MSG_ERROR, "ACS: No available channels found");
1460 		os_free(params.freqs);
1461 		return -1;
1462 	}
1463 
1464 	if (!iface->acs_num_retries)
1465 		wpa_printf(MSG_DEBUG, "ACS: Scanning %d / %d",
1466 			   iface->acs_num_completed_scans + 1,
1467 			   iface->conf->acs_num_scans);
1468 	else
1469 		wpa_printf(MSG_DEBUG,
1470 			   "ACS: Re-try scanning attempt %d (%d / %d)",
1471 			   iface->acs_num_retries,
1472 			   iface->acs_num_completed_scans + 1,
1473 			   iface->conf->acs_num_scans);
1474 
1475 	ret = hostapd_driver_scan(iface->bss[0], &params);
1476 	os_free(params.freqs);
1477 
1478 	if (ret == -EBUSY) {
1479 		iface->acs_num_retries++;
1480 		if (iface->acs_num_retries >= ACS_SCAN_RETRY_MAX_COUNT) {
1481 			wpa_printf(MSG_ERROR,
1482 				   "ACS: Failed to request initial scan (all re-attempts failed)");
1483 			acs_fail(iface);
1484 			return -1;
1485 		}
1486 
1487 		wpa_printf(MSG_INFO,
1488 			   "Failed to request acs scan ret=%d (%s) - try to scan after %d seconds",
1489 			   ret, strerror(-ret), ACS_SCAN_RETRY_INTERVAL);
1490 		eloop_cancel_timeout(acs_scan_retry, iface, NULL);
1491 		eloop_register_timeout(ACS_SCAN_RETRY_INTERVAL, 0,
1492 				       acs_scan_retry, iface, NULL);
1493 		return 0;
1494 	}
1495 
1496 	if (ret < 0) {
1497 		wpa_printf(MSG_ERROR, "ACS: Failed to request initial scan");
1498 		acs_cleanup(iface);
1499 		return -1;
1500 	}
1501 
1502 	iface->scan_cb = acs_scan_complete;
1503 
1504 	return 0;
1505 }
1506 
1507 
acs_scan_retry(void * eloop_data,void * user_data)1508 static void acs_scan_retry(void *eloop_data, void *user_data)
1509 {
1510 	struct hostapd_iface *iface = eloop_data;
1511 
1512 	if (acs_request_scan(iface)) {
1513 		wpa_printf(MSG_ERROR,
1514 			   "ACS: Failed to request re-try of initial scan");
1515 		acs_fail(iface);
1516 	}
1517 }
1518 
1519 
acs_init(struct hostapd_iface * iface)1520 enum hostapd_chan_status acs_init(struct hostapd_iface *iface)
1521 {
1522 	int err;
1523 
1524 	wpa_printf(MSG_INFO, "ACS: Automatic channel selection started, this may take a bit");
1525 
1526 	if (iface->drv_flags & WPA_DRIVER_FLAGS_ACS_OFFLOAD) {
1527 		wpa_printf(MSG_INFO, "ACS: Offloading to driver");
1528 
1529 		err = hostapd_drv_do_acs(iface->bss[0]);
1530 		if (err) {
1531 			if (err == 1)
1532 				return HOSTAPD_CHAN_INVALID_NO_IR;
1533 			return HOSTAPD_CHAN_INVALID;
1534 		}
1535 
1536 		return HOSTAPD_CHAN_ACS;
1537 	}
1538 
1539 	if (!iface->current_mode &&
1540 	    iface->conf->hw_mode != HOSTAPD_MODE_IEEE80211ANY)
1541 		return HOSTAPD_CHAN_INVALID;
1542 
1543 	acs_cleanup(iface);
1544 
1545 	if (acs_request_scan(iface) < 0)
1546 		return HOSTAPD_CHAN_INVALID;
1547 
1548 	hostapd_set_state(iface, HAPD_IFACE_ACS);
1549 	wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, ACS_EVENT_STARTED);
1550 
1551 	return HOSTAPD_CHAN_ACS;
1552 }
1553