[PATCH 3/6] S1G: Add support for S1G Channel widths.
Bassem Dawood
bassem at morsemicro.com
Tue Oct 31 22:34:28 PDT 2023
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
More information about the Hostap
mailing list