2014-02-20 12:52:26

by Janusz Dziedzic

[permalink] [raw]
Subject: [PATCH] cfg80211: regulatory, introduce NL80211_RRF_AUTO_BW rule flag

Introduce NL80211_RRF_AUTO_BW rule flag. If this flag set
maximum available bandwidth should be calculated base on
contiguous rules and wider channels will be allowed to cross
multiple contiguous/overlapping frequency ranges.

In case of old kernels maximum bandwidth from regulatory
rule will be used, while there is no NL80211_RRF_AUTO_BW flag.

This extend patch:
cfg80211: regulatory introduce maximum bandwidth calculation

Signed-off-by: Janusz Dziedzic <[email protected]>
---
include/uapi/linux/nl80211.h | 9 ++---
net/wireless/genregdb.awk | 2 ++
net/wireless/nl80211.c | 7 ++--
net/wireless/reg.c | 76 ++++++++++++++++++++++++------------------
4 files changed, 54 insertions(+), 40 deletions(-)

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index ba1f762..bd2cb58 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2437,10 +2437,7 @@ enum nl80211_reg_type {
* in KHz. This is not a center a frequency but an actual regulatory
* band edge.
* @NL80211_ATTR_FREQ_RANGE_MAX_BW: maximum allowed bandwidth for this
- * frequency range, in KHz. If not present or 0, maximum available
- * bandwidth should be calculated base on contiguous rules and wider
- * channels will be allowed to cross multiple contiguous/overlapping
- * frequency ranges.
+ * frequency range, in KHz.
* @NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN: the maximum allowed antenna gain
* for a given frequency range. The value is in mBi (100 * dBi).
* If you don't have one then don't send this.
@@ -2511,6 +2508,9 @@ enum nl80211_sched_scan_match_attr {
* @NL80211_RRF_NO_IR: no mechanisms that initiate radiation are allowed,
* this includes probe requests or modes of operation that require
* beaconing.
+ * @NL80211_RRF_AUTO_BW: maximum available bandwidth should be calculated
+ * base on contiguous rules and wider channels will be allowed to cross
+ * multiple contiguous/overlapping frequency ranges.
*/
enum nl80211_reg_rule_flags {
NL80211_RRF_NO_OFDM = 1<<0,
@@ -2522,6 +2522,7 @@ enum nl80211_reg_rule_flags {
NL80211_RRF_PTMP_ONLY = 1<<6,
NL80211_RRF_NO_IR = 1<<7,
__NL80211_RRF_NO_IBSS = 1<<8,
+ NL80211_RRF_AUTO_BW = 1<<9,
};

#define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR
diff --git a/net/wireless/genregdb.awk b/net/wireless/genregdb.awk
index 9a8217d..fdfd3f0 100644
--- a/net/wireless/genregdb.awk
+++ b/net/wireless/genregdb.awk
@@ -105,6 +105,8 @@ function parse_reg_rule()
flags = flags "\n\t\t\tNL80211_RRF_NO_IR | "
} else if (flagarray[arg] == "NO-IR") {
flags = flags "\n\t\t\tNL80211_RRF_NO_IR | "
+ } else if (flagarray[arg] == "AUTO-BW") {
+ flags = flags "\n\t\t\tNL80211_RRF_AUTO_BW | "
}

}
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 1797864..71a1fdb 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -4626,6 +4626,8 @@ static int parse_reg_rule(struct nlattr *tb[],
return -EINVAL;
if (!tb[NL80211_ATTR_FREQ_RANGE_END])
return -EINVAL;
+ if (!tb[NL80211_ATTR_FREQ_RANGE_MAX_BW])
+ return -EINVAL;
if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP])
return -EINVAL;

@@ -4635,9 +4637,8 @@ static int parse_reg_rule(struct nlattr *tb[],
nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]);
freq_range->end_freq_khz =
nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]);
- if (tb[NL80211_ATTR_FREQ_RANGE_MAX_BW])
- freq_range->max_bandwidth_khz =
- nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]);
+ freq_range->max_bandwidth_khz =
+ nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]);

