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