Exemplo n.º 1
0
/* only update beacons if started */
void ieee802_11_update_beacons(struct hostapd_iface *iface)
{
	size_t i;
	for (i = 0; i < iface->num_bss; i++)
		if (iface->bss[i]->beacon_set_done)
			ieee802_11_set_beacon(iface->bss[i]);
}
Exemplo n.º 2
0
static int hostapd_wps_set_ie_cb(void *ctx, struct wpabuf *beacon_ie,
				 struct wpabuf *probe_resp_ie)
{
	struct hostapd_data *hapd = ctx;
	wpabuf_free(hapd->wps_beacon_ie);
	hapd->wps_beacon_ie = beacon_ie;
	wpabuf_free(hapd->wps_probe_resp_ie);
	hapd->wps_probe_resp_ie = probe_resp_ie;
	ieee802_11_set_beacon(hapd);
	return hostapd_set_ap_wps_ie(hapd);
}
Exemplo n.º 3
0
/* only update beacons if started */
int ieee802_11_update_beacons(struct hostapd_iface *iface)
{
	size_t i;
	int ret = 0;

	for (i = 0; i < iface->num_bss; i++) {
		if (iface->bss[i]->beacon_set_done && iface->bss[i]->started &&
		    ieee802_11_set_beacon(iface->bss[i]) < 0)
			ret = -1;
	}

	return ret;
}
Exemplo n.º 4
0
static void hostapd_reload_bss(struct hostapd_data *hapd)
{
#ifndef CONFIG_NO_RADIUS
	radius_client_reconfig(hapd->radius, hapd->conf->radius);
#endif /* CONFIG_NO_RADIUS */

	if (hostapd_setup_wpa_psk(hapd->conf)) {
		wpa_printf(MSG_ERROR, "Failed to re-configure WPA PSK "
			   "after reloading configuration");
	}

	if (hapd->conf->ieee802_1x || hapd->conf->wpa)
		hostapd_set_drv_ieee8021x(hapd, hapd->conf->iface, 1);
	else
		hostapd_set_drv_ieee8021x(hapd, hapd->conf->iface, 0);

	if (hapd->conf->wpa && hapd->wpa_auth == NULL) {
		hostapd_setup_wpa(hapd);
		if (hapd->wpa_auth)
			wpa_init_keys(hapd->wpa_auth);
	} else if (hapd->conf->wpa) {
		const u8 *wpa_ie;
		size_t wpa_ie_len;
		hostapd_reconfig_wpa(hapd);
		wpa_ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &wpa_ie_len);
		if (hostapd_set_generic_elem(hapd, wpa_ie, wpa_ie_len))
			wpa_printf(MSG_ERROR, "Failed to configure WPA IE for "
				   "the kernel driver.");
	} else if (hapd->wpa_auth) {
		wpa_deinit(hapd->wpa_auth);
		hapd->wpa_auth = NULL;
		hostapd_set_privacy(hapd, 0);
		hostapd_setup_encryption(hapd->conf->iface, hapd);
		hostapd_set_generic_elem(hapd, (u8 *) "", 0);
	}

	ieee802_11_set_beacon(hapd);
	hostapd_update_wps(hapd);

	if (hapd->conf->ssid.ssid_set &&
	    hostapd_set_ssid(hapd, (u8 *) hapd->conf->ssid.ssid,
			     hapd->conf->ssid.ssid_len)) {
		wpa_printf(MSG_ERROR, "Could not set SSID for kernel driver");
		/* try to continue */
	}
	wpa_printf(MSG_DEBUG, "Reconfigured interface %s", hapd->conf->iface);
}
Exemplo n.º 5
0
void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
			     int offset)
{
#ifdef NEED_AP_MLME
	int channel;

	hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
		       HOSTAPD_LEVEL_INFO, "driver had channel switch: "
		       "freq=%d, ht=%d, offset=%d", freq, ht, offset);

	channel = hostapd_hw_get_channel(hapd, freq);
	if (!channel) {
		hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
			       HOSTAPD_LEVEL_WARNING, "driver switched to "
			       "bad channel!");
		return;
	}

	hapd->iconf->channel = channel;
	hapd->iconf->ieee80211n = ht;
	hapd->iconf->secondary_channel = offset;


	if (hapd->iface->freq == freq)
	        return;

	hapd->iface->freq = freq;

	if (hostapd_set_freq(hapd, hapd->iconf->hw_mode, freq,
			     hapd->iconf->channel,
			     hapd->iconf->ieee80211n,
			     hapd->iconf->secondary_channel)) {
		hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
			       HOSTAPD_LEVEL_WARNING,
			       "failed to update the freq !");
		return;
	}

	hapd->next_channel = NULL;

	/* update the DS IE */
	ieee802_11_set_beacon(hapd);

	wpa_printf(MSG_DEBUG, "AP/GO moved to channel %d", channel);

