diff options
-rw-r--r-- | net/wireless/reg.c | 43 |
1 files changed, 27 insertions, 16 deletions
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 186b7f2a27b6..0ec40715a67b 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -55,8 +55,17 @@ | |||
55 | #define REG_DBG_PRINT(args...) | 55 | #define REG_DBG_PRINT(args...) |
56 | #endif | 56 | #endif |
57 | 57 | ||
58 | static struct regulatory_request core_request_world = { | ||
59 | .initiator = NL80211_REGDOM_SET_BY_CORE, | ||
60 | .alpha2[0] = '0', | ||
61 | .alpha2[1] = '0', | ||
62 | .intersect = false, | ||
63 | .processed = true, | ||
64 | .country_ie_env = ENVIRON_ANY, | ||
65 | }; | ||
66 | |||
58 | /* Receipt of information from last regulatory request */ | 67 | /* Receipt of information from last regulatory request */ |
59 | static struct regulatory_request *last_request; | 68 | static struct regulatory_request *last_request = &core_request_world; |
60 | 69 | ||
61 | /* To trigger userspace events */ | 70 | /* To trigger userspace events */ |
62 | static struct platform_device *reg_pdev; | 71 | static struct platform_device *reg_pdev; |
@@ -148,7 +157,7 @@ static char user_alpha2[2]; | |||
148 | module_param(ieee80211_regdom, charp, 0444); | 157 | module_param(ieee80211_regdom, charp, 0444); |
149 | MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code"); | 158 | MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code"); |
150 | 159 | ||
151 | static void reset_regdomains(void) | 160 | static void reset_regdomains(bool full_reset) |
152 | { | 161 | { |
153 | /* avoid freeing static information or freeing something twice */ | 162 | /* avoid freeing static information or freeing something twice */ |
154 | if (cfg80211_regdomain == cfg80211_world_regdom) | 163 | if (cfg80211_regdomain == cfg80211_world_regdom) |
@@ -163,6 +172,13 @@ static void reset_regdomains(void) | |||
163 | 172 | ||
164 | cfg80211_world_regdom = &world_regdom; | 173 | cfg80211_world_regdom = &world_regdom; |
165 | cfg80211_regdomain = NULL; | 174 | cfg80211_regdomain = NULL; |
175 | |||
176 | if (!full_reset) | ||
177 | return; | ||
178 | |||
179 | if (last_request != &core_request_world) | ||
180 | kfree(last_request); | ||
181 | last_request = &core_request_world; | ||
166 | } | 182 | } |
167 | 183 | ||
168 | /* | 184 | /* |
@@ -173,7 +189,7 @@ static void update_world_regdomain(const struct ieee80211_regdomain *rd) | |||
173 | { | 189 | { |
174 | BUG_ON(!last_request); | 190 | BUG_ON(!last_request); |
175 | 191 | ||
176 | reset_regdomains(); | 192 | reset_regdomains(false); |
177 | 193 | ||
178 | cfg80211_world_regdom = rd; | 194 | cfg80211_world_regdom = rd; |
179 | cfg80211_regdomain = rd; | 195 | cfg80211_regdomain = rd; |
@@ -1405,7 +1421,8 @@ static int __regulatory_hint(struct wiphy *wiphy, | |||
1405 | } | 1421 | } |
1406 | 1422 | ||
1407 | new_request: | 1423 | new_request: |
1408 | kfree(last_request); | 1424 | if (last_request != &core_request_world) |
1425 | kfree(last_request); | ||
1409 | 1426 | ||
1410 | last_request = pending_request; | 1427 | last_request = pending_request; |
1411 | last_request->intersect = intersect; | 1428 | last_request->intersect = intersect; |
@@ -1575,9 +1592,6 @@ static int regulatory_hint_core(const char *alpha2) | |||
1575 | { | 1592 | { |
1576 | struct regulatory_request *request; | 1593 | struct regulatory_request *request; |
1577 | 1594 | ||
1578 | kfree(last_request); | ||
1579 | last_request = NULL; | ||
1580 | |||
1581 | request = kzalloc(sizeof(struct regulatory_request), | 1595 | request = kzalloc(sizeof(struct regulatory_request), |
1582 | GFP_KERNEL); | 1596 | GFP_KERNEL); |
1583 | if (!request) | 1597 | if (!request) |
@@ -1775,7 +1789,7 @@ static void restore_regulatory_settings(bool reset_user) | |||
1775 | mutex_lock(&cfg80211_mutex); | 1789 | mutex_lock(&cfg80211_mutex); |
1776 | mutex_lock(®_mutex); | 1790 | mutex_lock(®_mutex); |
1777 | 1791 | ||
1778 | reset_regdomains(); | 1792 | reset_regdomains(true); |
1779 | restore_alpha2(alpha2, reset_user); | 1793 | restore_alpha2(alpha2, reset_user); |
1780 | 1794 | ||
1781 | /* | 1795 | /* |
@@ -2044,7 +2058,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd) | |||
2044 | int r; | 2058 | int r; |
2045 | 2059 | ||
2046 | if (last_request->initiator != NL80211_REGDOM_SET_BY_DRIVER) { | 2060 | if (last_request->initiator != NL80211_REGDOM_SET_BY_DRIVER) { |
2047 | reset_regdomains(); | 2061 | reset_regdomains(false); |
2048 | cfg80211_regdomain = rd; | 2062 | cfg80211_regdomain = rd; |
2049 | return 0; | 2063 | return 0; |
2050 | } | 2064 | } |
@@ -2065,7 +2079,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd) | |||
2065 | if (r) | 2079 | if (r) |
2066 | return r; | 2080 | return r; |
2067 | 2081 | ||
2068 | reset_regdomains(); | 2082 | reset_regdomains(false); |
2069 | cfg80211_regdomain = rd; | 2083 | cfg80211_regdomain = rd; |
2070 | return 0; | 2084 | return 0; |
2071 | } | 2085 | } |
@@ -2090,7 +2104,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd) | |||
2090 | 2104 | ||
2091 | rd = NULL; | 2105 | rd = NULL; |
2092 | 2106 | ||
2093 | reset_regdomains(); | 2107 | reset_regdomains(false); |
2094 | cfg80211_regdomain = intersected_rd; | 2108 | cfg80211_regdomain = intersected_rd; |
2095 | 2109 | ||
2096 | return 0; | 2110 | return 0; |
@@ -2110,7 +2124,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd) | |||
2110 | kfree(rd); | 2124 | kfree(rd); |
2111 | rd = NULL; | 2125 | rd = NULL; |
2112 | 2126 | ||
2113 | reset_regdomains(); | 2127 | reset_regdomains(false); |
2114 | cfg80211_regdomain = intersected_rd; | 2128 | cfg80211_regdomain = intersected_rd; |
2115 | 2129 | ||
2116 | return 0; | 2130 | return 0; |
@@ -2263,11 +2277,8 @@ void /* __init_or_exit */ regulatory_exit(void) | |||
2263 | mutex_lock(&cfg80211_mutex); | 2277 | mutex_lock(&cfg80211_mutex); |
2264 | mutex_lock(®_mutex); | 2278 | mutex_lock(®_mutex); |
2265 | 2279 | ||
2266 | reset_regdomains(); | 2280 | reset_regdomains(true); |
2267 | |||
2268 | kfree(last_request); | ||
2269 | 2281 | ||
2270 | last_request = NULL; | ||
2271 | dev_set_uevent_suppress(®_pdev->dev, true); | 2282 | dev_set_uevent_suppress(®_pdev->dev, true); |
2272 | 2283 | ||
2273 | platform_device_unregister(reg_pdev); | 2284 | platform_device_unregister(reg_pdev); |