aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/ap/ap_drv_ops.c59
-rw-r--r--src/common/qca-vendor.h1
-rw-r--r--src/drivers/driver.h1
-rw-r--r--src/drivers/driver_nl80211.c23
4 files changed, 69 insertions, 15 deletions
diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
index e4176142..6cafcb74 100644
--- a/src/ap/ap_drv_ops.c
+++ b/src/ap/ap_drv_ops.c
@@ -743,6 +743,25 @@ int hostapd_drv_set_qos_map(struct hostapd_data *hapd,
}
+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;
@@ -750,6 +769,7 @@ int hostapd_drv_do_acs(struct hostapd_data *hapd)
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;
@@ -765,24 +785,35 @@ int hostapd_drv_do_acs(struct hostapd_data *hapd)
acs_ch_list_all = 1;
mode = hapd->iface->current_mode;
- if (mode == NULL)
- return -1;
- 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 (!(chan->flag & HOSTAPD_CHAN_DISABLED))
- channels[num_channels++] = chan->chan;
+ 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 (!(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 &
diff --git a/src/common/qca-vendor.h b/src/common/qca-vendor.h
index d626495a..28985f51 100644
--- a/src/common/qca-vendor.h
+++ b/src/common/qca-vendor.h
@@ -223,6 +223,7 @@ enum qca_wlan_vendor_attr_acs_offload {
QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST,
QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL,
QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL,
+ QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST,
/* keep last */
QCA_WLAN_VENDOR_ATTR_ACS_AFTER_LAST,
QCA_WLAN_VENDOR_ATTR_ACS_MAX =
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index f9847839..b637570f 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -1602,6 +1602,7 @@ struct drv_acs_params {
/* ACS channel list info */
unsigned int ch_list_len;
const u8 *ch_list;
+ const int *freq_list;
};
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 55028868..09c4054d 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -8424,6 +8424,26 @@ static int hw_mode_to_qca_acs(enum hostapd_hw_mode hw_mode)
}
+static int add_acs_freq_list(struct nl_msg *msg, const int *freq_list)
+{
+ int i, len, ret;
+ u32 *freqs;
+
+ if (!freq_list)
+ return 0;
+ len = int_array_len(freq_list);
+ freqs = os_malloc(sizeof(u32) * len);
+ if (!freqs)
+ return -1;
+ for (i = 0; i < len; i++)
+ freqs[i] = freq_list[i];
+ ret = nla_put(msg, QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST,
+ sizeof(u32) * len, freqs);
+ os_free(freqs);
+ return ret;
+}
+
+
static int wpa_driver_do_acs(void *priv, struct drv_acs_params *params)
{
struct i802_bss *bss = priv;
@@ -8453,7 +8473,8 @@ static int wpa_driver_do_acs(void *priv, struct drv_acs_params *params)
params->ch_width) ||
(params->ch_list_len &&
nla_put(msg, QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST, params->ch_list_len,
- params->ch_list))) {
+ params->ch_list)) ||
+ add_acs_freq_list(msg, params->freq_list)) {
nlmsg_free(msg);
return -ENOBUFS;
}