[PATCH 3/6] S1G: Add support for S1G Channel widths.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux