aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorLuis R. Rodriguez <mcgrof@qca.qualcomm.com>2011-10-11 13:59:02 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-11-21 16:20:41 -0500
commit8b60b07805d557542160d852874fa6a1b969184e (patch)
tree74b96b63c62cf7cef9684c19bda8f8d51ceabe0d /net/wireless
parent4713e962c5d98901890c446843ae4e0a9d37b7b3 (diff)
cfg80211: process regulatory DFS region for countries
The wireless-regdb now has support for mapping a country to one DFS region. CRDA sends this to us now so process it so we can provide that hint to drivers. This will later be used by code for processing DFS in a way that meets the criteria for the DFS region the country belongs to. Signed-off-by: Luis R. Rodriguez <mcgrof@qca.qualcomm.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/nl80211.c15
-rw-r--r--net/wireless/reg.c37
-rw-r--r--net/wireless/reg.h1
3 files changed, 53 insertions, 0 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 6bc7c4b32fa5..50482e129263 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -199,6 +199,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
199 [NL80211_ATTR_DONT_WAIT_FOR_ACK] = { .type = NLA_FLAG }, 199 [NL80211_ATTR_DONT_WAIT_FOR_ACK] = { .type = NLA_FLAG },
200 [NL80211_ATTR_PROBE_RESP] = { .type = NLA_BINARY, 200 [NL80211_ATTR_PROBE_RESP] = { .type = NLA_BINARY,
201 .len = IEEE80211_MAX_DATA_LEN }, 201 .len = IEEE80211_MAX_DATA_LEN },
202 [NL80211_ATTR_DFS_REGION] = { .type = NLA_U8 },
202}; 203};
203 204
204/* policy for the key attributes */ 205/* policy for the key attributes */
@@ -3382,6 +3383,9 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
3382 3383
3383 NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2, 3384 NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2,
3384 cfg80211_regdomain->alpha2); 3385 cfg80211_regdomain->alpha2);
3386 if (cfg80211_regdomain->dfs_region)
3387 NLA_PUT_U8(msg, NL80211_ATTR_DFS_REGION,
3388 cfg80211_regdomain->dfs_region);
3385 3389
3386 nl_reg_rules = nla_nest_start(msg, NL80211_ATTR_REG_RULES); 3390 nl_reg_rules = nla_nest_start(msg, NL80211_ATTR_REG_RULES);
3387 if (!nl_reg_rules) 3391 if (!nl_reg_rules)
@@ -3440,6 +3444,7 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
3440 char *alpha2 = NULL; 3444 char *alpha2 = NULL;
3441 int rem_reg_rules = 0, r = 0; 3445 int rem_reg_rules = 0, r = 0;
3442 u32 num_rules = 0, rule_idx = 0, size_of_regd; 3446 u32 num_rules = 0, rule_idx = 0, size_of_regd;
3447 u8 dfs_region = 0;
3443 struct ieee80211_regdomain *rd = NULL; 3448 struct ieee80211_regdomain *rd = NULL;
3444 3449
3445 if (!info->attrs[NL80211_ATTR_REG_ALPHA2]) 3450 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
@@ -3450,6 +3455,9 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
3450 3455
3451 alpha2 = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]); 3456 alpha2 = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
3452 3457
3458 if (info->attrs[NL80211_ATTR_DFS_REGION])
3459 dfs_region = nla_get_u8(info->attrs[NL80211_ATTR_DFS_REGION]);
3460
3453 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES], 3461 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
3454 rem_reg_rules) { 3462 rem_reg_rules) {
3455 num_rules++; 3463 num_rules++;
@@ -3477,6 +3485,13 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
3477 rd->alpha2[0] = alpha2[0]; 3485 rd->alpha2[0] = alpha2[0];
3478 rd->alpha2[1] = alpha2[1]; 3486 rd->alpha2[1] = alpha2[1];
3479 3487
3488 /*
3489 * Disable DFS master mode if the DFS region was
3490 * not supported or known on this kernel.
3491 */
3492 if (reg_supported_dfs_region(dfs_region))
3493 rd->dfs_region = dfs_region;
3494
3480 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES], 3495 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
3481 rem_reg_rules) { 3496 rem_reg_rules) {
3482 nla_parse(tb, NL80211_REG_RULE_ATTR_MAX, 3497 nla_parse(tb, NL80211_REG_RULE_ATTR_MAX,
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 2520a1b7e7db..69141ed1f6df 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1946,6 +1946,42 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd)
1946 } 1946 }
1947} 1947}
1948 1948
1949bool reg_supported_dfs_region(u8 dfs_region)
1950{
1951 switch (dfs_region) {
1952 case NL80211_DFS_UNSET:
1953 case NL80211_DFS_FCC:
1954 case NL80211_DFS_ETSI:
1955 case NL80211_DFS_JP:
1956 return true;
1957 default:
1958 REG_DBG_PRINT("Ignoring uknown DFS master region: %d\n",
1959 dfs_region);
1960 return false;
1961 }
1962}
1963
1964static void print_dfs_region(u8 dfs_region)
1965{
1966 if (!dfs_region)
1967 return;
1968
1969 switch (dfs_region) {
1970 case NL80211_DFS_FCC:
1971 pr_info(" DFS Master region FCC");
1972 break;
1973 case NL80211_DFS_ETSI:
1974 pr_info(" DFS Master region ETSI");
1975 break;
1976 case NL80211_DFS_JP:
1977 pr_info(" DFS Master region JP");
1978 break;
1979 default:
1980 pr_info(" DFS Master region Uknown");
1981 break;
1982 }
1983}
1984
1949static void print_regdomain(const struct ieee80211_regdomain *rd) 1985static void print_regdomain(const struct ieee80211_regdomain *rd)
1950{ 1986{
1951 1987
@@ -1973,6 +2009,7 @@ static void print_regdomain(const struct ieee80211_regdomain *rd)
1973 pr_info("Regulatory domain changed to country: %c%c\n", 2009 pr_info("Regulatory domain changed to country: %c%c\n",
1974 rd->alpha2[0], rd->alpha2[1]); 2010 rd->alpha2[0], rd->alpha2[1]);
1975 } 2011 }
2012 print_dfs_region(rd->dfs_region);
1976 print_rd_rules(rd); 2013 print_rd_rules(rd);
1977} 2014}
1978 2015
diff --git a/net/wireless/reg.h b/net/wireless/reg.h
index 4a56799d868d..786e414afd91 100644
--- a/net/wireless/reg.h
+++ b/net/wireless/reg.h
@@ -5,6 +5,7 @@ extern const struct ieee80211_regdomain *cfg80211_regdomain;
5 5
6bool is_world_regdom(const char *alpha2); 6bool is_world_regdom(const char *alpha2);
7bool reg_is_valid_request(const char *alpha2); 7bool reg_is_valid_request(const char *alpha2);
8bool reg_supported_dfs_region(u8 dfs_region);
8 9
9int regulatory_hint_user(const char *alpha2); 10int regulatory_hint_user(const char *alpha2);
10 11