aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJanusz Dziedzic <janusz.dziedzic@tieto.com>2014-02-21 13:46:12 -0500
committerJohannes Berg <johannes.berg@intel.com>2014-02-25 11:29:25 -0500
commit089027e57cfa79337feffdd7252c8ba0be352afa (patch)
tree076b28e399d4ae3eca61a5e1dea50057e1ebb1c0 /net
parentfb5c96368fa306dae0f79d0078d2d4e505278204 (diff)
cfg80211: regulatory: allow getting DFS CAC time from userspace
Introduce DFS CAC time as a regd param, configured per REG_RULE and set per channel in cfg80211. DFS CAC time is close connected with regulatory database configuration. Instead of using hardcoded values, get DFS CAC time form regulatory database. Pass DFS CAC time to user mode (mainly for iw reg get, iw list, iw info). Allow setting DFS CAC time via CRDA. Add support for internal regulatory database. Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com> [rewrap commit log] Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r--net/wireless/genregdb.awk8
-rw-r--r--net/wireless/nl80211.c13
-rw-r--r--net/wireless/reg.c32
3 files changed, 45 insertions, 8 deletions
diff --git a/net/wireless/genregdb.awk b/net/wireless/genregdb.awk
index fdfd3f063a9b..b35da8dc85de 100644
--- a/net/wireless/genregdb.awk
+++ b/net/wireless/genregdb.awk
@@ -66,6 +66,7 @@ function parse_reg_rule()
66 units = $8 66 units = $8
67 sub(/\)/, "", units) 67 sub(/\)/, "", units)
68 sub(/,/, "", units) 68 sub(/,/, "", units)
69 dfs_cac = $9
69 if (units == "mW") { 70 if (units == "mW") {
70 if (power == 100) { 71 if (power == 100) {
71 power = 20 72 power = 20
@@ -78,7 +79,12 @@ function parse_reg_rule()
78 } else { 79 } else {
79 print "Unknown power value in database!" 80 print "Unknown power value in database!"
80 } 81 }
82 } else {
83 dfs_cac = $8
81 } 84 }
85 sub(/,/, "", dfs_cac)
86 sub(/\(/, "", dfs_cac)
87 sub(/\)/, "", dfs_cac)
82 flagstr = "" 88 flagstr = ""
83 for (i=8; i<=NF; i++) 89 for (i=8; i<=NF; i++)
84 flagstr = flagstr $i 90 flagstr = flagstr $i
@@ -111,7 +117,7 @@ function parse_reg_rule()
111 117
112 } 118 }
113 flags = flags "0" 119 flags = flags "0"
114 printf "\t\tREG_RULE(%d, %d, %d, %d, %d, %s),\n", start, end, bw, gain, power, flags 120 printf "\t\tREG_RULE_EXT(%d, %d, %d, %d, %d, %d, %s),\n", start, end, bw, gain, power, dfs_cac, flags
115 rules++ 121 rules++
116} 122}
117 123
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 2c38b28a85b9..9f7ebf94a050 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -593,6 +593,10 @@ static int nl80211_msg_put_channel(struct sk_buff *msg,
593 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_TIME, 593 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_TIME,
594 time)) 594 time))
595 goto nla_put_failure; 595 goto nla_put_failure;
596 if (nla_put_u32(msg,
597 NL80211_FREQUENCY_ATTR_DFS_CAC_TIME,
598 chan->dfs_cac_ms))
599 goto nla_put_failure;
596 } 600 }
597 } 601 }
598 602
@@ -4614,6 +4618,7 @@ static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] =
4614 [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 }, 4618 [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 },
4615 [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 }, 4619 [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 },
4616 [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 }, 4620 [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
4621 [NL80211_ATTR_DFS_CAC_TIME] = { .type = NLA_U32 },
4617}; 4622};
4618 4623
4619static int parse_reg_rule(struct nlattr *tb[], 4624static int parse_reg_rule(struct nlattr *tb[],
@@ -4649,6 +4654,10 @@ static int parse_reg_rule(struct nlattr *tb[],
4649 power_rule->max_antenna_gain = 4654 power_rule->max_antenna_gain =
4650 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]); 4655 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]);
4651 4656
4657 if (tb[NL80211_ATTR_DFS_CAC_TIME])
4658 reg_rule->dfs_cac_ms =
4659 nla_get_u32(tb[NL80211_ATTR_DFS_CAC_TIME]);
4660
4652 return 0; 4661 return 0;
4653} 4662}
4654 4663
@@ -5136,7 +5145,9 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
5136 nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN, 5145 nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN,
5137 power_rule->max_antenna_gain) || 5146 power_rule->max_antenna_gain) ||
5138 nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_EIRP, 5147 nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_EIRP,
5139 power_rule->max_eirp)) 5148 power_rule->max_eirp) ||
5149 nla_put_u32(msg, NL80211_ATTR_DFS_CAC_TIME,
5150 reg_rule->dfs_cac_ms))
5140 goto nla_put_failure_rcu; 5151 goto nla_put_failure_rcu;
5141 5152
5142 nla_nest_end(msg, nl_reg_rule); 5153 nla_nest_end(msg, nl_reg_rule);
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 651404c22de9..b95e9cf139c0 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -756,6 +756,9 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1,
756 power_rule->max_antenna_gain = min(power_rule1->max_antenna_gain, 756 power_rule->max_antenna_gain = min(power_rule1->max_antenna_gain,
757 power_rule2->max_antenna_gain); 757 power_rule2->max_antenna_gain);
758 758
759 intersected_rule->dfs_cac_ms = max(rule1->dfs_cac_ms,
760 rule2->dfs_cac_ms);
761
759 if (!is_valid_reg_rule(intersected_rule)) 762 if (!is_valid_reg_rule(intersected_rule))
760 return -EINVAL; 763 return -EINVAL;
761 764
@@ -1078,6 +1081,14 @@ static void handle_channel(struct wiphy *wiphy,
1078 min_t(int, chan->orig_mag, 1081 min_t(int, chan->orig_mag,
1079 MBI_TO_DBI(power_rule->max_antenna_gain)); 1082 MBI_TO_DBI(power_rule->max_antenna_gain));
1080 chan->max_reg_power = (int) MBM_TO_DBM(power_rule->max_eirp); 1083 chan->max_reg_power = (int) MBM_TO_DBM(power_rule->max_eirp);
1084
1085 if (chan->flags & IEEE80211_CHAN_RADAR) {
1086 if (reg_rule->dfs_cac_ms)
1087 chan->dfs_cac_ms = reg_rule->dfs_cac_ms;
1088 else
1089 chan->dfs_cac_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
1090 }
1091
1081 if (chan->orig_mpwr) { 1092 if (chan->orig_mpwr) {
1082 /* 1093 /*
1083 * Devices that use REGULATORY_COUNTRY_IE_FOLLOW_POWER 1094 * Devices that use REGULATORY_COUNTRY_IE_FOLLOW_POWER
@@ -2256,9 +2267,9 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd)
2256 const struct ieee80211_reg_rule *reg_rule = NULL; 2267 const struct ieee80211_reg_rule *reg_rule = NULL;
2257 const struct ieee80211_freq_range *freq_range = NULL; 2268 const struct ieee80211_freq_range *freq_range = NULL;
2258 const struct ieee80211_power_rule *power_rule = NULL; 2269 const struct ieee80211_power_rule *power_rule = NULL;
2259 char bw[32]; 2270 char bw[32], cac_time[32];
2260 2271
2261 pr_info(" (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)\n"); 2272 pr_info(" (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp), (dfs_cac_time)\n");
2262 2273
2263 for (i = 0; i < rd->n_reg_rules; i++) { 2274 for (i = 0; i < rd->n_reg_rules; i++) {
2264 reg_rule = &rd->reg_rules[i]; 2275 reg_rule = &rd->reg_rules[i];
@@ -2273,23 +2284,32 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd)
2273 snprintf(bw, sizeof(bw), "%d KHz", 2284 snprintf(bw, sizeof(bw), "%d KHz",
2274 freq_range->max_bandwidth_khz); 2285 freq_range->max_bandwidth_khz);
2275 2286
2287 if (reg_rule->flags & NL80211_RRF_DFS)
2288 scnprintf(cac_time, sizeof(cac_time), "%u s",
2289 reg_rule->dfs_cac_ms/1000);
2290 else
2291 scnprintf(cac_time, sizeof(cac_time), "N/A");
2292
2293
2276 /* 2294 /*
2277 * There may not be documentation for max antenna gain 2295 * There may not be documentation for max antenna gain
2278 * in certain regions 2296 * in certain regions
2279 */ 2297 */
2280 if (power_rule->max_antenna_gain) 2298 if (power_rule->max_antenna_gain)
2281 pr_info(" (%d KHz - %d KHz @ %s), (%d mBi, %d mBm)\n", 2299 pr_info(" (%d KHz - %d KHz @ %s), (%d mBi, %d mBm), (%s)\n",
2282 freq_range->start_freq_khz, 2300 freq_range->start_freq_khz,
2283 freq_range->end_freq_khz, 2301 freq_range->end_freq_khz,
2284 bw, 2302 bw,
2285 power_rule->max_antenna_gain, 2303 power_rule->max_antenna_gain,
2286 power_rule->max_eirp); 2304 power_rule->max_eirp,
2305 cac_time);
2287 else 2306 else
2288 pr_info(" (%d KHz - %d KHz @ %s), (N/A, %d mBm)\n", 2307 pr_info(" (%d KHz - %d KHz @ %s), (N/A, %d mBm), (%s)\n",
2289 freq_range->start_freq_khz, 2308 freq_range->start_freq_khz,
2290 freq_range->end_freq_khz, 2309 freq_range->end_freq_khz,
2291 bw, 2310 bw,
2292 power_rule->max_eirp); 2311 power_rule->max_eirp,
2312 cac_time);
2293 } 2313 }
2294} 2314}
2295 2315