iwd.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 1/4] wiphy: use enum band_freq with rates getter
@ 2022-12-09 18:23 James Prestwood
  2022-12-09 18:23 ` [PATCH v2 2/4] ap: add support for 5GHz frequencies in AP mode James Prestwood
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: James Prestwood @ 2022-12-09 18:23 UTC (permalink / raw)
  To: iwd; +Cc: James Prestwood

wiphy_get_supported_rates expected an enum defined in the nl80211
header but the argument type was an unsigned int, not exactly
intuitive to anyone using the API. Since the nl80211 enum value
was only used in a switch statement it could just as well be IWD's
internal enum band_freq.

This also allows modules which do not reference nl80211.h to use
wiphy_get_supported_rates().
---
 src/scan.c  | 2 +-
 src/wiphy.c | 9 +++++----
 src/wiphy.h | 4 +++-
 3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/src/scan.c b/src/scan.c
index ef222f66..5d2f2957 100644
--- a/src/scan.c
+++ b/src/scan.c
@@ -426,7 +426,7 @@ static struct l_genl_msg *scan_build_cmd(struct scan_context *sc,
 		 * rates we don't want to advertise support for 802.11b rates.
 		 */
 		if (L_WARN_ON(!(supported = wiphy_get_supported_rates(sc->wiphy,
-							NL80211_BAND_2GHZ,
+							BAND_FREQ_2_4_GHZ,
 							&num_supported))))
 			goto done;
 
diff --git a/src/wiphy.c b/src/wiphy.c
index 10514572..37e0cdb8 100644
--- a/src/wiphy.c
+++ b/src/wiphy.c
@@ -788,19 +788,20 @@ bool wiphy_supports_iftype(struct wiphy *wiphy, uint32_t iftype)
 	return wiphy->supported_iftypes & (1 << (iftype - 1));
 }
 
-const uint8_t *wiphy_get_supported_rates(struct wiphy *wiphy, unsigned int band,
+const uint8_t *wiphy_get_supported_rates(struct wiphy *wiphy,
+						enum band_freq band,
 						unsigned int *out_num)
 {
 	struct band *bandp;
 
 	switch (band) {
-	case NL80211_BAND_2GHZ:
+	case BAND_FREQ_2_4_GHZ:
 		bandp = wiphy->band_2g;
 		break;
-	case NL80211_BAND_5GHZ:
+	case BAND_FREQ_5_GHZ:
 		bandp = wiphy->band_5g;
 		break;
-	case NL80211_BAND_6GHZ:
+	case BAND_FREQ_6_GHZ:
 		bandp = wiphy->band_6g;
 		break;
 	default:
diff --git a/src/wiphy.h b/src/wiphy.h
index f8de7e0e..410105dd 100644
--- a/src/wiphy.h
+++ b/src/wiphy.h
@@ -29,6 +29,7 @@ struct scan_freq_set;
 struct wiphy_radio_work_item;
 struct ie_rsn_info;
 enum security;
+enum band_freq;
 
 typedef bool (*wiphy_radio_work_func_t)(struct wiphy_radio_work_item *item);
 typedef void (*wiphy_radio_work_destroy_func_t)(
@@ -112,7 +113,8 @@ uint8_t wiphy_get_max_num_ssids_per_scan(struct wiphy *wiphy);
 uint16_t wiphy_get_max_scan_ie_len(struct wiphy *wiphy);
 uint32_t wiphy_get_max_roc_duration(struct wiphy *wiphy);
 bool wiphy_supports_iftype(struct wiphy *wiphy, uint32_t iftype);
-const uint8_t *wiphy_get_supported_rates(struct wiphy *wiphy, unsigned int band,
+const uint8_t *wiphy_get_supported_rates(struct wiphy *wiphy,
+						enum band_freq band,
 						unsigned int *out_num);
 bool wiphy_supports_adhoc_rsn(struct wiphy *wiphy);
 bool wiphy_can_offchannel_tx(struct wiphy *wiphy);
-- 
2.34.3


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v2 2/4] ap: add support for 5GHz frequencies in AP mode
  2022-12-09 18:23 [PATCH v2 1/4] wiphy: use enum band_freq with rates getter James Prestwood
@ 2022-12-09 18:23 ` James Prestwood
  2022-12-09 18:23 ` [PATCH v2 3/4] ap: select rates from hardware capabilities James Prestwood
  2022-12-09 18:23 ` [PATCH v2 4/4] doc: document new AP profile key: [General].Band James Prestwood
  2 siblings, 0 replies; 4+ messages in thread