power_rule->max_eirp =
nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]);
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 27c5253..7e09b4e 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -563,9 +563,6 @@ unsigned int reg_get_max_bandwidth(const struct ieee80211_regdomain *rd,
if (freq_range_tmp->end_freq_khz < freq_range->start_freq_khz)
break;

- if (freq_range_tmp->max_bandwidth_khz)
- break;
-
freq_range = freq_range_tmp;
}

@@ -582,9 +579,6 @@ unsigned int reg_get_max_bandwidth(const struct ieee80211_regdomain *rd,
if (freq_range_tmp->start_freq_khz > freq_range->end_freq_khz)
break;

- if (freq_range_tmp->max_bandwidth_khz)
- break;
-
freq_range = freq_range_tmp;
}

@@ -729,21 +723,29 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1,
max_bandwidth1 = freq_range1->max_bandwidth_khz;
max_bandwidth2 = freq_range2->max_bandwidth_khz;

- /*
- * In case max_bandwidth1 == 0 and max_bandwith2 == 0 set
- * output bandwidth as 0 (auto calculation). Next we will
- * calculate this correctly in handle_channel function.
- * In other case calculate output bandwidth here.
- */
- if (max_bandwidth1 || max_bandwidth2) {
- if (!max_bandwidth1)
- max_bandwidth1 = reg_get_max_bandwidth(rd1, rule1);
- if (!max_bandwidth2)
- max_bandwidth2 = reg_get_max_bandwidth(rd2, rule2);
- }
+ if (rule1->flags & NL80211_RRF_AUTO_BW)
+ max_bandwidth1 = reg_get_max_bandwidth(rd1, rule1);
+ if (rule2->flags & NL80211_RRF_AUTO_BW)
+ max_bandwidth2 = reg_get_max_bandwidth(rd2, rule2);

freq_range->max_bandwidth_khz = min(max_bandwidth1, max_bandwidth2);

+ intersected_rule->flags = rule1->flags | rule2->flags;
+
+ /*
+ * In case NL80211_RRF_AUTO_BW requested for both rules
+ * set AUTO_BW in intersected rule also. Next we will
+ * calculate BW correctly in handle_channel function.
+ * In other case remove AUTO_BW flag while we calculate
+ * maximum bandwidth correctly and auto calculation is
+ * not required.
+ */
+ if ((rule1->flags & NL80211_RRF_AUTO_BW) &&
+ (rule2->flags & NL80211_RRF_AUTO_BW))
+ intersected_rule->flags |= NL80211_RRF_AUTO_BW;
+ else
+ intersected_rule->flags &= ~NL80211_RRF_AUTO_BW;
+
freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz;
if (freq_range->max_bandwidth_khz > freq_diff)
freq_range->max_bandwidth_khz = freq_diff;
@@ -753,8 +755,6 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1,
power_rule->max_antenna_gain = min(power_rule1->max_antenna_gain,
power_rule2->max_antenna_gain);

- intersected_rule->flags = rule1->flags | rule2->flags;
-
if (!is_valid_reg_rule(intersected_rule))
return -EINVAL;

@@ -938,12 +938,13 @@ const char *reg_initiator_name(enum nl80211_reg_initiator initiator)
EXPORT_SYMBOL(reg_initiator_name);

