aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorIlan peer <ilan.peer@intel.com>2015-03-30 08:15:49 -0400
committerJohannes Berg <johannes.berg@intel.com>2015-04-01 05:22:38 -0400
commitc37722bd1972118142ee54c0e1a727142d944068 (patch)
tree6f07eb73e85fdc58258044610586726138f3a5ee /net/wireless
parent7bedd0cfad4e122bc0ddaf3fc955a38c88c95d35 (diff)
cfg80211: Stop calling crda if it is not responsive
Patch eeca9fce1d71a4955855ceb0c3b13c1eb9db27c1 (cfg80211: Schedule timeout for all CRDA call) introduced a regression, where in case that crda is not installed (or not configured properly etc.), the regulatory core will needlessly continue to call it, polluting the log with the following log: "cfg80211: Calling CRDA to update world regulatory domain" Fix this by limiting the number of continuous CRDA request failures. Signed-off-by: Ilan Peer <ilan.peer@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/nl80211.c2
-rw-r--r--net/wireless/reg.c34
-rw-r--r--net/wireless/reg.h9
3 files changed, 38 insertions, 7 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 6dd1ab3b10ea..dd78445c7d50 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -5664,7 +5664,7 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
5664 } 5664 }
5665 } 5665 }
5666 5666
5667 r = set_regdom(rd); 5667 r = set_regdom(rd, REGD_SOURCE_CRDA);
5668 /* set_regdom took ownership */ 5668 /* set_regdom took ownership */
5669 rd = NULL; 5669 rd = NULL;
5670 5670
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index be5f81caa488..0e347f888fe9 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -135,6 +135,11 @@ 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 */
139#define REG_MAX_CRDA_TIMEOUTS 10
140
141static u32 reg_crda_timeouts;
142
138static const struct ieee80211_regdomain *get_cfg80211_regdom(void) 143static const struct ieee80211_regdomain *get_cfg80211_regdom(void)
139{ 144{
140 return rtnl_dereference(cfg80211_regdomain); 145 return rtnl_dereference(cfg80211_regdomain);
@@ -485,7 +490,7 @@ static void reg_regdb_search(struct work_struct *work)
485 mutex_unlock(&reg_regdb_search_mutex); 490 mutex_unlock(&reg_regdb_search_mutex);
486 491
487 if (!IS_ERR_OR_NULL(regdom)) 492 if (!IS_ERR_OR_NULL(regdom))
488 set_regdom(regdom); 493 set_regdom(regdom, REGD_SOURCE_INTERNAL_DB);
489 494
490 rtnl_unlock(); 495 rtnl_unlock();
491} 496}
@@ -535,15 +540,20 @@ static int call_crda(const char *alpha2)
535 snprintf(country, sizeof(country), "COUNTRY=%c%c", 540 snprintf(country, sizeof(country), "COUNTRY=%c%c",
536 alpha2[0], alpha2[1]); 541 alpha2[0], alpha2[1]);
537 542
543 /* query internal regulatory database (if it exists) */
544 reg_regdb_query(alpha2);
545
546 if (reg_crda_timeouts > REG_MAX_CRDA_TIMEOUTS) {
547 pr_info("Exceeded CRDA call max attempts. Not calling CRDA\n");
548 return -EINVAL;
549 }
550
538 if (!is_world_regdom((char *) alpha2)) 551 if (!is_world_regdom((char *) alpha2))
539 pr_info("Calling CRDA for country: %c%c\n", 552 pr_info("Calling CRDA for country: %c%c\n",
540 alpha2[0], alpha2[1]); 553 alpha2[0], alpha2[1]);
541 else 554 else
542 pr_info("Calling CRDA to update world regulatory domain\n"); 555 pr_info("Calling CRDA to update world regulatory domain\n");
543 556
544 /* query internal regulatory database (if it exists) */
545 reg_regdb_query(alpha2);
546
547 return kobject_uevent_env(&reg_pdev->dev.kobj, KOBJ_CHANGE, env); 557 return kobject_uevent_env(&reg_pdev->dev.kobj, KOBJ_CHANGE, env);
548} 558}
549 559
@@ -2293,6 +2303,9 @@ int regulatory_hint_user(const char *alpha2,
2293 request->initiator = NL80211_REGDOM_SET_BY_USER; 2303 request->initiator = NL80211_REGDOM_SET_BY_USER;
2294 request->user_reg_hint_type = user_reg_hint_type; 2304 request->user_reg_hint_type = user_reg_hint_type;
2295 2305
2306 /* Allow calling CRDA again */
2307 reg_crda_timeouts = 0;
2308
2296 queue_regulatory_request(request); 2309 queue_regulatory_request(request);
2297 2310
2298 return 0; 2311 return 0;
@@ -2362,6 +2375,9 @@ int regulatory_hint(struct wiphy *wiphy, const char *alpha2)
2362 request->alpha2[1] = alpha2[1]; 2375 request->alpha2[1] = alpha2[1];
2363 request->initiator = NL80211_REGDOM_SET_BY_DRIVER; 2376 request->initiator = NL80211_REGDOM_SET_BY_DRIVER;
2364 2377
2378 /* Allow calling CRDA again */
2379 reg_crda_timeouts = 0;
2380
2365 queue_regulatory_request(request); 2381 queue_regulatory_request(request);
2366 2382
2367 return 0; 2383 return 0;
@@ -2415,6 +2431,9 @@ void regulatory_hint_country_ie(struct wiphy *wiphy, enum ieee80211_band band,
2415 request->initiator = NL80211_REGDOM_SET_BY_COUNTRY_IE; 2431 request->initiator = NL80211_REGDOM_SET_BY_COUNTRY_IE;
2416 request->country_ie_env = env; 2432 request->country_ie_env = env;
2417 2433
2434 /* Allow calling CRDA again */
2435 reg_crda_timeouts = 0;
2436
2418 queue_regulatory_request(request); 2437 queue_regulatory_request(request);
2419 request = NULL; 2438 request = NULL;
2420out: 2439out:
@@ -2893,7 +2912,8 @@ static int reg_set_rd_country_ie(const struct ieee80211_regdomain *rd,
2893 * multiple drivers can be ironed out later. Caller must've already 2912 * multiple drivers can be ironed out later. Caller must've already
2894 * kmalloc'd the rd structure. 2913 * kmalloc'd the rd structure.
2895 */ 2914 */
2896int set_regdom(const struct ieee80211_regdomain *rd) 2915int set_regdom(const struct ieee80211_regdomain *rd,
2916 enum ieee80211_regd_source regd_src)
2897{ 2917{
2898 struct regulatory_request *lr; 2918 struct regulatory_request *lr;
2899 bool user_reset = false; 2919 bool user_reset = false;
@@ -2904,6 +2924,9 @@ int set_regdom(const struct ieee80211_regdomain *rd)
2904 return -EINVAL; 2924 return -EINVAL;
2905 } 2925 }
2906 2926
2927 if (regd_src == REGD_SOURCE_CRDA)
2928 reg_crda_timeouts = 0;
2929
2907 lr = get_last_request(); 2930 lr = get_last_request();
2908 2931
2909 /* Note that this doesn't update the wiphys, this is done below */ 2932 /* Note that this doesn't update the wiphys, this is done below */
@@ -3063,6 +3086,7 @@ static void reg_timeout_work(struct work_struct *work)
3063{ 3086{
3064 REG_DBG_PRINT("Timeout while waiting for CRDA to reply, restoring regulatory settings\n"); 3087 REG_DBG_PRINT("Timeout while waiting for CRDA to reply, restoring regulatory settings\n");
3065 rtnl_lock(); 3088 rtnl_lock();
3089 reg_crda_timeouts++;
3066 restore_regulatory_settings(true); 3090 restore_regulatory_settings(true);
3067 rtnl_unlock(); 3091 rtnl_unlock();
3068} 3092}
diff --git a/net/wireless/reg.h b/net/wireless/reg.h
index a2c4e16459da..9f495d76eca0 100644
--- a/net/wireless/reg.h
+++ b/net/wireless/reg.h
@@ -16,6 +16,11 @@
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */ 17 */
18 18
19enum ieee80211_regd_source {
20 REGD_SOURCE_INTERNAL_DB,
21 REGD_SOURCE_CRDA,
22};
23
19extern const struct ieee80211_regdomain __rcu *cfg80211_regdomain; 24extern const struct ieee80211_regdomain __rcu *cfg80211_regdomain;
20 25
21bool reg_is_valid_request(const char *alpha2); 26bool reg_is_valid_request(const char *alpha2);
@@ -46,7 +51,9 @@ void wiphy_regulatory_deregister(struct wiphy *wiphy);
46int __init regulatory_init(void); 51int __init regulatory_init(void);
47void regulatory_exit(void); 52void regulatory_exit(void);
48 53
49int set_regdom(const struct ieee80211_regdomain *rd); 54int set_regdom(const struct ieee80211_regdomain *rd,
55 enum ieee80211_regd_source regd_src);
56
50unsigned int reg_get_max_bandwidth(const struct ieee80211_regdomain *rd, 57unsigned int reg_get_max_bandwidth(const struct ieee80211_regdomain *rd,
51 const struct ieee80211_reg_rule *rule); 58 const struct ieee80211_reg_rule *rule);
52 59