This commit includes the changes required for configuring an AP on 1/2/4/8/16 MHz channel widths. --- src/common/hw_features_common.c | 15 +++++++++++++ src/drivers/driver.h | 8 ++++++- src/drivers/driver_nl80211.c | 35 ++++++++++++++++++++++++++++++- src/drivers/driver_nl80211_capa.c | 19 +++++++++++++++++ 4 files changed, 75 insertions(+), 2 deletions(-) diff --git a/src/common/hw_features_common.c b/src/common/hw_features_common.c index 58f0dcc4e..f8ac9b5be 100644 --- a/src/common/hw_features_common.c +++ b/src/common/hw_features_common.c @@ -434,6 +434,11 @@ int hostapd_set_freq_params(struct hostapd_freq_params *data, hostapd_encode_edmg_chan(enable_edmg, edmg_channel, channel, &data->edmg); + if (s1g_enabled) { + data->bandwidth = oper_chwidth; + return 0; + } + if (is_6ghz_freq(freq)) { if (!data->he_enabled && !data->eht_enabled) { wpa_printf(MSG_ERROR, @@ -852,6 +857,16 @@ int chan_bw_allowed(const struct hostapd_channel_data *chan, u32 bw, u32 bw_mask; switch (bw) { + case 1: + return chan->allowed_bw & HOSTAPD_CHAN_WIDTH_1; + case 2: + return chan->allowed_bw & HOSTAPD_CHAN_WIDTH_2; + case 4: + return chan->allowed_bw & HOSTAPD_CHAN_WIDTH_4; + case 8: + return chan->allowed_bw & HOSTAPD_CHAN_WIDTH_8; + case 16: + return chan->allowed_bw & HOSTAPD_CHAN_WIDTH_16; case 20: bw_mask = HOSTAPD_CHAN_WIDTH_20; break; diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 543e97aff..7825dfca3 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -56,6 +56,11 @@ enum hostapd_chan_width_attr { HOSTAPD_CHAN_WIDTH_80 = BIT(4), HOSTAPD_CHAN_WIDTH_160 = BIT(5), HOSTAPD_CHAN_WIDTH_320 = BIT(6), + HOSTAPD_CHAN_WIDTH_1 = BIT(7), + HOSTAPD_CHAN_WIDTH_2 = BIT(8), + HOSTAPD_CHAN_WIDTH_4 = BIT(9), + HOSTAPD_CHAN_WIDTH_8 = BIT(10), + HOSTAPD_CHAN_WIDTH_16 = BIT(11), }; /* Filter gratuitous ARP */ @@ -837,7 +842,8 @@ struct hostapd_freq_params { int center_freq2; /** - * bandwidth - Channel bandwidth in MHz (20, 40, 80, 160) + * bandwidth - Channel bandwidth in MHz (1, 2, 4, 8, 16, 20, 40, 80, + * 160) */ int bandwidth; diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index cee08571a..582eddd98 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -4854,6 +4854,27 @@ err: #endif /* CONFIG_DRIVER_NL80211_QCA */ +static enum nl80211_chan_width nl80211_s1g_ch_width_parse( + const struct hostapd_freq_params *freq) +{ + switch (freq->bandwidth) { + case 1: + return NL80211_CHAN_WIDTH_1; + case 2: + return NL80211_CHAN_WIDTH_2; + case 4: + return NL80211_CHAN_WIDTH_4; + case 8: + return NL80211_CHAN_WIDTH_8; + case 16: + return NL80211_CHAN_WIDTH_16; + default: + return 0; + } + return 0; +} + + static int nl80211_put_freq_params(struct nl_msg *msg, const struct hostapd_freq_params *freq) { @@ -4882,6 +4903,7 @@ static int nl80211_put_freq_params(struct nl_msg *msg, wpa_printf(MSG_DEBUG, " * he_enabled=%d", freq->he_enabled); wpa_printf(MSG_DEBUG, " * vht_enabled=%d", freq->vht_enabled); wpa_printf(MSG_DEBUG, " * ht_enabled=%d", freq->ht_enabled); + wpa_printf(MSG_DEBUG, " * s1g_enabled=%d", freq->s1g_enabled); wpa_printf(MSG_DEBUG, " * radar_background=%d", freq->radar_background); @@ -4889,7 +4911,14 @@ static int nl80211_put_freq_params(struct nl_msg *msg, is_24ghz = hw_mode == HOSTAPD_MODE_IEEE80211G || hw_mode == HOSTAPD_MODE_IEEE80211B; - if (freq->vht_enabled || + if (freq->s1g_enabled) { + wpa_printf(MSG_DEBUG, " * bandwidth=%d", freq->bandwidth); + cw = nl80211_s1g_ch_width_parse(freq); + if (!cw) + return -EINVAL; + if (nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, cw)) + return -ENOBUFS; + } else if (freq->vht_enabled || ((freq->he_enabled || freq->eht_enabled) && !is_24ghz)) { enum nl80211_chan_width cw; @@ -5046,6 +5075,10 @@ static int wpa_driver_nl80211_set_ap(void *priv, nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ_OFFSET, KHZ_TO_S1G_OFFSET(params->freq->freq_khz))) goto fail; + + cw = nl80211_s1g_ch_width_parse(params->freq); + if (cw && nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, cw)) + goto fail; } if (params->mld_ap) { diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c index fb6fd3c83..1ae381e49 100644 --- a/src/drivers/driver_nl80211_capa.c +++ b/src/drivers/driver_nl80211_capa.c @@ -1688,6 +1688,25 @@ static void phy_info_freq(struct hostapd_hw_modes *mode, if (tb_freq[NL80211_FREQUENCY_ATTR_NO_160MHZ]) chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_160; + /* The kernel treats S1G channel bandwidths different by marking them as + * allowed instead of disallowed */ + chan->allowed_bw &= ~(HOSTAPD_CHAN_WIDTH_1 | + HOSTAPD_CHAN_WIDTH_2 | + HOSTAPD_CHAN_WIDTH_4 | + HOSTAPD_CHAN_WIDTH_8 | + HOSTAPD_CHAN_WIDTH_16); + + if (tb_freq[NL80211_FREQUENCY_ATTR_1MHZ]) + chan->allowed_bw |= HOSTAPD_CHAN_WIDTH_1; + if (tb_freq[NL80211_FREQUENCY_ATTR_2MHZ]) + chan->allowed_bw |= HOSTAPD_CHAN_WIDTH_2; + if (tb_freq[NL80211_FREQUENCY_ATTR_4MHZ]) + chan->allowed_bw |= HOSTAPD_CHAN_WIDTH_4; + if (tb_freq[NL80211_FREQUENCY_ATTR_8MHZ]) + chan->allowed_bw |= HOSTAPD_CHAN_WIDTH_8; + if (tb_freq[NL80211_FREQUENCY_ATTR_16MHZ]) + chan->allowed_bw |= HOSTAPD_CHAN_WIDTH_16; + if (tb_freq[NL80211_FREQUENCY_ATTR_DFS_STATE]) { enum nl80211_dfs_state state = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_DFS_STATE]); -- 2.25.1 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap