aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/wireless/Kconfig10
-rw-r--r--net/wireless/nl80211.c104
-rw-r--r--net/wireless/reg.c73
3 files changed, 114 insertions, 73 deletions
diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig
index 4f5543dd2524..da72ed32f143 100644
--- a/net/wireless/Kconfig
+++ b/net/wireless/Kconfig
@@ -174,6 +174,16 @@ config CFG80211_INTERNAL_REGDB
174 174
175 Most distributions have a CRDA package. So if unsure, say N. 175 Most distributions have a CRDA package. So if unsure, say N.
176 176
177config CFG80211_CRDA_SUPPORT
178 bool "support CRDA" if CFG80211_INTERNAL_REGDB
179 default y
180 depends on CFG80211
181 help
182 You should enable this option unless you know for sure you have no
183 need for it, for example when using internal regdb (above.)
184
185 If unsure, say Y.
186
177config CFG80211_WEXT 187config CFG80211_WEXT
178 bool "cfg80211 wireless extensions compatibility" if !CFG80211_WEXT_EXPORT 188 bool "cfg80211 wireless extensions compatibility" if !CFG80211_WEXT_EXPORT
179 depends on CFG80211 189 depends on CFG80211
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 28c29e7da749..d693c9d031fc 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -4944,56 +4944,6 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
4944 return err; 4944 return err;
4945} 4945}
4946 4946
4947static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = {
4948 [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 },
4949 [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 },
4950 [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 },
4951 [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 },
4952 [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 },
4953 [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
4954 [NL80211_ATTR_DFS_CAC_TIME] = { .type = NLA_U32 },
4955};
4956
4957static int parse_reg_rule(struct nlattr *tb[],
4958 struct ieee80211_reg_rule *reg_rule)
4959{
4960 struct ieee80211_freq_range *freq_range = &reg_rule->freq_range;
4961 struct ieee80211_power_rule *power_rule = &reg_rule->power_rule;
4962
4963 if (!tb[NL80211_ATTR_REG_RULE_FLAGS])
4964 return -EINVAL;
4965 if (!tb[NL80211_ATTR_FREQ_RANGE_START])
4966 return -EINVAL;
4967 if (!tb[NL80211_ATTR_FREQ_RANGE_END])
4968 return -EINVAL;
4969 if (!tb[NL80211_ATTR_FREQ_RANGE_MAX_BW])
4970 return -EINVAL;
4971 if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP])
4972 return -EINVAL;
4973
4974 reg_rule->flags = nla_get_u32(tb[NL80211_ATTR_REG_RULE_FLAGS]);
4975
4976 freq_range->start_freq_khz =
4977 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]);
4978 freq_range->end_freq_khz =
4979 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]);
4980 freq_range->max_bandwidth_khz =
4981 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]);
4982
4983 power_rule->max_eirp =
4984 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]);
4985
4986 if (tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN])
4987 power_rule->max_antenna_gain =
4988 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]);
4989
4990 if (tb[NL80211_ATTR_DFS_CAC_TIME])
4991 reg_rule->dfs_cac_ms =
4992 nla_get_u32(tb[NL80211_ATTR_DFS_CAC_TIME]);
4993
4994 return 0;
4995}
4996
4997static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info) 4947static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
4998{ 4948{
4999 char *data = NULL; 4949 char *data = NULL;
@@ -5625,6 +5575,57 @@ out_err:
5625 return err; 5575 return err;
5626} 5576}
5627 5577
5578#ifdef CONFIG_CFG80211_CRDA_SUPPORT
5579static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = {
5580 [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 },
5581 [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 },
5582 [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 },
5583 [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 },
5584 [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 },
5585 [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
5586 [NL80211_ATTR_DFS_CAC_TIME] = { .type = NLA_U32 },
5587};
5588
5589static int parse_reg_rule(struct nlattr *tb[],
5590 struct ieee80211_reg_rule *reg_rule)
5591{
5592 struct ieee80211_freq_range *freq_range = &reg_rule->freq_range;
5593 struct ieee80211_power_rule *power_rule = &reg_rule->power_rule;
5594
5595 if (!tb[NL80211_ATTR_REG_RULE_FLAGS])
5596 return -EINVAL;
5597 if (!tb[NL80211_ATTR_FREQ_RANGE_START])
5598 return -EINVAL;
5599 if (!tb[NL80211_ATTR_FREQ_RANGE_END])
5600 return -EINVAL;
5601 if (!tb[NL80211_ATTR_FREQ_RANGE_MAX_BW])
5602 return -EINVAL;
5603 if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP])
5604 return -EINVAL;
5605
5606 reg_rule->flags = nla_get_u32(tb[NL80211_ATTR_REG_RULE_FLAGS]);
5607
5608 freq_range->start_freq_khz =
5609 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]);
5610 freq_range->end_freq_khz =
5611 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]);
5612 freq_range->max_bandwidth_khz =
5613 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]);
5614
5615 power_rule->max_eirp =
5616 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]);
5617
5618 if (tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN])
5619 power_rule->max_antenna_gain =
5620 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]);
5621
5622 if (tb[NL80211_ATTR_DFS_CAC_TIME])
5623 reg_rule->dfs_cac_ms =
5624 nla_get_u32(tb[NL80211_ATTR_DFS_CAC_TIME]);
5625
5626 return 0;
5627}
5628
5628static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info) 5629static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
5629{ 5630{
5630 struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1]; 5631 struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1];
@@ -5701,6 +5702,7 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
5701 kfree(rd); 5702 kfree(rd);
5702 return r; 5703 return r;
5703} 5704}
5705#endif /* CONFIG_CFG80211_CRDA_SUPPORT */
5704 5706
5705static int validate_scan_freqs(struct nlattr *freqs) 5707static int validate_scan_freqs(struct nlattr *freqs)
5706{ 5708{
@@ -10895,6 +10897,7 @@ static const struct genl_ops nl80211_ops[] = {
10895 .internal_flags = NL80211_FLAG_NEED_RTNL, 10897 .internal_flags = NL80211_FLAG_NEED_RTNL,
10896 /* can be retrieved by unprivileged users */ 10898 /* can be retrieved by unprivileged users */
10897 }, 10899 },
10900#ifdef CONFIG_CFG80211_CRDA_SUPPORT
10898 { 10901 {
10899 .cmd = NL80211_CMD_SET_REG, 10902 .cmd = NL80211_CMD_SET_REG,
10900 .doit = nl80211_set_reg, 10903 .doit = nl80211_set_reg,
@@ -10902,6 +10905,7 @@ static const struct genl_ops nl80211_ops[] = {
10902 .flags = GENL_ADMIN_PERM, 10905 .flags = GENL_ADMIN_PERM,
10903 .internal_flags = NL80211_FLAG_NEED_RTNL, 10906 .internal_flags = NL80211_FLAG_NEED_RTNL,
10904 }, 10907 },
10908#endif
10905 { 10909 {
10906 .cmd = NL80211_CMD_REQ_SET_REG, 10910 .cmd = NL80211_CMD_REQ_SET_REG,
10907 .doit = nl80211_req_set_reg, 10911 .doit = nl80211_req_set_reg,
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 3b3119fa87ae..55462fe04d5d 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -135,10 +135,7 @@ static spinlock_t reg_indoor_lock;
135/* Used to track the userspace process controlling the indoor setting */ 135/* Used to track the userspace process controlling the indoor setting */
136static u32 reg_is_indoor_portid; 136static u32 reg_is_indoor_portid;
137 137
138/* Max number of consecutive attempts to communicate with CRDA */ 138static void restore_regulatory_settings(bool reset_user);
139#define REG_MAX_CRDA_TIMEOUTS 10
140
141static u32 reg_crda_timeouts;
142 139
143static const struct ieee80211_regdomain *get_cfg80211_regdom(void) 140static const struct ieee80211_regdomain *get_cfg80211_regdom(void)
144{ 141{
@@ -226,9 +223,6 @@ static DECLARE_DELAYED_WORK(reg_check_chans, reg_check_chans_work);
226static void reg_todo(struct work_struct *work); 223static void reg_todo(struct work_struct *work);
227static DECLARE_WORK(reg_work, reg_todo); 224static DECLARE_WORK(reg_work, reg_todo);
228 225
229static void reg_timeout_work(struct work_struct *work);
230static DECLARE_DELAYED_WORK(reg_timeout, reg_timeout_work);
231
232/* We keep a static world regulatory domain in case of the absence of CRDA */ 226/* We keep a static world regulatory domain in case of the absence of CRDA */
233static const struct ieee80211_regdomain world_regdom = { 227static const struct ieee80211_regdomain world_regdom = {
234 .n_reg_rules = 8, 228 .n_reg_rules = 8,
@@ -533,6 +527,39 @@ static inline int reg_regdb_query(const char *alpha2)
533} 527}
534#endif /* CONFIG_CFG80211_INTERNAL_REGDB */ 528#endif /* CONFIG_CFG80211_INTERNAL_REGDB */
535 529
530#ifdef CONFIG_CFG80211_CRDA_SUPPORT
531/* Max number of consecutive attempts to communicate with CRDA */
532#define REG_MAX_CRDA_TIMEOUTS 10
533
534static u32 reg_crda_timeouts;
535
536static void crda_timeout_work(struct work_struct *work);
537static DECLARE_DELAYED_WORK(crda_timeout, crda_timeout_work);
538
539static void crda_timeout_work(struct work_struct *work)
540{
541 REG_DBG_PRINT("Timeout while waiting for CRDA to reply, restoring regulatory settings\n");
542 rtnl_lock();
543 reg_crda_timeouts++;
544 restore_regulatory_settings(true);
545 rtnl_unlock();
546}
547
548static void cancel_crda_timeout(void)
549{
550 cancel_delayed_work(&crda_timeout);
551}
552
553static void cancel_crda_timeout_sync(void)
554{
555 cancel_delayed_work_sync(&crda_timeout);
556}
557
558static void reset_crda_timeouts(void)
559{
560 reg_crda_timeouts = 0;
561}
562
536/* 563/*
537 * This lets us keep regulatory code which is updated on a regulatory 564 * This lets us keep regulatory code which is updated on a regulatory
538 * basis in userspace. 565 * basis in userspace.
@@ -562,9 +589,18 @@ static int call_crda(const char *alpha2)
562 return ret; 589 return ret;
563 590
564 queue_delayed_work(system_power_efficient_wq, 591 queue_delayed_work(system_power_efficient_wq,
565 &reg_timeout, msecs_to_jiffies(3142)); 592 &crda_timeout, msecs_to_jiffies(3142));
566 return 0; 593 return 0;
567} 594}
595#else
596static inline void cancel_crda_timeout(void) {}
597static inline void cancel_crda_timeout_sync(void) {}
598static inline void reset_crda_timeouts(void) {}
599static inline int call_crda(const char *alpha2)
600{
601 return -ENODATA;
602}
603#endif /* CONFIG_CFG80211_CRDA_SUPPORT */
568 604
569static bool reg_query_database(struct regulatory_request *request) 605static bool reg_query_database(struct regulatory_request *request)
570{ 606{
@@ -1856,7 +1892,7 @@ static void reg_set_request_processed(void)
1856 need_more_processing = true; 1892 need_more_processing = true;
1857 spin_unlock(&reg_requests_lock); 1893 spin_unlock(&reg_requests_lock);
1858 1894
1859 cancel_delayed_work(&reg_timeout); 1895 cancel_crda_timeout();
1860 1896
1861 if (need_more_processing) 1897 if (need_more_processing)
1862 schedule_work(&reg_work); 1898 schedule_work(&reg_work);
@@ -2355,7 +2391,7 @@ int regulatory_hint_user(const char *alpha2,
2355 request->user_reg_hint_type = user_reg_hint_type; 2391 request->user_reg_hint_type = user_reg_hint_type;
2356 2392
2357 /* Allow calling CRDA again */ 2393 /* Allow calling CRDA again */
2358 reg_crda_timeouts = 0; 2394 reset_crda_timeouts();
2359 2395
2360 queue_regulatory_request(request); 2396 queue_regulatory_request(request);
2361 2397
@@ -2427,7 +2463,7 @@ int regulatory_hint(struct wiphy *wiphy, const char *alpha2)
2427 request->initiator = NL80211_REGDOM_SET_BY_DRIVER; 2463 request->initiator = NL80211_REGDOM_SET_BY_DRIVER;
2428 2464
2429 /* Allow calling CRDA again */ 2465 /* Allow calling CRDA again */
2430 reg_crda_timeouts = 0; 2466 reset_crda_timeouts();
2431 2467
2432 queue_regulatory_request(request); 2468 queue_regulatory_request(request);
2433 2469
@@ -2483,7 +2519,7 @@ void regulatory_hint_country_ie(struct wiphy *wiphy, enum ieee80211_band band,
2483 request->country_ie_env = env; 2519 request->country_ie_env = env;
2484 2520
2485 /* Allow calling CRDA again */ 2521 /* Allow calling CRDA again */
2486 reg_crda_timeouts = 0; 2522 reset_crda_timeouts();
2487 2523
2488 queue_regulatory_request(request); 2524 queue_regulatory_request(request);
2489 request = NULL; 2525 request = NULL;
@@ -2970,7 +3006,7 @@ int set_regdom(const struct ieee80211_regdomain *rd,
2970 } 3006 }
2971 3007
2972 if (regd_src == REGD_SOURCE_CRDA) 3008 if (regd_src == REGD_SOURCE_CRDA)
2973 reg_crda_timeouts = 0; 3009 reset_crda_timeouts();
2974 3010
2975 lr = get_last_request(); 3011 lr = get_last_request();
2976 3012
@@ -3127,15 +3163,6 @@ void wiphy_regulatory_deregister(struct wiphy *wiphy)
3127 lr->country_ie_env = ENVIRON_ANY; 3163 lr->country_ie_env = ENVIRON_ANY;
3128} 3164}
3129 3165
3130static void reg_timeout_work(struct work_struct *work)
3131{
3132 REG_DBG_PRINT("Timeout while waiting for CRDA to reply, restoring regulatory settings\n");
3133 rtnl_lock();
3134 reg_crda_timeouts++;
3135 restore_regulatory_settings(true);
3136 rtnl_unlock();
3137}
3138
3139/* 3166/*
3140 * See http://www.fcc.gov/document/5-ghz-unlicensed-spectrum-unii, for 3167 * See http://www.fcc.gov/document/5-ghz-unlicensed-spectrum-unii, for
3141 * UNII band definitions 3168 * UNII band definitions
@@ -3221,7 +3248,7 @@ void regulatory_exit(void)
3221 struct reg_beacon *reg_beacon, *btmp; 3248 struct reg_beacon *reg_beacon, *btmp;
3222 3249
3223 cancel_work_sync(&reg_work); 3250 cancel_work_sync(&reg_work);
3224 cancel_delayed_work_sync(&reg_timeout); 3251 cancel_crda_timeout_sync();
3225 cancel_delayed_work_sync(&reg_check_chans); 3252 cancel_delayed_work_sync(&reg_check_chans);
3226 3253
3227 /* Lock to suppress warnings */ 3254 /* Lock to suppress warnings */