Message ID | 20220830022017.51017-2-kieran.frewen@morsemicro.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Johannes Berg |
Headers | show |
Series | Additional Support for 802.11ah (S1G) | expand |
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/202208301259.DiwKm3rQ-lkp@intel.com/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 <lkp@intel.com> 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
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/202208301755.3ARl5XbS-lkp@intel.com/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 <lkp@intel.com> 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
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/202209020018.S33cD0dC-lkp@intel.com/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 <lkp@intel.com> Reported-by: Dan Carpenter <dan.carpenter@oracle.com> 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 = ®_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 }
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) {
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 <kieran.frewen@morsemicro.com> --- 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