iwd.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 1/4] wiphy: use enum band_freq with rates getter
@ 2022-12-09 19:39 James Prestwood
  2022-12-09 19:39 ` [PATCH v3 2/4] ap: add support for 5GHz frequencies in AP mode James Prestwood
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: James Prestwood @ 2022-12-09 19:39 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] 5+ messages in thread

* [PATCH v3 2/4] ap: add support for 5GHz frequencies in AP mode
  2022-12-09 19:39 [PATCH v3 1/4] wiphy: use enum band_freq with rates getter James Prestwood
@ 2022-12-09 19:39 ` James Prestwood
  2022-12-09 19:39 ` [PATCH v3 3/4] ap: select rates from hardware capabilities James Prestwood
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: James Prestwood @ 2022-12-09 19:39 UTC (permalink / raw)
  To: iwd; +Cc: James Prestwood

This enables IWD to use 5GHz frequencies in AP mode. Currently
6GHz is not supported so we can assume a [General].Channel value
36 or above indicates the 5GHz band.

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] 5+ messages in thread

* [PATCH v3 3/4] ap: select rates from hardware capabilities
  2022-12-09 19:39 [PATCH v3 1/4] wiphy: use enum band_freq with rates getter James Prestwood
  2022-12-09 19:39 ` [PATCH v3 2/4] ap: add support for 5GHz frequencies in AP mode James Prestwood
@ 2022-12-09 19:39 ` James Prestwood
  2022-12-09 19:39 ` [PATCH v3 4/4] doc: document 5GHz AP support James Prestwood
  2022-12-09 21:00 ` [PATCH v3 1/4] wiphy: use enum band_freq with rates getter Denis Kenzior
  3 siblings, 0 replies; 5+ messages in thread
From: James Prestwood @ 2022-12-09 19:39 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..32d9e1c4 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 && !L_IN_SET(rates[i], 2, 4, 11, 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] 5+ messages in thread

* [PATCH v3 4/4] doc: document 5GHz AP support
  2022-12-09 19:39 [PATCH v3 1/4] wiphy: use enum band_freq with rates getter James Prestwood
  2022-12-09 19:39 ` [PATCH v3 2/4] ap: add support for 5GHz frequencies in AP mode James Prestwood
  2022-12-09 19:39 ` [PATCH v3 3/4] ap: select rates from hardware capabilities James Prestwood
@ 2022-12-09 19:39 ` James Prestwood
  2022-12-09 21:00 ` [PATCH v3 1/4] wiphy: use enum band_freq with rates getter Denis Kenzior
  3 siblings, 0 replies; 5+ messages in thread
From: James Prestwood @ 2022-12-09 19:39 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] 5+ messages in thread

* Re: [PATCH v3 1/4] wiphy: use enum band_freq with rates getter
  2022-12-09 19:39 [PATCH v3 1/4] wiphy: use enum band_freq with rates getter James Prestwood
                   ` (2 preceding siblings ...)
  2022-12-09 19:39 ` [PATCH v3 4/4] doc: document 5GHz AP support James Prestwood
@ 2022-12-09 21:00 ` Denis Kenzior
  3 siblings, 0 replies; 5+ messages in thread
From: Denis Kenzior @ 2022-12-09 21:00 UTC (permalink / raw)
  To: James Prestwood, iwd

Hi James,

On 12/9/22 13:39, James Prestwood wrote:
> 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(-)
> 

All applied, thanks.

Regards,
-Denis


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

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

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

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).