aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/wireless/reg.c43
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
58static 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 */
59static struct regulatory_request *last_request; 68static struct regulatory_request *last_request = &core_request_world;
60 69
61/* To trigger userspace events */ 70/* To trigger userspace events */
62static struct platform_device *reg_pdev; 71static struct platform_device *reg_pdev;
@@ -148,7 +157,7 @@ static char user_alpha2[2];
148module_param(ieee80211_regdom, charp, 0444); 157module_param(ieee80211_regdom, charp, 0444);
149MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code"); 158MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code");
150 159
151static void reset_regdomains(void) 160static 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
1407new_request: 1423new_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(&reg_mutex); 1790 mutex_lock(&reg_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(&reg_mutex); 2278 mutex_lock(&reg_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(&reg_pdev->dev, true); 2282 dev_set_uevent_suppress(&reg_pdev->dev, true);
2272 2283
2273 platform_device_unregister(reg_pdev); 2284 platform_device_unregister(reg_pdev);