2022-08-30 02:21:26

by Kieran Frewen

[permalink] [raw]
Subject: [PATCH v2 00/12] Additional Support for 802.11ah (S1G)

This patchset builds on the work down by Thomas Pedersen to add further
support for 802.11ah in cfg80211 and mac80211. The ultimate goal is
to enable the successful starting of an AP on 802.11ah using 802.11ah
terms by implementing the various features that are required by the
AP. The features are split into their own commits, please see those
patches for more details.
The patchset has been tested on both real hardware (Morse Micro MM610x)
and mac80211_hwsim, in AP and STA modes. Basic regression testing was
performed on 802.11n with mac80211_hwsim by starting an AP and having a
STA interface connect to it.
802.11ah features/support missing:

Rate control integration
Regulatory database updates (only US regulatory information exists)
Optional 802.11ah (S1G) features such as RAW, TWT and AID grouping

Changelog
v2:

[PATCH 01/12]
Added validation to assignment of s1g_oper_class and class_idx.
Changed align_to_end from u8 to bool.
Added clarification of usage requirements for country code in
s1g_oper_class struct.
Changed cc field in s1g_oper_class struct from char * to cc[3].
Moved initialised structs and arrays and from reg_s1g.h to reg_s1g.c.
Moved reg_s1g_get_oper_class from reg_s1g.h to reg_s1g.c
reg_s1g_get_oper_class now defaults to NULL if no natching
s1g_oper_class is found.
[PATCH 04/12]
NL80211_ATTR_SHORT_BEACON_PERIOD changed to NLA_U16.
[PATCH 07/12]
Implemented ieee80211_ie_build_s1g_cap fuction to build S1G
capability IE in place. Mimicing behaviour of
ieee80211_ie_build_ht_cap.
[PATCH 08/12]
Capatilisation of MCS in description of RATE_INFO_FLAGS_S1G_MCS.
Re-ordered grouping of fields in rate_info struct to order by size.
[PATCH 09/12]
Capatilisation of MCS in field naming of NL80211_RATE_INFO_S1G_MSS.
Reordering of info->bw cases in switch to numberical order.

Kieran Frewen (12):
cfg80211: regulatory: extend regulatory support for S1G
mac80211: update TIM for S1G specification changes
mac80211: S1G beacon/short beacon support
nl80211: support setting S1G short beacon period
nl80211: support advertising S1G capabilities
mac80211: support ieee80211_ext format
mac80211: S1G capabilities information element in probe request
cfg80211: S1G rate flags
nl80211: support advertising S1G rate information
mac80211: support S1G rate encoding.
cfg80211: support for calculating S1G bitrates
mac80211_hwsim: support for S1G rate information

drivers/net/wireless/mac80211_hwsim.c | 40 +++--
include/net/cfg80211.h | 18 +-
include/net/mac80211.h | 33 +++-
include/uapi/linux/nl80211.h | 28 ++++
net/mac80211/cfg.c | 43 +++--
net/mac80211/ieee80211_i.h | 2 +
net/mac80211/rx.c | 32 +++-
net/mac80211/sta_info.c | 7 +
net/mac80211/sta_info.h | 7 +
net/mac80211/tx.c | 27 ++-
net/mac80211/util.c | 51 +++++-
net/wireless/Makefile | 2 +-
net/wireless/nl80211.c | 37 ++++
net/wireless/reg.c | 60 +++++--
net/wireless/reg_s1g.c | 232 ++++++++++++++++++++++++++
net/wireless/reg_s1g.h | 55 ++++++
net/wireless/util.c | 148 +++++++++++++++-
17 files changed, 767 insertions(+), 55 deletions(-)
create mode 100755 net/wireless/reg_s1g.c
create mode 100644 net/wireless/reg_s1g.h

--
2.25.1


2022-08-30 02:21:26

by Kieran Frewen

[permalink] [raw]
Subject: [PATCH v2 01/12] cfg80211: regulatory: extend regulatory support for S1G

Extend the S1G regulatory information to support all regulatory
domains. An reg_s1g.h file is included containing structs with key
regulatory class information. These structs were required to ensure
the right combination of information was available to a series of
functions which support the mapping between frequencies, bandwidths,
and channels.

Signed-off-by: Kieran Frewen <[email protected]>
---
net/wireless/Makefile | 2 +-
net/wireless/reg.c | 60 ++++++++---
net/wireless/reg_s1g.c | 232 +++++++++++++++++++++++++++++++++++++++++
net/wireless/reg_s1g.h | 55 ++++++++++
net/wireless/util.c | 35 ++++++-
5 files changed, 370 insertions(+), 14 deletions(-)
create mode 100755 net/wireless/reg_s1g.c
create mode 100644 net/wireless/reg_s1g.h

diff --git a/net/wireless/Makefile b/net/wireless/Makefile
index 527ae669f6f7..10cc0db5a935 100644
--- a/net/wireless/Makefile
+++ b/net/wireless/Makefile
@@ -10,7 +10,7 @@ obj-$(CONFIG_WEXT_PROC) += wext-proc.o
obj-$(CONFIG_WEXT_SPY) += wext-spy.o
obj-$(CONFIG_WEXT_PRIV) += wext-priv.o

-cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o
+cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o reg_s1g.o scan.o nl80211.o
cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o mesh.o ap.o trace.o ocb.o
cfg80211-y += pmsr.o
cfg80211-$(CONFIG_OF) += of.o
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index c7383ede794f..de68e356927d 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -62,6 +62,7 @@
#include "reg.h"
#include "rdev-ops.h"
#include "nl80211.h"
+#include "reg_s1g.h"

/*
* Grace period we give before making sure all current interfaces reside on
@@ -1737,26 +1738,54 @@ static uint32_t reg_rule_to_chan_bw_flags(const struct ieee80211_regdomain *regd
* the largest bandwidth which cleanly divides the freq_range.
*/
int edge_offset;
- int ch_bw = max_bandwidth_khz;
+ int ch_bw, freq_end, freq_start, class_idx = -1;
+ unsigned int i;
+ const struct s1g_oper_class *oper = reg_s1g_get_oper_class(regd->alpha2);
+
+ if (!oper) {
+ bw_flags |= IEEE80211_CHAN_DISABLED;
+ return bw_flags;
+ }
+
+ for (i = 0; i < oper->class_count; i++) {
+ if (center_freq_khz >= oper->class[i].start_freq &&
+ center_freq_khz <= oper->class[i].end_freq) {
+ class_idx = i;
+ break;
+ }
+ }
+
+ if (class_idx == -1) {
+ bw_flags |= IEEE80211_CHAN_DISABLED;
+ return bw_flags;
+ }
+
+ ch_bw = oper->class[class_idx].max_bw_khz;
+ freq_start = oper->class[class_idx].start_freq;
+ freq_end = oper->class[class_idx].end_freq;