#ifdef CONFIG_CFG80211_REG_DEBUG
-static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan,
+static void chan_reg_rule_print_dbg(const struct ieee80211_regdomain *regd,
+ struct ieee80211_channel *chan,
const struct ieee80211_reg_rule *reg_rule)
{
const struct ieee80211_power_rule *power_rule;
const struct ieee80211_freq_range *freq_range;
- char max_antenna_gain[32];
+ char max_antenna_gain[32], bw[32];

power_rule = &reg_rule->power_rule;
freq_range = &reg_rule->freq_range;
@@ -953,16 +954,25 @@ static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan,
else
snprintf(max_antenna_gain, 32, "%d", power_rule->max_antenna_gain);

+ if (reg_rule->flags & NL80211_RRF_AUTO_BW)
+ snprintf(bw, 32, "%d KHz, %d KHz AUTO",
+ freq_range->max_bandwidth_khz,
+ reg_get_max_bandwidth(regd, reg_rule));
+ else
+ snprintf(bw, 32, "%d KHz",
+ freq_range->max_bandwidth_khz);
+
REG_DBG_PRINT("Updating information on frequency %d MHz with regulatory rule:\n",
chan->center_freq);

- REG_DBG_PRINT("%d KHz - %d KHz @ %d KHz), (%s mBi, %d mBm)\n",
+ REG_DBG_PRINT("%d KHz - %d KHz @ %s), (%s mBi, %d mBm)\n",
freq_range->start_freq_khz, freq_range->end_freq_khz,
- freq_range->max_bandwidth_khz, max_antenna_gain,
+ bw, max_antenna_gain,
power_rule->max_eirp);
}
#else
-static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan,
+static void chan_reg_rule_print_dbg(const struct ieee80211_regdomain *regd,
+ struct ieee80211_channel *chan,
const struct ieee80211_reg_rule *reg_rule)
{
return;
@@ -1022,17 +1032,16 @@ static void handle_channel(struct wiphy *wiphy,
return;
}

- chan_reg_rule_print_dbg(chan, reg_rule);
+ regd = reg_get_regdomain(wiphy);
+ chan_reg_rule_print_dbg(regd, chan, reg_rule);

power_rule = &reg_rule->power_rule;
freq_range = &reg_rule->freq_range;

max_bandwidth_khz = freq_range->max_bandwidth_khz;
/* Check if auto calculation requested */
- if (!max_bandwidth_khz) {
- regd = reg_get_regdomain(wiphy);
+ if (reg_rule->flags & NL80211_RRF_AUTO_BW)
max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule);
- }

if (max_bandwidth_khz < MHZ_TO_KHZ(40))
bw_flags = IEEE80211_CHAN_NO_HT40;
@@ -1437,14 +1446,14 @@ static void handle_channel_custom(struct wiphy *wiphy,
return;
}

- chan_reg_rule_print_dbg(chan, reg_rule);
+ chan_reg_rule_print_dbg(regd, chan, reg_rule);

power_rule = &reg_rule->power_rule;
freq_range = &reg_rule->freq_range;

max_bandwidth_khz = freq_range->max_bandwidth_khz;
/* Check if auto calculation requested */
- if (!max_bandwidth_khz)
+ if (reg_rule->flags & NL80211_RRF_AUTO_BW)
max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule);

if (max_bandwidth_khz < MHZ_TO_KHZ(40))
@@ -2254,8 +2263,9 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd)
freq_range = &reg_rule->freq_range;
power_rule = &reg_rule->power_rule;

