* [PATCH 1/7] band: introduce new method of tracking frequencies
@ 2022-12-13 20:36 James Prestwood
2022-12-13 20:36 ` [PATCH 2/7] util: add scan_freq_set_remove James Prestwood
` (5 more replies)
0 siblings, 6 replies; 9+ messages in thread
From: James Prestwood @ 2022-12-13 20:36 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
Currently the wiphy object keeps track of supported and disabled
frequencies as two separate scan_freq_set's. This is very expensive
and limiting since we have to add more sets in order to track
additional frequency flags (no-IR, no-HT, no-HE etc).
Instead we can refactor how frequencies are stored. They will now
be part of the band object and stored as a uint16_t array where
each index corresponds to a channel, and the value will contain
various flags for that frequency.
---
src/band.c | 2 ++
src/band.h | 8 ++++++++
2 files changed, 10 insertions(+)
diff --git a/src/band.c b/src/band.c
index 01166b62..82ffc13e 100644
--- a/src/band.c
+++ b/src/band.c
@@ -36,6 +36,8 @@ void band_free(struct band *band)
if (band->he_capabilities)
l_queue_destroy(band->he_capabilities, l_free);
+ l_free(band->frequencies);
+
l_free(band);
}
diff --git a/src/band.h b/src/band.h
index 9b307a77..06a8402a 100644
--- a/src/band.h
+++ b/src/band.h
@@ -55,8 +55,16 @@ struct band_he_capabilities {
uint8_t he_mcs_set[12];
};
+enum band_freq_attribute {
+ BAND_FREQ_ATTR_SUPPORTED = 1 << 0,
+ BAND_FREQ_ATTR_DISABLED = 1 << 1,
+ BAND_FREQ_ATTR_NO_IR = 1 << 2,
+};
+
struct band {
enum band_freq freq;
+ uint16_t *frequencies;
+ size_t freqs_len;
/* Each entry is type struct band_he_capabilities */
struct l_queue *he_capabilities;
uint8_t vht_mcs_set[8];
--
2.34.3
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/7] util: add scan_freq_set_remove
2022-12-13 20:36 [PATCH 1/7] band: introduce new method of tracking frequencies James Prestwood
@ 2022-12-13 20:36 ` James Prestwood
2022-12-14 21:37 ` Denis Kenzior
2022-12-13 20:36 ` [PATCH 3/7] wiphy: parse/store frequency info in band object James Prestwood
` (4 subsequent siblings)
5 siblings, 1 reply; 9+ messages in thread
From: James Prestwood @ 2022-12-13 20:36 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
Removes one frequency from a scan_freq_set object.
---
src/util.c | 22 ++++++++++++++++++++++
src/util.h | 1 +
2 files changed, 23 insertions(+)
diff --git a/src/util.c b/src/util.c
index d564ebc0..69019dc8 100644
--- a/src/util.c
+++ b/src/util.c
@@ -360,6 +360,28 @@ bool scan_freq_set_add(struct scan_freq_set *freqs, uint32_t freq)
return false;
}
+bool scan_freq_set_remove(struct scan_freq_set *freqs, uint32_t freq)
+{
+ enum band_freq band;
+ uint8_t channel;
+
+ channel = band_freq_to_channel(freq, &band);
+ if (!channel)
+ return false;
+
+ switch (band) {
+ case BAND_FREQ_2_4_GHZ:
+ freqs->channels_2ghz &= ~(1 << (channel - 1));
+ return true;
+ case BAND_FREQ_5_GHZ:
+ return l_uintset_take(freqs->channels_5ghz, channel);
+ case BAND_FREQ_6_GHZ:
+ return l_uintset_take(freqs->channels_6ghz, channel);
+ }
+
+ return false;
+}
+
bool scan_freq_set_contains(const struct scan_freq_set *freqs, uint32_t freq)
{
enum band_freq band;
diff --git a/src/util.h b/src/util.h
index cc45059f..dafa446d 100644
--- a/src/util.h
+++ b/src/util.h
@@ -111,6 +111,7 @@ typedef void (*scan_freq_set_func_t)(uint32_t freq, void *userdata);
struct scan_freq_set *scan_freq_set_new(void);
void scan_freq_set_free(struct scan_freq_set *freqs);
bool scan_freq_set_add(struct scan_freq_set *freqs, uint32_t freq);
+bool scan_freq_set_remove(struct scan_freq_set *freqs, uint32_t freq);
bool scan_freq_set_contains(const struct scan_freq_set *freqs, uint32_t freq);
uint32_t scan_freq_set_get_bands(const struct scan_freq_set *freqs);
void scan_freq_set_foreach(const struct scan_freq_set *freqs,
--
2.34.3
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 3/7] wiphy: parse/store frequency info in band object
2022-12-13 20:36 [PATCH 1/7] band: introduce new method of tracking frequencies James Prestwood
2022-12-13 20:36 ` [PATCH 2/7] util: add scan_freq_set_remove James Prestwood
@ 2022-12-13 20:36 ` James Prestwood
2022-12-14 22:11 ` Denis Kenzior
2022-12-13 20:36 ` [PATCH 4/7] wiphy: add wiphy_check_{frequency,band} James Prestwood
` (3 subsequent siblings)
5 siblings, 1 reply; 9+ messages in thread
From: James Prestwood @ 2022-12-13 20:36 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
As additional frequency info is needed it doesn't make sense to
store a full list of frequencies for every attribute (i.e.
supported, disabled, no-IR, etc).
This changes nl80211_parse_supported_frequencies to take a uint16_t
array where each index corresponds to a channel, and each value
can be filled with flag bits to signal any limitations on that
frequency.
wiphy.c then had to be updated to use this rather than the existing
scan_freq_set lists. This, as-is, will break anything using
wiphy_get_disabled_freqs().
---
src/nl80211util.c | 19 +++++----
src/nl80211util.h | 3 +-
src/wiphy.c | 105 ++++++++++++++++++++++++++++++++++++++++++----
3 files changed, 109 insertions(+), 18 deletions(-)
diff --git a/src/nl80211util.c b/src/nl80211util.c
index da36d936..a2cd882d 100644
--- a/src/nl80211util.c
+++ b/src/nl80211util.c
@@ -501,20 +501,20 @@ int nl80211_parse_chandef(struct l_genl_msg *msg, struct band_chandef *out)
}
int nl80211_parse_supported_frequencies(struct l_genl_attr *band_freqs,
- struct scan_freq_set *supported_list,
- struct scan_freq_set *disabled_list)
+ uint16_t *list, size_t num_channels)
{
uint16_t type, len;
const void *data;
struct l_genl_attr attr;
struct l_genl_attr nested;
+ uint8_t channel;
if (!l_genl_attr_recurse(band_freqs, &nested))
return -EBADMSG;
while (l_genl_attr_next(&nested, NULL, NULL, NULL)) {
uint32_t freq = 0;
- bool disabled = false;
+ uint16_t flags = BAND_FREQ_ATTR_SUPPORTED;
if (!l_genl_attr_recurse(&nested, &attr))
continue;
@@ -525,7 +525,10 @@ int nl80211_parse_supported_frequencies(struct l_genl_attr *band_freqs,
freq = *((uint32_t *) data);
break;
case NL80211_FREQUENCY_ATTR_DISABLED:
- disabled = true;
+ flags |= BAND_FREQ_ATTR_DISABLED;
+ break;
+ case NL80211_FREQUENCY_ATTR_NO_IR:
+ flags |= BAND_FREQ_ATTR_NO_IR;
break;
}
}
@@ -533,11 +536,11 @@ int nl80211_parse_supported_frequencies(struct l_genl_attr *band_freqs,
if (!freq)
continue;
- if (supported_list)
- scan_freq_set_add(supported_list, freq);
+ channel = band_freq_to_channel(freq, NULL);
+ if (!channel || channel > num_channels)
+ continue;
- if (disabled && disabled_list)
- scan_freq_set_add(disabled_list, freq);
+ list[channel] = flags;
}
return 0;
diff --git a/src/nl80211util.h b/src/nl80211util.h
index 44555a25..f12f4695 100644
--- a/src/nl80211util.h
+++ b/src/nl80211util.h
@@ -58,5 +58,4 @@ struct l_genl_msg *nl80211_build_cmd_frame(uint32_t ifindex,
int nl80211_parse_chandef(struct l_genl_msg *msg, struct band_chandef *out);
int nl80211_parse_supported_frequencies(struct l_genl_attr *band_freqs,
- struct scan_freq_set *supported,
- struct scan_freq_set *disabled);
+ uint16_t *list, size_t num_channels);
diff --git a/src/wiphy.c b/src/wiphy.c
index 37e0cdb8..c8ef5937 100644
--- a/src/wiphy.c
+++ b/src/wiphy.c
@@ -745,8 +745,33 @@ void wiphy_generate_address_from_ssid(struct wiphy *wiphy, const char *ssid,
bool wiphy_constrain_freq_set(const struct wiphy *wiphy,
struct scan_freq_set *set)
{
+ struct band *bands[3] = { wiphy->band_2g,
+ wiphy->band_5g, wiphy->band_6g };
+ unsigned int b;
+ unsigned int i;
+
scan_freq_set_constrain(set, wiphy->supported_freqs);
- scan_freq_set_subtract(set, wiphy->disabled_freqs);
+
+ for (b = 0; b < L_ARRAY_SIZE(bands); b++) {
+ struct band *band = bands[b];
+
+ if (!band)
+ continue;
+
+ for (i = 0; i < band->freqs_len; i++) {
+ uint32_t freq;
+
+ if (!(band->frequencies[i] & BAND_FREQ_ATTR_SUPPORTED))
+ continue;
+
+ freq = band_channel_to_freq(i, band->freq);
+ if (!freq)
+ continue;
+
+ if (band->frequencies[i] & BAND_FREQ_ATTR_DISABLED)
+ scan_freq_set_remove(set, freq);
+ }
+ }
if (!scan_freq_set_get_bands(set))
/* The set is empty. */
@@ -952,7 +977,7 @@ int wiphy_estimate_data_rate(struct wiphy *wiphy,
bool wiphy_regdom_is_updating(struct wiphy *wiphy)
{
- return wiphy->pending_freqs != NULL;
+ return wiphy->dump_id || (!wiphy->self_managed && wiphy_dump_id);
}
uint32_t wiphy_state_watch_add(struct wiphy *wiphy,
@@ -1471,19 +1496,23 @@ static void parse_supported_bands(struct wiphy *wiphy,
struct band **bandp;
struct band *band;
enum band_freq freq;
+ size_t num_channels;
switch (type) {
case NL80211_BAND_2GHZ:
bandp = &wiphy->band_2g;
freq = BAND_FREQ_2_4_GHZ;
+ num_channels = 14;
break;
case NL80211_BAND_5GHZ:
bandp = &wiphy->band_5g;
freq = BAND_FREQ_5_GHZ;
+ num_channels = 196;
break;
case NL80211_BAND_6GHZ:
bandp = &wiphy->band_6g;
freq = BAND_FREQ_6_GHZ;
+ num_channels = 233;
break;
default:
continue;
@@ -1498,6 +1527,8 @@ static void parse_supported_bands(struct wiphy *wiphy,
continue;
band->freq = freq;
+ band->frequencies = l_new(uint16_t, num_channels);
+ band->freqs_len = num_channels;
/* Reset iter to beginning */
if (!l_genl_attr_recurse(bands, &attr)) {
@@ -1507,15 +1538,14 @@ static void parse_supported_bands(struct wiphy *wiphy,
} else
band = *bandp;
-
while (l_genl_attr_next(&attr, &type, &len, &data)) {
struct l_genl_attr nested;
switch (type) {
case NL80211_BAND_ATTR_FREQS:
nl80211_parse_supported_frequencies(&attr,
- wiphy->supported_freqs,
- wiphy->disabled_freqs);
+ band->frequencies,
+ band->freqs_len);
break;
case NL80211_BAND_ATTR_RATES:
@@ -1970,6 +2000,7 @@ static void wiphy_dump_callback(struct l_genl_msg *msg,
struct l_genl_attr bands;
struct l_genl_attr attr;
uint16_t type;
+ struct band *band;
if (nl80211_parse_attrs(msg, NL80211_ATTR_WIPHY, &id,
NL80211_ATTR_WIPHY_BANDS, &bands,
@@ -1980,7 +2011,28 @@ static void wiphy_dump_callback(struct l_genl_msg *msg,
if (L_WARN_ON(!wiphy))
return;
- while (l_genl_attr_next(&bands, NULL, NULL, NULL)) {
+ /* Unregistered means the wiphy is blacklisted, don't bother parsing */
+ if (!wiphy->registered)
+ return;
+
+ while (l_genl_attr_next(&bands, &type, NULL, NULL)) {
+ switch (type) {
+ case NL80211_BAND_2GHZ:
+ band = wiphy->band_2g;
+ break;
+ case NL80211_BAND_5GHZ:
+ band = wiphy->band_5g;
+ break;
+ case NL80211_BAND_6GHZ:
+ band = wiphy->band_6g;
+ break;
+ default:
+ continue;
+ }
+
+ if (L_WARN_ON(!band))
+ continue;
+
if (!l_genl_attr_recurse(&bands, &attr))
return;
@@ -1988,8 +2040,14 @@ static void wiphy_dump_callback(struct l_genl_msg *msg,
if (type != NL80211_BAND_ATTR_FREQS)
continue;
- nl80211_parse_supported_frequencies(&attr, NULL,
- wiphy->pending_freqs);
+ /*
+ * Just write over the old list for each frequency. In
+ * theory no new frequencies should be added so there
+ * should never be any stale values.
+ */
+ nl80211_parse_supported_frequencies(&attr,
+ band->frequencies,
+ band->freqs_len);
}
}
}
@@ -2178,6 +2236,36 @@ static void wiphy_get_reg_domain(struct wiphy *wiphy)
}
}
+static void setup_supported_freqs(struct wiphy *wiphy)
+{
+ struct band *bands[3] = { wiphy->band_2g,
+ wiphy->band_5g, wiphy->band_6g };
+ unsigned int b;
+ unsigned int i;
+
+ wiphy->supported_freqs = scan_freq_set_new();
+
+ for (b = 0; b < L_ARRAY_SIZE(bands); b++) {
+ struct band *band = bands[b];
+
+ if (!band)
+ continue;
+
+ for (i = 0; i < band->freqs_len; i++) {
+ uint32_t freq;
+
+ if (!(band->frequencies[i] & BAND_FREQ_ATTR_SUPPORTED))
+ continue;
+
+ freq = band_channel_to_freq(i, band->freq);
+ if (!freq)
+ continue;
+
+ scan_freq_set_add(wiphy->supported_freqs, freq);
+ }
+ }
+}
+
void wiphy_create_complete(struct wiphy *wiphy)
{
wiphy_register(wiphy);
@@ -2193,6 +2281,7 @@ void wiphy_create_complete(struct wiphy *wiphy)
wiphy_set_station_capability_bits(wiphy);
wiphy_setup_rm_enabled_capabilities(wiphy);
wiphy_get_reg_domain(wiphy);
+ setup_supported_freqs(wiphy);
wiphy_print_basic_info(wiphy);
}
--
2.34.3
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 4/7] wiphy: add wiphy_check_{frequency,band}
2022-12-13 20:36 [PATCH 1/7] band: introduce new method of tracking frequencies James Prestwood
2022-12-13 20:36 ` [PATCH 2/7] util: add scan_freq_set_remove James Prestwood
2022-12-13 20:36 ` [PATCH 3/7] wiphy: parse/store frequency info in band object James Prestwood
@ 2022-12-13 20:36 ` James Prestwood
2022-12-13 20:36 ` [PATCH 5/7] station: use wiphy_check_{frequency,band} James Prestwood
` (2 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: James Prestwood @ 2022-12-13 20:36 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
Add two new APIs as a replacement for wiphy_get_disabled_freqs().
wiphy_check_frequency() serves as a way to check a single frequency
for certain attributes, currently: supported, disabled, and no-IR.
wiphy_check_band() similarly checks the entire band. This is mainly
targeted at station which needs to check if a given band is disabled
and is only meant to be used with the supported and disabled flags.
---
src/wiphy.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++
src/wiphy.h | 4 +++
2 files changed, 93 insertions(+)
diff --git a/src/wiphy.c b/src/wiphy.c
index c8ef5937..f5b7c05e 100644
--- a/src/wiphy.c
+++ b/src/wiphy.c
@@ -496,6 +496,95 @@ const struct scan_freq_set *wiphy_get_disabled_freqs(const struct wiphy *wiphy)
return wiphy->disabled_freqs;
}
+static struct band *wiphy_get_band(const struct wiphy *wiphy, enum band_freq band)
+{
+ switch (band) {
+ case BAND_FREQ_2_4_GHZ:
+ return wiphy->band_2g;
+ case BAND_FREQ_5_GHZ:
+ return wiphy->band_5g;
+ case BAND_FREQ_6_GHZ:
+ return wiphy->band_6g;
+ default:
+ return NULL;
+ }
+}
+
+bool wiphy_check_frequency(const struct wiphy *wiphy, uint32_t freq,
+ uint16_t flags)
+{
+ enum band_freq band;
+ struct band *bandp;
+ uint8_t channel;
+ uint16_t mask;
+
+ channel = band_freq_to_channel(freq, &band);
+ if (!channel)
+ return false;
+
+ bandp = wiphy_get_band(wiphy, band);
+ if (!bandp)
+ return false;
+
+ if (L_WARN_ON(channel > bandp->freqs_len))
+ return false;
+
+
+ mask = bandp->frequencies[channel];
+
+ if ((flags & mask) != flags)
+ return false;
+
+ return true;
+}
+
+bool wiphy_check_band(const struct wiphy *wiphy, enum band_freq band,
+ uint16_t flags)
+{
+ unsigned int i;
+ bool supported = false;
+ bool disabled = true;
+ bool ret = false;
+ struct band *bandp = wiphy_get_band(wiphy, band);
+
+ /*
+ * Caller should either include the SUPPORTED flag, or verify support
+ * before calling otherwise this return could be misleading i.e.
+ * checking a band for only DISABLED that isn't supported would
+ * return false which could be interpreted that the band is enabled.
+ */
+ if ((flags & BAND_FREQ_ATTR_SUPPORTED) && !bandp)
+ return false;
+
+ if (L_WARN_ON(!bandp))
+ return false;
+
+ /*
+ * This should only be used with SUPPORTED/DISABLED flags. For supported
+ * only ONE frequency needs to be supported. And for DISABLED ALL
+ * frequencies must be disabled.
+ */
+ for (i = 0; i < bandp->freqs_len; i++) {
+ uint16_t mask = bandp->frequencies[i];
+
+ if (!(mask & BAND_FREQ_ATTR_SUPPORTED))
+ continue;
+
+ supported = true;
+
+ if (!(mask & BAND_FREQ_ATTR_DISABLED))
+ disabled = false;
+ }
+
+ if (supported && (flags & BAND_FREQ_ATTR_SUPPORTED))
+ ret = true;
+
+ if (disabled && (flags & BAND_FREQ_ATTR_DISABLED))
+ ret &= true;
+
+ return ret;
+}
+
bool wiphy_supports_probe_resp_offload(struct wiphy *wiphy)
{
return wiphy->ap_probe_resp_offload;
diff --git a/src/wiphy.h b/src/wiphy.h
index 410105dd..469ccdc8 100644
--- a/src/wiphy.h
+++ b/src/wiphy.h
@@ -100,6 +100,10 @@ uint32_t wiphy_get_supported_bands(struct wiphy *wiphy);
const struct scan_freq_set *wiphy_get_supported_freqs(
const struct wiphy *wiphy);
const struct scan_freq_set *wiphy_get_disabled_freqs(const struct wiphy *wiphy);
+bool wiphy_check_frequency(const struct wiphy *wiphy, uint32_t freq,
+ uint16_t flags);
+bool wiphy_check_band(const struct wiphy *wiphy, enum band_freq band,
+ uint16_t flags);
bool wiphy_supports_probe_resp_offload(struct wiphy *wiphy);
bool wiphy_can_transition_disable(struct wiphy *wiphy);
bool wiphy_can_offload(struct wiphy *wiphy);
--
2.34.3
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 5/7] station: use wiphy_check_{frequency,band}
2022-12-13 20:36 [PATCH 1/7] band: introduce new method of tracking frequencies James Prestwood
` (2 preceding siblings ...)
2022-12-13 20:36 ` [PATCH 4/7] wiphy: add wiphy_check_{frequency,band} James Prestwood
@ 2022-12-13 20:36 ` James Prestwood
2022-12-13 20:36 ` [PATCH 6/7] ap: " James Prestwood
2022-12-13 20:36 ` [PATCH 7/7] wiphy: remove disabled_freqs and related dump code James Prestwood
5 siblings, 0 replies; 9+ messages in thread
From: James Prestwood @ 2022-12-13 20:36 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
Remove uses of supported/disabled scan_freq_set's and replace
with the equivalent calls to wiphy_check_frequency/band.
---
src/station.c | 19 ++++++++-----------
1 file changed, 8 insertions(+), 11 deletions(-)
diff --git a/src/station.c b/src/station.c
index a467b4e9..95a6d830 100644
--- a/src/station.c
+++ b/src/station.c
@@ -1407,8 +1407,6 @@ static int station_quick_scan_trigger(struct station *station)
{
_auto_(scan_freq_set_free) struct scan_freq_set *known_freq_set = NULL;
bool known_6ghz;
- const struct scan_freq_set *disabled = wiphy_get_disabled_freqs(
- station->wiphy);
if (wiphy_regdom_is_updating(station->wiphy)) {
l_debug("regdom is updating, delaying quick scan");
@@ -1430,9 +1428,10 @@ static int station_quick_scan_trigger(struct station *station)
* this since its so limited, so return an error which will fall back to
* full autoconnect.
*/
- if ((scan_freq_set_get_bands(disabled) & BAND_FREQ_6_GHZ) &&
- wiphy_country_is_unknown(station->wiphy) &&
- known_6ghz)
+ if (wiphy_check_band(station->wiphy, BAND_FREQ_6_GHZ,
+ BAND_FREQ_ATTR_SUPPORTED | BAND_FREQ_ATTR_DISABLED) &&
+ wiphy_country_is_unknown(station->wiphy) &&
+ known_6ghz)
return -ENOTSUP;
if (!wiphy_constrain_freq_set(station->wiphy, known_freq_set)) {
@@ -1812,10 +1811,6 @@ static void parse_neighbor_report(struct station *station,
struct scan_freq_set *freq_set_md, *freq_set_no_md;
uint32_t current_freq = 0;
struct handshake_state *hs = netdev_get_handshake(station->netdev);
- const struct scan_freq_set *supported =
- wiphy_get_supported_freqs(station->wiphy);
- const struct scan_freq_set *disabled =
- wiphy_get_disabled_freqs(station->wiphy);
freq_set_md = scan_freq_set_new();
freq_set_no_md = scan_freq_set_new();
@@ -1853,8 +1848,10 @@ static void parse_neighbor_report(struct station *station,
continue;
/* Skip if frequency is not supported or disabled */
- if (!scan_freq_set_contains(supported, freq) ||
- scan_freq_set_contains(disabled, freq))
+ if (!wiphy_check_frequency(station->wiphy, freq,
+ BAND_FREQ_ATTR_SUPPORTED) ||
+ wiphy_check_frequency(station->wiphy, freq,
+ BAND_FREQ_ATTR_DISABLED))
continue;
if (!memcmp(info.addr,
--
2.34.3
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 6/7] ap: use wiphy_check_{frequency,band}
2022-12-13 20:36 [PATCH 1/7] band: introduce new method of tracking frequencies James Prestwood
` (3 preceding siblings ...)
2022-12-13 20:36 ` [PATCH 5/7] station: use wiphy_check_{frequency,band} James Prestwood
@ 2022-12-13 20:36 ` James Prestwood
2022-12-13 20:36 ` [PATCH 7/7] wiphy: remove disabled_freqs and related dump code James Prestwood
5 siblings, 0 replies; 9+ messages in thread
From: James Prestwood @ 2022-12-13 20:36 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
Replace disabled/supported frequency list with the new
wiphy_check_* equivalent APIs.
---
src/ap.c | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/src/ap.c b/src/ap.c
index 32d9e1c4..ed20d763 100644
--- a/src/ap.c
+++ b/src/ap.c
@@ -3174,8 +3174,6 @@ static char **ap_ciphers_to_strv(uint16_t ciphers)
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)) {
@@ -3191,15 +3189,12 @@ static bool ap_validate_band_channel(struct ap_state *ap)
return false;
}
- supported = wiphy_get_supported_freqs(wiphy);
- disabled = wiphy_get_disabled_freqs(wiphy);
-
- if (!scan_freq_set_contains(supported, freq)) {
+ if (!wiphy_check_frequency(wiphy, freq, BAND_FREQ_ATTR_SUPPORTED)) {
l_error("AP hardware does not support frequency %u", freq);
return false;
}
- if (scan_freq_set_contains(disabled, freq)) {
+ if (wiphy_check_frequency(wiphy, freq, BAND_FREQ_ATTR_DISABLED)) {
l_error("AP hardware has frequency %u disabled", freq);
return false;
}
--
2.34.3
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 7/7] wiphy: remove disabled_freqs and related dump code
2022-12-13 20:36 [PATCH 1/7] band: introduce new method of tracking frequencies James Prestwood
` (4 preceding siblings ...)
2022-12-13 20:36 ` [PATCH 6/7] ap: " James Prestwood
@ 2022-12-13 20:36 ` James Prestwood
5 siblings, 0 replies; 9+ messages in thread
From: James Prestwood @ 2022-12-13 20:36 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
The disabled_freqs list is being removed and replaced with a new
list in the band object. This completely removes the need for
the pending_freqs list as well since any regdom related dumps
can just overwrite the existing frequency list.
---
src/wiphy.c | 38 ++------------------------------------
src/wiphy.h | 1 -
2 files changed, 2 insertions(+), 37 deletions(-)
diff --git a/src/wiphy.c b/src/wiphy.c
index f5b7c05e..79dd2dff 100644
--- a/src/wiphy.c
+++ b/src/wiphy.c
@@ -105,8 +105,6 @@ struct wiphy {
uint16_t supported_iftypes;
uint16_t supported_ciphers;
struct scan_freq_set *supported_freqs;
- struct scan_freq_set *disabled_freqs;
- struct scan_freq_set *pending_freqs;
struct band *band_2g;
struct band *band_5g;
struct band *band_6g;
@@ -345,7 +343,6 @@ static struct wiphy *wiphy_new(uint32_t id)
wiphy->id = id;
wiphy->supported_freqs = scan_freq_set_new();
- wiphy->disabled_freqs = scan_freq_set_new();
watchlist_init(&wiphy->state_watches, NULL);
wiphy->extended_capabilities[0] = IE_TYPE_EXTENDED_CAPABILITIES;
wiphy->extended_capabilities[1] = EXT_CAP_LEN;
@@ -393,7 +390,6 @@ static void wiphy_free(void *data)
}
scan_freq_set_free(wiphy->supported_freqs);
- scan_freq_set_free(wiphy->disabled_freqs);
watchlist_destroy(&wiphy->state_watches);
l_free(wiphy->model_str);
l_free(wiphy->vendor_str);
@@ -491,11 +487,6 @@ const struct scan_freq_set *wiphy_get_supported_freqs(
return wiphy->supported_freqs;
}
-const struct scan_freq_set *wiphy_get_disabled_freqs(const struct wiphy *wiphy)
-{
- return wiphy->disabled_freqs;
-}
-
static struct band *wiphy_get_band(const struct wiphy *wiphy, enum band_freq band)
{
switch (band) {
@@ -2051,9 +2042,6 @@ static void wiphy_dump_done(void *user_data)
if (wiphy) {
wiphy->dump_id = 0;
- scan_freq_set_free(wiphy->disabled_freqs);
- wiphy->disabled_freqs = wiphy->pending_freqs;
- wiphy->pending_freqs = NULL;
WATCHLIST_NOTIFY(&wiphy->state_watches,
wiphy_state_watch_func_t, wiphy,
@@ -2067,13 +2055,9 @@ static void wiphy_dump_done(void *user_data)
for (e = l_queue_get_entries(wiphy_list); e; e = e->next) {
wiphy = e->data;
- if (!wiphy->pending_freqs || wiphy->self_managed)
+ if (wiphy->self_managed)
continue;
- scan_freq_set_free(wiphy->disabled_freqs);
- wiphy->disabled_freqs = wiphy->pending_freqs;
- wiphy->pending_freqs = NULL;
-
WATCHLIST_NOTIFY(&wiphy->state_watches,
wiphy_state_watch_func_t, wiphy,
WIPHY_STATE_WATCH_EVENT_REGDOM_DONE);
@@ -2143,33 +2127,18 @@ static void wiphy_dump_callback(struct l_genl_msg *msg,
static bool wiphy_cancel_last_dump(struct wiphy *wiphy)
{
- const struct l_queue_entry *e;
unsigned int id = 0;
/*
* Zero command ID to signal that wiphy_dump_done doesn't need to do
- * anything. For a self-managed wiphy just free/NULL pending_freqs. For
- * a global dump each wiphy needs to be checked and dealt with.
+ * anything.
*/
if (wiphy && wiphy->dump_id) {
id = wiphy->dump_id;
wiphy->dump_id = 0;
-
- scan_freq_set_free(wiphy->pending_freqs);
- wiphy->pending_freqs = NULL;
} else if (!wiphy && wiphy_dump_id) {
id = wiphy_dump_id;
wiphy_dump_id = 0;
-
- for (e = l_queue_get_entries(wiphy_list); e; e = e->next) {
- struct wiphy *w = e->data;
-
- if (!w->pending_freqs || w->self_managed)
- continue;
-
- scan_freq_set_free(w->pending_freqs);
- w->pending_freqs = NULL;
- }
}
if (id) {
@@ -2214,7 +2183,6 @@ static void wiphy_dump_after_regdom(struct wiphy *wiphy)
/* Limited dump so just emit the event for this wiphy */
if (wiphy) {
wiphy->dump_id = id;
- wiphy->pending_freqs = scan_freq_set_new();
if (no_start_event)
return;
@@ -2234,8 +2202,6 @@ static void wiphy_dump_after_regdom(struct wiphy *wiphy)
if (w->self_managed)
continue;
- w->pending_freqs = scan_freq_set_new();
-
if (no_start_event)
continue;
diff --git a/src/wiphy.h b/src/wiphy.h
index 469ccdc8..09ddca65 100644
--- a/src/wiphy.h
+++ b/src/wiphy.h
@@ -99,7 +99,6 @@ const char *wiphy_get_path(struct wiphy *wiphy);
uint32_t wiphy_get_supported_bands(struct wiphy *wiphy);
const struct scan_freq_set *wiphy_get_supported_freqs(
const struct wiphy *wiphy);
-const struct scan_freq_set *wiphy_get_disabled_freqs(const struct wiphy *wiphy);
bool wiphy_check_frequency(const struct wiphy *wiphy, uint32_t freq,
uint16_t flags);
bool wiphy_check_band(const struct wiphy *wiphy, enum band_freq band,
--
2.34.3
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 2/7] util: add scan_freq_set_remove
2022-12-13 20:36 ` [PATCH 2/7] util: add scan_freq_set_remove James Prestwood
@ 2022-12-14 21:37 ` Denis Kenzior
0 siblings, 0 replies; 9+ messages in thread
From: Denis Kenzior @ 2022-12-14 21:37 UTC (permalink / raw)
To: James Prestwood, iwd
Hi James,
On 12/13/22 14:36, James Prestwood wrote:
> Removes one frequency from a scan_freq_set object.
> ---
> src/util.c | 22 ++++++++++++++++++++++
> src/util.h | 1 +
> 2 files changed, 23 insertions(+)
>
Applied, thanks.
Regards,
-Denis
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 3/7] wiphy: parse/store frequency info in band object
2022-12-13 20:36 ` [PATCH 3/7] wiphy: parse/store frequency info in band object James Prestwood
@ 2022-12-14 22:11 ` Denis Kenzior
0 siblings, 0 replies; 9+ messages in thread
From: Denis Kenzior @ 2022-12-14 22:11 UTC (permalink / raw)
To: James Prestwood, iwd
Hi James,
On 12/13/22 14:36, James Prestwood wrote:
> As additional frequency info is needed it doesn't make sense to
> store a full list of frequencies for every attribute (i.e.
> supported, disabled, no-IR, etc).
>
> This changes nl80211_parse_supported_frequencies to take a uint16_t
> array where each index corresponds to a channel, and each value
> can be filled with flag bits to signal any limitations on that
> frequency.
>
> wiphy.c then had to be updated to use this rather than the existing
> scan_freq_set lists. This, as-is, will break anything using
> wiphy_get_disabled_freqs().
> ---
> src/nl80211util.c | 19 +++++----
> src/nl80211util.h | 3 +-
> src/wiphy.c | 105 ++++++++++++++++++++++++++++++++++++++++++----
> 3 files changed, 109 insertions(+), 18 deletions(-)
>
> diff --git a/src/nl80211util.c b/src/nl80211util.c
> index da36d936..a2cd882d 100644
> --- a/src/nl80211util.c
> +++ b/src/nl80211util.c
> @@ -501,20 +501,20 @@ int nl80211_parse_chandef(struct l_genl_msg *msg, struct band_chandef *out)
> }
>
> int nl80211_parse_supported_frequencies(struct l_genl_attr *band_freqs,
> - struct scan_freq_set *supported_list,
> - struct scan_freq_set *disabled_list)
> + uint16_t *list, size_t num_channels)
Hmm, I wonder if you can simply build the supported_list at this time as well?
> {
> uint16_t type, len;
> const void *data;
> struct l_genl_attr attr;
> struct l_genl_attr nested;
> + uint8_t channel;
>
> if (!l_genl_attr_recurse(band_freqs, &nested))
> return -EBADMSG;
>
> while (l_genl_attr_next(&nested, NULL, NULL, NULL)) {
> uint32_t freq = 0;
> - bool disabled = false;
> + uint16_t flags = BAND_FREQ_ATTR_SUPPORTED;
That way you could probably not even need this flag. Also I would use a packed
bitfield struct for this instead of uint16_t.
>
> if (!l_genl_attr_recurse(&nested, &attr))
> continue;
> @@ -525,7 +525,10 @@ int nl80211_parse_supported_frequencies(struct l_genl_attr *band_freqs,
> freq = *((uint32_t *) data);
> break;
> case NL80211_FREQUENCY_ATTR_DISABLED:
> - disabled = true;
> + flags |= BAND_FREQ_ATTR_DISABLED;
> + break;
> + case NL80211_FREQUENCY_ATTR_NO_IR:
> + flags |= BAND_FREQ_ATTR_NO_IR;
> break;
> }
> }
> @@ -533,11 +536,11 @@ int nl80211_parse_supported_frequencies(struct l_genl_attr *band_freqs,
> if (!freq)
> continue;
>
> - if (supported_list)
> - scan_freq_set_add(supported_list, freq);
> + channel = band_freq_to_channel(freq, NULL);
> + if (!channel || channel > num_channels)
> + continue;
Hmm, this probably deserves a WARN_ON then.
>
> - if (disabled && disabled_list)
> - scan_freq_set_add(disabled_list, freq);
> + list[channel] = flags;
> }
>
> return 0;
<snip>
> @@ -952,7 +977,7 @@ int wiphy_estimate_data_rate(struct wiphy *wiphy,
>
> bool wiphy_regdom_is_updating(struct wiphy *wiphy)
> {
> - return wiphy->pending_freqs != NULL;
> + return wiphy->dump_id || (!wiphy->self_managed && wiphy_dump_id);
> }
>
Maybe this belongs in a separate patch?
> @@ -1980,7 +2011,28 @@ static void wiphy_dump_callback(struct l_genl_msg *msg,
> if (L_WARN_ON(!wiphy))
> return;
>
> - while (l_genl_attr_next(&bands, NULL, NULL, NULL)) {
> + /* Unregistered means the wiphy is blacklisted, don't bother parsing */
> + if (!wiphy->registered)
> + return;
Probably should be a separate commit as well.
> +
> + while (l_genl_attr_next(&bands, &type, NULL, NULL)) {
> + switch (type) {
> + case NL80211_BAND_2GHZ:
> + band = wiphy->band_2g;
> + break;
> + case NL80211_BAND_5GHZ:
> + band = wiphy->band_5g;
> + break;
> + case NL80211_BAND_6GHZ:
> + band = wiphy->band_6g;
> + break;
> + default:
> + continue;
> + }
> +
> + if (L_WARN_ON(!band))
> + continue;
> +
> if (!l_genl_attr_recurse(&bands, &attr))
> return;
>
> @@ -1988,8 +2040,14 @@ static void wiphy_dump_callback(struct l_genl_msg *msg,
> if (type != NL80211_BAND_ATTR_FREQS)
> continue;
>
> - nl80211_parse_supported_frequencies(&attr, NULL,
> - wiphy->pending_freqs);
> + /*
> + * Just write over the old list for each frequency. In
> + * theory no new frequencies should be added so there
> + * should never be any stale values.
> + */
> + nl80211_parse_supported_frequencies(&attr,
> + band->frequencies,
> + band->freqs_len);
> }
> }
> }
> @@ -2178,6 +2236,36 @@ static void wiphy_get_reg_domain(struct wiphy *wiphy)
> }
> }
>
> +static void setup_supported_freqs(struct wiphy *wiphy)
> +{
> + struct band *bands[3] = { wiphy->band_2g,
> + wiphy->band_5g, wiphy->band_6g };
> + unsigned int b;
> + unsigned int i;
> +
> + wiphy->supported_freqs = scan_freq_set_new();
> +
> + for (b = 0; b < L_ARRAY_SIZE(bands); b++) {
> + struct band *band = bands[b];
> +
> + if (!band)
> + continue;
> +
> + for (i = 0; i < band->freqs_len; i++) {
> + uint32_t freq;
> +
> + if (!(band->frequencies[i] & BAND_FREQ_ATTR_SUPPORTED))
> + continue;
> +
> + freq = band_channel_to_freq(i, band->freq);
> + if (!freq)
> + continue;
> +
> + scan_freq_set_add(wiphy->supported_freqs, freq);
> + }
> + }
If you mark the supported frequencies during
nl80211_parse_supported_frequencies(), then this wouldn't be needed, right?
> +}
> +
> void wiphy_create_complete(struct wiphy *wiphy)
> {
> wiphy_register(wiphy);
> @@ -2193,6 +2281,7 @@ void wiphy_create_complete(struct wiphy *wiphy)
> wiphy_set_station_capability_bits(wiphy);
> wiphy_setup_rm_enabled_capabilities(wiphy);
> wiphy_get_reg_domain(wiphy);
> + setup_supported_freqs(wiphy);
Or this
>
> wiphy_print_basic_info(wiphy);
> }
Regards,
-Denis
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2022-12-14 22:18 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-12-13 20:36 [PATCH 1/7] band: introduce new method of tracking frequencies James Prestwood
2022-12-13 20:36 ` [PATCH 2/7] util: add scan_freq_set_remove James Prestwood
2022-12-14 21:37 ` Denis Kenzior
2022-12-13 20:36 ` [PATCH 3/7] wiphy: parse/store frequency info in band object James Prestwood
2022-12-14 22:11 ` Denis Kenzior
2022-12-13 20:36 ` [PATCH 4/7] wiphy: add wiphy_check_{frequency,band} James Prestwood
2022-12-13 20:36 ` [PATCH 5/7] station: use wiphy_check_{frequency,band} James Prestwood
2022-12-13 20:36 ` [PATCH 6/7] ap: " James Prestwood
2022-12-13 20:36 ` [PATCH 7/7] wiphy: remove disabled_freqs and related dump code James Prestwood
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.