diff options
-rw-r--r-- | net/wireless/core.c | 35 | ||||
-rw-r--r-- | net/wireless/core.h | 6 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 20 | ||||
-rw-r--r-- | net/wireless/reg.c | 18 |
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 */ |
33 | LIST_HEAD(cfg80211_drv_list); | 33 | LIST_HEAD(cfg80211_drv_list); |
34 | DEFINE_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 | */ | ||
39 | DEFINE_MUTEX(cfg80211_mutex); | ||
35 | 40 | ||
36 | /* for debugfs */ | 41 | /* for debugfs */ |
37 | static struct dentry *ieee80211_debugfs_dir; | 42 | static 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! */ |
59 | static struct cfg80211_registered_device * | 64 | static 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; |
199 | out_unlock: | 204 | out_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; |
336 | out_unlock: | 341 | out_unlock: |
337 | mutex_unlock(&cfg80211_drv_mutex); | 342 | mutex_unlock(&cfg80211_mutex); |
338 | return res; | 343 | return res; |
339 | } | 344 | } |
340 | EXPORT_SYMBOL(wiphy_register); | 345 | EXPORT_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 | } |
375 | EXPORT_SYMBOL(wiphy_unregister); | 380 | EXPORT_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 | ||
73 | extern struct mutex cfg80211_drv_mutex; | 73 | extern struct mutex cfg80211_mutex; |
74 | extern struct list_head cfg80211_drv_list; | 74 | extern struct list_head cfg80211_drv_list; |
75 | 75 | ||
76 | struct cfg80211_internal_bss { | 76 | struct 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; |
2177 | out: | 2177 | out: |
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 */ |
1120 | int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by, | 1120 | int __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 | } |
1199 | EXPORT_SYMBOL(regulatory_hint); | 1199 | EXPORT_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 | ||
1309 | out: | 1309 | out: |
1310 | mutex_unlock(&cfg80211_drv_mutex); | 1310 | mutex_unlock(&cfg80211_mutex); |
1311 | } | 1311 | } |
1312 | EXPORT_SYMBOL(regulatory_hint_11d); | 1312 | EXPORT_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 */ |
1566 | int set_regdom(const struct ieee80211_regdomain *rd) | 1566 | int 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 */ |
1590 | void reg_device_remove(struct wiphy *wiphy) | 1590 | void 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 | ||
1634 | void regulatory_exit(void) | 1634 | void 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 | } |