#endif /* NEED_AP_MLME */
}
Exemplo n.º 6
0
static void update_channel_utilization(void *eloop_data, void *user_data)
{
	struct hostapd_data *hapd = eloop_data;
	unsigned int sec, usec;
	int err;

	if (!(hapd->beacon_set_done && hapd->started))
		return;

	err = hostapd_drv_get_survey(hapd, hapd->iface->freq);
	if (err) {
		wpa_printf(MSG_ERROR, "BSS Load: Failed to get survey data");
		return;
	}

	ieee802_11_set_beacon(hapd);

	sec = ((hapd->bss_load_update_timeout / 1000) * 1024) / 1000;
	usec = (hapd->bss_load_update_timeout % 1000) * 1024;
	eloop_register_timeout(sec, usec, update_channel_utilization, hapd,
			       NULL);
}
Exemplo n.º 7
0
static void update_channel_utilization(void *eloop_data, void *user_data)
{
	struct hostapd_data *hapd = eloop_data;
	unsigned int sec, usec;
	int err;
	struct hostapd_iface *iface = hapd->iface;

	if (!(hapd->beacon_set_done && hapd->started))
		return;

	err = hostapd_drv_get_survey(hapd, hapd->iface->freq);
	if (err) {
		wpa_printf(MSG_ERROR, "BSS Load: Failed to get survey data");
		return;
	}

	ieee802_11_set_beacon(hapd);

	if (get_bss_load_update_timeout(hapd, &sec, &usec) < 0)
		return;

	if (hapd->conf->chan_util_avg_period) {
		iface->chan_util_samples_sum += iface->channel_utilization;
		iface->chan_util_num_sample_periods +=
			hapd->conf->bss_load_update_period;
		if (iface->chan_util_num_sample_periods >=
		    hapd->conf->chan_util_avg_period) {
			iface->chan_util_average =
				iface->chan_util_samples_sum /
				(iface->chan_util_num_sample_periods /
				 hapd->conf->bss_load_update_period);
			iface->chan_util_samples_sum = 0;
			iface->chan_util_num_sample_periods = 0;
		}
	}

	eloop_register_timeout(sec, usec, update_channel_utilization, hapd,
			       NULL);
}
void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
			     int offset, int width, int cf1, int cf2)
{
#ifdef NEED_AP_MLME
	int channel, chwidth, seg0_idx = 0, seg1_idx = 0;

	hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
		       HOSTAPD_LEVEL_INFO, "driver had channel switch: "
		       "freq=%d, ht=%d, offset=%d, width=%d, cf1=%d, cf2=%d",
		       freq, ht, offset, width, cf1, cf2);

	hapd->iface->freq = freq;

	channel = hostapd_hw_get_channel(hapd, freq);
	if (!channel) {
		hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
			       HOSTAPD_LEVEL_WARNING, "driver switched to "
			       "bad channel!");
		return;
	}

	switch (width) {
	case CHAN_WIDTH_80:
		chwidth = VHT_CHANWIDTH_80MHZ;
		break;
	case CHAN_WIDTH_80P80:
		chwidth = VHT_CHANWIDTH_80P80MHZ;
		break;
	case CHAN_WIDTH_160:
		chwidth = VHT_CHANWIDTH_160MHZ;
		break;
	case CHAN_WIDTH_20_NOHT:
	case CHAN_WIDTH_20:
	case CHAN_WIDTH_40:
	default:
		chwidth = VHT_CHANWIDTH_USE_HT;
		break;
	}

	switch (hapd->iface->current_mode->mode) {
	case HOSTAPD_MODE_IEEE80211A:
		if (cf1 > 5000)
			seg0_idx = (cf1 - 5000) / 5;
		if (cf2 > 5000)
			seg1_idx = (cf2 - 5000) / 5;
		break;
	default:
		seg0_idx = hostapd_hw_get_channel(hapd, cf1);
		seg1_idx = hostapd_hw_get_channel(hapd, cf2);
		break;
	}

	hapd->iconf->channel = channel;
	hapd->iconf->ieee80211n = ht;
	hapd->iconf->secondary_channel = offset;
	hapd->iconf->vht_oper_chwidth = chwidth;
	hapd->iconf->vht_oper_centr_freq_seg0_idx = seg0_idx;
	hapd->iconf->vht_oper_centr_freq_seg1_idx = seg1_idx;

	if (hapd->csa_in_progress &&
	    freq == hapd->cs_freq_params.freq) {
		hostapd_cleanup_cs_params(hapd);
		ieee802_11_set_beacon(hapd);

		wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED "freq=%d",
			freq);
	}
