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(¶ms, 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], ¶ms);
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