int hostapd_check_ht_capab(struct hostapd_iface *iface) { #ifdef CONFIG_IEEE80211N int ret; if (!iface->conf->ieee80211n) return 0; if (iface->current_mode->mode != HOSTAPD_MODE_IEEE80211B && iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G && (iface->conf->ht_capab & HT_CAP_INFO_DSSS_CCK40MHZ)) { wpa_printf(MSG_DEBUG, "Disable HT capability [DSSS_CCK-40] on 5 GHz band"); iface->conf->ht_capab &= ~HT_CAP_INFO_DSSS_CCK40MHZ; } if (!ieee80211n_supported_ht_capab(iface)) return -1; #ifdef CONFIG_IEEE80211AC if (!ieee80211ac_supported_vht_capab(iface)) return -1; #endif /* CONFIG_IEEE80211AC */ ret = ieee80211n_check_40mhz(iface); if (ret) return ret; if (!ieee80211n_allowed_ht40_channel_pair(iface)) return -1; #endif /* CONFIG_IEEE80211N */ return 0; }
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; } res = ieee80211n_allowed_ht40_channel_pair(iface); hostapd_setup_interface_complete(iface, !res); }
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); iface->secondary_ch = iface->conf->secondary_channel; 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; if (iface->drv_flags & WPA_DRIVER_FLAGS_HT_2040_COEX) { /* * TODO: Could consider scheduling another scan to check * if channel width can be changed if no coex reports * are received from associating stations. */ } } res = ieee80211n_allowed_ht40_channel_pair(iface); if (!res) { iface->conf->secondary_channel = 0; iface->conf->vht_oper_centr_freq_seg0_idx = 0; iface->conf->vht_oper_centr_freq_seg1_idx = 0; iface->conf->vht_oper_chwidth = VHT_CHANWIDTH_USE_HT; res = 1; wpa_printf(MSG_INFO, "Fallback to 20 MHz"); } hostapd_setup_interface_complete(iface, !res); }
int hostapd_check_ht_capab(struct hostapd_iface *iface) { #ifdef CONFIG_IEEE80211N int ret; ret = ieee80211n_check_40mhz(iface); if (ret) return ret; if (!ieee80211n_allowed_ht40_channel_pair(iface)) return -1; if (!ieee80211n_supported_ht_capab(iface)) return -1; #endif /* CONFIG_IEEE80211N */ return 0; }