while (ch_bw) {
- edge_offset = (center_freq_khz - ch_bw / 2) -
- freq_range->start_freq_khz;
- if (edge_offset % ch_bw == 0) {
- switch (KHZ_TO_MHZ(ch_bw)) {
- case 1:
+ if (oper->class[class_idx].align_to_end)
+ edge_offset = freq_end -
+ (center_freq_khz - (ch_bw) / 2);
+ else
+ edge_offset = (center_freq_khz - (ch_bw) / 2) -
+ freq_start;
+ if (edge_offset % (ch_bw) == 0) {
+ switch (ch_bw) {
+ case MHZ_TO_KHZ(1):
bw_flags |= IEEE80211_CHAN_1MHZ;
break;
- case 2:
+ case MHZ_TO_KHZ(2):
bw_flags |= IEEE80211_CHAN_2MHZ;
break;
- case 4:
+ case MHZ_TO_KHZ(4):
bw_flags |= IEEE80211_CHAN_4MHZ;
break;
- case 8:
+ case MHZ_TO_KHZ(8):
bw_flags |= IEEE80211_CHAN_8MHZ;
break;
- case 16:
+ case MHZ_TO_KHZ(16):
bw_flags |= IEEE80211_CHAN_16MHZ;
break;
default:
@@ -2555,9 +2584,16 @@ static void handle_channel_custom(struct wiphy *wiphy,
const struct ieee80211_reg_rule *reg_rule = NULL;
const struct ieee80211_power_rule *power_rule = NULL;
u32 bw, center_freq_khz;
+ bool is_s1g = chan->band == NL80211_BAND_S1GHZ;

- center_freq_khz = ieee80211_channel_to_khz(chan);
- for (bw = MHZ_TO_KHZ(20); bw >= min_bw; bw = bw / 2) {
+ if (is_s1g) {
+ bw = MHZ_TO_KHZ(16);
+ min_bw = MHZ_TO_KHZ(1);
+ } else {
+ bw = MHZ_TO_KHZ(20);
+ }
+
+ for (; bw >= min_bw; bw = bw / 2) {
reg_rule = freq_reg_info_regd(center_freq_khz, regd, bw);
if (!IS_ERR(reg_rule))
break;
diff --git a/net/wireless/reg_s1g.c b/net/wireless/reg_s1g.c
new file mode 100755
index 000000000000..8529c65dd6c8
--- /dev/null
+++ b/net/wireless/reg_s1g.c
@@ -0,0 +1,232 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include "reg_s1g.h"
+
+/* The following channel lists have been retrieved from
+ * IEEE Std 802.11-2020 Table E-5
+ */
+static const u8 us_supported_channels[] = {
+ 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51
+};
+
+static const u8 eu_supported_channels_863[] = {
+ 1, 3, 5, 7, 9
+};
+
+static const u8 eu_supported_channels_901_4[] = {
+ 33, 35
+};
+
+static const u8 jp_supported_channels[] = {
+ 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21
+};
+
+static const u8 kr_supported_channels[] = {
+ 1, 2, 3, 5, 6, 7, 8, 9, 10, 11
+};
+
+static const u8 sg_supported_channels_863[] = {
+ 7, 9, 10, 11
+};
+
+static const u8 sg_supported_channels_902[] = {
+ 37, 38, 39, 40, 41, 42, 43, 45
+};
+
+static const u8 au_nz_supported_channels[] = {
+ 27, 29, 30, 31, 32, 33, 34, 35, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51
+};
+
+
+/* The following s1g_oper_class structs are taken from
+ * IEEE Std 802.11-2020 Table E-5
+ */
+static const struct s1g_oper_class country_class_au = {
+ .cc = "AU",
+ .class_count = 2,
+ .class = {
+ {
+ .band_start = 902000,
+ .start_freq = 915000,
+ .end_freq = 920000,
+ .max_bw_khz = MHZ_TO_KHZ(4),
+ .align_to_end = false,
+ .supported_chan = au_nz_supported_channels,
+ .n_supported_chan = sizeof(au_nz_supported_channels),
+ },
+ {
+ .band_start = 902000,
+ .start_freq = 920000,
+ .end_freq = 928000,
+ .max_bw_khz = MHZ_TO_KHZ(8),
+ .align_to_end = true,
+ .supported_chan = NULL,
+ .n_supported_chan = 0,
+ }
+ },
+};
+
+static const struct s1g_oper_class country_class_nz = {
+ .cc = "NZ",
+ .class_count = 2,
+ .class = {
+ {
+ .band_start = 902000,
+ .start_freq = 915000,
+ .end_freq = 924000,
+ .max_bw_khz = MHZ_TO_KHZ(8),
+ .align_to_end = false,
+ .supported_chan = au_nz_supported_channels,
+ .n_supported_chan = sizeof(au_nz_supported_channels),
+ },
+ {
+ .band_start = 902000,
+ .start_freq = 924000,
+ .end_freq = 928000,
+ .max_bw_khz = MHZ_TO_KHZ(8),
+ .align_to_end = false,
+ .supported_chan = NULL,
+ .n_supported_chan = 0,
+ }
+ },
+};
+
+static const struct s1g_oper_class country_class_us = {
+ .cc = "US",
+ .class_count = 3,
+ .class = {
+ {
+ .band_start = 902000,
+ .start_freq = 902000,
+ .end_freq = 904000,
+ .max_bw_khz = MHZ_TO_KHZ(16),
+ .align_to_end = false,
+ .supported_chan = us_supported_channels,
+ .n_supported_chan = sizeof(us_supported_channels),
+ },
+ {
+ .band_start = 902000,
+ .start_freq = 920000,
+ .end_freq = 928000,
+ .max_bw_khz = MHZ_TO_KHZ(16),
+ .align_to_end = false,
+ .supported_chan = NULL,
+ .n_supported_chan = 0,
+ },
+ {
+ .band_start = 902000,
+ .start_freq = 904000,
+ .end_freq = 920000,
+ .max_bw_khz = MHZ_TO_KHZ(16),
+ .align_to_end = false,
+ .supported_chan = NULL,
+ .n_supported_chan = 0,
+ }
+ },
+};
+
+static const struct s1g_oper_class country_class_sg = {
+ .cc = "SG",
+ .class_count = 2,
+ .class = {
+ {
+ .band_start = 863000,
+ .start_freq = 866000,
+ .end_freq = 869000,
+ .max_bw_khz = MHZ_TO_KHZ(2),
+ .align_to_end = true,
+ .supported_chan = sg_supported_channels_863,
+ .n_supported_chan = sizeof(sg_supported_channels_863),
+ },
+ {
+ .band_start = 902000,
+ .start_freq = 920000,
+ .end_freq = 925000,
+ .max_bw_khz = MHZ_TO_KHZ(4),
+ .align_to_end = false,
+ .supported_chan = sg_supported_channels_902,
+ .n_supported_chan = sizeof(sg_supported_channels_902),
+ },
+ },
+};
+
+static const struct s1g_oper_class country_class_kr = {
+ .cc = "KR",
+ .class_count = 1,
+ .class = {
+ {
+ .band_start = 917500,
+ .start_freq = 917500,
+ .end_freq = 923500,
+ .max_bw_khz = MHZ_TO_KHZ(4),
+ .align_to_end = true,
+ .supported_chan = kr_supported_channels,
+ .n_supported_chan = sizeof(kr_supported_channels),
+ }
+ },
+};
+
+static const struct s1g_oper_class country_class_eu = {
+ .cc = "EU",
+ .class_count = 1,
+ .class = {
+ {
+ .band_start = 863000,
+ .start_freq = 863000,
+ .end_freq = 868000,
+ .max_bw_khz = MHZ_TO_KHZ(1),
+ .align_to_end = false,
+ .supported_chan = eu_supported_channels_863,
+ .n_supported_chan = sizeof(eu_supported_channels_863),
+ },
+ {
+ .band_start = 901400,
+ .start_freq = 917400,
+ .end_freq = 919400,
+ .max_bw_khz = MHZ_TO_KHZ(1),
+ .align_to_end = false,
+ .supported_chan = eu_supported_channels_901_4,
+ .n_supported_chan = sizeof(eu_supported_channels_901_4),
+ }
+ },
+};
+
+static const struct s1g_oper_class country_class_jp = {
+ .cc = "JP",
+ .class_count = 1,
+ .class = {
+ {
+ .band_start = 916500,
+ .start_freq = 916500,
+ .end_freq = 927500,
+ .max_bw_khz = MHZ_TO_KHZ(1),
+ .align_to_end = false,
+ .supported_chan = jp_supported_channels,
+ .n_supported_chan = sizeof(jp_supported_channels),
+ }
+ },
+};
+
+const struct s1g_oper_class *reg_s1g_get_oper_class(const char *cc)
+{
+ if (!strcmp(cc, "EU"))
+ return &country_class_eu;
+ if (!strcmp(cc, "SG"))
+ return &country_class_sg;
+ if (!strcmp(cc, "US"))
+ return &country_class_us;
+ if (!strcmp(cc, "AU"))
+ return &country_class_au;
+ if (!strcmp(cc, "KR"))
+ return &country_class_kr;
+ if (!strcmp(cc, "JP"))
+ return &country_class_jp;
+ if (!strcmp(cc, "NZ"))
+ return &country_class_nz;
+ return NULL;
+}
diff --git a/net/wireless/reg_s1g.h b/net/wireless/reg_s1g.h
new file mode 100644
index 000000000000..3d7b1f810ed8
--- /dev/null
+++ b/net/wireless/reg_s1g.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __NET_WIRELESS_REG_S1G_H
+#define __NET_WIRELESS_REG_S1G_H
+
+#include "reg.h"
+
+/**
+ * Struct cca_class
+ *
+ * The specifics of a cca level classification used to validate bw/frequency
+ * combinations in a regulatory domain
+ * @band_start: The channel starting frequency (kHz) for that CCA classification
+ * @start_freq: The start of the valid frequency (kHz) range for the CCA
+ * classification
+ * @end_freq: The end of the valid frequency (kHz) range for the CCA
+ * classification
+ * @max_bw_khz: The maximum valid bandwidth for the CCA classification
+ * @align_to_end: True if the maximum valid bandwidth for the range is aligned
+ * to the end_freq
+ * @supported_chan: A list of supported channel indexes
+ * @n_supported_chan: A count of the supported channels for this CCA
+ * classification
+ */
+struct s1g_cca_classification {
+ u32 band_start;
+ u32 start_freq;
+ u32 end_freq;
+ u32 max_bw_khz;
+ bool align_to_end;
+ const u8 *supported_chan;
+ u8 n_supported_chan;
+};
+
+
+/**
+
+ * Struct s1g_oper_class
+ *
+ * An aggregated view of the operating classes for a single regulatory
+ * domain
+ * @cc: country code (2-character code)
+ * @class_count: The number of CCA level classifications that exist
+ * within that country
+ * @class: The specifics of a CCA level classification within a regulatory
+ * domain.
+ */
+struct s1g_oper_class {
+ char cc[3];
+ int class_count;
+ struct s1g_cca_classification class[];
+};
+
+const struct s1g_oper_class *reg_s1g_get_oper_class(const char *cc);
+
+#endif /*__NET_WIRELESS_REG_S1G_H */
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 2c127951764a..aeccb6ce595c 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -22,6 +22,7 @@
#include <linux/nospec.h>
#include "core.h"
#include "rdev-ops.h"
+#include "reg_s1g.h"


const struct ieee80211_rate *
@@ -72,6 +73,27 @@ u32 ieee80211_mandatory_rates(struct ieee80211_supported_band *sband,
}
EXPORT_SYMBOL(ieee80211_mandatory_rates);

+static u32 ieee80211_s1g_base_freq(int chan)
+{
+ const struct ieee80211_regdomain *regd = rtnl_dereference(cfg80211_regdomain);
+ const struct s1g_oper_class *oper = reg_s1g_get_oper_class(regd->alpha2);
+ u8 i, j, index = 0;
+
+ if (!oper)
+ return 0;
+
+ if (oper->class_count > 1)
+ for (i = 0; i < oper->class_count; i++)
+ for (j = 0; j < oper->class[i].n_supported_chan; j++)
+ if (oper->class[i].supported_chan[j] == chan) {
+ index = i;
+ goto out;
+ }
+ return 0; /* not supported */
+out:
+ return oper->class[index].band_start;
+}
+
u32 ieee80211_channel_to_freq_khz(int chan, enum nl80211_band band)
{
/* see 802.11 17.3.8.3.2 and Annex J
@@ -104,7 +126,7 @@ u32 ieee80211_channel_to_freq_khz(int chan, enum nl80211_band band)
return MHZ_TO_KHZ(56160 + chan * 2160);
break;
case NL80211_BAND_S1GHZ:
- return 902000 + chan * 500;
+ return ieee80211_s1g_base_freq(chan) + chan * 500;
default:
;
}
@@ -112,6 +134,17 @@ u32 ieee80211_channel_to_freq_khz(int chan, enum nl80211_band band)
}
EXPORT_SYMBOL(ieee80211_channel_to_freq_khz);

+u32 ieee80211_s1g_channel_to_freq_khz(int chan)
+{
+ u32 base = ieee80211_s1g_base_freq(chan);
+
+ if (!base)
+ return 0;
+
+ return (base + chan * 500);
+}
+EXPORT_SYMBOL(ieee80211_s1g_channel_to_freq_khz);
+
enum nl80211_chan_width
ieee80211_s1g_channel_width(const struct ieee80211_channel *chan)
{
--
2.25.1

2022-08-30 02:21:27

by Kieran Frewen

[permalink] [raw]
Subject: [PATCH v2 02/12] mac80211: update TIM for S1G specification changes

Updates to the TIM information element to match changes made in the
IEEE Std 802.11ah-2020.

Signed-off-by: Kieran Frewen <[email protected]>
---
net/mac80211/tx.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 45df9932d0ba..bf85a01fcf9d 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -4749,9 +4749,9 @@ static void __ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata,
ps->dtim_count--;
}

- tim = pos = skb_put(skb, 6);
+ tim = pos = skb_put(skb, 5);
*pos++ = WLAN_EID_TIM;
- *pos++ = 4;
+ *pos++ = 3;
*pos++ = ps->dtim_count;
*pos++ = link_conf->dtim_period;

@@ -4782,13 +4782,18 @@ static void __ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata,
/* Bitmap control */
*pos++ = n1 | aid0;
/* Part Virt Bitmap */
- skb_put(skb, n2 - n1);
+ skb_put(skb, n2 - n1 + 1);
memcpy(pos, ps->tim + n1, n2 - n1 + 1);

tim[1] = n2 - n1 + 4;
} else {
*pos++ = aid0; /* Bitmap control */
- *pos++ = 0; /* Part Virt Bitmap */
+
+ if (ieee80211_get_sband(sdata)->band != NL80211_BAND_S1GHZ) {
+ skb_put(skb, 1);
+ tim[1] = 4;
+ *pos++ = 0; /* Part Virt Bitmap */
+ }
}
}

--
2.25.1

2022-08-30 02:21:33

by Kieran Frewen

[permalink] [raw]
Subject: [PATCH v2 04/12] nl80211: support setting S1G short beacon period

With the kernel able to send both short and long S1G beacons, include
the ability for setting the short beacon period.

Signed-off-by: Kieran Frewen <[email protected]>
---
include/uapi/linux/nl80211.h | 7 +++++++
net/wireless/nl80211.c | 4 ++++
2 files changed, 11 insertions(+)

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index ffb7c573e299..7daa2ce1cb57 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2741,6 +2741,9 @@ enum nl80211_commands {
* When used with %NL80211_CMD_FRAME_TX_STATUS, indicates the ack RX
* timestamp. When used with %NL80211_CMD_FRAME RX notification, indicates
* the incoming frame RX timestamp.
+ *
+ * @NL80211_ATTR_SHORT_BEACON_PERIOD: S1G short beacon period in TUs.
+ *
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3269,6 +3272,8 @@ enum nl80211_attrs {
NL80211_ATTR_TX_HW_TIMESTAMP,
NL80211_ATTR_RX_HW_TIMESTAMP,

+ NL80211_ATTR_SHORT_BEACON_PERIOD,
+
/* add attributes here, update the policy in nl80211.c */

__NL80211_ATTR_AFTER_LAST,
@@ -4951,6 +4956,7 @@ enum nl80211_bss_scan_width {
* using the nesting index as the antenna number.
* @NL80211_BSS_FREQUENCY_OFFSET: frequency offset in KHz
* @NL80211_BSS_MLO_LINK_ID: MLO link ID of the BSS (u8).
+ * @NL80211_BSS_SHORT_BEACON_PERIOD: S1G short beacon period in TUs
* @__NL80211_BSS_AFTER_LAST: internal
* @NL80211_BSS_MAX: highest BSS attribute
*/
@@ -4977,6 +4983,7 @@ enum nl80211_bss {
NL80211_BSS_CHAIN_SIGNAL,
NL80211_BSS_FREQUENCY_OFFSET,
NL80211_BSS_MLO_LINK_ID,
+ NL80211_BSS_SHORT_BEACON_PERIOD,

/* keep last */
__NL80211_BSS_AFTER_LAST,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 2705e3ee8fc4..5e9aaa8c0d7d 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -805,6 +805,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_MLD_ADDR] = NLA_POLICY_EXACT_LEN(ETH_ALEN),
[NL80211_ATTR_MLO_SUPPORT] = { .type = NLA_FLAG },
[NL80211_ATTR_MAX_NUM_AKM_SUITES] = { .type = NLA_REJECT },
+ [NL80211_ATTR_SHORT_BEACON_PERIOD] = { .type = NLA_U16 },
};

/* policy for the key attributes */
@@ -5711,6 +5712,9 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
params->dtim_period =
nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
+ if (info->attrs[NL80211_ATTR_SHORT_BEACON_PERIOD])
+ params->short_beacon_period =
+ nla_get_u32(info->attrs[NL80211_ATTR_SHORT_BEACON_PERIOD]);

err = cfg80211_validate_beacon_int(rdev, dev->ieee80211_ptr->iftype,
params->beacon_interval);
--
2.25.1

2022-08-30 02:21:47

by Kieran Frewen

[permalink] [raw]
Subject: [PATCH v2 07/12] mac80211: S1G capabilities information element in probe request

Add the missing S1G capabilities information element to probe requests.

Signed-off-by: Kieran Frewen <[email protected]>
---
net/mac80211/ieee80211_i.h | 1 +
net/mac80211/util.c | 21 +++++++++++++++++++++
2 files changed, 22 insertions(+)

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index cd8879998739..e8ff4af9fc03 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -2400,6 +2400,7 @@ void ieee80211_add_s1g_capab_ie(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb);
void ieee80211_add_aid_request_ie(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb);
+u8 *ieee80211_ie_build_s1g_cap(u8 *pos, struct ieee80211_sta_s1g_cap *s1g_cap);

/* channel management */
bool ieee80211_chandef_ht_oper(const struct ieee80211_ht_operation *ht_oper,
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 53826c663723..78e8c286011e 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1857,6 +1857,12 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_sub_if_data *sdata,
rate_flags = ieee80211_chandef_rate_flags(chandef);
shift = ieee80211_chandef_get_shift(chandef);

+ /* For direct mac80211 scan (probe request), add S1G IE and consider its override bits */
+ if (band == NL80211_BAND_S1GHZ) {
+ pos = ieee80211_ie_build_s1g_cap(pos, &sband->s1g_cap);
+ goto done;
+ }
+
num_rates = 0;
for (i = 0; i < sband->n_bitrates; i++) {
if ((BIT(i) & rate_mask) == 0)
@@ -2919,6 +2925,21 @@ size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset)
return pos;
}

+u8 *ieee80211_ie_build_s1g_cap(u8 *pos, struct ieee80211_sta_s1g_cap *s1g_cap)
+{
+ *pos++ = WLAN_EID_S1G_CAPABILITIES;
+ *pos++ = sizeof(struct ieee80211_s1g_cap);
+ memset(pos, 0, sizeof(struct ieee80211_s1g_cap));
+
+ memcpy(pos, &s1g_cap->cap, sizeof(s1g_cap->cap));
+ pos += sizeof(s1g_cap->cap);
+
+ memcpy(pos, &s1g_cap->nss_mcs, sizeof(s1g_cap->nss_mcs));
+ pos += sizeof(s1g_cap->nss_mcs);
+
+ return pos;
+}
+
u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
u16 cap)
{
--
2.25.1

2022-08-30 02:21:49

by Kieran Frewen

[permalink] [raw]
Subject: [PATCH v2 08/12] cfg80211: S1G rate flags

Increase the size of S1G rate_info flags to support S1G. Add flags for new
S1G bandwidths and S1G MCS.

Signed-off-by: Kieran Frewen <[email protected]>
---
include/net/cfg80211.h | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index f462dcdd023a..cdd43ba9c62e 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1660,6 +1660,7 @@ int cfg80211_check_station_change(struct wiphy *wiphy,
* @RATE_INFO_FLAGS_EDMG: 60GHz MCS in EDMG mode
* @RATE_INFO_FLAGS_EXTENDED_SC_DMG: 60GHz extended SC MCS
* @RATE_INFO_FLAGS_EHT_MCS: EHT MCS information
+ * @RATE_INFO_FLAGS_S1G_MCS: MCS field filled with S1G MCS
*/
enum rate_info_flags {
RATE_INFO_FLAGS_MCS = BIT(0),
@@ -1670,6 +1671,7 @@ enum rate_info_flags {
RATE_INFO_FLAGS_EDMG = BIT(5),
RATE_INFO_FLAGS_EXTENDED_SC_DMG = BIT(6),
RATE_INFO_FLAGS_EHT_MCS = BIT(7),
+ RATE_INFO_FLAGS_S1G_MCS = BIT(8),
};

/**
@@ -1686,6 +1688,11 @@ enum rate_info_flags {
* @RATE_INFO_BW_HE_RU: bandwidth determined by HE RU allocation
* @RATE_INFO_BW_320: 320 MHz bandwidth
* @RATE_INFO_BW_EHT_RU: bandwidth determined by EHT RU allocation
+ * @RATE_INFO_BW_1: 1 MHz bandwidth
+ * @RATE_INFO_BW_2: 2 MHz bandwidth
+ * @RATE_INFO_BW_4: 4 MHz bandwidth
+ * @RATE_INFO_BW_8: 8 MHz bandwidth
+ * @RATE_INFO_BW_16: 16 MHz bandwidth
*/
enum rate_info_bw {
RATE_INFO_BW_20 = 0,
@@ -1697,6 +1704,11 @@ enum rate_info_bw {
RATE_INFO_BW_HE_RU,
RATE_INFO_BW_320,
RATE_INFO_BW_EHT_RU,
+ RATE_INFO_BW_1,
+ RATE_INFO_BW_2,
+ RATE_INFO_BW_4,
+ RATE_INFO_BW_8,
+ RATE_INFO_BW_16,
};

/**
@@ -1719,9 +1731,9 @@ enum rate_info_bw {
* only valid if bw is %RATE_INFO_BW_EHT_RU)
*/
struct rate_info {
- u8 flags;
- u8 mcs;
+ u16 flags;
u16 legacy;
+ u8 mcs;
u8 nss;
u8 bw;
u8 he_gi;
--
2.25.1

2022-08-30 02:21:58

by Kieran Frewen

[permalink] [raw]
Subject: [PATCH v2 03/12] mac80211: S1G beacon/short beacon support

If configured, use the S1G short beacon format. The S1G short beacon
format includes a limited set of information elements.

Signed-off-by: Kieran Frewen <[email protected]>
---
include/net/cfg80211.h | 2 +-
include/net/mac80211.h | 1 +
net/mac80211/cfg.c | 1 +
net/mac80211/ieee80211_i.h | 1 +
net/mac80211/tx.c | 14 +++++++++++++-
5 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 908d58393484..f462dcdd023a 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1328,7 +1328,7 @@ struct cfg80211_ap_settings {

struct cfg80211_beacon_data beacon;

- int beacon_interval, dtim_period;
+ int beacon_interval, dtim_period, short_beacon_period;
const u8 *ssid;
size_t ssid_len;
enum nl80211_hidden_ssid hidden_ssid;
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index f198af600b5e..359edfa9ec1c 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -672,6 +672,7 @@ struct ieee80211_bss_conf {
bool enable_beacon;
u8 dtim_period;
u16 beacon_int;
+ u8 short_beacon_period;
u16 assoc_capability;
u64 sync_tsf;
u32 sync_device_ts;
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index a4f6971b7a19..03ed90ce9a84 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1236,6 +1236,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
}

link_conf->dtim_period = params->dtim_period;
+ link_conf->short_beacon_period = params->short_beacon_period;
link_conf->enable_beacon = true;
link_conf->allow_p2p_go_ps = sdata->vif.p2p;
link_conf->twt_responder = params->twt_responder;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index e192e1ec0261..cd8879998739 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -267,6 +267,7 @@ struct beacon_data {
struct ieee80211_meshconf_ie *meshconf;
u16 cntdwn_counter_offsets[IEEE80211_MAX_CNTDWN_COUNTERS_NUM];
u8 cntdwn_current_counter;
+ u8 long_beacon_count;
struct cfg80211_mbssid_elems *mbssid_ies;
struct rcu_head rcu_head;
};
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index bf85a01fcf9d..48c737aeb3f7 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -5099,6 +5099,18 @@ ieee80211_beacon_get_ap(struct ieee80211_hw *hw,
struct sk_buff *skb = NULL;
u16 csa_off_base = 0;
int mbssid_len;
+ bool is_short = false;
+
+ if (vif->cfg.s1g) {
+ if (beacon->long_beacon_count == 0) {
+ is_short = false;
+ beacon->long_beacon_count =
+ vif->bss_conf.short_beacon_period - 1;
+ } else {
+ is_short = true;
+ beacon->long_beacon_count--;
+ }
+ }

if (beacon->cntdwn_counter_offsets[0]) {
if (!is_template)
@@ -5136,7 +5148,7 @@ ieee80211_beacon_get_ap(struct ieee80211_hw *hw,
csa_off_base = skb->len;
}

- if (beacon->tail)
+ if (beacon->tail && !is_short)
skb_put_data(skb, beacon->tail, beacon->tail_len);

if (ieee80211_beacon_protect(skb, local, sdata, link) < 0)
--
2.25.1

2022-08-30 02:22:09

by Kieran Frewen

[permalink] [raw]
Subject: [PATCH v2 06/12] mac80211: support ieee80211_ext format

Ensure S1G beacons use the new ieee80211_ext format when required.

Signed-off-by: Kieran Frewen <[email protected]>
---
net/mac80211/rx.c | 24 ++++++++++++++++++------
1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 57df21e2170a..d46eeebedb4b 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -4895,6 +4895,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
struct ieee80211_local *local = hw_to_local(hw);
struct ieee80211_sub_if_data *sdata;
struct ieee80211_hdr *hdr;
+ struct ieee80211_ext *ext_hdr;
__le16 fc;
struct ieee80211_rx_data rx;
struct ieee80211_sub_if_data *prev;
@@ -4911,7 +4912,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc))
I802_DEBUG_INC(local->dot11ReceivedFragmentCount);

- if (ieee80211_is_mgmt(fc)) {
+ if (ieee80211_is_mgmt(fc) || ieee80211_is_s1g_beacon(fc)) {
/* drop frame if too short for header */
if (skb->len < ieee80211_hdrlen(fc))
err = -ENOBUFS;
@@ -4926,13 +4927,17 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
return;
}

- hdr = (struct ieee80211_hdr *)skb->data;
+ if (ieee80211_is_s1g_beacon(fc))
+ ext_hdr = (struct ieee80211_ext *)skb->data;
+ else
+ hdr = (struct ieee80211_hdr *)skb->data;
+
ieee80211_parse_qos(&rx);
ieee80211_verify_alignment(&rx);

- if (unlikely(ieee80211_is_probe_resp(hdr->frame_control) ||
- ieee80211_is_beacon(hdr->frame_control) ||
- ieee80211_is_s1g_beacon(hdr->frame_control)))
+ if (unlikely(ieee80211_is_probe_resp(fc) ||
+ ieee80211_is_beacon(fc) ||
+ ieee80211_is_s1g_beacon(fc)))
ieee80211_scan_rx(local, skb);

if (ieee80211_is_data(fc)) {
@@ -4991,7 +4996,10 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
prev = sdata;
continue;
}
-
+ if (ieee80211_is_s1g_beacon(fc))
+ rx.sta = sta_info_get_bss(prev, ext_hdr->u.s1g_beacon.sa);
+ else
+ rx.sta = sta_info_get_bss(prev, hdr->addr2);
rx.sdata = prev;
ieee80211_rx_for_interface(&rx, skb, false);

@@ -4999,6 +5007,10 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
}

if (prev) {
+ if (ieee80211_is_s1g_beacon(fc))
+ rx.sta = sta_info_get_bss(prev, ext_hdr->u.s1g_beacon.sa);
+ else
+ rx.sta = sta_info_get_bss(prev, hdr->addr2);
rx.sdata = prev;

if (ieee80211_rx_for_interface(&rx, skb, true))
--
2.25.1

2022-08-30 02:22:23

by Kieran Frewen

[permalink] [raw]
Subject: [PATCH v2 09/12] nl80211: support advertising S1G rate information

Add S1G rate information to netlink STA rate message.

Signed-off-by: Kieran Frewen <[email protected]>
---
include/uapi/linux/nl80211.h | 14 ++++++++++++++
net/wireless/nl80211.c | 23 +++++++++++++++++++++++
2 files changed, 37 insertions(+)

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index f20b9aefd420..5ae301905671 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -3600,6 +3600,13 @@ enum nl80211_eht_ru_alloc {
* (u8, see &enum nl80211_eht_gi)
* @NL80211_RATE_INFO_EHT_RU_ALLOC: EHT RU allocation, if not present then
* non-OFDMA was used (u8, see &enum nl80211_eht_ru_alloc)
+ * @NL80211_RATE_INFO_S1G_MCS: S1G MCS index (u8, 0-10)
+ * @NL80211_RATE_INFO_S1G_NSS: S1G NSS value (u8, 1-4)
+ * @NL80211_RATE_INFO_1_MHZ_WIDTH: 1 MHz S1G rate
+ * @NL80211_RATE_INFO_2_MHZ_WIDTH: 2 MHz S1G rate
+ * @NL80211_RATE_INFO_4_MHZ_WIDTH: 4 MHz S1G rate
+ * @NL80211_RATE_INFO_8_MHZ_WIDTH: 8 MHz S1G rate
+ * @NL80211_RATE_INFO_16_MHZ_WIDTH: 16 MHz S1G rate
* @__NL80211_RATE_INFO_AFTER_LAST: internal use
*/
enum nl80211_rate_info {
@@ -3626,6 +3633,13 @@ enum nl80211_rate_info {
NL80211_RATE_INFO_EHT_NSS,
NL80211_RATE_INFO_EHT_GI,
NL80211_RATE_INFO_EHT_RU_ALLOC,
+ NL80211_RATE_INFO_S1G_MCS,
+ NL80211_RATE_INFO_S1G_NSS,
+ NL80211_RATE_INFO_1_MHZ_WIDTH,
+ NL80211_RATE_INFO_2_MHZ_WIDTH,
+ NL80211_RATE_INFO_4_MHZ_WIDTH,
+ NL80211_RATE_INFO_8_MHZ_WIDTH,
+ NL80211_RATE_INFO_16_MHZ_WIDTH,

/* keep last */
__NL80211_RATE_INFO_AFTER_LAST,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 931e35619cf4..73eef7e9f4c3 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -6133,12 +6133,27 @@ bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info, int attr)
return false;

switch (info->bw) {
+ case RATE_INFO_BW_1:
+ rate_flg = NL80211_RATE_INFO_1_MHZ_WIDTH;
+ break;
+ case RATE_INFO_BW_2:
+ rate_flg = NL80211_RATE_INFO_2_MHZ_WIDTH;
+ break;
+ case RATE_INFO_BW_4:
+ rate_flg = NL80211_RATE_INFO_4_MHZ_WIDTH;
+ break;
case RATE_INFO_BW_5:
rate_flg = NL80211_RATE_INFO_5_MHZ_WIDTH;
break;
+ case RATE_INFO_BW_8:
+ rate_flg = NL80211_RATE_INFO_8_MHZ_WIDTH;
+ break;
case RATE_INFO_BW_10:
rate_flg = NL80211_RATE_INFO_10_MHZ_WIDTH;
break;
+ case RATE_INFO_BW_16:
+ rate_flg = NL80211_RATE_INFO_16_MHZ_WIDTH;
+ break;
default:
WARN_ON(1);
fallthrough;
@@ -6197,6 +6212,14 @@ bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info, int attr)
nla_put_u8(msg, NL80211_RATE_INFO_HE_RU_ALLOC,
info->he_ru_alloc))
return false;
+ } else if (info->flags & RATE_INFO_FLAGS_S1G_MCS) {
+ if (nla_put_u8(msg, NL80211_RATE_INFO_S1G_MCS, info->mcs))
+ return false;
+ if (nla_put_u8(msg, NL80211_RATE_INFO_S1G_NSS, info->nss))
+ return false;
+ if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
+ nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
+ return false;
} else if (info->flags & RATE_INFO_FLAGS_EHT_MCS) {
if (nla_put_u8(msg, NL80211_RATE_INFO_EHT_MCS, info->mcs))
return false;
--
2.25.1

2022-08-30 02:23:14

by Kieran Frewen

[permalink] [raw]
Subject: [PATCH v2 10/12] mac80211: support S1G rate encoding.

Add support for receiving and transmitting S1G frames.

Signed-off-by: Kieran Frewen <[email protected]>
---
drivers/net/wireless/mac80211_hwsim.c | 2 +-
include/net/mac80211.h | 32 ++++++++++++++++----
net/mac80211/cfg.c | 42 ++++++++++++++++++++-------
net/mac80211/rx.c | 8 +++++
net/mac80211/sta_info.c | 7 +++++
net/mac80211/sta_info.h | 7 +++++
net/mac80211/util.c | 30 ++++++++++++++++++-
7 files changed, 110 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 6e55f153ff26..5ecbc80be338 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -1575,7 +1575,7 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
memset(&rx_status, 0, sizeof(rx_status));
rx_status.flag |= RX_FLAG_MACTIME_START;
rx_status.freq = chan->center_freq;
- rx_status.freq_offset = chan->freq_offset ? 1 : 0;
+ rx_status.freq_offset = chan->freq_offset;
rx_status.band = chan->band;
if (info->control.rates[0].flags & IEEE80211_TX_RC_VHT_MCS) {
rx_status.rate_idx =
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 359edfa9ec1c..2e4a78301e3d 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -863,6 +863,10 @@ enum mac80211_tx_info_flags {
#define IEEE80211_TX_CTL_STBC_SHIFT 23

#define IEEE80211_TX_RC_S1G_MCS IEEE80211_TX_RC_VHT_MCS
+#define IEEE80211_TX_RC_2_MHZ_WIDTH IEEE80211_TX_RC_MCS
+#define IEEE80211_TX_RC_4_MHZ_WIDTH IEEE80211_TX_RC_40_MHZ_WIDTH
+#define IEEE80211_TX_RC_8_MHZ_WIDTH IEEE80211_TX_RC_80_MHZ_WIDTH
+#define IEEE80211_TX_RC_16_MHZ_WIDTH IEEE80211_TX_RC_160_MHZ_WIDTH

/**
* enum mac80211_tx_control_flags - flags to describe transmit control
@@ -1051,6 +1055,20 @@ ieee80211_rate_get_vht_nss(const struct ieee80211_tx_rate *rate)
return (rate->idx >> 4) + 1;
}

+static inline u8
+ieee80211_rate_get_s1g_mcs(const struct ieee80211_tx_rate *rate)
+{
+ /* S1G uses the same MCS encoding as VHT */
+ return ieee80211_rate_get_vht_mcs(rate);
+}
+
+static inline u8
+ieee80211_rate_get_s1g_nss(const struct ieee80211_tx_rate *rate)
+{
+ /* S1G uses the same NSS encoding as VHT */
+ return ieee80211_rate_get_vht_nss(rate);
+}
+
/**
* struct ieee80211_tx_info - skb transmit information
*
@@ -1435,6 +1453,7 @@ enum mac80211_rx_encoding {
RX_ENC_HT,
RX_ENC_VHT,
RX_ENC_HE,
+ RX_ENC_S1G,
};

/**
@@ -1491,10 +1510,11 @@ struct ieee80211_rx_status {
u32 device_timestamp;
u32 ampdu_reference;
u32 flag;
- u16 freq: 13, freq_offset: 1;
+ u16 freq;
+ u16 freq_offset;
u8 enc_flags;
- u8 encoding:2, bw:3, he_ru:3;
- u8 he_gi:2, he_dcm:1;
+ u8 encoding:3, bw:5;
+ u8 he_ru:3, he_gi:2, he_dcm:1;
u8 rate_idx;
u8 nss;
u8 rx_flags;
@@ -1510,8 +1530,7 @@ struct ieee80211_rx_status {
static inline u32
ieee80211_rx_status_to_khz(struct ieee80211_rx_status *rx_status)
{
- return MHZ_TO_KHZ(rx_status->freq) +
- (rx_status->freq_offset ? 500 : 0);
+ return MHZ_TO_KHZ(rx_status->freq) + rx_status->freq_offset;
}

/**
@@ -6568,6 +6587,9 @@ bool rate_usable_index_exists(struct ieee80211_supported_band *sband,
{
unsigned int i;

+ if (sband->band == NL80211_BAND_S1GHZ)
+ return true;
+
for (i = 0; i < sband->n_bitrates; i++)
if (rate_supported(sta, sband->band, i))
return true;
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 03ed90ce9a84..7cbf85338c9e 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -747,8 +747,16 @@ void sta_set_rate_info_tx(struct sta_info *sta,
const struct ieee80211_tx_rate *rate,
struct rate_info *rinfo)
{
+ struct ieee80211_supported_band *sband;
+
+ sband = ieee80211_get_sband(sta->sdata);
rinfo->flags = 0;
- if (rate->flags & IEEE80211_TX_RC_MCS) {
+ if (rate->flags & IEEE80211_TX_RC_S1G_MCS &&
+ sband->band == NL80211_BAND_S1GHZ) {
+ rinfo->flags |= RATE_INFO_FLAGS_S1G_MCS;
+ rinfo->mcs = ieee80211_rate_get_s1g_mcs(rate);
+ rinfo->nss = ieee80211_rate_get_s1g_nss(rate);
+ } else if (rate->flags & IEEE80211_TX_RC_MCS) {
rinfo->flags |= RATE_INFO_FLAGS_MCS;
rinfo->mcs = rate->idx;
} else if (rate->flags & IEEE80211_TX_RC_VHT_MCS) {
@@ -756,25 +764,37 @@ void sta_set_rate_info_tx(struct sta_info *sta,
rinfo->mcs = ieee80211_rate_get_vht_mcs(rate);
rinfo->nss = ieee80211_rate_get_vht_nss(rate);
} else {
- struct ieee80211_supported_band *sband;
int shift = ieee80211_vif_get_shift(&sta->sdata->vif);
u16 brate;

- sband = ieee80211_get_sband(sta->sdata);
WARN_ON_ONCE(sband && !sband->bitrates);
if (sband && sband->bitrates) {
brate = sband->bitrates[rate->idx].bitrate;
rinfo->legacy = DIV_ROUND_UP(brate, 1 << shift);
}
}
- if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
- rinfo->bw = RATE_INFO_BW_40;
- else if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
- rinfo->bw = RATE_INFO_BW_80;
- else if (rate->flags & IEEE80211_TX_RC_160_MHZ_WIDTH)
- rinfo->bw = RATE_INFO_BW_160;
- else
- rinfo->bw = RATE_INFO_BW_20;
+ if (sband->band == NL80211_BAND_S1GHZ) {
+ if (rate->flags & IEEE80211_TX_RC_2_MHZ_WIDTH)
+ rinfo->bw = RATE_INFO_BW_2;
+ else if (rate->flags & IEEE80211_TX_RC_4_MHZ_WIDTH)
+ rinfo->bw = RATE_INFO_BW_4;
+ else if (rate->flags & IEEE80211_TX_RC_8_MHZ_WIDTH)
+ rinfo->bw = RATE_INFO_BW_8;
+ else if (rate->flags & IEEE80211_TX_RC_16_MHZ_WIDTH)
+ rinfo->bw = RATE_INFO_BW_16;
+ else
+ rinfo->bw = RATE_INFO_BW_1;
+ } else {
+ if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+ rinfo->bw = RATE_INFO_BW_40;
+ else if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
+ rinfo->bw = RATE_INFO_BW_80;
+ else if (rate->flags & IEEE80211_TX_RC_160_MHZ_WIDTH)
+ rinfo->bw = RATE_INFO_BW_160;
+ else
+ rinfo->bw = RATE_INFO_BW_20;
+ }
+
if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI;
}
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index d46eeebedb4b..9eab2af626d6 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -5106,6 +5106,14 @@ void ieee80211_rx_list(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,
status->rate_idx, status->nss))
goto drop;
break;
+ case RX_ENC_S1G:
+ if (WARN_ONCE(status->rate_idx > 10 ||
+ !status->nss ||
+ status->nss > 8,
+ "Rate marked as a S1G rate but data is invalid: MCS: %d, NSS: %d\n",
+ status->rate_idx, status->nss))
+ goto drop;
+ break;
default:
WARN_ON_ONCE(1);
fallthrough;
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index cb23da9aff1e..331f5551477e 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -2295,6 +2295,13 @@ static void sta_stats_decode_rate(struct ieee80211_local *local, u32 rate,
rinfo->he_ru_alloc = STA_STATS_GET(HE_RU, rate);
rinfo->he_dcm = STA_STATS_GET(HE_DCM, rate);
break;
+ case STA_STATS_RATE_TYPE_S1G:
+ rinfo->flags = RATE_INFO_FLAGS_S1G_MCS;
+ rinfo->mcs = STA_STATS_GET(S1G_MCS, rate);
+ rinfo->nss = STA_STATS_GET(S1G_NSS, rate);
+ if (STA_STATS_GET(SGI, rate))
+ rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI;
+ break;
}
}

diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 2eb3a9452e07..1c0547769803 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -935,6 +935,8 @@ enum sta_stats_type {
#define STA_STATS_FIELD_VHT_NSS GENMASK( 7, 4)
#define STA_STATS_FIELD_HE_MCS GENMASK( 3, 0)
#define STA_STATS_FIELD_HE_NSS GENMASK( 7, 4)
+#define STA_STATS_FIELD_S1G_MCS GENMASK( 3, 0)
+#define STA_STATS_FIELD_S1G_NSS GENMASK( 7, 4)
#define STA_STATS_FIELD_BW GENMASK(11, 8)
#define STA_STATS_FIELD_SGI GENMASK(12, 12)
#define STA_STATS_FIELD_TYPE GENMASK(15, 13)
@@ -979,6 +981,11 @@ static inline u32 sta_stats_encode_rate(struct ieee80211_rx_status *s)
r |= STA_STATS_FIELD(HE_RU, s->he_ru);
r |= STA_STATS_FIELD(HE_DCM, s->he_dcm);
break;
+ case RX_ENC_S1G:
+ r |= STA_STATS_FIELD(TYPE, STA_STATS_RATE_TYPE_S1G);
+ r |= STA_STATS_FIELD(S1G_NSS, s->nss);
+ r |= STA_STATS_FIELD(S1G_MCS, s->rate_idx);
+ break;
default:
WARN_ON(1);
return STA_STATS_RATE_INVALID;
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 78e8c286011e..5147f688751d 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -3929,7 +3929,7 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
u64 ts = status->mactime;
struct rate_info ri;
u16 rate;
- u8 n_ltf;
+ u8 n_ltf, guard_factor;

if (WARN_ON(!ieee80211_have_rx_timestamp(status)))
return 0;
@@ -4016,6 +4016,34 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
ts += 4 * n_ltf;
}

+ break;
+ case RX_ENC_S1G:
+ /* Set to duration of S1G OFDM symbol with normal GI */
+ guard_factor = 40;
+ ri.flags |= RATE_INFO_FLAGS_S1G_MCS;
+ ri.mcs = status->rate_idx;
+ ri.nss = status->nss;
+ if (status->enc_flags & RX_ENC_FLAG_SHORT_GI) {
+ ri.flags |= RATE_INFO_FLAGS_SHORT_GI;
+ guard_factor = 36;
+ }
+
+ /*
+ * See 80211-2020, section 23.3.2 for S1G PPDU
+ * format and 23.3.6 for timing-related parameters.
+ * Here using the general structure for S1G_1M as
+ * in figure 23-3.
+ */
+ if (status->flag & RX_FLAG_MACTIME_PLCP_START) {
+ mpdu_offset += 2;
+ ts += (14 * guard_factor);
+
+ /* Add S1G-LTFs per streams */
+ n_ltf = (ri.nss != 1) && (ri.nss % 2) ?
+ ri.nss + 1 : ri.nss;
+ ts += (guard_factor * n_ltf);
+ }
+
break;
default:
WARN_ON(1);
--
2.25.1

2022-08-30 02:23:14

by Kieran Frewen

[permalink] [raw]
Subject: [PATCH v2 11/12] cfg80211: support for calculating S1G bitrates

Support for reporting and calculating S1G MCS bitrates.

Signed-off-by: Kieran Frewen <[email protected]>
---
net/wireless/util.c | 113 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 113 insertions(+)

diff --git a/net/wireless/util.c b/net/wireless/util.c
index aeccb6ce595c..d9d7dde3d4f2 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1384,6 +1384,117 @@ static u32 cfg80211_calculate_bitrate_vht(struct rate_info *rate)
return 0;
}

+static u32 cfg80211_calculate_bitrate_s1g(struct rate_info *rate)
+{
+ /* For 1, 2, 4, 8 and 16 MHz channels */
+ static const u32 base[5][12] = {
+ { 300000,
+ 600000,
+ 900000,
+ 1200000,
+ 1800000,
+ 2400000,
+ 2700000,
+ 3000000,
+ 3600000,
+ 4000000,
+ /* MCS 10 supported in 1 MHz only */
+ 150000,
+ },
+ { 650000,
+ 1300000,
+ 1950000,
+ 2600000,
+ 3900000,
+ 5200000,
+ 5850000,
+ 6500000,
+ 7800000,
+ /* MCS 9 not valid */
+ },
+ { 1350000,
+ 2700000,
+ 4050000,
+ 5400000,
+ 8100000,
+ 10800000,
+ 12150000,
+ 13500000,
+ 16200000,
+ 18000000,
+ },
+ { 2925000,
+ 5850000,
+ 8775000,
+ 11700000,
+ 17550000,
+ 23400000,
+ 26325000,
+ 29250000,
+ 35100000,
+ 39000000,
+ },
+ { 8580000,
+ 11700000,
+ 17550000,
+ 23400000,
+ 35100000,
+ 46800000,
+ 52650000,
+ 58500000,
+ 70200000,
+ 78000000,
+ },
+ };
+ u32 bitrate;
+ /* default is 1 MHz index */
+ int idx = 0;
+
+ if (rate->mcs > 11)
+ goto warn;
+
+ switch (rate->bw) {
+ case RATE_INFO_BW_16:
+ idx = 4;
+ break;
+ case RATE_INFO_BW_8:
+ idx = 3;
+ break;
+ case RATE_INFO_BW_4:
+ idx = 2;
+ break;
+ case RATE_INFO_BW_2:
+ idx = 1;
+ break;
+ case RATE_INFO_BW_1:
+ idx = 0;
+ break;
+ case RATE_INFO_BW_5:
+ case RATE_INFO_BW_10:
+ case RATE_INFO_BW_20:
+ case RATE_INFO_BW_40:
+ case RATE_INFO_BW_80:
+ case RATE_INFO_BW_160:
+ default:
+ goto warn;
+ }
+
+ bitrate = base[idx][rate->mcs];
+ bitrate *= rate->nss;
+
+ if (rate->flags & RATE_INFO_FLAGS_SHORT_GI)
+ bitrate = (bitrate / 9) * 10;
+ /* do NOT round down here */
+ return (bitrate + 50000) / 100000;
+warn:
+ if (!rate->bw && !rate->mcs && !rate->nss)
+ pr_debug("%s: rx status was not received yet!", __func__);
+ else
+ WARN_ONCE(1, "invalid rate bw=%d, mcs=%d, nss=%d\n",
+ rate->bw, rate->mcs, rate->nss);
+ return 0;
+}
+
static u32 cfg80211_calculate_bitrate_he(struct rate_info *rate)
{
#define SCALE 6144
@@ -1612,6 +1723,8 @@ u32 cfg80211_calculate_bitrate(struct rate_info *rate)
return cfg80211_calculate_bitrate_he(rate);
if (rate->flags & RATE_INFO_FLAGS_EHT_MCS)
return cfg80211_calculate_bitrate_eht(rate);
+ if (rate->flags & RATE_INFO_FLAGS_S1G_MCS)
+ return cfg80211_calculate_bitrate_s1g(rate);

return rate->legacy;
}
--
2.25.1

2022-08-30 02:23:15

by Kieran Frewen

[permalink] [raw]
Subject: [PATCH v2 12/12] mac80211_hwsim: support for S1G rate information

Include S1G rate information in S1G frames.

Signed-off-by: Kieran Frewen<[email protected]>
---
drivers/net/wireless/mac80211_hwsim.c | 38 ++++++++++++++++++++-------
1 file changed, 29 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 5ecbc80be338..6742f308ef7a 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -1577,7 +1577,14 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
rx_status.freq = chan->center_freq;
rx_status.freq_offset = chan->freq_offset;
rx_status.band = chan->band;
- if (info->control.rates[0].flags & IEEE80211_TX_RC_VHT_MCS) {
+ if (info->control.rates[0].flags & IEEE80211_TX_RC_S1G_MCS &&
+ rx_status.band == NL80211_BAND_S1GHZ) {
+ rx_status.rate_idx =
+ ieee80211_rate_get_s1g_mcs(&info->control.rates[0]);
+ rx_status.nss =
+ ieee80211_rate_get_s1g_nss(&info->control.rates[0]);
+ rx_status.encoding = RX_ENC_S1G;
+ } else if (info->control.rates[0].flags & IEEE80211_TX_RC_VHT_MCS) {
rx_status.rate_idx =
ieee80211_rate_get_vht_mcs(&info->control.rates[0]);
rx_status.nss =
@@ -1588,14 +1595,27 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS)
rx_status.encoding = RX_ENC_HT;
}
- if (info->control.rates[0].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
- rx_status.bw = RATE_INFO_BW_40;
- else if (info->control.rates[0].flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
- rx_status.bw = RATE_INFO_BW_80;
- else if (info->control.rates[0].flags & IEEE80211_TX_RC_160_MHZ_WIDTH)
- rx_status.bw = RATE_INFO_BW_160;
- else
- rx_status.bw = RATE_INFO_BW_20;
+ if (rx_status.band == NL80211_BAND_S1GHZ) {
+ if (info->control.rates[0].flags & IEEE80211_TX_RC_2_MHZ_WIDTH)
+ rx_status.bw = RATE_INFO_BW_2;
+ else if (info->control.rates[0].flags & IEEE80211_TX_RC_4_MHZ_WIDTH)
+ rx_status.bw = RATE_INFO_BW_4;
+ else if (info->control.rates[0].flags & IEEE80211_TX_RC_8_MHZ_WIDTH)
+ rx_status.bw = RATE_INFO_BW_8;
+ else if (info->control.rates[0].flags & IEEE80211_TX_RC_16_MHZ_WIDTH)
+ rx_status.bw = RATE_INFO_BW_16;
+ else
+ rx_status.bw = RATE_INFO_BW_1;
+ } else {
+ if (info->control.rates[0].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+ rx_status.bw = RATE_INFO_BW_40;
+ else if (info->control.rates[0].flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
+ rx_status.bw = RATE_INFO_BW_80;
+ else if (info->control.rates[0].flags & IEEE80211_TX_RC_160_MHZ_WIDTH)
+ rx_status.bw = RATE_INFO_BW_160;
+ else
+ rx_status.bw = RATE_INFO_BW_20;
+ }
if (info->control.rates[0].flags & IEEE80211_TX_RC_SHORT_GI)
rx_status.enc_flags |= RX_ENC_FLAG_SHORT_GI;
/* TODO: simulate optional packet loss */
--
2.25.1

2022-08-30 02:24:22

by Kieran Frewen

[permalink] [raw]
Subject: [PATCH v2 05/12] nl80211: support advertising S1G capabilities

Include S1G capabilities in netlink band info messages.

Signed-off-by: Kieran Frewen <[email protected]>
---
include/uapi/linux/nl80211.h | 7 +++++++
net/wireless/nl80211.c | 10 ++++++++++
2 files changed, 17 insertions(+)

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 7daa2ce1cb57..f20b9aefd420 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -3994,6 +3994,10 @@ enum nl80211_band_iftype_attr {
* @NL80211_BAND_ATTR_EDMG_BW_CONFIG: Channel BW Configuration subfield encodes
* the allowed channel bandwidth configurations.
* Defined by IEEE P802.11ay/D4.0 section 9.4.2.251, Table 13.
+ * @NL80211_BAND_ATTR_S1G_MCS_NSS_SET: S1G capabilities, supported S1G-MCS and NSS
+ * set subfield, as in the S1G information IE, 5 bytes
+ * @NL80211_BAND_ATTR_S1G_CAPA: S1G capabilities information subfield as in the
+ * S1G information IE, 10 bytes
* @NL80211_BAND_ATTR_MAX: highest band attribute currently defined
* @__NL80211_BAND_ATTR_AFTER_LAST: internal use
*/
@@ -4014,6 +4018,9 @@ enum nl80211_band_attr {
NL80211_BAND_ATTR_EDMG_CHANNELS,
NL80211_BAND_ATTR_EDMG_BW_CONFIG,

+ NL80211_BAND_ATTR_S1G_MCS_NSS_SET,
+ NL80211_BAND_ATTR_S1G_CAPA,
+
/* keep last */
__NL80211_BAND_ATTR_AFTER_LAST,
NL80211_BAND_ATTR_MAX = __NL80211_BAND_ATTR_AFTER_LAST - 1
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 5e9aaa8c0d7d..931e35619cf4 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1949,6 +1949,16 @@ static int nl80211_send_band_rateinfo(struct sk_buff *msg,

nla_nest_end(msg, nl_rates);

+ /* S1G capabilities */
+ if (sband->band == NL80211_BAND_S1GHZ && sband->s1g_cap.s1g &&
+ (nla_put(msg, NL80211_BAND_ATTR_S1G_CAPA,
+ sizeof(sband->s1g_cap.cap),
+ sband->s1g_cap.cap) ||
+ nla_put(msg, NL80211_BAND_ATTR_S1G_MCS_NSS_SET,
+ sizeof(sband->s1g_cap.nss_mcs),
+ sband->s1g_cap.nss_mcs)))
+ return -ENOBUFS;
+
return 0;
}

--
2.25.1

2022-08-30 05:05:48

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v2 01/12] cfg80211: regulatory: extend regulatory support for S1G

Hi Kieran,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on wireless/main]
[also build test WARNING on linus/master v6.0-rc3 next-20220829]
[cannot apply to wireless-next/main]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Kieran-Frewen/Additional-Support-for-802-11ah-S1G/20220830-102217
base: https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless.git main
config: m68k-allyesconfig (https://download.01.org/0day-ci/archive/20220830/[email protected]/config)
compiler: m68k-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/7c0e7a45e22911c6e1b16ecdce1a4d6022fd66ee
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Kieran-Frewen/Additional-Support-for-802-11ah-S1G/20220830-102217
git checkout 7c0e7a45e22911c6e1b16ecdce1a4d6022fd66ee
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=m68k SHELL=/bin/bash net/wireless/

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <[email protected]>

All warnings (new ones prefixed by >>):

>> net/wireless/util.c:137:5: warning: no previous prototype for 'ieee80211_s1g_channel_to_freq_khz' [-Wmissing-prototypes]
137 | u32 ieee80211_s1g_channel_to_freq_khz(int chan)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--
net/wireless/reg.c: In function 'handle_channel_custom.constprop':
>> net/wireless/reg.c:2597:28: warning: 'center_freq_khz' is used uninitialized [-Wuninitialized]
2597 | reg_rule = freq_reg_info_regd(center_freq_khz, regd, bw);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
net/wireless/reg.c:2586:17: note: 'center_freq_khz' was declared here
2586 | u32 bw, center_freq_khz;
| ^~~~~~~~~~~~~~~


vim +/ieee80211_s1g_channel_to_freq_khz +137 net/wireless/util.c

136
> 137 u32 ieee80211_s1g_channel_to_freq_khz(int chan)
138 {
139 u32 base = ieee80211_s1g_base_freq(chan);
140
141 if (!base)
142 return 0;
143
144 return (base + chan * 500);
145 }
146 EXPORT_SYMBOL(ieee80211_s1g_channel_to_freq_khz);
147

--
0-DAY CI Kernel Test Service
https://01.org/lkp

2022-08-30 09:39:56

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v2 01/12] cfg80211: regulatory: extend regulatory support for S1G

Hi Kieran,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on wireless/main]
[also build test WARNING on linus/master v6.0-rc3 next-20220830]
[cannot apply to wireless-next/main]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Kieran-Frewen/Additional-Support-for-802-11ah-S1G/20220830-102217
base: https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless.git main
config: arm-colibri_pxa270_defconfig (https://download.01.org/0day-ci/archive/20220830/[email protected]/config)
compiler: clang version 16.0.0 (https://github.com/llvm/llvm-project c7df82e4693c19e3fd2e25c83eb04d9deb7b7b59)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install arm cross compiling tool for clang build
# apt-get install binutils-arm-linux-gnueabi
# https://github.com/intel-lab-lkp/linux/commit/7c0e7a45e22911c6e1b16ecdce1a4d6022fd66ee
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Kieran-Frewen/Additional-Support-for-802-11ah-S1G/20220830-102217
git checkout 7c0e7a45e22911c6e1b16ecdce1a4d6022fd66ee
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=arm SHELL=/bin/bash net/wireless/

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <[email protected]>

All warnings (new ones prefixed by >>):

>> net/wireless/util.c:137:5: warning: no previous prototype for function 'ieee80211_s1g_channel_to_freq_khz' [-Wmissing-prototypes]
u32 ieee80211_s1g_channel_to_freq_khz(int chan)
^
net/wireless/util.c:137:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
u32 ieee80211_s1g_channel_to_freq_khz(int chan)
^
static
1 warning generated.
--
>> net/wireless/reg.c:2597:33: warning: variable 'center_freq_khz' is uninitialized when used here [-Wuninitialized]
reg_rule = freq_reg_info_regd(center_freq_khz, regd, bw);
^~~~~~~~~~~~~~~
net/wireless/reg.c:2586:25: note: initialize the variable 'center_freq_khz' to silence this warning
u32 bw, center_freq_khz;
^
= 0
1 warning generated.


vim +/ieee80211_s1g_channel_to_freq_khz +137 net/wireless/util.c

136
> 137 u32 ieee80211_s1g_channel_to_freq_khz(int chan)
138 {
139 u32 base = ieee80211_s1g_base_freq(chan);
140
141 if (!base)
142 return 0;
143
144 return (base + chan * 500);
145 }
146 EXPORT_SYMBOL(ieee80211_s1g_channel_to_freq_khz);
147

--
0-DAY CI Kernel Test Service
https://01.org/lkp

2022-09-02 08:47:11

by Dan Carpenter

[permalink] [raw]
Subject: Re: [PATCH v2 01/12] cfg80211: regulatory: extend regulatory support for S1G

Hi Kieran,

https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Kieran-Frewen/Additional-Support-for-802-11ah-S1G/20220830-102217
base: https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless.git main
config: csky-randconfig-m031-20220901 (https://download.01.org/0day-ci/archive/20220902/[email protected]/config)
compiler: csky-linux-gcc (GCC) 12.1.0

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <[email protected]>
Reported-by: Dan Carpenter <[email protected]>

smatch warnings:
net/wireless/reg.c:2597 handle_channel_custom() error: uninitialized symbol 'center_freq_khz'.

vim +/center_freq_khz +2597 net/wireless/reg.c

1fa25e413659f9 Luis R. Rodriguez 2009-01-22 2578 static void handle_channel_custom(struct wiphy *wiphy,
fdc9d7b2863ce6 Johannes Berg 2012-12-03 2579 struct ieee80211_channel *chan,
c4b9d655e445a8 Ganapathi Bhat 2019-12-20 2580 const struct ieee80211_regdomain *regd,
c4b9d655e445a8 Ganapathi Bhat 2019-12-20 2581 u32 min_bw)
1fa25e413659f9 Luis R. Rodriguez 2009-01-22 2582 {
038659e7c6b385 Luis R. Rodriguez 2009-05-02 2583 u32 bw_flags = 0;
1fa25e413659f9 Luis R. Rodriguez 2009-01-22 2584 const struct ieee80211_reg_rule *reg_rule = NULL;
1fa25e413659f9 Luis R. Rodriguez 2009-01-22 2585 const struct ieee80211_power_rule *power_rule = NULL;
934f4c7dd3a544 Thomas Pedersen 2020-04-01 2586 u32 bw, center_freq_khz;
7c0e7a45e22911 Kieran Frewen 2022-08-30 2587 bool is_s1g = chan->band == NL80211_BAND_S1GHZ;
1fa25e413659f9 Luis R. Rodriguez 2009-01-22 2588
7c0e7a45e22911 Kieran Frewen 2022-08-30 2589 if (is_s1g) {
7c0e7a45e22911 Kieran Frewen 2022-08-30 2590 bw = MHZ_TO_KHZ(16);
7c0e7a45e22911 Kieran Frewen 2022-08-30 2591 min_bw = MHZ_TO_KHZ(1);
7c0e7a45e22911 Kieran Frewen 2022-08-30 2592 } else {
7c0e7a45e22911 Kieran Frewen 2022-08-30 2593 bw = MHZ_TO_KHZ(20);
7c0e7a45e22911 Kieran Frewen 2022-08-30 2594 }
7c0e7a45e22911 Kieran Frewen 2022-08-30 2595
7c0e7a45e22911 Kieran Frewen 2022-08-30 2596 for (; bw >= min_bw; bw = bw / 2) {
934f4c7dd3a544 Thomas Pedersen 2020-04-01 @2597 reg_rule = freq_reg_info_regd(center_freq_khz, regd, bw);

Never initialized.

4edd56981c8fbb Matthias May 2015-07-17 2598 if (!IS_ERR(reg_rule))
4edd56981c8fbb Matthias May 2015-07-17 2599 break;
4edd56981c8fbb Matthias May 2015-07-17 2600 }
1fa25e413659f9 Luis R. Rodriguez 2009-01-22 2601
a7ee7d44b57c9a Johannes Berg 2020-02-21 2602 if (IS_ERR_OR_NULL(reg_rule)) {
934f4c7dd3a544 Thomas Pedersen 2020-04-01 2603 pr_debug("Disabling freq %d.%03d MHz as custom regd has no rule that fits it\n",
934f4c7dd3a544 Thomas Pedersen 2020-04-01 2604 chan->center_freq, chan->freq_offset);
db8dfee57d37d2 Arik Nemtsov 2014-12-15 2605 if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) {
db8dfee57d37d2 Arik Nemtsov 2014-12-15 2606 chan->flags |= IEEE80211_CHAN_DISABLED;
db8dfee57d37d2 Arik Nemtsov 2014-12-15 2607 } else {
cc493e4f5296f4 Luis R. Rodriguez 2013-11-06 2608 chan->orig_flags |= IEEE80211_CHAN_DISABLED;
cc493e4f5296f4 Luis R. Rodriguez 2013-11-06 2609 chan->flags = chan->orig_flags;
db8dfee57d37d2 Arik Nemtsov 2014-12-15 2610 }
1fa25e413659f9 Luis R. Rodriguez 2009-01-22 2611 return;
1fa25e413659f9 Luis R. Rodriguez 2009-01-22 2612 }
1fa25e413659f9 Luis R. Rodriguez 2009-01-22 2613
1fa25e413659f9 Luis R. Rodriguez 2009-01-22 2614 power_rule = &reg_rule->power_rule;
1aeb135f84fe40 Michal Sojka 2015-11-23 2615 bw_flags = reg_rule_to_chan_bw_flags(regd, reg_rule, chan);
1fa25e413659f9 Luis R. Rodriguez 2009-01-22 2616
2e18b38fc8fb03 Arik Nemtsov 2014-11-16 2617 chan->dfs_state_entered = jiffies;
c7ab508190aee6 Arik Nemtsov 2014-11-16 2618 chan->dfs_state = NL80211_DFS_USABLE;
c7ab508190aee6 Arik Nemtsov 2014-11-16 2619
c7ab508190aee6 Arik Nemtsov 2014-11-16 2620 chan->beacon_found = false;
db8dfee57d37d2 Arik Nemtsov 2014-12-15 2621
db8dfee57d37d2 Arik Nemtsov 2014-12-15 2622 if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED)
db8dfee57d37d2 Arik Nemtsov 2014-12-15 2623 chan->flags = chan->orig_flags | bw_flags |
db8dfee57d37d2 Arik Nemtsov 2014-12-15 2624 map_regdom_flags(reg_rule->flags);
db8dfee57d37d2 Arik Nemtsov 2014-12-15 2625 else
038659e7c6b385 Luis R. Rodriguez 2009-05-02 2626 chan->flags |= map_regdom_flags(reg_rule->flags) | bw_flags;
db8dfee57d37d2 Arik Nemtsov 2014-12-15 2627
1fa25e413659f9 Luis R. Rodriguez 2009-01-22 2628 chan->max_antenna_gain = (int) MBI_TO_DBI(power_rule->max_antenna_gain);
279f0f55249820 Felix Fietkau 2012-10-17 2629 chan->max_reg_power = chan->max_power =
279f0f55249820 Felix Fietkau 2012-10-17 2630 (int) MBM_TO_DBM(power_rule->max_eirp);
2e18b38fc8fb03 Arik Nemtsov 2014-11-16 2631
2e18b38fc8fb03 Arik Nemtsov 2014-11-16 2632 if (chan->flags & IEEE80211_CHAN_RADAR) {
2e18b38fc8fb03 Arik Nemtsov 2014-11-16 2633 if (reg_rule->dfs_cac_ms)
2e18b38fc8fb03 Arik Nemtsov 2014-11-16 2634 chan->dfs_cac_ms = reg_rule->dfs_cac_ms;
2e18b38fc8fb03 Arik Nemtsov 2014-11-16 2635 else
2e18b38fc8fb03 Arik Nemtsov 2014-11-16 2636 chan->dfs_cac_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
2e18b38fc8fb03 Arik Nemtsov 2014-11-16 2637 }
2e18b38fc8fb03 Arik Nemtsov 2014-11-16 2638
2e18b38fc8fb03 Arik Nemtsov 2014-11-16 2639 chan->max_power = chan->max_reg_power;
1fa25e413659f9 Luis R. Rodriguez 2009-01-22 2640 }

--
0-DAY CI Kernel Test Service
https://01.org/lkp