#endif /* NEED_AP_MLME */
}
Exemplo n.º 9
0
void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
			  union wpa_event_data *data)
{
	struct hostapd_data *hapd = ctx;
#ifndef CONFIG_NO_STDOUT_DEBUG
	int level = MSG_DEBUG;

	if (event == EVENT_RX_MGMT && data->rx_mgmt.frame &&
	    data->rx_mgmt.frame_len >= 24) {
		const struct ieee80211_hdr *hdr;
		u16 fc;

		hdr = (const struct ieee80211_hdr *) data->rx_mgmt.frame;
		fc = le_to_host16(hdr->frame_control);
		if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
		    WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON)
			level = MSG_EXCESSIVE;
		if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
		    WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_REQ)
			level = MSG_EXCESSIVE;
	}

	wpa_dbg(hapd->msg_ctx, level, "Event %s (%d) received",
		event_to_string(event), event);
#endif /* CONFIG_NO_STDOUT_DEBUG */

	switch (event) {
	case EVENT_MICHAEL_MIC_FAILURE:
		michael_mic_failure(hapd, data->michael_mic_failure.src, 1);
		break;
	case EVENT_SCAN_RESULTS:
		if (hapd->iface->scan_cb)
			hapd->iface->scan_cb(hapd->iface);
		break;
	case EVENT_WPS_BUTTON_PUSHED:
		hostapd_wps_button_pushed(hapd, NULL);
		break;
#ifdef NEED_AP_MLME
	case EVENT_TX_STATUS:
		switch (data->tx_status.type) {
		case WLAN_FC_TYPE_MGMT:
			hostapd_mgmt_tx_cb(hapd, data->tx_status.data,
					   data->tx_status.data_len,
					   data->tx_status.stype,
					   data->tx_status.ack);
			break;
		case WLAN_FC_TYPE_DATA:
			hostapd_tx_status(hapd, data->tx_status.dst,
					  data->tx_status.data,
					  data->tx_status.data_len,
					  data->tx_status.ack);
			break;
		}
		break;
	case EVENT_EAPOL_TX_STATUS:
		hostapd_eapol_tx_status(hapd, data->eapol_tx_status.dst,
					data->eapol_tx_status.data,
					data->eapol_tx_status.data_len,
					data->eapol_tx_status.ack);
		break;
	case EVENT_DRIVER_CLIENT_POLL_OK:
		hostapd_client_poll_ok(hapd, data->client_poll.addr);
		break;
	case EVENT_RX_FROM_UNKNOWN:
		hostapd_rx_from_unknown_sta(hapd, data->rx_from_unknown.bssid,
					    data->rx_from_unknown.addr,
					    data->rx_from_unknown.wds);
		break;
#endif /* NEED_AP_MLME */
	case EVENT_RX_MGMT:
		if (!data->rx_mgmt.frame)
			break;
#ifdef NEED_AP_MLME
		if (hostapd_mgmt_rx(hapd, &data->rx_mgmt) > 0)
			break;
#endif /* NEED_AP_MLME */
		hostapd_action_rx(hapd, &data->rx_mgmt);
		break;
	case EVENT_RX_PROBE_REQ:
		if (data->rx_probe_req.sa == NULL ||
		    data->rx_probe_req.ie == NULL)
			break;
		hostapd_probe_req_rx(hapd, data->rx_probe_req.sa,
				     data->rx_probe_req.da,
				     data->rx_probe_req.bssid,
				     data->rx_probe_req.ie,
				     data->rx_probe_req.ie_len,
				     data->rx_probe_req.ssi_signal);
		break;
	case EVENT_NEW_STA:
		hostapd_event_new_sta(hapd, data->new_sta.addr);
		break;
	case EVENT_EAPOL_RX:
		hostapd_event_eapol_rx(hapd, data->eapol_rx.src,
				       data->eapol_rx.data,
				       data->eapol_rx.data_len);
		break;
	case EVENT_ASSOC:
		if (!data)
			return;
		hostapd_notif_assoc(hapd, data->assoc_info.addr,
				    data->assoc_info.req_ies,
				    data->assoc_info.req_ies_len,
				    data->assoc_info.reassoc);
		break;
	case EVENT_DISASSOC:
		if (data)
			hostapd_notif_disassoc(hapd, data->disassoc_info.addr);
		break;
	case EVENT_DEAUTH:
		if (data)
			hostapd_notif_disassoc(hapd, data->deauth_info.addr);
		break;
	case EVENT_STATION_LOW_ACK:
		if (!data)
			break;
		hostapd_event_sta_low_ack(hapd, data->low_ack.addr);
		break;
	case EVENT_AUTH:
		hostapd_notif_auth(hapd, &data->auth);
		break;
	case EVENT_CH_SWITCH:
		if (!data)
			break;
		hostapd_event_ch_switch(hapd, data->ch_switch.freq,
					data->ch_switch.ht_enabled,
					data->ch_switch.ch_offset,
					data->ch_switch.ch_width,
					data->ch_switch.cf1,
					data->ch_switch.cf2);
		break;
	case EVENT_CONNECT_FAILED_REASON:
		if (!data)
			break;
		hostapd_event_connect_failed_reason(
			hapd, data->connect_failed_reason.addr,
			data->connect_failed_reason.code);
		break;
	case EVENT_SURVEY:
		hostapd_event_get_survey(hapd->iface, &data->survey_results);
		break;
#ifdef NEED_AP_MLME
	case EVENT_INTERFACE_UNAVAILABLE:
		hostapd_event_iface_unavailable(hapd);
		break;
	case EVENT_DFS_RADAR_DETECTED:
		if (!data)
			break;
		hostapd_event_dfs_radar_detected(hapd, &data->dfs_event);
		break;
	case EVENT_DFS_CAC_FINISHED:
		if (!data)
			break;
		hostapd_event_dfs_cac_finished(hapd, &data->dfs_event);
		break;
	case EVENT_DFS_CAC_ABORTED:
		if (!data)
			break;
		hostapd_event_dfs_cac_aborted(hapd, &data->dfs_event);
		break;
	case EVENT_DFS_NOP_FINISHED:
		if (!data)
			break;
		hostapd_event_dfs_nop_finished(hapd, &data->dfs_event);
		break;
	case EVENT_CHANNEL_LIST_CHANGED:
		/* channel list changed (regulatory?), update channel list */
		/* TODO: check this. hostapd_get_hw_features() initializes
		 * too much stuff. */
		/* hostapd_get_hw_features(hapd->iface); */
		hostapd_channel_list_updated(
			hapd->iface, data->channel_list_changed.initiator);
		break;
	case EVENT_DFS_CAC_STARTED:
		if (!data)
			break;
		hostapd_event_dfs_cac_started(hapd, &data->dfs_event);
		break;
#endif /* NEED_AP_MLME */
	case EVENT_INTERFACE_ENABLED:
		wpa_msg(hapd->msg_ctx, MSG_INFO, INTERFACE_ENABLED);
		if (hapd->disabled && hapd->started) {
			hapd->disabled = 0;
			/*
			 * Try to re-enable interface if the driver stopped it
			 * when the interface got disabled.
			 */
			wpa_auth_reconfig_group_keys(hapd->wpa_auth);
			hapd->reenable_beacon = 1;
			ieee802_11_set_beacon(hapd);
		}
		break;
	case EVENT_INTERFACE_DISABLED:
		hostapd_free_stas(hapd);
		wpa_msg(hapd->msg_ctx, MSG_INFO, INTERFACE_DISABLED);
		hapd->disabled = 1;
		break;
#ifdef CONFIG_ACS
	case EVENT_ACS_CHANNEL_SELECTED:
		hostapd_acs_channel_selected(hapd,
					     &data->acs_selected_channels);
		break;
#endif /* CONFIG_ACS */
	default:
		wpa_printf(MSG_DEBUG, "Unknown event %d", event);
		break;
	}
}
static void hostapd_reconfig_bss(struct hostapd_data *hapd,
				 struct hostapd_bss_config *newbss,
				 struct hostapd_bss_config *oldbss,
				 struct hostapd_config *oldconf,
				 int beacon_changed)
{
	struct hostapd_config_change change;
	int encr_changed = 0;
	struct radius_client_data *old_radius;

	radius_client_flush(hapd->radius, 0);

	if (hostapd_set_dtim_period(hapd, newbss->dtim_period))
		printf("Could not set DTIM period for kernel driver\n");

	if (newbss->ssid.ssid_len != oldbss->ssid.ssid_len ||
	    memcmp(newbss->ssid.ssid, oldbss->ssid.ssid,
		   newbss->ssid.ssid_len) != 0) {
		if (hostapd_set_ssid(hapd, (u8 *) newbss->ssid.ssid,
				     newbss->ssid.ssid_len))
			printf("Could not set SSID for kernel driver\n");
		beacon_changed++;
	}

	if (newbss->ignore_broadcast_ssid != oldbss->ignore_broadcast_ssid)
		beacon_changed++;

	if (hostapd_wep_key_cmp(&newbss->ssid.wep, &oldbss->ssid.wep)) {
		encr_changed++;
		beacon_changed++;
	}

	vlan_reconfig(hapd, oldconf, oldbss);

	if (beacon_changed) {
		HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "Updating beacon frame "
			      "information\n");
		ieee802_11_set_beacon(hapd);
	}

	change.hapd = hapd;
	change.oldconf = oldconf;
	change.newconf = hapd->iconf;
	change.oldbss = oldbss;
	change.newbss = newbss;
	change.mac_acl_changed = hostapd_acl_diff(newbss, oldbss);
	if (newbss->max_num_sta != oldbss->max_num_sta &&
	    newbss->max_num_sta < hapd->num_sta) {
		change.num_sta_remove = hapd->num_sta - newbss->max_num_sta;
	} else
		change.num_sta_remove = 0;
	ap_for_each_sta(hapd, hostapd_config_reload_sta, &change);

	old_radius = hapd->radius;
	hapd->radius = radius_client_reconfig(hapd->radius, hapd,
					      oldbss->radius, newbss->radius);
	hapd->radius_client_reconfigured = old_radius != hapd->radius ||
		hostapd_ip_diff(&newbss->own_ip_addr, &oldbss->own_ip_addr);

	ieee802_1x_reconfig(hapd, oldconf, oldbss);
	iapp_reconfig(hapd, oldconf, oldbss);

	hostapd_acl_reconfig(hapd, oldconf);
	accounting_reconfig(hapd, oldconf);
}
Exemplo n.º 11
0
static void asd_reconfig_bss(struct asd_data *wasd,
				 struct asd_bss_config *newbss,
				 struct asd_bss_config *oldbss,
				 struct asd_config *oldconf,
				 int beacon_changed)
{
	struct asd_config_change change;
	int encr_changed = 0;
	struct radius_client_data *old_radius;

	//radius_client_flush(wasd->radius, 0);

	if (asd_set_dtim_period(wasd, newbss->dtim_period))
		asd_printf(ASD_DEFAULT,MSG_DEBUG,"Could not set DTIM period for kernel driver\n");

	if (newbss->ssid.ssid_len != oldbss->ssid.ssid_len ||
	    os_memcmp(newbss->ssid.ssid, oldbss->ssid.ssid,
		      newbss->ssid.ssid_len) != 0) {
		if (asd_set_ssid(wasd, (u8 *) newbss->ssid.ssid,
				     newbss->ssid.ssid_len))
			asd_printf(ASD_DEFAULT,MSG_DEBUG,"Could not set SSID for kernel driver\n");
		beacon_changed++;
	}

	if (newbss->ignore_broadcast_ssid != oldbss->ignore_broadcast_ssid)
		beacon_changed++;

	if (asd_wep_key_cmp(&newbss->ssid.wep, &oldbss->ssid.wep)) {
		encr_changed++;
		beacon_changed++;
	}

	vlan_reconfig(wasd, oldconf, oldbss);

	if (beacon_changed) {
		asd_printf(ASD_DEFAULT,MSG_DEBUG, "Updating beacon frame information");
		ieee802_11_set_beacon(wasd);
	}

	change.wasd = wasd;
	change.oldconf = oldconf;
	change.newconf = wasd->iconf;
	change.oldbss = oldbss;
	change.newbss = newbss;
	change.mac_acl_changed = asd_acl_diff(newbss, oldbss);
	if (newbss->max_num_sta != oldbss->max_num_sta &&
	    newbss->max_num_sta < wasd->num_sta) {
		change.num_sta_remove = wasd->num_sta - newbss->max_num_sta;
	} else
		change.num_sta_remove = 0;
	ap_for_each_sta(wasd, asd_config_reload_sta, &change);

	old_radius = wasd->radius;
	wasd->radius = radius_client_reconfig(wasd->radius, wasd,
					      oldbss->radius, newbss->radius);
	wasd->radius_client_reconfigured = old_radius != wasd->radius ||
		asd_ip_diff(&newbss->own_ip_addr, &oldbss->own_ip_addr);

	ieee802_1x_reconfig(wasd, oldconf, oldbss);
	iapp_reconfig(wasd, oldconf, oldbss);

	asd_acl_reconfig(wasd, oldconf);
	accounting_reconfig(wasd, oldconf);
}
Exemplo n.º 12
0
void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
			     int offset, int width, int cf1, int cf2)
{
	/* TODO: If OCV is enabled deauth STAs that don't perform a SA Query */

#ifdef NEED_AP_MLME
	int channel, chwidth, is_dfs;
	u8 seg0_idx = 0, seg1_idx = 0;
	size_t i;

	hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
		       HOSTAPD_LEVEL_INFO,
		       "driver had channel switch: freq=%d, ht=%d, vht_ch=0x%x, offset=%d, width=%d (%s), cf1=%d, cf2=%d",
		       freq, ht, hapd->iconf->ch_switch_vht_config, offset,
		       width, channel_width_to_string(width), cf1, cf2);

	hapd->iface->freq = freq;

	channel = hostapd_hw_get_channel(hapd, freq);
	if (!channel) {
		hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
			       HOSTAPD_LEVEL_WARNING,
			       "driver switched to bad channel!");
		return;
	}

	switch (width) {
	case CHAN_WIDTH_80:
		chwidth = VHT_CHANWIDTH_80MHZ;
		break;
	case CHAN_WIDTH_80P80:
		chwidth = VHT_CHANWIDTH_80P80MHZ;
		break;
	case CHAN_WIDTH_160:
		chwidth = VHT_CHANWIDTH_160MHZ;
		break;
	case CHAN_WIDTH_20_NOHT:
	case CHAN_WIDTH_20:
	case CHAN_WIDTH_40:
	default:
		chwidth = VHT_CHANWIDTH_USE_HT;
		break;
	}

	switch (hapd->iface->current_mode->mode) {
	case HOSTAPD_MODE_IEEE80211A:
		if (cf1 > 5000)
			seg0_idx = (cf1 - 5000) / 5;
		if (cf2 > 5000)
			seg1_idx = (cf2 - 5000) / 5;
		break;
	default:
		ieee80211_freq_to_chan(cf1, &seg0_idx);
		ieee80211_freq_to_chan(cf2, &seg1_idx);
		break;
	}

	hapd->iconf->channel = channel;
	hapd->iconf->ieee80211n = ht;
	if (!ht) {
		hapd->iconf->ieee80211ac = 0;
	} else if (hapd->iconf->ch_switch_vht_config) {
		/* CHAN_SWITCH VHT config */
		if (hapd->iconf->ch_switch_vht_config &
		    CH_SWITCH_VHT_ENABLED)
			hapd->iconf->ieee80211ac = 1;
		else if (hapd->iconf->ch_switch_vht_config &
			 CH_SWITCH_VHT_DISABLED)
			hapd->iconf->ieee80211ac = 0;
	}
	hapd->iconf->ch_switch_vht_config = 0;

	hapd->iconf->secondary_channel = offset;
	hapd->iconf->vht_oper_chwidth = chwidth;
	hapd->iconf->vht_oper_centr_freq_seg0_idx = seg0_idx;
	hapd->iconf->vht_oper_centr_freq_seg1_idx = seg1_idx;

	is_dfs = ieee80211_is_dfs(freq, hapd->iface->hw_features,
				  hapd->iface->num_hw_features);

	if (hapd->csa_in_progress &&
	    freq == hapd->cs_freq_params.freq) {
		hostapd_cleanup_cs_params(hapd);
		ieee802_11_set_beacon(hapd);

		wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED
			"freq=%d dfs=%d", freq, is_dfs);
	} else if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) {
		wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED
			"freq=%d dfs=%d", freq, is_dfs);
	}

	for (i = 0; i < hapd->iface->num_bss; i++)
		hostapd_neighbor_set_own_report(hapd->iface->bss[i]);
#endif /* NEED_AP_MLME */
}