|
@@ -55,8 +55,17 @@
|
|
|
#define REG_DBG_PRINT(args...)
|
|
|
#endif
|
|
|
|
|
|
+static struct regulatory_request core_request_world = {
|
|
|
+ .initiator = NL80211_REGDOM_SET_BY_CORE,
|
|
|
+ .alpha2[0] = '0',
|
|
|
+ .alpha2[1] = '0',
|
|
|
+ .intersect = false,
|
|
|
+ .processed = true,
|
|
|
+ .country_ie_env = ENVIRON_ANY,
|
|
|
+};
|
|
|
+
|
|
|
/* Receipt of information from last regulatory request */
|
|
|
-static struct regulatory_request *last_request;
|
|
|
+static struct regulatory_request *last_request = &core_request_world;
|
|
|
|
|
|
/* To trigger userspace events */
|
|
|
static struct platform_device *reg_pdev;
|
|
@@ -148,7 +157,7 @@ static char user_alpha2[2];
|
|
|
module_param(ieee80211_regdom, charp, 0444);
|
|
|
MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code");
|
|
|
|
|
|
-static void reset_regdomains(void)
|
|
|
+static void reset_regdomains(bool full_reset)
|
|
|
{
|
|
|
/* avoid freeing static information or freeing something twice */
|
|
|
if (cfg80211_regdomain == cfg80211_world_regdom)
|
|
@@ -163,6 +172,13 @@ static void reset_regdomains(void)
|
|
|
|
|
|
cfg80211_world_regdom = &world_regdom;
|
|
|
cfg80211_regdomain = NULL;
|
|
|
+
|
|
|
+ if (!full_reset)
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (last_request != &core_request_world)
|
|
|
+ kfree(last_request);
|
|
|
+ last_request = &core_request_world;
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -173,7 +189,7 @@ static void update_world_regdomain(const struct ieee80211_regdomain *rd)
|
|
|
{
|
|
|
BUG_ON(!last_request);
|
|
|
|
|
|
- reset_regdomains();
|
|
|
+ reset_regdomains(false);
|
|
|
|
|
|
cfg80211_world_regdom = rd;
|
|
|
cfg80211_regdomain = rd;
|
|
@@ -1405,7 +1421,8 @@ static int __regulatory_hint(struct wiphy *wiphy,
|
|
|
}
|
|
|
|
|
|
new_request:
|
|
|
- kfree(last_request);
|
|
|
+ if (last_request != &core_request_world)
|
|
|
+ kfree(last_request);
|
|
|
|
|
|
last_request = pending_request;
|
|
|
last_request->intersect = intersect;
|
|
@@ -1575,9 +1592,6 @@ static int regulatory_hint_core(const char *alpha2)
|
|
|
{
|
|
|
struct regulatory_request *request;
|
|
|
|
|
|
- kfree(last_request);
|
|
|
- last_request = NULL;
|
|
|
-
|
|
|
request = kzalloc(sizeof(struct regulatory_request),
|
|
|
GFP_KERNEL);
|
|
|
if (!request)
|
|
@@ -1775,7 +1789,7 @@ static void restore_regulatory_settings(bool reset_user)
|
|
|
mutex_lock(&cfg80211_mutex);
|
|
|
mutex_lock(®_mutex);
|
|
|
|
|
|
- reset_regdomains();
|
|
|
+ reset_regdomains(true);
|
|
|
restore_alpha2(alpha2, reset_user);
|
|
|
|
|
|
/*
|
|
@@ -2044,7 +2058,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
|
|
|
int r;
|
|
|
|
|
|
if (last_request->initiator != NL80211_REGDOM_SET_BY_DRIVER) {
|
|
|
- reset_regdomains();
|
|
|
+ reset_regdomains(false);
|
|
|
cfg80211_regdomain = rd;
|
|
|
return 0;
|
|
|
}
|
|
@@ -2065,7 +2079,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
|
|
|
if (r)
|
|
|
return r;
|
|
|
|
|
|
- reset_regdomains();
|
|
|
+ reset_regdomains(false);
|
|
|
cfg80211_regdomain = rd;
|
|
|
return 0;
|
|
|
}
|
|
@@ -2090,7 +2104,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
|
|
|
|
|
|
rd = NULL;
|
|
|
|
|
|
- reset_regdomains();
|
|
|
+ reset_regdomains(false);
|
|
|
cfg80211_regdomain = intersected_rd;
|
|
|
|
|
|
return 0;
|
|
@@ -2110,7 +2124,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
|
|
|
kfree(rd);
|
|
|
rd = NULL;
|
|
|
|
|
|
- reset_regdomains();
|
|
|
+ reset_regdomains(false);
|
|
|
cfg80211_regdomain = intersected_rd;
|
|
|
|
|
|
return 0;
|
|
@@ -2263,11 +2277,8 @@ void /* __init_or_exit */ regulatory_exit(void)
|
|
|
mutex_lock(&cfg80211_mutex);
|
|
|
mutex_lock(®_mutex);
|
|
|
|
|
|
- reset_regdomains();
|
|
|
-
|
|
|
- kfree(last_request);
|
|
|
+ reset_regdomains(true);
|
|
|
|
|
|
- last_request = NULL;
|
|
|
dev_set_uevent_suppress(®_pdev->dev, true);
|
|
|
|
|
|
platform_device_unregister(reg_pdev);
|