From: James Prestwood @ 2022-12-09 18:23 UTC (permalink / raw)
  To: iwd; +Cc: James Prestwood

This enables IWD to use 5GHz frequencies in AP mode. Only profile
based AP's can use this feature since additional information is
needed. A new profile key [General].Band was added which is optional
and expects a string, either "2.4GHz" or "5GHz". The existing
Channel key can then be used to specify any 5GHz channel.

It should be noted that the system will probably need a regulatory
domain set in order for 5GHz to be allowed in AP mode. This is due
to world roaming (00) restricting any/all 5GHz frequencies. This
can be accomplished by setting main.conf [General].Country=CC to
the country this AP will operate in.
---
 src/ap.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 65 insertions(+), 8 deletions(-)

diff --git a/src/ap.c b/src/ap.c
index 69412174..72951320 100644
--- a/src/ap.c
+++ b/src/ap.c
@@ -70,6 +70,7 @@ struct ap_state {
 	char ssid[33];
 	char passphrase[64];
 	uint8_t psk[32];
+	enum band_freq band;
 	uint8_t channel;
 	uint8_t *authorized_macs;
 	unsigned int authorized_macs_num;
@@ -985,7 +986,7 @@ static uint32_t ap_send_mgmt_frame(struct ap_state *ap,
 					frame_xchg_cb_t callback,
 					void *user_data)
 {
-	uint32_t ch_freq = band_channel_to_freq(ap->channel, BAND_FREQ_2_4_GHZ);
+	uint32_t ch_freq = band_channel_to_freq(ap->channel, ap->band);
 	uint64_t wdev_id = netdev_get_wdev_id(ap->netdev);
 	struct iovec iov[2];
 
@@ -2408,7 +2409,7 @@ 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, BAND_FREQ_2_4_GHZ);
+	uint32_t ch_freq = band_channel_to_freq(ap->channel, ap->band);
 	uint32_t ch_width = NL80211_CHAN_WIDTH_20;
 	unsigned int i;
 
@@ -3170,6 +3171,42 @@ static char **ap_ciphers_to_strv(uint16_t ciphers)
 	return list;
 }
 
