Here's a set of updates to cfg80211 for regulatory.
This paves the way for 11d support and also addresses
recent complaints about no working 5 GHz channels. I believe
the compromise is reasonable.
I haven't tested this yet though, but I'll let you know tomorrow
how they go. Just wanted to get these out for review for now.
I've tested intersection in userspace on CRDA, check out running
./intersect regulatory.bin for an example of it intersecting
all regulatory domains. Special review with this is greatly
appreciated.
Working on 11d should be fairly easy after this.
Luis
On Thu, 2008-10-30 at 09:09 -0700, Luis R. Rodriguez wrote:
> On Thu, Oct 30, 2008 at 2:24 AM, Johannes Berg
> <[email protected]> wrote:
> > Luis R. Rodriguez wrote:
> >> Technically speaking since some countries do not support
> >> some channels in 5 GHz the world regulatory domain should not
> >> use them however APs should *not* be shipped in those countries
> >> which don't allow 5 GHz operation. Because of this we can
> >> safely assume we operate correctly in STA mode by forcing
> >> passive scan and disabling ad-hoc in 5 GHz. We leave out
> >> all DFS channels as we don't support DFS yet.
> >
> > No, this is incorrect. The linux kernel can well act as an AP.
>
> An AP would/should not want to use the world regulatory domain though :)
Yeah but if a user just starts hostapd without crda then we shouldn't
allow it to operate in 5GHz
johannes
There are certain scenerios where we require intersecting
two regulatory domains. This adds intersection support.
When we enable 802.11d support we will use this to intersect
the regulatory domain from the AP's country IE and what our
regulatory agent believes is correct for a country.
This patch enables intersection for now in the case where
the last regdomain was set by a country IE which was parsed
and the user then wants to set the regulatory domain. Since
we don't support country IE parsing yet this code path will not
be hit, however this allows us to pave the way for 11d support.
Intersection code has been tested in userspace with CRDA.
Signed-off-by: Luis R. Rodriguez <[email protected]>
---
net/wireless/reg.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 158 insertions(+), 8 deletions(-)
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index ff706f9..c996a74 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -50,6 +50,7 @@ struct regulatory_request {
struct wiphy *wiphy;
enum reg_set_by initiator;
char alpha2[2];
+ bool intersect;
};
static struct regulatory_request *last_request;
@@ -359,6 +360,143 @@ static u32 freq_max_bandwidth(const struct ieee80211_freq_range *freq_range,
return 0;
}
+/* Helper for regdom_intersect(), this does the real
+ * mathematical intersection fun */
+static int reg_rules_intersect(
+ const struct ieee80211_reg_rule *rule1,
+ const struct ieee80211_reg_rule *rule2,
+ struct ieee80211_reg_rule *intersected_rule)
+{
+ const struct ieee80211_freq_range *freq_range1, *freq_range2;
+ struct ieee80211_freq_range *freq_range;
+ const struct ieee80211_power_rule *power_rule1, *power_rule2;
+ struct ieee80211_power_rule *power_rule;
+ u32 freq_diff;
+
+ freq_range1 = &rule1->freq_range;
+ freq_range2 = &rule2->freq_range;
+ freq_range = &intersected_rule->freq_range;
+
+ power_rule1 = &rule1->power_rule;
+ power_rule2 = &rule2->power_rule;
+ power_rule = &intersected_rule->power_rule;
+
+ freq_range->start_freq_khz = max(freq_range1->start_freq_khz,
+ freq_range2->start_freq_khz);
+ freq_range->end_freq_khz = min(freq_range1->end_freq_khz,
+ freq_range2->end_freq_khz);
+ freq_range->max_bandwidth_khz = min(freq_range1->max_bandwidth_khz,
+ freq_range2->max_bandwidth_khz);
+
+ 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;
+
+ power_rule->max_eirp = min(power_rule1->max_eirp,
+ power_rule2->max_eirp);
+ 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;
+
+ return 0;
+}
+
+/**
+ * regdom_intersect - do the intersection between two regulatory domains
+ * @rd1: first regulatory domain
+ * @rd2: second regulatory domain
+ *
+ * Use this function to get the intersection between two regulatory domains.
+ * Once completed we will mark the alpha2 for the rd as intersected, "98",
+ * as no one single alpha2 can represent this regulatory domain.
+ *
+ * Returns a pointer to the regulatory domain structure which will hold the
+ * resulting intersection of rules between rd1 and rd2. We will
+ * kzalloc() this structure for you.
+ */
+static struct ieee80211_regdomain *regdom_intersect(
+ const struct ieee80211_regdomain *rd1,
+ const struct ieee80211_regdomain *rd2)
+{
+ int r, size_of_regd;
+ unsigned int x, y;
+ unsigned int num_rules = 0, rule_idx = 0;
+ const struct ieee80211_reg_rule *rule1, *rule2;
+ struct ieee80211_reg_rule *intersected_rule;
+ struct ieee80211_regdomain *rd;
+ /* This is just a dummy holder to help us count */
+ struct ieee80211_reg_rule irule;
+
+ /* Uses the stack temporarily for counter arithmetic */
+ intersected_rule = &irule;
+
+ memset(intersected_rule, 0, sizeof(struct ieee80211_reg_rule));
+
+ if (!rd1 || !rd2)
+ return NULL;
+
+ /* First we get a count of the rules we'll need, then we actually
+ * build them. This is to so we can malloc() and free() a
+ * regdomain once. The reason we use reg_rules_intersect() here
+ * is it will return -EINVAL if the rule computed makes no sense.
+ * All rules that do check out OK are valid. */
+
+ for (x = 0; x < rd1->n_reg_rules; x++) {
+ rule1 = &rd1->reg_rules[x];
+ for (y = 0; y < rd2->n_reg_rules; y++) {
+ rule2 = &rd2->reg_rules[y];
+ if (!reg_rules_intersect(rule1, rule2,
+ intersected_rule))
+ num_rules++;
+ memset(intersected_rule, 0,
+ sizeof(struct ieee80211_reg_rule));
+ }
+ }
+
+ if (!num_rules)
+ return NULL;
+
+ size_of_regd = sizeof(struct ieee80211_regdomain) +
+ ((num_rules + 1) * sizeof(struct ieee80211_reg_rule));
+
+ rd = kzalloc(size_of_regd, GFP_KERNEL);
+ if (!rd)
+ return NULL;
+
+ for (x = 0; x < rd1->n_reg_rules; x++) {
+ rule1 = &rd1->reg_rules[x];
+ for (y = 0; y < rd2->n_reg_rules; y++) {
+ rule2 = &rd2->reg_rules[y];
+ /* This time around instead of using the stack lets
+ * write to the target rule directly saving ourselves
+ * a memcpy() */
+ intersected_rule = &rd->reg_rules[rule_idx];
+ r = reg_rules_intersect(rule1, rule2,
+ intersected_rule);
+ /* No need to memset 0 here the intersected rule here as we're
+ * not using the stack anymore on each iteration */
+ if (r)
+ continue;
+ rule_idx++;
+ }
+ }
+
+ if (rule_idx != num_rules) {
+ kfree(rd);
+ return NULL;
+ }
+
+ rd->n_reg_rules = num_rules;
+ rd->alpha2[0] = '9';
+ rd->alpha2[1] = '8';
+
+ return rd;
+}
+
/* XXX: add support for the rest of enum nl80211_reg_rule_flags, we may
* want to just have the channel structure use these */
static u32 map_regdom_flags(u32 rd_flags)
@@ -468,6 +606,10 @@ void wiphy_update_regulatory(struct wiphy *wiphy, enum reg_set_by setby)
}
}
+/* Return value which can be used by ignore_request() to indicate
+ * it has been determined we shoud intersect two regulatory domains */
+#define REG_INTERSECT 1
+
/* This has the logic which determines when a new request
* should be ignored. */
static int ignore_request(struct wiphy *wiphy, enum reg_set_by set_by,
@@ -517,14 +659,8 @@ static int ignore_request(struct wiphy *wiphy, enum reg_set_by set_by,
return -EALREADY;
return 0;
case REGDOM_SET_BY_USER:
- /*
- * If the user wants to override the AP's hint, we may
- * need to follow both and use the intersection. For now,
- * reject any such attempt (but we don't support country
- * IEs right now anyway.)
- */
if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE)
- return -EOPNOTSUPP;
+ return REG_INTERSECT;
return 0;
}
@@ -536,10 +672,14 @@ int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by,
const char *alpha2)
{
struct regulatory_request *request;
+ bool intersect = false;
int r = 0;
r = ignore_request(wiphy, set_by, alpha2);
- if (r)
+
+ if (r == REG_INTERSECT)
+ intersect = true;
+ else if (r)
return r;
switch (set_by) {
@@ -556,6 +696,7 @@ int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by,
request->alpha2[1] = alpha2[1];
request->initiator = set_by;
request->wiphy = wiphy;
+ request->intersect = intersect;
kfree(last_request);
last_request = request;
@@ -648,6 +789,7 @@ void print_regdomain_info(const struct ieee80211_regdomain *rd)
/* Takes ownership of rd only if it doesn't fail */
static int __set_regdom(const struct ieee80211_regdomain *rd)
{
+ const struct ieee80211_regdomain *intersected_rd = NULL;
/* Some basic sanity checks first */
if (is_world_regdom(rd->alpha2)) {
@@ -697,6 +839,14 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
return -EOPNOTSUPP;
}
+ if (unlikely(last_request->intersect)) {
+ intersected_rd = regdom_intersect(rd, cfg80211_regdomain);
+ if (!intersected_rd)
+ return -EINVAL;
+ kfree(rd);
+ rd = intersected_rd;
+ }
+
/* Tada! */
cfg80211_regdomain = rd;
--
1.5.6.3
Technically speaking since some countries do not support
some channels in 5 GHz the world regulatory domain should not
use them however APs should *not* be shipped in those countries
which don't allow 5 GHz operation. Because of this we can
safely assume we operate correctly in STA mode by forcing
passive scan and disabling ad-hoc in 5 GHz. We leave out
all DFS channels as we don't support DFS yet.
Signed-off-by: Luis R. Rodriguez <[email protected]>
---
net/wireless/reg.c | 12 +++++++++++-
1 files changed, 11 insertions(+), 1 deletions(-)
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index dd1020b..ce0c730 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -85,7 +85,11 @@ static u32 supported_bandwidths[] = {
* information to give us an alpha2 */
static const struct ieee80211_regdomain *cfg80211_regdomain;
-/* We keep a static world regulatory domain in case of the absence of CRDA */
+/* We keep a static world regulatory domain in case of the absence of CRDA.
+ * Although some countries disable 5 GHz completely it is up to the APs
+ * sold in those countries to not beacon, we can safely passive scan though
+ * on non DFS channels. We don't support yet DFS so don't include DFS
+ * channels yet (5260 MHz - 5700 MHz) */
static const struct ieee80211_regdomain world_regdom = {
.n_reg_rules = 1,
.alpha2 = "00",
@@ -93,6 +97,12 @@ static const struct ieee80211_regdomain world_regdom = {
REG_RULE(2412-10, 2462+10, 40, 6, 20,
NL80211_RRF_PASSIVE_SCAN |
NL80211_RRF_NO_IBSS),
+ REG_RULE(5170, 5260, 40, 6, 20,
+ NL80211_RRF_PASSIVE_SCAN |
+ NL80211_RRF_NO_IBSS),
+ REG_RULE(5700, 5835, 40, 6, 20,
+ NL80211_RRF_PASSIVE_SCAN |
+ NL80211_RRF_NO_IBSS),
}
};
--
1.5.6.3
Ensure regulatory converstion macros safely accept
multiple arguments and make REG_RULE() use them.
Signed-off-by: Luis R. Rodriguez <[email protected]>
---
include/net/cfg80211.h | 22 +++++++++++-----------
1 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 03e1e88..81c97a7 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -331,19 +331,19 @@ struct ieee80211_regdomain {
struct ieee80211_reg_rule reg_rules[];
};
-#define MHZ_TO_KHZ(freq) (freq * 1000)
-#define KHZ_TO_MHZ(freq) (freq / 1000)
-#define DBI_TO_MBI(gain) (gain * 100)
-#define MBI_TO_DBI(gain) (gain / 100)
-#define DBM_TO_MBM(gain) (gain * 100)
-#define MBM_TO_DBM(gain) (gain / 100)
+#define MHZ_TO_KHZ(freq) ((freq) * 1000)
+#define KHZ_TO_MHZ(freq) ((freq) / 1000)
+#define DBI_TO_MBI(gain) ((gain) * 100)
+#define MBI_TO_DBI(gain) ((gain) / 100)
+#define DBM_TO_MBM(gain) ((gain) * 100)
+#define MBM_TO_DBM(gain) ((gain) / 100)
#define REG_RULE(start, end, bw, gain, eirp, reg_flags) { \
- .freq_range.start_freq_khz = (start) * 1000, \
- .freq_range.end_freq_khz = (end) * 1000, \
- .freq_range.max_bandwidth_khz = (bw) * 1000, \
- .power_rule.max_antenna_gain = (gain) * 100, \
- .power_rule.max_eirp = (eirp) * 100, \
+ .freq_range.start_freq_khz = MHZ_TO_KHZ(start), \
+ .freq_range.end_freq_khz = MHZ_TO_KHZ(end), \
+ .freq_range.max_bandwidth_khz = MHZ_TO_KHZ(bw), \
+ .power_rule.max_antenna_gain = DBI_TO_MBI(gain), \
+ .power_rule.max_eirp = DBM_TO_MBM(eirp), \
.flags = reg_flags, \
}
--
1.5.6.3
On Thu, Oct 30, 2008 at 2:24 AM, Johannes Berg
<[email protected]> wrote:
> Luis R. Rodriguez wrote:
>> Technically speaking since some countries do not support
>> some channels in 5 GHz the world regulatory domain should not
>> use them however APs should *not* be shipped in those countries
>> which don't allow 5 GHz operation. Because of this we can
>> safely assume we operate correctly in STA mode by forcing
>> passive scan and disabling ad-hoc in 5 GHz. We leave out
>> all DFS channels as we don't support DFS yet.
>
> No, this is incorrect. The linux kernel can well act as an AP.
An AP would/should not want to use the world regulatory domain though :)
Luis
On Thu, Oct 30, 2008 at 06:18:57PM +0100, Johannes Berg wrote:
> Yeah but if a user just starts hostapd without crda then we shouldn't
> allow it to operate in 5GHz
Currently, we don't allow that or well, to be more exact, hostapd does
not since it has hardcoded channel list that only allows 2.4 GHz
channels 1-11. Anyway, that is about to change and hostapd will read the
channel lists through nl80211. It looks like 'iw phy info' shows some 5
GHz channels with "radar detection" flag, so it looks like hostapd can,
for now, just drop those channels when CRDA is available. I haven't
actually looked at what happens without CRDA, but anyway, that will
hopefully have similar flag available somehow (or the channels disabled
until such flag becomes available).
--
Jouni Malinen PGP id EFC895FA
As regulatory_request gets bigger there will be more questions
of what things means, so clarify documenation for it and
keep track of the special alpha2 codes we use internally
and on the userspace regulatory agents.
Signed-off-by: Luis R. Rodriguez <[email protected]>
---
net/wireless/reg.c | 22 +++++++++++++++++++---
1 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index be6667a..dd1020b 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -42,9 +42,24 @@
#include "core.h"
#include "reg.h"
-/*
- * wiphy is set if this request's initiator is
- * REGDOM_SET_BY_COUNTRY_IE or _DRIVER
+/**
+ * struct regulatory_request - receipt of last regulatory request
+ *
+ * @wiphy: this is set if this request's initiator is
+ * %REGDOM_SET_BY_COUNTRY_IE or %REGDOM_SET_BY_DRIVER. This
+ * can be used by the wireless core to deal with conflicts
+ * and potentially inform users of which devices specifically
+ * cased the conflicts.
+ * @initiator: indicates who sent this request, could be any of
+ * of those set in reg_set_by, %REGDOM_SET_BY_*
+ * @alpha2: the ISO / IEC 3166 alpha2 country code of the requested
+ * regulatory domain. We have a few special codes:
+ * 00 - World regulatory domain
+ * 99 - built by driver but a specific alpha2 cannot be determined
+ * 98 - result of an intersection between two regulatory domains
+ * @intersect: indicates whether the wireless core should intersect
+ * the requested regulatory domain with the presently set regulatory
+ * domain.
*/
struct regulatory_request {
struct wiphy *wiphy;
@@ -53,6 +68,7 @@ struct regulatory_request {
bool intersect;
};
+/* Receipt of information from last regulatory request */
static struct regulatory_request *last_request;
/* To trigger userspace events */
--
1.5.6.3
Luis R. Rodriguez wrote:
> A regulatory rule is invalid when the frequency difference
> between the end of the frequency range and the start is 0.
>
> Signed-off-by: Luis R. Rodriguez <[email protected]>
> ---
> net/wireless/reg.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/net/wireless/reg.c b/net/wireless/reg.c
> index 9dff716..ff706f9 100644
> --- a/net/wireless/reg.c
> +++ b/net/wireless/reg.c
> @@ -321,7 +321,7 @@ static bool is_valid_reg_rule(const struct
> ieee80211_reg_rule *rule)
>
> freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz;
>
> - if (freq_range->max_bandwidth_khz > freq_diff)
> + if (freq_diff == 0 || freq_range->max_bandwidth_khz > freq_diff)
Might want to make that <= 0 just in case?
johannes
Thix fixes this sparse warning:
net/wireless/reg.c:782:6: warning: symbol 'print_regdomain_info' was not
declared. Should it be static?
Signed-off-by: Luis R. Rodriguez <[email protected]>
---
net/wireless/reg.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index c996a74..be6667a 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -779,7 +779,7 @@ static void print_regdomain(const struct ieee80211_regdomain *rd)
print_rd_rules(rd);
}
-void print_regdomain_info(const struct ieee80211_regdomain *rd)
+static void print_regdomain_info(const struct ieee80211_regdomain *rd)
{
printk(KERN_INFO "cfg80211: Regulatory domain: %c%c\n",
rd->alpha2[0], rd->alpha2[1]);
--
1.5.6.3
A regulatory rule is invalid when the frequency difference
between the end of the frequency range and the start is 0.
Signed-off-by: Luis R. Rodriguez <[email protected]>
---
net/wireless/reg.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 9dff716..ff706f9 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -321,7 +321,7 @@ static bool is_valid_reg_rule(const struct ieee80211_reg_rule *rule)
freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz;
- if (freq_range->max_bandwidth_khz > freq_diff)
+ if (freq_diff == 0 || freq_range->max_bandwidth_khz > freq_diff)
return false;
return true;
--
1.5.6.3
On Thu, Oct 30, 2008 at 2:22 AM, Johannes Berg
<[email protected]> wrote:
> Luis R. Rodriguez wrote:
>> A regulatory rule is invalid when the frequency difference
>> between the end of the frequency range and the start is 0.
>>
>> Signed-off-by: Luis R. Rodriguez <[email protected]>
>> ---
>> net/wireless/reg.c | 2 +-
>> 1 files changed, 1 insertions(+), 1 deletions(-)
>>
>> diff --git a/net/wireless/reg.c b/net/wireless/reg.c
>> index 9dff716..ff706f9 100644
>> --- a/net/wireless/reg.c
>> +++ b/net/wireless/reg.c
>> @@ -321,7 +321,7 @@ static bool is_valid_reg_rule(const struct
>> ieee80211_reg_rule *rule)
>>
>> freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz;
>>
>> - if (freq_range->max_bandwidth_khz > freq_diff)
>> + if (freq_diff == 0 || freq_range->max_bandwidth_khz > freq_diff)
>
> Might want to make that <= 0 just in case?
Absolutely, thanks.
Luis
Luis R. Rodriguez wrote:
> Technically speaking since some countries do not support
> some channels in 5 GHz the world regulatory domain should not
> use them however APs should *not* be shipped in those countries
> which don't allow 5 GHz operation. Because of this we can
> safely assume we operate correctly in STA mode by forcing
> passive scan and disabling ad-hoc in 5 GHz. We leave out
> all DFS channels as we don't support DFS yet.
No, this is incorrect. The linux kernel can well act as an AP.
> Signed-off-by: Luis R. Rodriguez <[email protected]>
> ---
> net/wireless/reg.c | 12 +++++++++++-
> 1 files changed, 11 insertions(+), 1 deletions(-)
>
> diff --git a/net/wireless/reg.c b/net/wireless/reg.c
> index dd1020b..ce0c730 100644
> --- a/net/wireless/reg.c
> +++ b/net/wireless/reg.c
> @@ -85,7 +85,11 @@ static u32 supported_bandwidths[] = {
> * information to give us an alpha2 */
> static const struct ieee80211_regdomain *cfg80211_regdomain;
>
> -/* We keep a static world regulatory domain in case of the absence of
> CRDA */
> +/* We keep a static world regulatory domain in case of the absence of
> CRDA.
> + * Although some countries disable 5 GHz completely it is up to the APs
> + * sold in those countries to not beacon, we can safely passive scan
> though
> + * on non DFS channels. We don't support yet DFS so don't include DFS
> + * channels yet (5260 MHz - 5700 MHz) */
> static const struct ieee80211_regdomain world_regdom = {
> .n_reg_rules = 1,
> .alpha2 = "00",
> @@ -93,6 +97,12 @@ static const struct ieee80211_regdomain world_regdom =
> {
> REG_RULE(2412-10, 2462+10, 40, 6, 20,
> NL80211_RRF_PASSIVE_SCAN |
> NL80211_RRF_NO_IBSS),
> + REG_RULE(5170, 5260, 40, 6, 20,
> + NL80211_RRF_PASSIVE_SCAN |
> + NL80211_RRF_NO_IBSS),
> + REG_RULE(5700, 5835, 40, 6, 20,
> + NL80211_RRF_PASSIVE_SCAN |
> + NL80211_RRF_NO_IBSS),
> }
> };
>
> --
> 1.5.6.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless"
> in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
>
On Thu, Oct 30, 2008 at 10:18 AM, Johannes Berg
<[email protected]> wrote:
> On Thu, 2008-10-30 at 09:09 -0700, Luis R. Rodriguez wrote:
>> On Thu, Oct 30, 2008 at 2:24 AM, Johannes Berg
>> <[email protected]> wrote:
>> > Luis R. Rodriguez wrote:
>> >> Technically speaking since some countries do not support
>> >> some channels in 5 GHz the world regulatory domain should not
>> >> use them however APs should *not* be shipped in those countries
>> >> which don't allow 5 GHz operation. Because of this we can
>> >> safely assume we operate correctly in STA mode by forcing
>> >> passive scan and disabling ad-hoc in 5 GHz. We leave out
>> >> all DFS channels as we don't support DFS yet.
>> >
>> > No, this is incorrect. The linux kernel can well act as an AP.
>>
>> An AP would/should not want to use the world regulatory domain though :)
>
> Yeah but if a user just starts hostapd without crda then we shouldn't
> allow it to operate in 5GHz
Should we rename NO-IBSS to NO-BEACONS ? This would mean we would not
allow IBSS, AP or Mesh.
Luis