static void ieee80211n_check_scan(struct hostapd_iface *iface) { struct wpa_scan_results *scan_res; int oper40; int res; /* Check list of neighboring BSSes (from scan) to see whether 40 MHz is * allowed per IEEE Std 802.11-2012, 10.15.3.2 */ iface->scan_cb = NULL; scan_res = hostapd_driver_get_scan_results(iface->bss[0]); if (scan_res == NULL) { hostapd_setup_interface_complete(iface, 1); return; } if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A) oper40 = ieee80211n_check_40mhz_5g(iface, scan_res); else oper40 = ieee80211n_check_40mhz_2g4(iface, scan_res); wpa_scan_results_free(scan_res); if (!oper40) { wpa_printf(MSG_INFO, "20/40 MHz operation not permitted on " "channel pri=%d sec=%d based on overlapping BSSes", iface->conf->channel, iface->conf->channel + iface->conf->secondary_channel * 4); iface->conf->secondary_channel = 0; iface->conf->ht_capab &= ~HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET; } res = ieee80211n_allowed_ht40_channel_pair(iface); hostapd_setup_interface_complete(iface, !res); }
int hostapd_acs_completed(struct hostapd_iface *iface, int err) { int ret = -1; if (err) goto out; switch (hostapd_check_chans(iface)) { case HOSTAPD_CHAN_VALID: wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, ACS_EVENT_COMPLETED "freq=%d channel=%d", hostapd_hw_get_freq(iface->bss[0], iface->conf->channel), iface->conf->channel); break; case HOSTAPD_CHAN_ACS: wpa_printf(MSG_ERROR, "ACS error - reported complete, but no result available"); wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, ACS_EVENT_FAILED); hostapd_notify_bad_chans(iface); goto out; case HOSTAPD_CHAN_INVALID: default: wpa_printf(MSG_ERROR, "ACS picked unusable channels"); wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, ACS_EVENT_FAILED); hostapd_notify_bad_chans(iface); goto out; } ret = hostapd_check_ht_capab(iface); if (ret < 0) goto out; if (ret == 1) { wpa_printf(MSG_DEBUG, "Interface initialization will be completed in a callback"); return 0; } ret = 0; out: return hostapd_setup_interface_complete(iface, ret); }
static int hostapd_dfs_start_channel_switch_cac(struct hostapd_iface *iface) { struct hostapd_channel_data *channel; int secondary_channel; u8 vht_oper_centr_freq_seg0_idx = 0; u8 vht_oper_centr_freq_seg1_idx = 0; int skip_radar = 0; int err = 1; /* Radar detected during active CAC */ iface->cac_started = 0; channel = dfs_get_valid_channel(iface, &secondary_channel, &vht_oper_centr_freq_seg0_idx, &vht_oper_centr_freq_seg1_idx, skip_radar); if (!channel) { wpa_printf(MSG_ERROR, "No valid channel available"); return err; } wpa_printf(MSG_DEBUG, "DFS will switch to a new channel %d", channel->chan); wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_NEW_CHANNEL "freq=%d chan=%d sec_chan=%d", channel->freq, channel->chan, secondary_channel); iface->freq = channel->freq; iface->conf->channel = channel->chan; iface->conf->secondary_channel = secondary_channel; iface->conf->vht_oper_centr_freq_seg0_idx = vht_oper_centr_freq_seg0_idx; iface->conf->vht_oper_centr_freq_seg1_idx = vht_oper_centr_freq_seg1_idx; err = 0; hostapd_setup_interface_complete(iface, err); return err; }
static void ap_ht40_scan_retry(void *eloop_data, void *user_data) { #define HT2040_COEX_SCAN_RETRY 15 struct hostapd_iface *iface = eloop_data; struct wpa_driver_scan_params params; int ret; os_memset(¶ms, 0, sizeof(params)); if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G) ieee80211n_scan_channels_2g4(iface, ¶ms); else ieee80211n_scan_channels_5g(iface, ¶ms); ret = hostapd_driver_scan(iface->bss[0], ¶ms); iface->num_ht40_scan_tries++; os_free(params.freqs); if (ret == -EBUSY && iface->num_ht40_scan_tries < HT2040_COEX_SCAN_RETRY) { wpa_printf(MSG_ERROR, "Failed to request a scan of neighboring BSSes ret=%d (%s) - try to scan again (attempt %d)", ret, strerror(-ret), iface->num_ht40_scan_tries); eloop_register_timeout(1, 0, ap_ht40_scan_retry, iface, NULL); return; } if (ret == 0) { iface->scan_cb = ieee80211n_check_scan; return; } wpa_printf(MSG_DEBUG, "Failed to request a scan in device, bringing up in HT20 mode"); iface->conf->secondary_channel = 0; iface->conf->ht_capab &= ~HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET; hostapd_setup_interface_complete(iface, 0); }