+static bool ap_validate_band_channel(struct ap_state *ap)
+{
+	struct wiphy *wiphy = netdev_get_wiphy(ap->netdev);
+	const struct scan_freq_set *supported;
+	const struct scan_freq_set *disabled;
+	uint32_t freq;
+
+	if (!(wiphy_get_supported_bands(wiphy) & ap->band)) {
+		l_error("AP hardware does not support band");
+		return -EINVAL;
+	}
+
+	freq = band_channel_to_freq(ap->channel, ap->band);
+	if (!freq) {
+		l_error("AP invalid band (%s) and channel (%u) combination",
+			(ap->band & BAND_FREQ_5_GHZ) ? "5Ghz" : "2.4GHz",
+			ap->channel);
+		return false;
+	}
+
+	supported = wiphy_get_supported_freqs(wiphy);
+	disabled = wiphy_get_disabled_freqs(wiphy);
+
+	if (!scan_freq_set_contains(supported, freq)) {
+		l_error("AP hardware does not support frequency %u", freq);
+		return false;
+	}
+
+	if (scan_freq_set_contains(disabled, freq)) {
+		l_error("AP hardware has frequency %u disabled", freq);
+		return false;
+	}
+
+	return true;
+}
+
 static int ap_load_config(struct ap_state *ap, const struct l_settings *config,
 				bool *out_cck_rates)
 {
@@ -3214,17 +3251,31 @@ static int ap_load_config(struct ap_state *ap, const struct l_settings *config,
 		unsigned int uintval;
 
 		if (!l_settings_get_uint(config, "General", "Channel",
-						&uintval) ||
-				!band_channel_to_freq(uintval,
-							BAND_FREQ_2_4_GHZ)) {
+						&uintval)) {
 			l_error("AP Channel value unsupported");
 			return -EINVAL;
 		}
 
 		ap->channel = uintval;
-	} else
+
+		/*
+		 * 6GHz is not supported so we can use only a channel number to
+		 * distinguish between 2.4 and 5GHz.
+		 */
+		if (ap->channel >= 36)
+			ap->band = BAND_FREQ_5_GHZ;
+		else
+			ap->band = BAND_FREQ_2_4_GHZ;
+	} else {
 		/* TODO: Start a Get Survey to decide the channel */
 		ap->channel = 6;
+		ap->band = BAND_FREQ_2_4_GHZ;
+	}
+
+	if (!ap_validate_band_channel(ap)) {
+		l_error("AP Band and Channel combination invalid");
+		return -EINVAL;
+	}
 
 	strval = l_settings_get_string(config, "WSC", "DeviceName");
 	if (strval) {
@@ -3290,7 +3341,13 @@ static int ap_load_config(struct ap_state *ap, const struct l_settings *config,
 		l_strfreev(strvval);
 	}
 
-	if (l_settings_get_value(config, "General", "NoCCKRates")) {
+	/*
+	 * Since 5GHz won't ever support only CCK rates we can ignore this
+	 * setting on that band.
+	 */
+	if (ap->band & BAND_FREQ_5_GHZ)
+		*out_cck_rates = false;
+	else if (l_settings_get_value(config, "General", "NoCCKRates")) {
 		bool boolval;
 
 		if (!l_settings_get_bool(config, "General", "NoCCKRates",
@@ -4080,7 +4137,7 @@ static bool ap_dbus_property_get_freq(struct l_dbus *dbus,
 	if (!ap_if->ap || !ap_if->ap->started)
 		return false;
 
-	freq = band_channel_to_freq(ap_if->ap->channel, BAND_FREQ_2_4_GHZ);
+	freq = band_channel_to_freq(ap_if->ap->channel, ap_if->ap->band);
 
 	l_dbus_message_builder_append_basic(builder, 'u', &freq);
 
-- 
2.34.3


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v2 3/4] ap: select rates from hardware capabilities
  2022-12-09 18:23 [PATCH v2 1/4] wiphy: use enum band_freq with rates getter James Prestwood
  2022-12-09 18:23 ` [PATCH v2 2/4] ap: add support for 5GHz frequencies in AP mode James Prestwood
@ 2022-12-09 18:23 ` James Prestwood
  2022-12-09 18:23 ` [PATCH v2 4/4] doc: document new AP profile key: [General].Band James Prestwood
  2 siblings, 0 replies; 4+ messages in thread
From: James Prestwood @ 2022-12-09 18:23 UTC (permalink / raw)
  To: iwd; +Cc: James Prestwood

Rather than a list of static rates, choose what the hardware
advertises. For the case of CCK rates only include rates 11mbps
or lower.
---
 src/ap.c | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/src/ap.c b/src/ap.c
index 72951320..77fdc561 100644
--- a/src/ap.c
+++ b/src/ap.c
@@ -3438,6 +3438,9 @@ struct ap_state *ap_start(struct netdev *netdev, struct l_settings *config,
 	uint64_t wdev_id = netdev_get_wdev_id(netdev);
 	int err;
 	bool cck_rates = true;
+	const uint8_t *rates;
+	unsigned int num_rates;
+	unsigned int i;
 
 	if (L_WARN_ON(!config)) {
 		if (err_out)
@@ -3463,22 +3466,17 @@ struct ap_state *ap_start(struct netdev *netdev, struct l_settings *config,
 
 	wsc_uuid_from_addr(netdev_get_address(netdev), ap->wsc_uuid_r);
 
+	rates = wiphy_get_supported_rates(wiphy, ap->band, &num_rates);
+	if (!rates)
+		goto error;
+
 	ap->rates = l_uintset_new(200);
 
-	/* TODO: Pick from actual supported rates */
-	if (!cck_rates) {
-		l_uintset_put(ap->rates, 12); /* 6 Mbps*/
-		l_uintset_put(ap->rates, 18); /* 9 Mbps*/
-		l_uintset_put(ap->rates, 24); /* 12 Mbps*/
-		l_uintset_put(ap->rates, 36); /* 18 Mbps*/
-		l_uintset_put(ap->rates, 48); /* 24 Mbps*/
-		l_uintset_put(ap->rates, 72); /* 36 Mbps*/
-		l_uintset_put(ap->rates, 96); /* 48 Mbps*/
-		l_uintset_put(ap->rates, 108); /* 54 Mbps*/
-	} else {
-		l_uintset_put(ap->rates, 2); /* 1 Mbps*/
-		l_uintset_put(ap->rates, 11); /* 5.5 Mbps*/
-		l_uintset_put(ap->rates, 22); /* 11 Mbps*/
+	for (i = 0; i < num_rates; i++) {
+		if (cck_rates && rates[i] > 22)
+			continue;
+
+		l_uintset_put(ap->rates, rates[i]);
 	}
 
 	if (!frame_watch_add(wdev_id, 0, 0x0000 |
-- 
2.34.3


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v2 4/4] doc: document new AP profile key: [General].Band
  2022-12-09 18:23 [PATCH v2 1/4] wiphy: use enum band_freq with rates getter James Prestwood
  2022-12-09 18:23 ` [PATCH v2 2/4] ap: add support for 5GHz frequencies in AP mode James Prestwood
  2022-12-09 18:23 ` [PATCH v2 3/4] ap: select rates from hardware capabilities James Prestwood
@ 2022-12-09 18:23 ` James Prestwood
  2 siblings, 0 replies; 4+ messages in thread
From: James Prestwood @ 2022-12-09 18:23 UTC (permalink / raw)
  To: iwd; +Cc: James Prestwood

---
 src/iwd.ap.rst | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/src/iwd.ap.rst b/src/iwd.ap.rst
index 7b8844e7..823aba99 100644
--- a/src/iwd.ap.rst
+++ b/src/iwd.ap.rst
@@ -55,8 +55,17 @@ The group ``[General]`` contains general AP configuration.
    * - Channel
      - Channel number
 
-       Optional channel number for the access point to operate on.  Only the
-       2.4GHz-band channels are currently allowed.
+       Optional channel number for the access point to operate on. If omitted
+       the channel will be chosen automatically. Channels greater than or equal
+       to 36 will select the 5GHz band for the AP to operate on.
+
+       Note: Due to regulatory requirements the linux kernel does not allow or
+       strictly limits 5GHz use in AP mode while in world roaming. These
+       frequencies become available once the country is set, either via IWD's
+       main.conf option ``[General].Country`` (see ``man iwd.config``) or
+       externally (e.g. iw reg set <CC>). If you are having trouble using 5GHz
+       ensure the country is set, and that the desired frequency/channel is
+       unrestricted.
 
 Network Authentication Settings
 -------------------------------
-- 
2.34.3


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2022-12-09 18:23 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-09 18:23 [PATCH v2 1/4] wiphy: use enum band_freq with rates getter James Prestwood
2022-12-09 18:23 ` [PATCH v2 2/4] ap: add support for 5GHz frequencies in AP mode James Prestwood
2022-12-09 18:23 ` [PATCH v2 3/4] ap: select rates from hardware capabilities James Prestwood
2022-12-09 18:23 ` [PATCH v2 4/4] doc: document new AP profile key: [General].Band James Prestwood

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).