- if (!freq_range->max_bandwidth_khz)
- snprintf(bw, 32, "%d KHz, AUTO",
+ if (reg_rule->flags & NL80211_RRF_AUTO_BW)
+ snprintf(bw, 32, "%d KHz, %d KHz AUTO",
+ freq_range->max_bandwidth_khz,
reg_get_max_bandwidth(rd, reg_rule));
else
snprintf(bw, 32, "%d KHz",
--
1.7.9.5



2014-02-25 15:28:20

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH] cfg80211: regulatory, introduce NL80211_RRF_AUTO_BW rule flag

On Fri, 2014-02-21 at 16:19 -0800, Luis R. Rodriguez wrote:
> On Fri, Feb 21, 2014 at 12:28 AM, Johannes Berg
> <[email protected]> wrote:
> > However, Luis, please sort out this situation, and if bits 9/10 were
> > ever used by userspace (they were never used by the kernel!) then please
> > submit a kernel patch that marks them as reserved in nl80211.h. The
> > kernel header file should be the master file defining the API, not some
> > "random" userspace tool.
>
> Pretty sure NO-HT40 was never used (claimed bit 10), and not sure why
> bit bit 9 says reserved, I'm pretty sure it never got used too.

Ok, thanks.

johannes


2014-02-21 08:23:21

by Janusz Dziedzic

[permalink] [raw]
Subject: Re: [PATCH] cfg80211: regulatory, introduce NL80211_RRF_AUTO_BW rule flag

On 20 February 2014 13:52, Janusz Dziedzic <[email protected]> wrote:
> Introduce NL80211_RRF_AUTO_BW rule flag. If this flag set
> maximum available bandwidth should be calculated base on
> contiguous rules and wider channels will be allowed to cross
> multiple contiguous/overlapping frequency ranges.
>
> In case of old kernels maximum bandwidth from regulatory
> rule will be used, while there is no NL80211_RRF_AUTO_BW flag.
>
> This extend patch:
> cfg80211: regulatory introduce maximum bandwidth calculation
>
> Signed-off-by: Janusz Dziedzic <[email protected]>
> ---
> include/uapi/linux/nl80211.h | 9 ++---
> net/wireless/genregdb.awk | 2 ++
> net/wireless/nl80211.c | 7 ++--
> net/wireless/reg.c | 76 ++++++++++++++++++++++++------------------
> 4 files changed, 54 insertions(+), 40 deletions(-)
>
> diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
> index ba1f762..bd2cb58 100644
> --- a/include/uapi/linux/nl80211.h
> +++ b/include/uapi/linux/nl80211.h
> @@ -2437,10 +2437,7 @@ enum nl80211_reg_type {
> * in KHz. This is not a center a frequency but an actual regulatory
> * band edge.
> * @NL80211_ATTR_FREQ_RANGE_MAX_BW: maximum allowed bandwidth for this
> - * frequency range, in KHz. If not present or 0, maximum available
> - * bandwidth should be calculated base on contiguous rules and wider
> - * channels will be allowed to cross multiple contiguous/overlapping
> - * frequency ranges.
> + * frequency range, in KHz.
> * @NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN: the maximum allowed antenna gain
> * for a given frequency range. The value is in mBi (100 * dBi).
> * If you don't have one then don't send this.
> @@ -2511,6 +2508,9 @@ enum nl80211_sched_scan_match_attr {
> * @NL80211_RRF_NO_IR: no mechanisms that initiate radiation are allowed,
> * this includes probe requests or modes of operation that require
> * beaconing.
> + * @NL80211_RRF_AUTO_BW: maximum available bandwidth should be calculated
> + * base on contiguous rules and wider channels will be allowed to cross
> + * multiple contiguous/overlapping frequency ranges.
> */
> enum nl80211_reg_rule_flags {
> NL80211_RRF_NO_OFDM = 1<<0,
> @@ -2522,6 +2522,7 @@ enum nl80211_reg_rule_flags {
> NL80211_RRF_PTMP_ONLY = 1<<6,
> NL80211_RRF_NO_IR = 1<<7,
> __NL80211_RRF_NO_IBSS = 1<<8,
> + NL80211_RRF_AUTO_BW = 1<<9,
> };

I have one doubt here. While updating wireless-regdb I found this:

# must match <linux/nl80211.h> enum nl80211_reg_rule_flags

flag_definitions = {
'NO-OFDM': 1<<0,
'NO-CCK': 1<<1,
'NO-INDOOR': 1<<2,
'NO-OUTDOOR': 1<<3,
'DFS': 1<<4,
'PTP-ONLY': 1<<5,
'PTMP-ONLY': 1<<6,
'NO-IR': 1<<7,
# hole at bit 8
# hole at bit 9. FIXME: Where is NO-HT40 defined?
'NO-HT40': 1<<10,
}

Which definition is correct now? Should I remove bit9 and bit10 from
wireless-regdb or skip them in nl80211.h?


>
> #define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR
> diff --git a/net/wireless/genregdb.awk b/net/wireless/genregdb.awk
> index 9a8217d..fdfd3f0 100644
> --- a/net/wireless/genregdb.awk
> +++ b/net/wireless/genregdb.awk
> @@ -105,6 +105,8 @@ function parse_reg_rule()
> flags = flags "\n\t\t\tNL80211_RRF_NO_IR | "
> } else if (flagarray[arg] == "NO-IR") {
> flags = flags "\n\t\t\tNL80211_RRF_NO_IR | "
> + } else if (flagarray[arg] == "AUTO-BW") {
> + flags = flags "\n\t\t\tNL80211_RRF_AUTO_BW | "
> }
>
> }
> diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
> index 1797864..71a1fdb 100644
> --- a/net/wireless/nl80211.c
> +++ b/net/wireless/nl80211.c
> @@ -4626,6 +4626,8 @@ static int parse_reg_rule(struct nlattr *tb[],
> return -EINVAL;
> if (!tb[NL80211_ATTR_FREQ_RANGE_END])
> return -EINVAL;
> + if (!tb[NL80211_ATTR_FREQ_RANGE_MAX_BW])
> + return -EINVAL;
> if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP])
> return -EINVAL;
>
> @@ -4635,9 +4637,8 @@ static int parse_reg_rule(struct nlattr *tb[],
> nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]);
> freq_range->end_freq_khz =
> nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]);
> - if (tb[NL80211_ATTR_FREQ_RANGE_MAX_BW])
> - freq_range->max_bandwidth_khz =
> - nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]);
> + freq_range->max_bandwidth_khz =
> + nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]);
>
> power_rule->max_eirp =
> nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]);
> diff --git a/net/wireless/reg.c b/net/wireless/reg.c
> index 27c5253..7e09b4e 100644
> --- a/net/wireless/reg.c
> +++ b/net/wireless/reg.c
> @@ -563,9 +563,6 @@ unsigned int reg_get_max_bandwidth(const struct ieee80211_regdomain *rd,
> if (freq_range_tmp->end_freq_khz < freq_range->start_freq_khz)
> break;
>
> - if (freq_range_tmp->max_bandwidth_khz)
> - break;
> -
> freq_range = freq_range_tmp;
> }
>
> @@ -582,9 +579,6 @@ unsigned int reg_get_max_bandwidth(const struct ieee80211_regdomain *rd,
> if (freq_range_tmp->start_freq_khz > freq_range->end_freq_khz)
> break;
>
> - if (freq_range_tmp->max_bandwidth_khz)
> - break;
> -
> freq_range = freq_range_tmp;
> }
>
> @@ -729,21 +723,29 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1,
> max_bandwidth1 = freq_range1->max_bandwidth_khz;
> max_bandwidth2 = freq_range2->max_bandwidth_khz;
>
> - /*
> - * In case max_bandwidth1 == 0 and max_bandwith2 == 0 set
> - * output bandwidth as 0 (auto calculation). Next we will
> - * calculate this correctly in handle_channel function.
> - * In other case calculate output bandwidth here.
> - */
> - if (max_bandwidth1 || max_bandwidth2) {
> - if (!max_bandwidth1)
> - max_bandwidth1 = reg_get_max_bandwidth(rd1, rule1);
> - if (!max_bandwidth2)
> - max_bandwidth2 = reg_get_max_bandwidth(rd2, rule2);
> - }
> + if (rule1->flags & NL80211_RRF_AUTO_BW)
> + max_bandwidth1 = reg_get_max_bandwidth(rd1, rule1);
> + if (rule2->flags & NL80211_RRF_AUTO_BW)
> + max_bandwidth2 = reg_get_max_bandwidth(rd2, rule2);
>
> freq_range->max_bandwidth_khz = min(max_bandwidth1, max_bandwidth2);
>
> + intersected_rule->flags = rule1->flags | rule2->flags;
> +
> + /*
> + * In case NL80211_RRF_AUTO_BW requested for both rules
> + * set AUTO_BW in intersected rule also. Next we will
> + * calculate BW correctly in handle_channel function.
> + * In other case remove AUTO_BW flag while we calculate
> + * maximum bandwidth correctly and auto calculation is
> + * not required.
> + */
> + if ((rule1->flags & NL80211_RRF_AUTO_BW) &&
> + (rule2->flags & NL80211_RRF_AUTO_BW))
> + intersected_rule->flags |= NL80211_RRF_AUTO_BW;
> + else
> + intersected_rule->flags &= ~NL80211_RRF_AUTO_BW;
> +
> freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz;
> if (freq_range->max_bandwidth_khz > freq_diff)
> freq_range->max_bandwidth_khz = freq_diff;
> @@ -753,8 +755,6 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1,
> power_rule->max_antenna_gain = min(power_rule1->max_antenna_gain,
> power_rule2->max_antenna_gain);
>
> - intersected_rule->flags = rule1->flags | rule2->flags;
> -
> if (!is_valid_reg_rule(intersected_rule))
> return -EINVAL;
>
> @@ -938,12 +938,13 @@ const char *reg_initiator_name(enum nl80211_reg_initiator initiator)
> EXPORT_SYMBOL(reg_initiator_name);
>
> #ifdef CONFIG_CFG80211_REG_DEBUG
> -static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan,
> +static void chan_reg_rule_print_dbg(const struct ieee80211_regdomain *regd,
> + struct ieee80211_channel *chan,
> const struct ieee80211_reg_rule *reg_rule)
> {
> const struct ieee80211_power_rule *power_rule;
> const struct ieee80211_freq_range *freq_range;
> - char max_antenna_gain[32];
> + char max_antenna_gain[32], bw[32];
>
> power_rule = &reg_rule->power_rule;
> freq_range = &reg_rule->freq_range;
> @@ -953,16 +954,25 @@ static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan,
> else
> snprintf(max_antenna_gain, 32, "%d", power_rule->max_antenna_gain);
>
> + if (reg_rule->flags & NL80211_RRF_AUTO_BW)
> + snprintf(bw, 32, "%d KHz, %d KHz AUTO",
> + freq_range->max_bandwidth_khz,
> + reg_get_max_bandwidth(regd, reg_rule));
> + else
> + snprintf(bw, 32, "%d KHz",
> + freq_range->max_bandwidth_khz);
> +
> REG_DBG_PRINT("Updating information on frequency %d MHz with regulatory rule:\n",
> chan->center_freq);
>
> - REG_DBG_PRINT("%d KHz - %d KHz @ %d KHz), (%s mBi, %d mBm)\n",
> + REG_DBG_PRINT("%d KHz - %d KHz @ %s), (%s mBi, %d mBm)\n",
> freq_range->start_freq_khz, freq_range->end_freq_khz,
> - freq_range->max_bandwidth_khz, max_antenna_gain,
> + bw, max_antenna_gain,
> power_rule->max_eirp);
> }
> #else
> -static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan,
> +static void chan_reg_rule_print_dbg(const struct ieee80211_regdomain *regd,
> + struct ieee80211_channel *chan,
> const struct ieee80211_reg_rule *reg_rule)
> {
> return;
> @@ -1022,17 +1032,16 @@ static void handle_channel(struct wiphy *wiphy,
> return;
> }
>
> - chan_reg_rule_print_dbg(chan, reg_rule);
> + regd = reg_get_regdomain(wiphy);
> + chan_reg_rule_print_dbg(regd, chan, reg_rule);
>
> power_rule = &reg_rule->power_rule;
> freq_range = &reg_rule->freq_range;
>
> max_bandwidth_khz = freq_range->max_bandwidth_khz;
> /* Check if auto calculation requested */
> - if (!max_bandwidth_khz) {
> - regd = reg_get_regdomain(wiphy);
> + if (reg_rule->flags & NL80211_RRF_AUTO_BW)
> max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule);
> - }
>
> if (max_bandwidth_khz < MHZ_TO_KHZ(40))
> bw_flags = IEEE80211_CHAN_NO_HT40;
> @@ -1437,14 +1446,14 @@ static void handle_channel_custom(struct wiphy *wiphy,
> return;
> }
>
> - chan_reg_rule_print_dbg(chan, reg_rule);
> + chan_reg_rule_print_dbg(regd, chan, reg_rule);
>
> power_rule = &reg_rule->power_rule;
> freq_range = &reg_rule->freq_range;
>
> max_bandwidth_khz = freq_range->max_bandwidth_khz;
> /* Check if auto calculation requested */
> - if (!max_bandwidth_khz)
> + if (reg_rule->flags & NL80211_RRF_AUTO_BW)
> max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule);
>
> if (max_bandwidth_khz < MHZ_TO_KHZ(40))
> @@ -2254,8 +2263,9 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd)
> freq_range = &reg_rule->freq_range;
> power_rule = &reg_rule->power_rule;
>
> - if (!freq_range->max_bandwidth_khz)
> - snprintf(bw, 32, "%d KHz, AUTO",
> + if (reg_rule->flags & NL80211_RRF_AUTO_BW)
> + snprintf(bw, 32, "%d KHz, %d KHz AUTO",
> + freq_range->max_bandwidth_khz,
> reg_get_max_bandwidth(rd, reg_rule));
> else
> snprintf(bw, 32, "%d KHz",
> --
> 1.7.9.5
>

2014-02-21 08:28:23

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH] cfg80211: regulatory, introduce NL80211_RRF_AUTO_BW rule flag

On Fri, 2014-02-21 at 09:23 +0100, Janusz Dziedzic wrote:

> # must match <linux/nl80211.h> enum nl80211_reg_rule_flags

Well, it already doesn't:

> flag_definitions = {
> 'NO-OFDM': 1<<0,
> 'NO-CCK': 1<<1,
> 'NO-INDOOR': 1<<2,
> 'NO-OUTDOOR': 1<<3,
> 'DFS': 1<<4,
> 'PTP-ONLY': 1<<5,
> 'PTMP-ONLY': 1<<6,

Those are fine, and have been like this forever.

> 'NO-IR': 1<<7,
> # hole at bit 8

These used to be PASSIVE-SCAN and NO-IBSS, but bit 8 is still reserved
in the kernel.

> # hole at bit 9. FIXME: Where is NO-HT40 defined?
> 'NO-HT40': 1<<10,

Neither bit 9 nor bit 10 were ever used by the kernel.

Did old userspace create them?

> Which definition is correct now? Should I remove bit9 and bit10 from
> wireless-regdb or skip them in nl80211.h?

Since it's safer to not even have to worry about it, I'll change your
patch to use bit 11.

However, Luis, please sort out this situation, and if bits 9/10 were
ever used by userspace (they were never used by the kernel!) then please
submit a kernel patch that marks them as reserved in nl80211.h. The
kernel header file should be the master file defining the API, not some
"random" userspace tool.

johannes


2014-02-21 08:23:23

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH] cfg80211: regulatory, introduce NL80211_RRF_AUTO_BW rule flag

On Thu, 2014-02-20 at 13:52 +0100, Janusz Dziedzic wrote:
> Introduce NL80211_RRF_AUTO_BW rule flag. If this flag set
> maximum available bandwidth should be calculated base on
> contiguous rules and wider channels will be allowed to cross
> multiple contiguous/overlapping frequency ranges.
>
> In case of old kernels maximum bandwidth from regulatory
> rule will be used, while there is no NL80211_RRF_AUTO_BW flag.

Applied, thanks. I made the snrptinf() code use sizeof() instead of
hardcoding the size twice.

johannes


2014-02-22 00:19:23

by Luis Chamberlain

[permalink] [raw]
Subject: Re: [PATCH] cfg80211: regulatory, introduce NL80211_RRF_AUTO_BW rule flag

On Fri, Feb 21, 2014 at 12:28 AM, Johannes Berg
<[email protected]> wrote:
> However, Luis, please sort out this situation, and if bits 9/10 were
> ever used by userspace (they were never used by the kernel!) then please
> submit a kernel patch that marks them as reserved in nl80211.h. The
> kernel header file should be the master file defining the API, not some
> "random" userspace tool.

Pretty sure NO-HT40 was never used (claimed bit 10), and not sure why
bit bit 9 says reserved, I'm pretty sure it never got used too.

Luis