aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2011-12-02 15:44:03 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-12-02 15:44:03 -0500
commitd7a4858c0fde8383f7aa494eda0fba6bef3f2fec (patch)
tree2cbf6915ea069ada4e3e1bca0b91b12e06500681 /net/wireless
parentba5736a5e9ac20c378ae4179e8a0ed3cc4b44351 (diff)
parent9995ffe5f5fdddcc73e4465cc3f8b38714df8108 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
Conflicts: drivers/net/wireless/iwlwifi/iwl-agn.c drivers/net/wireless/libertas/cfg.c
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/nl80211.c4
-rw-r--r--net/wireless/reg.c48
2 files changed, 36 insertions, 16 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 0ee512b85a1f..8a9b4d817ae6 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -89,8 +89,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
89 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 }, 89 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
90 [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 }, 90 [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
91 91
92 [NL80211_ATTR_MAC] = { .type = NLA_BINARY, .len = ETH_ALEN }, 92 [NL80211_ATTR_MAC] = { .len = ETH_ALEN },
93 [NL80211_ATTR_PREV_BSSID] = { .type = NLA_BINARY, .len = ETH_ALEN }, 93 [NL80211_ATTR_PREV_BSSID] = { .len = ETH_ALEN },
94 94
95 [NL80211_ATTR_KEY] = { .type = NLA_NESTED, }, 95 [NL80211_ATTR_KEY] = { .type = NLA_NESTED, },
96 [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY, 96 [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 0e67016ce78f..70b171a52aea 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -57,8 +57,17 @@
57#define REG_DBG_PRINT(args...) 57#define REG_DBG_PRINT(args...)
58#endif 58#endif
59 59
60static struct regulatory_request core_request_world = {
61 .initiator = NL80211_REGDOM_SET_BY_CORE,
62 .alpha2[0] = '0',
63 .alpha2[1] = '0',
64 .intersect = false,
65 .processed = true,
66 .country_ie_env = ENVIRON_ANY,
67};
68
60/* Receipt of information from last regulatory request */ 69/* Receipt of information from last regulatory request */
61static struct regulatory_request *last_request; 70static struct regulatory_request *last_request = &core_request_world;
62 71
63/* To trigger userspace events */ 72/* To trigger userspace events */
64static struct platform_device *reg_pdev; 73static struct platform_device *reg_pdev;
@@ -150,7 +159,7 @@ static char user_alpha2[2];
150module_param(ieee80211_regdom, charp, 0444); 159module_param(ieee80211_regdom, charp, 0444);
151MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code"); 160MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code");
152 161
153static void reset_regdomains(void) 162static void reset_regdomains(bool full_reset)
154{ 163{
155 /* avoid freeing static information or freeing something twice */ 164 /* avoid freeing static information or freeing something twice */
156 if (cfg80211_regdomain == cfg80211_world_regdom) 165 if (cfg80211_regdomain == cfg80211_world_regdom)
@@ -165,6 +174,13 @@ static void reset_regdomains(void)
165 174
166 cfg80211_world_regdom = &world_regdom; 175 cfg80211_world_regdom = &world_regdom;
167 cfg80211_regdomain = NULL; 176 cfg80211_regdomain = NULL;
177
178 if (!full_reset)
179 return;
180
181 if (last_request != &core_request_world)
182 kfree(last_request);
183 last_request = &core_request_world;
168} 184}
169 185
170/* 186/*
@@ -175,7 +191,7 @@ static void update_world_regdomain(const struct ieee80211_regdomain *rd)
175{ 191{
176 BUG_ON(!last_request); 192 BUG_ON(!last_request);
177 193
178 reset_regdomains(); 194 reset_regdomains(false);
179 195
180 cfg80211_world_regdom = rd; 196 cfg80211_world_regdom = rd;
181 cfg80211_regdomain = rd; 197 cfg80211_regdomain = rd;
@@ -1409,7 +1425,8 @@ static int __regulatory_hint(struct wiphy *wiphy,
1409 } 1425 }
1410 1426
1411new_request: 1427new_request:
1412 kfree(last_request); 1428 if (last_request != &core_request_world)
1429 kfree(last_request);
1413 1430
1414 last_request = pending_request; 1431 last_request = pending_request;
1415 last_request->intersect = intersect; 1432 last_request->intersect = intersect;
@@ -1579,9 +1596,6 @@ static int regulatory_hint_core(const char *alpha2)
1579{ 1596{
1580 struct regulatory_request *request; 1597 struct regulatory_request *request;
1581 1598
1582 kfree(last_request);
1583 last_request = NULL;
1584
1585 request = kzalloc(sizeof(struct regulatory_request), 1599 request = kzalloc(sizeof(struct regulatory_request),
1586 GFP_KERNEL); 1600 GFP_KERNEL);
1587 if (!request) 1601 if (!request)
@@ -1779,7 +1793,7 @@ static void restore_regulatory_settings(bool reset_user)
1779 mutex_lock(&cfg80211_mutex); 1793 mutex_lock(&cfg80211_mutex);
1780 mutex_lock(&reg_mutex); 1794 mutex_lock(&reg_mutex);
1781 1795
1782 reset_regdomains(); 1796 reset_regdomains(true);
1783 restore_alpha2(alpha2, reset_user); 1797 restore_alpha2(alpha2, reset_user);
1784 1798
1785 /* 1799 /*
@@ -2076,12 +2090,18 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
2076 } 2090 }
2077 2091
2078 request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx); 2092 request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx);
2093 if (!request_wiphy &&
2094 (last_request->initiator == NL80211_REGDOM_SET_BY_DRIVER ||
2095 last_request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE)) {
2096 schedule_delayed_work(&reg_timeout, 0);
2097 return -ENODEV;
2098 }
2079 2099
2080 if (!last_request->intersect) { 2100 if (!last_request->intersect) {
2081 int r; 2101 int r;
2082 2102
2083 if (last_request->initiator != NL80211_REGDOM_SET_BY_DRIVER) { 2103 if (last_request->initiator != NL80211_REGDOM_SET_BY_DRIVER) {
2084 reset_regdomains(); 2104 reset_regdomains(false);
2085 cfg80211_regdomain = rd; 2105 cfg80211_regdomain = rd;
2086 return 0; 2106 return 0;
2087 } 2107 }
@@ -2102,7 +2122,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
2102 if (r) 2122 if (r)
2103 return r; 2123 return r;
2104 2124
2105 reset_regdomains(); 2125 reset_regdomains(false);
2106 cfg80211_regdomain = rd; 2126 cfg80211_regdomain = rd;
2107 return 0; 2127 return 0;
2108 } 2128 }
@@ -2127,7 +2147,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
2127 2147
2128 rd = NULL; 2148 rd = NULL;
2129 2149
2130 reset_regdomains(); 2150 reset_regdomains(false);
2131 cfg80211_regdomain = intersected_rd; 2151 cfg80211_regdomain = intersected_rd;
2132 2152
2133 return 0; 2153 return 0;
@@ -2147,7 +2167,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
2147 kfree(rd); 2167 kfree(rd);
2148 rd = NULL; 2168 rd = NULL;
2149 2169
2150 reset_regdomains(); 2170 reset_regdomains(false);
2151 cfg80211_regdomain = intersected_rd; 2171 cfg80211_regdomain = intersected_rd;
2152 2172
2153 return 0; 2173 return 0;
@@ -2300,9 +2320,9 @@ void /* __init_or_exit */ regulatory_exit(void)
2300 mutex_lock(&cfg80211_mutex); 2320 mutex_lock(&cfg80211_mutex);
2301 mutex_lock(&reg_mutex); 2321 mutex_lock(&reg_mutex);
2302 2322
2303 reset_regdomains(); 2323 reset_regdomains(true);
2304 2324
2305 kfree(last_request); 2325 dev_set_uevent_suppress(&reg_pdev->dev, true);
2306 2326
2307 platform_device_unregister(reg_pdev); 2327 platform_device_unregister(reg_pdev);
2308 2328