static void hostapd_get_hw_mode_any_channels(struct hostapd_data *hapd, struct hostapd_hw_modes *mode, int acs_ch_list_all, int **freq_list) { int i; for (i = 0; i < mode->num_channels; i++) { struct hostapd_channel_data *chan = &mode->channels[i]; if ((acs_ch_list_all || freq_range_list_includes(&hapd->iface->conf->acs_ch_list, chan->chan)) && !(chan->flag & HOSTAPD_CHAN_DISABLED)) int_array_add_unique(freq_list, chan->freq); } }
int hostapd_drv_do_acs(struct hostapd_data *hapd) { struct drv_acs_params params; int ret, i, acs_ch_list_all = 0; u8 *channels = NULL; unsigned int num_channels = 0; struct hostapd_hw_modes *mode; int *freq_list = NULL; if (hapd->driver == NULL || hapd->driver->do_acs == NULL) return 0; os_memset(¶ms, 0, sizeof(params)); params.hw_mode = hapd->iface->conf->hw_mode; /* * If no chanlist config parameter is provided, include all enabled * channels of the selected hw_mode. */ if (!hapd->iface->conf->acs_ch_list.num) acs_ch_list_all = 1; mode = hapd->iface->current_mode; if (mode) { channels = os_malloc(mode->num_channels); if (channels == NULL) return -1; for (i = 0; i < mode->num_channels; i++) { struct hostapd_channel_data *chan = &mode->channels[i]; if (!acs_ch_list_all && !freq_range_list_includes( &hapd->iface->conf->acs_ch_list, chan->chan)) continue; if (hapd->iface->conf->acs_exclude_dfs && (chan->flag & HOSTAPD_CHAN_RADAR)) continue; if (!(chan->flag & HOSTAPD_CHAN_DISABLED)) { channels[num_channels++] = chan->chan; int_array_add_unique(&freq_list, chan->freq); } } } else { for (i = 0; i < hapd->iface->num_hw_features; i++) { mode = &hapd->iface->hw_features[i]; hostapd_get_hw_mode_any_channels(hapd, mode, acs_ch_list_all, &freq_list); } } params.ch_list = channels; params.ch_list_len = num_channels; params.freq_list = freq_list; params.ht_enabled = !!(hapd->iface->conf->ieee80211n); params.ht40_enabled = !!(hapd->iface->conf->ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET); params.vht_enabled = !!(hapd->iface->conf->ieee80211ac); params.ch_width = 20; if (hapd->iface->conf->ieee80211n && params.ht40_enabled) params.ch_width = 40; /* Note: VHT20 is defined by combination of ht_capab & vht_oper_chwidth */ if (hapd->iface->conf->ieee80211ac && params.ht40_enabled) { if (hapd->iface->conf->vht_oper_chwidth == VHT_CHANWIDTH_80MHZ) params.ch_width = 80; else if (hapd->iface->conf->vht_oper_chwidth == VHT_CHANWIDTH_160MHZ || hapd->iface->conf->vht_oper_chwidth == VHT_CHANWIDTH_80P80MHZ) params.ch_width = 160; } ret = hapd->driver->do_acs(hapd->drv_priv, ¶ms); os_free(channels); return ret; }