diff mbox series

[v2,4/4] ap: generate chandef for starting AP

Message ID 20221228214403.2682418-4-prestwoj@gmail.com (mailing list archive)
State New
Headers show
Series [v2,1/4] band: generate HT chandef from frequency | expand

Checks

Context Check Description
tedd_an/pre-ci_am success Success
prestwoj/iwd-ci-gitlint success GitLint

Commit Message

James Prestwood Dec. 28, 2022, 9:44 p.m. UTC
To include HT support a chandef needs to be created for whatever
frequency is being used. This allows IWD to provide a secondary
channel to the kernel in the case of 40MHz operation. Now the AP
will generate a chandef when starting based on the channel set
in the user profile (or default).

If HT is not supported the chandef width is set to 20MHz no-HT,
otherwise band_freq_to_ht_chandef is used.
---
 src/ap.c | 38 ++++++++++++++++++++++++++++++++++----
 1 file changed, 34 insertions(+), 4 deletions(-)

v2:
 * Create chandef manually for non-HT since its very simple
 * Fall back to non-HT in the unlikely event the HT chandef
   fails to be created
diff mbox series

Patch

diff --git a/src/ap.c b/src/ap.c
index d9a81651..a989c454 100644
--- a/src/ap.c
+++ b/src/ap.c
@@ -72,6 +72,7 @@  struct ap_state {
 	uint8_t psk[32];
 	enum band_freq band;
 	uint8_t channel;
+	struct band_chandef chandef;
 	uint8_t *authorized_macs;
 	unsigned int authorized_macs_num;
 	char wsc_name[33];
@@ -2567,8 +2568,6 @@  static struct l_genl_msg *ap_build_cmd_start_ap(struct ap_state *ap)
 	uint32_t nl_akm = CRYPTO_AKM_PSK;
 	uint32_t wpa_version = NL80211_WPA_VERSION_2;
 	uint32_t auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM;
-	uint32_t ch_freq = band_channel_to_freq(ap->channel, ap->band);
-	uint32_t ch_width = NL80211_CHAN_WIDTH_20;
 	unsigned int i;
 
 	static const uint8_t bcast_addr[6] = {
@@ -2616,8 +2615,13 @@  static struct l_genl_msg *ap_build_cmd_start_ap(struct ap_state *ap)
 	l_genl_msg_append_attr(cmd, NL80211_ATTR_WPA_VERSIONS, 4, &wpa_version);
 	l_genl_msg_append_attr(cmd, NL80211_ATTR_AKM_SUITES, 4, &nl_akm);
 	l_genl_msg_append_attr(cmd, NL80211_ATTR_AUTH_TYPE, 4, &auth_type);
-	l_genl_msg_append_attr(cmd, NL80211_ATTR_WIPHY_FREQ, 4, &ch_freq);
-	l_genl_msg_append_attr(cmd, NL80211_ATTR_CHANNEL_WIDTH, 4, &ch_width);
+	l_genl_msg_append_attr(cmd, NL80211_ATTR_WIPHY_FREQ, 4,
+				&ap->chandef.frequency);
+	l_genl_msg_append_attr(cmd, NL80211_ATTR_CHANNEL_WIDTH, 4,
+				&ap->chandef.channel_width);
+	if (ap->chandef.center1_frequency)
+		l_genl_msg_append_attr(cmd, NL80211_ATTR_CENTER_FREQ1, 4,
+					&ap->chandef.center1_frequency);
 
 	if (wiphy_supports_probe_resp_offload(wiphy)) {
 		uint8_t probe_resp[head_len + tail_len];
@@ -3356,6 +3360,32 @@  static bool ap_validate_band_channel(struct ap_state *ap)
 		l_error("AP frequency %u disabled or unsupported", freq);
 		return false;
 	}
+
+	if (ap->supports_ht) {
+		if (band_freq_to_ht_chandef(freq, attr, &ap->chandef) < 0) {
+			/*
+			 * This is unlikely ever to fail since there are no
+			 * 20Mhz restrictions, but just in case fall back to
+			 * non-HT.
+			 */
+			ap->supports_ht = false;
+
+			l_warn("AP could not find HT chandef for frequency %u"
+				" using 20Mhz no-HT", freq);
+
+			goto no_ht;
+		}
+	} else {
+no_ht:
+		ap->chandef.frequency = freq;
+		ap->chandef.channel_width = BAND_CHANDEF_WIDTH_20NOHT;
+	}
+
+	l_debug("AP using frequency %u and channel width %s",
+			ap->chandef.frequency,
+			band_chandef_width_to_string(
+				ap->chandef.channel_width));
+
 	return true;
 }