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 /* This shouldn't really happen as survey data is checked in 313 * acs_sanity_check() */ 314 wpa_printf(MSG_ERROR, "ACS: Survey data missing"); 315 return 0; 316 } 317 318 total = survey->channel_time; 319 320 if (survey->filled & SURVEY_HAS_CHAN_TIME_TX) { 321 busy -= survey->channel_time_tx; 322 total -= survey->channel_time_tx; 323 } 324 325 /* TODO: figure out the best multiplier for noise floor base */ 326 factor = pow(10, survey->nf / 5.0L) + 327 (total ? (busy / total) : 0) * 328 pow(2, pow(10, (long double) survey->nf / 10.0L) - 329 pow(10, (long double) min_nf / 10.0L)); 330 331 return factor; 332 } 333 334 335 static void 336 acs_survey_chan_interference_factor(struct hostapd_iface *iface, 337 struct hostapd_channel_data *chan) 338 { 339 struct freq_survey *survey; 340 unsigned int i = 0; 341 long double int_factor = 0; 342 unsigned count = 0; 343 344 if (dl_list_empty(&chan->survey_list) || 345 (chan->flag & HOSTAPD_CHAN_DISABLED)) 346 return; 347 348 chan->interference_factor = 0; 349 350 dl_list_for_each(survey, &chan->survey_list, struct freq_survey, list) 351 { 352 i++; 353 354 if (!acs_survey_is_sufficient(survey)) { 355 wpa_printf(MSG_DEBUG, "ACS: %d: insufficient data", i); 356 continue; 357 } 358 359 count++; 360 int_factor = acs_survey_interference_factor(survey, 361 iface->lowest_nf); 362 chan->interference_factor += int_factor; 363 wpa_printf(MSG_DEBUG, "ACS: %d: min_nf=%d interference_factor=%Lg nf=%d time=%lu busy=%lu rx=%lu", 364 i, chan->min_nf, int_factor, 365 survey->nf, (unsigned long) survey->channel_time, 366 (unsigned long) survey->channel_time_busy, 367 (unsigned long) survey->channel_time_rx); 368 } 369 370 if (count) 371 chan->interference_factor /= count; 372 } 373 374 375 static int acs_usable_bw40_chan(const struct hostapd_channel_data *chan) 376 { 377 const int allowed[] = { 5180, 5220, 5260, 5300, 5500, 5540, 5580, 5620, 378 5660, 5745, 5785, 4920, 4960, 5955, 5995, 6035, 379 6075, 6115, 6155, 6195, 6235, 6275, 6315, 6355, 380 6395, 6435, 6475, 6515, 6555, 6595, 6635, 6675, 381 6715, 6755, 6795, 6835, 6875, 6915, 6955, 6995, 382 7035, 7075 }; 383 unsigned int i; 384 385 for (i = 0; i < ARRAY_SIZE(allowed); i++) 386 if (chan->freq == allowed[i]) 387 return 1; 388 389 return 0; 390 } 391 392 393 static int acs_usable_bw80_chan(const struct hostapd_channel_data *chan) 394 { 395 const int allowed[] = { 5180, 5260, 5550, 5580, 5660, 5745, 5955, 6035, 396 6115, 6195, 6275, 6355, 6435, 6515, 6595, 6675, 397 6755, 6835, 6915, 6995 }; 398 unsigned int i; 399 400 for (i = 0; i < ARRAY_SIZE(allowed); i++) 401 if (chan->freq == allowed[i]) 402 return 1; 403 404 return 0; 405 } 406 407 408 static int acs_usable_bw160_chan(const struct hostapd_channel_data *chan) 409 { 410 const int allowed[] = { 5180, 5500, 5955, 6115, 6275, 6435, 6595, 6755, 411 6915 }; 412 unsigned int i; 413 414 for (i = 0; i < ARRAY_SIZE(allowed); i++) 415 if (chan->freq == allowed[i]) 416 return 1; 417 418 return 0; 419 } 420 421 422 static int acs_survey_is_sufficient(struct freq_survey *survey) 423 { 424 if (!(survey->filled & SURVEY_HAS_NF)) { 425 wpa_printf(MSG_INFO, "ACS: Survey is missing noise floor"); 426 return 0; 427 } 428 429 if (!(survey->filled & SURVEY_HAS_CHAN_TIME)) { 430 wpa_printf(MSG_INFO, "ACS: Survey is missing channel time"); 431 return 0; 432 } 433 434 if (!(survey->filled & SURVEY_HAS_CHAN_TIME_BUSY) && 435 !(survey->filled & SURVEY_HAS_CHAN_TIME_RX)) { 436 wpa_printf(MSG_INFO, 437 "ACS: Survey is missing RX and busy time (at least one is required)"); 438 return 0; 439 } 440 441 return 1; 442 } 443 444 445 static int acs_survey_list_is_sufficient(struct hostapd_channel_data *chan) 446 { 447 struct freq_survey *survey; 448 int ret = -1; 449 450 dl_list_for_each(survey, &chan->survey_list, struct freq_survey, list) 451 { 452 if (acs_survey_is_sufficient(survey)) { 453 ret = 1; 454 break; 455 } 456 ret = 0; 457 } 458 459 if (ret == -1) 460 ret = 1; /* no survey list entries */ 461 462 if (!ret) { 463 wpa_printf(MSG_INFO, 464 "ACS: Channel %d has insufficient survey data", 465 chan->chan); 466 } 467 468 return ret; 469 } 470 471 472 static int acs_surveys_are_sufficient_mode(struct hostapd_hw_modes *mode) 473 { 474 int i; 475 struct hostapd_channel_data *chan; 476 477 for (i = 0; i < mode->num_channels; i++) { 478 chan = &mode->channels[i]; 479 if (!(chan->flag & HOSTAPD_CHAN_DISABLED) && 480 acs_survey_list_is_sufficient(chan)) 481 return 1; 482 } 483 484 return 0; 485 } 486 487 488 static int acs_surveys_are_sufficient(struct hostapd_iface *iface) 489 { 490 int i; 491 struct hostapd_hw_modes *mode; 492 493 for (i = 0; i < iface->num_hw_features; i++) { 494 mode = &iface->hw_features[i]; 495 if (!hostapd_hw_skip_mode(iface, mode) && 496 acs_surveys_are_sufficient_mode(mode)) 497 return 1; 498 } 499 500 return 0; 501 } 502 503 504 static int acs_usable_chan(struct hostapd_channel_data *chan) 505 { 506 return !dl_list_empty(&chan->survey_list) && 507 !(chan->flag & HOSTAPD_CHAN_DISABLED) && 508 acs_survey_list_is_sufficient(chan); 509 } 510 511 512 static int is_in_chanlist(struct hostapd_iface *iface, 513 struct hostapd_channel_data *chan) 514 { 515 if (!iface->conf->acs_ch_list.num) 516 return 1; 517 518 return freq_range_list_includes(&iface->conf->acs_ch_list, chan->chan); 519 } 520 521 522 static int is_in_freqlist(struct hostapd_iface *iface, 523 struct hostapd_channel_data *chan) 524 { 525 if (!iface->conf->acs_freq_list.num) 526 return 1; 527 528 return freq_range_list_includes(&iface->conf->acs_freq_list, 529 chan->freq); 530 } 531 532 533 static void acs_survey_mode_interference_factor( 534 struct hostapd_iface *iface, struct hostapd_hw_modes *mode) 535 { 536 int i; 537 struct hostapd_channel_data *chan; 538 539 for (i = 0; i < mode->num_channels; i++) { 540 chan = &mode->channels[i]; 541 542 if (!acs_usable_chan(chan)) 543 continue; 544 545 if (!is_in_chanlist(iface, chan)) 546 continue; 547 548 if (!is_in_freqlist(iface, chan)) 549 continue; 550 551 wpa_printf(MSG_DEBUG, "ACS: Survey analysis for channel %d (%d MHz)", 552 chan->chan, chan->freq); 553 554 acs_survey_chan_interference_factor(iface, chan); 555 556 wpa_printf(MSG_DEBUG, "ACS: * interference factor average: %Lg", 557 chan->interference_factor); 558 } 559 } 560 561 562 static void acs_survey_all_chans_interference_factor( 563 struct hostapd_iface *iface) 564 { 565 int i; 566 struct hostapd_hw_modes *mode; 567 568 for (i = 0; i < iface->num_hw_features; i++) { 569 mode = &iface->hw_features[i]; 570 if (!hostapd_hw_skip_mode(iface, mode)) 571 acs_survey_mode_interference_factor(iface, mode); 572 } 573 } 574 575 576 static struct hostapd_channel_data * 577 acs_find_chan_mode(struct hostapd_hw_modes *mode, int freq) 578 { 579 struct hostapd_channel_data *chan; 580 int i; 581 582 for (i = 0; i < mode->num_channels; i++) { 583 chan = &mode->channels[i]; 584 585 if (chan->flag & HOSTAPD_CHAN_DISABLED) 586 continue; 587 588 if (chan->freq == freq) 589 return chan; 590 } 591 592 return NULL; 593 } 594 595 596 static struct hostapd_channel_data * 597 acs_find_chan(struct hostapd_iface *iface, int freq) 598 { 599 int i; 600 struct hostapd_hw_modes *mode; 601 struct hostapd_channel_data *chan; 602 603 for (i = 0; i < iface->num_hw_features; i++) { 604 mode = &iface->hw_features[i]; 605 if (!hostapd_hw_skip_mode(iface, mode)) { 606 chan = acs_find_chan_mode(mode, freq); 607 if (chan) 608 return chan; 609 } 610 } 611 612 return NULL; 613 } 614 615 616 static int is_24ghz_mode(enum hostapd_hw_mode mode) 617 { 618 return mode == HOSTAPD_MODE_IEEE80211B || 619 mode == HOSTAPD_MODE_IEEE80211G; 620 } 621 622 623 static int is_common_24ghz_chan(int chan) 624 { 625 return chan == 1 || chan == 6 || chan == 11; 626 } 627 628 629 #ifndef ACS_ADJ_WEIGHT 630 #define ACS_ADJ_WEIGHT 0.85 631 #endif /* ACS_ADJ_WEIGHT */ 632 633 #ifndef ACS_NEXT_ADJ_WEIGHT 634 #define ACS_NEXT_ADJ_WEIGHT 0.55 635 #endif /* ACS_NEXT_ADJ_WEIGHT */ 636 637 #ifndef ACS_24GHZ_PREFER_1_6_11 638 /* 639 * Select commonly used channels 1, 6, 11 by default even if a neighboring 640 * channel has a smaller interference factor as long as it is not better by more 641 * than this multiplier. 642 */ 643 #define ACS_24GHZ_PREFER_1_6_11 0.8 644 #endif /* ACS_24GHZ_PREFER_1_6_11 */ 645 646 static void 647 acs_find_ideal_chan_mode(struct hostapd_iface *iface, 648 struct hostapd_hw_modes *mode, 649 int n_chans, u32 bw, 650 struct hostapd_channel_data **rand_chan, 651 struct hostapd_channel_data **ideal_chan, 652 long double *ideal_factor) 653 { 654 struct hostapd_channel_data *chan, *adj_chan = NULL; 655 long double factor; 656 int i, j; 657 unsigned int k; 658 659 for (i = 0; i < mode->num_channels; i++) { 660 double total_weight; 661 struct acs_bias *bias, tmp_bias; 662 663 chan = &mode->channels[i]; 664 665 /* Since in the current ACS implementation the first channel is 666 * always a primary channel, skip channels not available as 667 * primary until more sophisticated channel selection is 668 * implemented. */ 669 if (!chan_pri_allowed(chan)) 670 continue; 671 672 if (!is_in_chanlist(iface, chan)) 673 continue; 674 675 if (!is_in_freqlist(iface, chan)) 676 continue; 677 678 if (!chan_bw_allowed(chan, bw, 1, 1)) { 679 wpa_printf(MSG_DEBUG, 680 "ACS: Channel %d: BW %u is not supported", 681 chan->chan, bw); 682 continue; 683 } 684 685 /* HT40 on 5 GHz has a limited set of primary channels as per 686 * 11n Annex J */ 687 if (mode->mode == HOSTAPD_MODE_IEEE80211A && 688 ((iface->conf->ieee80211n && 689 iface->conf->secondary_channel) || 690 is_6ghz_freq(chan->freq)) && 691 !acs_usable_bw40_chan(chan)) { 692 wpa_printf(MSG_DEBUG, 693 "ACS: Channel %d: not allowed as primary channel for 40 MHz bandwidth", 694 chan->chan); 695 continue; 696 } 697 698 if (mode->mode == HOSTAPD_MODE_IEEE80211A && 699 (iface->conf->ieee80211ac || iface->conf->ieee80211ax)) { 700 if (hostapd_get_oper_chwidth(iface->conf) == 701 CHANWIDTH_80MHZ && 702 !acs_usable_bw80_chan(chan)) { 703 wpa_printf(MSG_DEBUG, 704 "ACS: Channel %d: not allowed as primary channel for 80 MHz bandwidth", 705 chan->chan); 706 continue; 707 } 708 709 if (hostapd_get_oper_chwidth(iface->conf) == 710 CHANWIDTH_160MHZ && 711 !acs_usable_bw160_chan(chan)) { 712 wpa_printf(MSG_DEBUG, 713 "ACS: Channel %d: not allowed as primary channel for 160 MHz bandwidth", 714 chan->chan); 715 continue; 716 } 717 } 718 719 factor = 0; 720 if (acs_usable_chan(chan)) 721 factor = chan->interference_factor; 722 total_weight = 1; 723 724 for (j = 1; j < n_chans; j++) { 725 adj_chan = acs_find_chan(iface, chan->freq + (j * 20)); 726 if (!adj_chan) 727 break; 728 729 if (!chan_bw_allowed(adj_chan, bw, 1, 0)) { 730 wpa_printf(MSG_DEBUG, 731 "ACS: PRI Channel %d: secondary channel %d BW %u is not supported", 732 chan->chan, adj_chan->chan, bw); 733 break; 734 } 735 736 if (acs_usable_chan(adj_chan)) { 737 factor += adj_chan->interference_factor; 738 total_weight += 1; 739 } 740 } 741 742 if (j != n_chans) { 743 wpa_printf(MSG_DEBUG, "ACS: Channel %d: not enough bandwidth", 744 chan->chan); 745 continue; 746 } 747 748 /* 2.4 GHz has overlapping 20 MHz channels. Include adjacent 749 * channel interference factor. */ 750 if (is_24ghz_mode(mode->mode)) { 751 for (j = 0; j < n_chans; j++) { 752 adj_chan = acs_find_chan(iface, chan->freq + 753 (j * 20) - 5); 754 if (adj_chan && acs_usable_chan(adj_chan)) { 755 factor += ACS_ADJ_WEIGHT * 756 adj_chan->interference_factor; 757 total_weight += ACS_ADJ_WEIGHT; 758 } 759 760 adj_chan = acs_find_chan(iface, chan->freq + 761 (j * 20) - 10); 762 if (adj_chan && acs_usable_chan(adj_chan)) { 763 factor += ACS_NEXT_ADJ_WEIGHT * 764 adj_chan->interference_factor; 765 total_weight += ACS_NEXT_ADJ_WEIGHT; 766 } 767 768 adj_chan = acs_find_chan(iface, chan->freq + 769 (j * 20) + 5); 770 if (adj_chan && acs_usable_chan(adj_chan)) { 771 factor += ACS_ADJ_WEIGHT * 772 adj_chan->interference_factor; 773 total_weight += ACS_ADJ_WEIGHT; 774 } 775 776 adj_chan = acs_find_chan(iface, chan->freq + 777 (j * 20) + 10); 778 if (adj_chan && acs_usable_chan(adj_chan)) { 779 factor += ACS_NEXT_ADJ_WEIGHT * 780 adj_chan->interference_factor; 781 total_weight += ACS_NEXT_ADJ_WEIGHT; 782 } 783 } 784 } 785 786 factor /= total_weight; 787 788 bias = NULL; 789 if (iface->conf->acs_chan_bias) { 790 for (k = 0; k < iface->conf->num_acs_chan_bias; k++) { 791 bias = &iface->conf->acs_chan_bias[k]; 792 if (bias->channel == chan->chan) 793 break; 794 bias = NULL; 795 } 796 } else if (is_24ghz_mode(mode->mode) && 797 is_common_24ghz_chan(chan->chan)) { 798 tmp_bias.channel = chan->chan; 799 tmp_bias.bias = ACS_24GHZ_PREFER_1_6_11; 800 bias = &tmp_bias; 801 } 802 803 if (bias) { 804 factor *= bias->bias; 805 wpa_printf(MSG_DEBUG, 806 "ACS: * channel %d: total interference = %Lg (%f bias)", 807 chan->chan, factor, bias->bias); 808 } else { 809 wpa_printf(MSG_DEBUG, 810 "ACS: * channel %d: total interference = %Lg", 811 chan->chan, factor); 812 } 813 814 if (acs_usable_chan(chan) && 815 (!*ideal_chan || factor < *ideal_factor)) { 816 *ideal_factor = factor; 817 *ideal_chan = chan; 818 } 819 820 /* This channel would at least be usable */ 821 if (!(*rand_chan)) 822 *rand_chan = chan; 823 } 824 } 825 826 827 /* 828 * At this point it's assumed chan->interference_factor has been computed. 829 * This function should be reusable regardless of interference computation 830 * option (survey, BSS, spectral, ...). chan->interference factor must be 831 * summable (i.e., must be always greater than zero). 832 */ 833 static struct hostapd_channel_data * 834 acs_find_ideal_chan(struct hostapd_iface *iface) 835 { 836 struct hostapd_channel_data *ideal_chan = NULL, 837 *rand_chan = NULL; 838 long double ideal_factor = 0; 839 int i; 840 int n_chans = 1; 841 u32 bw; 842 struct hostapd_hw_modes *mode; 843 844 if (is_6ghz_op_class(iface->conf->op_class)) { 845 bw = op_class_to_bandwidth(iface->conf->op_class); 846 n_chans = bw / 20; 847 goto bw_selected; 848 } 849 850 /* TODO: HT40- support */ 851 852 if (iface->conf->ieee80211n && 853 iface->conf->secondary_channel == -1) { 854 wpa_printf(MSG_ERROR, "ACS: HT40- is not supported yet. Please try HT40+"); 855 return NULL; 856 } 857 858 if (iface->conf->ieee80211n && 859 iface->conf->secondary_channel) 860 n_chans = 2; 861 862 if (iface->conf->ieee80211ac || iface->conf->ieee80211ax) { 863 switch (hostapd_get_oper_chwidth(iface->conf)) { 864 case CHANWIDTH_80MHZ: 865 n_chans = 4; 866 break; 867 case CHANWIDTH_160MHZ: 868 n_chans = 8; 869 break; 870 } 871 } 872 873 bw = num_chan_to_bw(n_chans); 874 875 bw_selected: 876 /* TODO: VHT/HE80+80. Update acs_adjust_center_freq() too. */ 877 878 wpa_printf(MSG_DEBUG, 879 "ACS: Survey analysis for selected bandwidth %d MHz", bw); 880 881 for (i = 0; i < iface->num_hw_features; i++) { 882 mode = &iface->hw_features[i]; 883 if (!hostapd_hw_skip_mode(iface, mode)) 884 acs_find_ideal_chan_mode(iface, mode, n_chans, bw, 885 &rand_chan, &ideal_chan, 886 &ideal_factor); 887 } 888 889 if (ideal_chan) { 890 wpa_printf(MSG_DEBUG, "ACS: Ideal channel is %d (%d MHz) with total interference factor of %Lg", 891 ideal_chan->chan, ideal_chan->freq, ideal_factor); 892 return ideal_chan; 893 } 894 895 return rand_chan; 896 } 897 898 899 static void acs_adjust_center_freq(struct hostapd_iface *iface) 900 { 901 int offset; 902 903 wpa_printf(MSG_DEBUG, "ACS: Adjusting VHT center frequency"); 904 905 switch (hostapd_get_oper_chwidth(iface->conf)) { 906 case CHANWIDTH_USE_HT: 907 offset = 2 * iface->conf->secondary_channel; 908 break; 909 case CHANWIDTH_80MHZ: 910 offset = 6; 911 break; 912 case CHANWIDTH_160MHZ: 913 offset = 14; 914 break; 915 default: 916 /* TODO: How can this be calculated? Adjust 917 * acs_find_ideal_chan() */ 918 wpa_printf(MSG_INFO, 919 "ACS: Only VHT20/40/80/160 is supported now"); 920 return; 921 } 922 923 hostapd_set_oper_centr_freq_seg0_idx(iface->conf, 924 iface->conf->channel + offset); 925 } 926 927 928 static int acs_study_survey_based(struct hostapd_iface *iface) 929 { 930 wpa_printf(MSG_DEBUG, "ACS: Trying survey-based ACS"); 931 932 if (!iface->chans_surveyed) { 933 wpa_printf(MSG_ERROR, "ACS: Unable to collect survey data"); 934 return -1; 935 } 936 937 if (!acs_surveys_are_sufficient(iface)) { 938 wpa_printf(MSG_ERROR, "ACS: Surveys have insufficient data"); 939 return -1; 940 } 941 942 acs_survey_all_chans_interference_factor(iface); 943 return 0; 944 } 945 946 947 static int acs_study_options(struct hostapd_iface *iface) 948 { 949 if (acs_study_survey_based(iface) == 0) 950 return 0; 951 952 /* TODO: If no surveys are available/sufficient this is a good 953 * place to fallback to BSS-based ACS */ 954 955 return -1; 956 } 957 958 959 static void acs_study(struct hostapd_iface *iface) 960 { 961 struct hostapd_channel_data *ideal_chan; 962 int err; 963 964 err = acs_study_options(iface); 965 if (err < 0) { 966 wpa_printf(MSG_ERROR, "ACS: All study options have failed"); 967 goto fail; 968 } 969 970 ideal_chan = acs_find_ideal_chan(iface); 971 if (!ideal_chan) { 972 wpa_printf(MSG_ERROR, "ACS: Failed to compute ideal channel"); 973 err = -1; 974 goto fail; 975 } 976 977 iface->conf->channel = ideal_chan->chan; 978 iface->freq = ideal_chan->freq; 979 980 if (iface->conf->ieee80211ac || iface->conf->ieee80211ax) 981 acs_adjust_center_freq(iface); 982 983 err = 0; 984 fail: 985 /* 986 * hostapd_setup_interface_complete() will return -1 on failure, 987 * 0 on success and 0 is HOSTAPD_CHAN_VALID :) 988 */ 989 if (hostapd_acs_completed(iface, err) == HOSTAPD_CHAN_VALID) { 990 acs_cleanup(iface); 991 return; 992 } 993 994 /* This can possibly happen if channel parameters (secondary 995 * channel, center frequencies) are misconfigured */ 996 wpa_printf(MSG_ERROR, "ACS: Possibly channel configuration is invalid, please report this along with your config file."); 997 acs_fail(iface); 998 } 999 1000 1001 static void acs_scan_complete(struct hostapd_iface *iface) 1002 { 1003 int err; 1004 1005 iface->scan_cb = NULL; 1006 1007 wpa_printf(MSG_DEBUG, "ACS: Using survey based algorithm (acs_num_scans=%d)", 1008 iface->conf->acs_num_scans); 1009 1010 err = hostapd_drv_get_survey(iface->bss[0], 0); 1011 if (err) { 1012 wpa_printf(MSG_ERROR, "ACS: Failed to get survey data"); 1013 goto fail; 1014 } 1015 1016 if (++iface->acs_num_completed_scans < iface->conf->acs_num_scans) { 1017 err = acs_request_scan(iface); 1018 if (err) { 1019 wpa_printf(MSG_ERROR, "ACS: Failed to request scan"); 1020 goto fail; 1021 } 1022 1023 return; 1024 } 1025 1026 acs_study(iface); 1027 return; 1028 fail: 1029 hostapd_acs_completed(iface, 1); 1030 acs_fail(iface); 1031 } 1032 1033 1034 static int * acs_request_scan_add_freqs(struct hostapd_iface *iface, 1035 struct hostapd_hw_modes *mode, 1036 int *freq) 1037 { 1038 struct hostapd_channel_data *chan; 1039 int i; 1040 1041 for (i = 0; i < mode->num_channels; i++) { 1042 chan = &mode->channels[i]; 1043 if (chan->flag & HOSTAPD_CHAN_DISABLED) 1044 continue; 1045 1046 if (!is_in_chanlist(iface, chan)) 1047 continue; 1048 1049 if (!is_in_freqlist(iface, chan)) 1050 continue; 1051 1052 *freq++ = chan->freq; 1053 } 1054 1055 return freq; 1056 } 1057 1058 1059 static int acs_request_scan(struct hostapd_iface *iface) 1060 { 1061 struct wpa_driver_scan_params params; 1062 int i, *freq; 1063 int num_channels; 1064 struct hostapd_hw_modes *mode; 1065 1066 os_memset(¶ms, 0, sizeof(params)); 1067 1068 num_channels = 0; 1069 for (i = 0; i < iface->num_hw_features; i++) { 1070 mode = &iface->hw_features[i]; 1071 if (!hostapd_hw_skip_mode(iface, mode)) 1072 num_channels += mode->num_channels; 1073 } 1074 1075 params.freqs = os_calloc(num_channels + 1, sizeof(params.freqs[0])); 1076 if (params.freqs == NULL) 1077 return -1; 1078 1079 freq = params.freqs; 1080 1081 for (i = 0; i < iface->num_hw_features; i++) { 1082 mode = &iface->hw_features[i]; 1083 if (!hostapd_hw_skip_mode(iface, mode)) 1084 freq = acs_request_scan_add_freqs(iface, mode, freq); 1085 } 1086 1087 *freq = 0; 1088 1089 if (params.freqs == freq) { 1090 wpa_printf(MSG_ERROR, "ACS: No available channels found"); 1091 os_free(params.freqs); 1092 return -1; 1093 } 1094 1095 iface->scan_cb = acs_scan_complete; 1096 1097 wpa_printf(MSG_DEBUG, "ACS: Scanning %d / %d", 1098 iface->acs_num_completed_scans + 1, 1099 iface->conf->acs_num_scans); 1100 1101 if (hostapd_driver_scan(iface->bss[0], ¶ms) < 0) { 1102 wpa_printf(MSG_ERROR, "ACS: Failed to request initial scan"); 1103 acs_cleanup(iface); 1104 os_free(params.freqs); 1105 return -1; 1106 } 1107 1108 os_free(params.freqs); 1109 return 0; 1110 } 1111 1112 1113 enum hostapd_chan_status acs_init(struct hostapd_iface *iface) 1114 { 1115 wpa_printf(MSG_INFO, "ACS: Automatic channel selection started, this may take a bit"); 1116 1117 if (iface->drv_flags & WPA_DRIVER_FLAGS_ACS_OFFLOAD) { 1118 wpa_printf(MSG_INFO, "ACS: Offloading to driver"); 1119 if (hostapd_drv_do_acs(iface->bss[0])) 1120 return HOSTAPD_CHAN_INVALID; 1121 return HOSTAPD_CHAN_ACS; 1122 } 1123 1124 if (!iface->current_mode && 1125 iface->conf->hw_mode != HOSTAPD_MODE_IEEE80211ANY) 1126 return HOSTAPD_CHAN_INVALID; 1127 1128 acs_cleanup(iface); 1129 1130 if (acs_request_scan(iface) < 0) 1131 return HOSTAPD_CHAN_INVALID; 1132 1133 hostapd_set_state(iface, HAPD_IFACE_ACS); 1134 wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, ACS_EVENT_STARTED); 1135 1136 return HOSTAPD_CHAN_ACS; 1137 } 1138