aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/wireless/core.c35
-rw-r--r--net/wireless/core.h6
-rw-r--r--net/wireless/nl80211.c20
-rw-r--r--net/wireless/reg.c18
4 files changed, 42 insertions, 37 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 35d457b2751e..39d40d1e06db 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -31,7 +31,12 @@ MODULE_DESCRIPTION("wireless configuration support");
31 * only read the list, and that can happen quite 31 * only read the list, and that can happen quite
32 * often because we need to do it for each command */ 32 * often because we need to do it for each command */
33LIST_HEAD(cfg80211_drv_list); 33LIST_HEAD(cfg80211_drv_list);
34DEFINE_MUTEX(cfg80211_drv_mutex); 34
35/*
36 * This is used to protect the cfg80211_drv_list, cfg80211_regdomain, and
37 * the last reguluatory request receipt in regd.c
38 */
39DEFINE_MUTEX(cfg80211_mutex);
35 40
36/* for debugfs */ 41/* for debugfs */
37static struct dentry *ieee80211_debugfs_dir; 42static struct dentry *ieee80211_debugfs_dir;
@@ -55,7 +60,7 @@ cfg80211_drv_by_wiphy_idx(int wiphy_idx)
55 return result; 60 return result;
56} 61}
57 62
58/* requires cfg80211_drv_mutex to be held! */ 63/* requires cfg80211_mutex to be held! */
59static struct cfg80211_registered_device * 64static struct cfg80211_registered_device *
60__cfg80211_drv_from_info(struct genl_info *info) 65__cfg80211_drv_from_info(struct genl_info *info)
61{ 66{
@@ -102,7 +107,7 @@ cfg80211_get_dev_from_info(struct genl_info *info)
102{ 107{
103 struct cfg80211_registered_device *drv; 108 struct cfg80211_registered_device *drv;
104 109
105 mutex_lock(&cfg80211_drv_mutex); 110 mutex_lock(&cfg80211_mutex);
106 drv = __cfg80211_drv_from_info(info); 111 drv = __cfg80211_drv_from_info(info);
107 112
108 /* if it is not an error we grab the lock on 113 /* if it is not an error we grab the lock on
@@ -111,7 +116,7 @@ cfg80211_get_dev_from_info(struct genl_info *info)
111 if (!IS_ERR(drv)) 116 if (!IS_ERR(drv))
112 mutex_lock(&drv->mtx); 117 mutex_lock(&drv->mtx);
113 118
114 mutex_unlock(&cfg80211_drv_mutex); 119 mutex_unlock(&cfg80211_mutex);
115 120
116 return drv; 121 return drv;
117} 122}
@@ -122,7 +127,7 @@ cfg80211_get_dev_from_ifindex(int ifindex)
122 struct cfg80211_registered_device *drv = ERR_PTR(-ENODEV); 127 struct cfg80211_registered_device *drv = ERR_PTR(-ENODEV);
123 struct net_device *dev; 128 struct net_device *dev;
124 129
125 mutex_lock(&cfg80211_drv_mutex); 130 mutex_lock(&cfg80211_mutex);
126 dev = dev_get_by_index(&init_net, ifindex); 131 dev = dev_get_by_index(&init_net, ifindex);
127 if (!dev) 132 if (!dev)
128 goto out; 133 goto out;
@@ -133,7 +138,7 @@ cfg80211_get_dev_from_ifindex(int ifindex)
133 drv = ERR_PTR(-ENODEV); 138 drv = ERR_PTR(-ENODEV);
134 dev_put(dev); 139 dev_put(dev);
135 out: 140 out:
136 mutex_unlock(&cfg80211_drv_mutex); 141 mutex_unlock(&cfg80211_mutex);
137 return drv; 142 return drv;
138} 143}
139 144
@@ -149,7 +154,7 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
149 struct cfg80211_registered_device *drv; 154 struct cfg80211_registered_device *drv;
150 int wiphy_idx, taken = -1, result, digits; 155 int wiphy_idx, taken = -1, result, digits;
151 156
152 mutex_lock(&cfg80211_drv_mutex); 157 mutex_lock(&cfg80211_mutex);
153 158
154 /* prohibit calling the thing phy%d when %d is not its number */ 159 /* prohibit calling the thing phy%d when %d is not its number */
155 sscanf(newname, PHY_NAME "%d%n", &wiphy_idx, &taken); 160 sscanf(newname, PHY_NAME "%d%n", &wiphy_idx, &taken);
@@ -197,7 +202,7 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
197 202
198 result = 0; 203 result = 0;
199out_unlock: 204out_unlock:
200 mutex_unlock(&cfg80211_drv_mutex); 205 mutex_unlock(&cfg80211_mutex);
201 if (result == 0) 206 if (result == 0)
202 nl80211_notify_dev_rename(rdev); 207 nl80211_notify_dev_rename(rdev);
203 208
@@ -224,19 +229,19 @@ struct wiphy *wiphy_new(struct cfg80211_ops *ops, int sizeof_priv)
224 229
225 drv->ops = ops; 230 drv->ops = ops;
226 231
227 mutex_lock(&cfg80211_drv_mutex); 232 mutex_lock(&cfg80211_mutex);
228 233
229 drv->wiphy_idx = wiphy_counter++; 234 drv->wiphy_idx = wiphy_counter++;
230 235
231 if (unlikely(!wiphy_idx_valid(drv->wiphy_idx))) { 236 if (unlikely(!wiphy_idx_valid(drv->wiphy_idx))) {
232 wiphy_counter--; 237 wiphy_counter--;
233 mutex_unlock(&cfg80211_drv_mutex); 238 mutex_unlock(&cfg80211_mutex);
234 /* ugh, wrapped! */ 239 /* ugh, wrapped! */
235 kfree(drv); 240 kfree(drv);
236 return NULL; 241 return NULL;
237 } 242 }
238 243
239 mutex_unlock(&cfg80211_drv_mutex); 244 mutex_unlock(&cfg80211_mutex);
240 245
241 /* give it a proper name */ 246 /* give it a proper name */
242 dev_set_name(&drv->wiphy.dev, PHY_NAME "%d", drv->wiphy_idx); 247 dev_set_name(&drv->wiphy.dev, PHY_NAME "%d", drv->wiphy_idx);
@@ -314,7 +319,7 @@ int wiphy_register(struct wiphy *wiphy)
314 /* check and set up bitrates */ 319 /* check and set up bitrates */
315 ieee80211_set_bitrate_flags(wiphy); 320 ieee80211_set_bitrate_flags(wiphy);
316 321
317 mutex_lock(&cfg80211_drv_mutex); 322 mutex_lock(&cfg80211_mutex);
318 323
319 /* set up regulatory info */ 324 /* set up regulatory info */
320 wiphy_update_regulatory(wiphy, REGDOM_SET_BY_CORE); 325 wiphy_update_regulatory(wiphy, REGDOM_SET_BY_CORE);
@@ -334,7 +339,7 @@ int wiphy_register(struct wiphy *wiphy)
334 339
335 res = 0; 340 res = 0;
336out_unlock: 341out_unlock:
337 mutex_unlock(&cfg80211_drv_mutex); 342 mutex_unlock(&cfg80211_mutex);
338 return res; 343 return res;
339} 344}
340EXPORT_SYMBOL(wiphy_register); 345EXPORT_SYMBOL(wiphy_register);
@@ -344,7 +349,7 @@ void wiphy_unregister(struct wiphy *wiphy)
344 struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy); 349 struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy);
345 350
346 /* protect the device list */ 351 /* protect the device list */
347 mutex_lock(&cfg80211_drv_mutex); 352 mutex_lock(&cfg80211_mutex);
348 353
349 BUG_ON(!list_empty(&drv->netdev_list)); 354 BUG_ON(!list_empty(&drv->netdev_list));
350 355
@@ -370,7 +375,7 @@ void wiphy_unregister(struct wiphy *wiphy)
370 device_del(&drv->wiphy.dev); 375 device_del(&drv->wiphy.dev);
371 debugfs_remove(drv->wiphy.debugfsdir); 376 debugfs_remove(drv->wiphy.debugfsdir);
372 377
373 mutex_unlock(&cfg80211_drv_mutex); 378 mutex_unlock(&cfg80211_mutex);
374} 379}
375EXPORT_SYMBOL(wiphy_unregister); 380EXPORT_SYMBOL(wiphy_unregister);
376 381
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 4f2e0fe38ce3..f3ab00cbf766 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -70,7 +70,7 @@ bool wiphy_idx_valid(int wiphy_idx)
70 return (wiphy_idx >= 0); 70 return (wiphy_idx >= 0);
71} 71}
72 72
73extern struct mutex cfg80211_drv_mutex; 73extern struct mutex cfg80211_mutex;
74extern struct list_head cfg80211_drv_list; 74extern struct list_head cfg80211_drv_list;
75 75
76struct cfg80211_internal_bss { 76struct cfg80211_internal_bss {
@@ -89,13 +89,13 @@ struct cfg80211_internal_bss {
89 * the driver's mutex! 89 * the driver's mutex!
90 * 90 *
91 * This means that you need to call cfg80211_put_dev() 91 * This means that you need to call cfg80211_put_dev()
92 * before being allowed to acquire &cfg80211_drv_mutex! 92 * before being allowed to acquire &cfg80211_mutex!
93 * 93 *
94 * This is necessary because we need to lock the global 94 * This is necessary because we need to lock the global
95 * mutex to get an item off the list safely, and then 95 * mutex to get an item off the list safely, and then
96 * we lock the drv mutex so it doesn't go away under us. 96 * we lock the drv mutex so it doesn't go away under us.
97 * 97 *
98 * We don't want to keep cfg80211_drv_mutex locked 98 * We don't want to keep cfg80211_mutex locked
99 * for all the time in order to allow requests on 99 * for all the time in order to allow requests on
100 * other interfaces to go through at the same time. 100 * other interfaces to go through at the same time.
101 * 101 *
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index b176bb800100..88a530f707e6 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -256,7 +256,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
256 int start = cb->args[0]; 256 int start = cb->args[0];
257 struct cfg80211_registered_device *dev; 257 struct cfg80211_registered_device *dev;
258 258
259 mutex_lock(&cfg80211_drv_mutex); 259 mutex_lock(&cfg80211_mutex);
260 list_for_each_entry(dev, &cfg80211_drv_list, list) { 260 list_for_each_entry(dev, &cfg80211_drv_list, list) {
261 if (++idx <= start) 261 if (++idx <= start)
262 continue; 262 continue;
@@ -267,7 +267,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
267 break; 267 break;
268 } 268 }
269 } 269 }
270 mutex_unlock(&cfg80211_drv_mutex); 270 mutex_unlock(&cfg80211_mutex);
271 271
272 cb->args[0] = idx; 272 cb->args[0] = idx;
273 273
@@ -470,7 +470,7 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
470 struct cfg80211_registered_device *dev; 470 struct cfg80211_registered_device *dev;
471 struct wireless_dev *wdev; 471 struct wireless_dev *wdev;
472 472
473 mutex_lock(&cfg80211_drv_mutex); 473 mutex_lock(&cfg80211_mutex);
474 list_for_each_entry(dev, &cfg80211_drv_list, list) { 474 list_for_each_entry(dev, &cfg80211_drv_list, list) {
475 if (wp_idx < wp_start) { 475 if (wp_idx < wp_start) {
476 wp_idx++; 476 wp_idx++;
@@ -497,7 +497,7 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
497 wp_idx++; 497 wp_idx++;
498 } 498 }
499 out: 499 out:
500 mutex_unlock(&cfg80211_drv_mutex); 500 mutex_unlock(&cfg80211_mutex);
501 501
502 cb->args[0] = wp_idx; 502 cb->args[0] = wp_idx;
503 cb->args[1] = if_idx; 503 cb->args[1] = if_idx;
@@ -1916,9 +1916,9 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
1916 if (is_world_regdom(data)) 1916 if (is_world_regdom(data))
1917 return -EINVAL; 1917 return -EINVAL;
1918#endif 1918#endif
1919 mutex_lock(&cfg80211_drv_mutex); 1919 mutex_lock(&cfg80211_mutex);
1920 r = __regulatory_hint(NULL, REGDOM_SET_BY_USER, data, 0, ENVIRON_ANY); 1920 r = __regulatory_hint(NULL, REGDOM_SET_BY_USER, data, 0, ENVIRON_ANY);
1921 mutex_unlock(&cfg80211_drv_mutex); 1921 mutex_unlock(&cfg80211_mutex);
1922 /* This means the regulatory domain was already set, however 1922 /* This means the regulatory domain was already set, however
1923 * we don't want to confuse userspace with a "successful error" 1923 * we don't want to confuse userspace with a "successful error"
1924 * message so lets just treat it as a success */ 1924 * message so lets just treat it as a success */
@@ -2112,7 +2112,7 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
2112 unsigned int i; 2112 unsigned int i;
2113 int err = -EINVAL; 2113 int err = -EINVAL;
2114 2114
2115 mutex_lock(&cfg80211_drv_mutex); 2115 mutex_lock(&cfg80211_mutex);
2116 2116
2117 if (!cfg80211_regdomain) 2117 if (!cfg80211_regdomain)
2118 goto out; 2118 goto out;
@@ -2175,7 +2175,7 @@ nla_put_failure:
2175 genlmsg_cancel(msg, hdr); 2175 genlmsg_cancel(msg, hdr);
2176 err = -EMSGSIZE; 2176 err = -EMSGSIZE;
2177out: 2177out:
2178 mutex_unlock(&cfg80211_drv_mutex); 2178 mutex_unlock(&cfg80211_mutex);
2179 return err; 2179 return err;
2180} 2180}
2181 2181
@@ -2234,9 +2234,9 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
2234 2234
2235 BUG_ON(rule_idx != num_rules); 2235 BUG_ON(rule_idx != num_rules);
2236 2236
2237 mutex_lock(&cfg80211_drv_mutex); 2237 mutex_lock(&cfg80211_mutex);
2238 r = set_regdom(rd); 2238 r = set_regdom(rd);
2239 mutex_unlock(&cfg80211_drv_mutex); 2239 mutex_unlock(&cfg80211_mutex);
2240 return r; 2240 return r;
2241 2241
2242 bad_reg: 2242 bad_reg:
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 2323644330cd..ba823120d245 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1116,7 +1116,7 @@ static int ignore_request(struct wiphy *wiphy, enum reg_set_by set_by,
1116 return -EINVAL; 1116 return -EINVAL;
1117} 1117}
1118 1118
1119/* Caller must hold &cfg80211_drv_mutex */ 1119/* Caller must hold &cfg80211_mutex */
1120int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by, 1120int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by,
1121 const char *alpha2, 1121 const char *alpha2,
1122 u32 country_ie_checksum, 1122 u32 country_ie_checksum,
@@ -1188,13 +1188,13 @@ void regulatory_hint(struct wiphy *wiphy, const char *alpha2)
1188 int r; 1188 int r;
1189 BUG_ON(!alpha2); 1189 BUG_ON(!alpha2);
1190 1190
1191 mutex_lock(&cfg80211_drv_mutex); 1191 mutex_lock(&cfg80211_mutex);
1192 r = __regulatory_hint(wiphy, REGDOM_SET_BY_DRIVER, 1192 r = __regulatory_hint(wiphy, REGDOM_SET_BY_DRIVER,
1193 alpha2, 0, ENVIRON_ANY); 1193 alpha2, 0, ENVIRON_ANY);
1194 /* This is required so that the orig_* parameters are saved */ 1194 /* This is required so that the orig_* parameters are saved */
1195 if (r == -EALREADY && wiphy->strict_regulatory) 1195 if (r == -EALREADY && wiphy->strict_regulatory)
1196 wiphy_update_regulatory(wiphy, REGDOM_SET_BY_DRIVER); 1196 wiphy_update_regulatory(wiphy, REGDOM_SET_BY_DRIVER);
1197 mutex_unlock(&cfg80211_drv_mutex); 1197 mutex_unlock(&cfg80211_mutex);
1198} 1198}
1199EXPORT_SYMBOL(regulatory_hint); 1199EXPORT_SYMBOL(regulatory_hint);
1200 1200
@@ -1225,7 +1225,7 @@ void regulatory_hint_11d(struct wiphy *wiphy,
1225 if (!last_request) 1225 if (!last_request)
1226 return; 1226 return;
1227 1227
1228 mutex_lock(&cfg80211_drv_mutex); 1228 mutex_lock(&cfg80211_mutex);
1229 1229
1230 /* IE len must be evenly divisible by 2 */ 1230 /* IE len must be evenly divisible by 2 */
1231 if (country_ie_len & 0x01) 1231 if (country_ie_len & 0x01)
@@ -1307,7 +1307,7 @@ void regulatory_hint_11d(struct wiphy *wiphy,
1307 country_ie_regdomain->alpha2, checksum, env); 1307 country_ie_regdomain->alpha2, checksum, env);
1308 1308
1309out: 1309out:
1310 mutex_unlock(&cfg80211_drv_mutex); 1310 mutex_unlock(&cfg80211_mutex);
1311} 1311}
1312EXPORT_SYMBOL(regulatory_hint_11d); 1312EXPORT_SYMBOL(regulatory_hint_11d);
1313 1313
@@ -1562,7 +1562,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
1562 1562
1563/* Use this call to set the current regulatory domain. Conflicts with 1563/* Use this call to set the current regulatory domain. Conflicts with
1564 * multiple drivers can be ironed out later. Caller must've already 1564 * multiple drivers can be ironed out later. Caller must've already
1565 * kmalloc'd the rd structure. Caller must hold cfg80211_drv_mutex */ 1565 * kmalloc'd the rd structure. Caller must hold cfg80211_mutex */
1566int set_regdom(const struct ieee80211_regdomain *rd) 1566int set_regdom(const struct ieee80211_regdomain *rd)
1567{ 1567{
1568 int r; 1568 int r;
@@ -1586,7 +1586,7 @@ int set_regdom(const struct ieee80211_regdomain *rd)
1586 return r; 1586 return r;
1587} 1587}
1588 1588
1589/* Caller must hold cfg80211_drv_mutex */ 1589/* Caller must hold cfg80211_mutex */
1590void reg_device_remove(struct wiphy *wiphy) 1590void reg_device_remove(struct wiphy *wiphy)
1591{ 1591{
1592 kfree(wiphy->regd); 1592 kfree(wiphy->regd);
@@ -1633,7 +1633,7 @@ int regulatory_init(void)
1633 1633
1634void regulatory_exit(void) 1634void regulatory_exit(void)
1635{ 1635{
1636 mutex_lock(&cfg80211_drv_mutex); 1636 mutex_lock(&cfg80211_mutex);
1637 1637
1638 reset_regdomains(); 1638 reset_regdomains();
1639 1639
@@ -1644,5 +1644,5 @@ void regulatory_exit(void)
1644 1644
1645 platform_device_unregister(reg_pdev); 1645 platform_device_unregister(reg_pdev);
1646 1646
1647 mutex_unlock(&cfg80211_drv_mutex); 1647 mutex_unlock(&cfg80211_mutex);
1648} 1648}