diff options
Diffstat (limited to 'net/wireless/ibss.c')
-rw-r--r-- | net/wireless/ibss.c | 61 |
1 files changed, 39 insertions, 22 deletions
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index 4d7a084b35e2..42840a01be74 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c | |||
@@ -78,10 +78,15 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, | |||
78 | struct cfg80211_cached_keys *connkeys) | 78 | struct cfg80211_cached_keys *connkeys) |
79 | { | 79 | { |
80 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 80 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
81 | struct ieee80211_channel *chan; | ||
81 | int err; | 82 | int err; |
82 | 83 | ||
83 | ASSERT_WDEV_LOCK(wdev); | 84 | ASSERT_WDEV_LOCK(wdev); |
84 | 85 | ||
86 | chan = rdev_fixed_channel(rdev, wdev); | ||
87 | if (chan && chan != params->channel) | ||
88 | return -EBUSY; | ||
89 | |||
85 | if (wdev->ssid_len) | 90 | if (wdev->ssid_len) |
86 | return -EALREADY; | 91 | return -EALREADY; |
87 | 92 | ||
@@ -112,9 +117,11 @@ int cfg80211_join_ibss(struct cfg80211_registered_device *rdev, | |||
112 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 117 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
113 | int err; | 118 | int err; |
114 | 119 | ||
120 | mutex_lock(&rdev->devlist_mtx); | ||
115 | wdev_lock(wdev); | 121 | wdev_lock(wdev); |
116 | err = __cfg80211_join_ibss(rdev, dev, params, connkeys); | 122 | err = __cfg80211_join_ibss(rdev, dev, params, connkeys); |
117 | wdev_unlock(wdev); | 123 | wdev_unlock(wdev); |
124 | mutex_unlock(&rdev->devlist_mtx); | ||
118 | 125 | ||
119 | return err; | 126 | return err; |
120 | } | 127 | } |
@@ -264,27 +271,32 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev, | |||
264 | 271 | ||
265 | int cfg80211_ibss_wext_siwfreq(struct net_device *dev, | 272 | int cfg80211_ibss_wext_siwfreq(struct net_device *dev, |
266 | struct iw_request_info *info, | 273 | struct iw_request_info *info, |
267 | struct iw_freq *freq, char *extra) | 274 | struct iw_freq *wextfreq, char *extra) |
268 | { | 275 | { |
269 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 276 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
270 | struct ieee80211_channel *chan; | 277 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); |
271 | int err; | 278 | struct ieee80211_channel *chan = NULL; |
279 | int err, freq; | ||
272 | 280 | ||
273 | /* call only for ibss! */ | 281 | /* call only for ibss! */ |
274 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) | 282 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) |
275 | return -EINVAL; | 283 | return -EINVAL; |
276 | 284 | ||
277 | if (!wiphy_to_dev(wdev->wiphy)->ops->join_ibss) | 285 | if (!rdev->ops->join_ibss) |
278 | return -EOPNOTSUPP; | 286 | return -EOPNOTSUPP; |
279 | 287 | ||
280 | chan = cfg80211_wext_freq(wdev->wiphy, freq); | 288 | freq = cfg80211_wext_freq(wdev->wiphy, wextfreq); |
281 | if (chan && IS_ERR(chan)) | 289 | if (freq < 0) |
282 | return PTR_ERR(chan); | 290 | return freq; |
283 | 291 | ||
284 | if (chan && | 292 | if (freq) { |
285 | (chan->flags & IEEE80211_CHAN_NO_IBSS || | 293 | chan = ieee80211_get_channel(wdev->wiphy, freq); |
286 | chan->flags & IEEE80211_CHAN_DISABLED)) | 294 | if (!chan) |
287 | return -EINVAL; | 295 | return -EINVAL; |
296 | if (chan->flags & IEEE80211_CHAN_NO_IBSS || | ||
297 | chan->flags & IEEE80211_CHAN_DISABLED) | ||
298 | return -EINVAL; | ||
299 | } | ||
288 | 300 | ||
289 | if (wdev->wext.ibss.channel == chan) | 301 | if (wdev->wext.ibss.channel == chan) |
290 | return 0; | 302 | return 0; |
@@ -292,8 +304,7 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev, | |||
292 | wdev_lock(wdev); | 304 | wdev_lock(wdev); |
293 | err = 0; | 305 | err = 0; |
294 | if (wdev->ssid_len) | 306 | if (wdev->ssid_len) |
295 | err = __cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy), | 307 | err = __cfg80211_leave_ibss(rdev, dev, true); |
296 | dev, true); | ||
297 | wdev_unlock(wdev); | 308 | wdev_unlock(wdev); |
298 | 309 | ||
299 | if (err) | 310 | if (err) |
@@ -307,9 +318,11 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev, | |||
307 | wdev->wext.ibss.channel_fixed = false; | 318 | wdev->wext.ibss.channel_fixed = false; |
308 | } | 319 | } |
309 | 320 | ||
321 | mutex_lock(&rdev->devlist_mtx); | ||
310 | wdev_lock(wdev); | 322 | wdev_lock(wdev); |
311 | err = cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev); | 323 | err = cfg80211_ibss_wext_join(rdev, wdev); |
312 | wdev_unlock(wdev); | 324 | wdev_unlock(wdev); |
325 | mutex_unlock(&rdev->devlist_mtx); | ||
313 | 326 | ||
314 | return err; | 327 | return err; |
315 | } | 328 | } |
@@ -347,6 +360,7 @@ int cfg80211_ibss_wext_siwessid(struct net_device *dev, | |||
347 | struct iw_point *data, char *ssid) | 360 | struct iw_point *data, char *ssid) |
348 | { | 361 | { |
349 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 362 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
363 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | ||
350 | size_t len = data->length; | 364 | size_t len = data->length; |
351 | int err; | 365 | int err; |
352 | 366 | ||
@@ -354,14 +368,13 @@ int cfg80211_ibss_wext_siwessid(struct net_device *dev, | |||
354 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) | 368 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) |
355 | return -EINVAL; | 369 | return -EINVAL; |
356 | 370 | ||
357 | if (!wiphy_to_dev(wdev->wiphy)->ops->join_ibss) | 371 | if (!rdev->ops->join_ibss) |
358 | return -EOPNOTSUPP; | 372 | return -EOPNOTSUPP; |
359 | 373 | ||
360 | wdev_lock(wdev); | 374 | wdev_lock(wdev); |
361 | err = 0; | 375 | err = 0; |
362 | if (wdev->ssid_len) | 376 | if (wdev->ssid_len) |
363 | err = __cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy), | 377 | err = __cfg80211_leave_ibss(rdev, dev, true); |
364 | dev, true); | ||
365 | wdev_unlock(wdev); | 378 | wdev_unlock(wdev); |
366 | 379 | ||
367 | if (err) | 380 | if (err) |
@@ -375,9 +388,11 @@ int cfg80211_ibss_wext_siwessid(struct net_device *dev, | |||
375 | memcpy(wdev->wext.ibss.ssid, ssid, len); | 388 | memcpy(wdev->wext.ibss.ssid, ssid, len); |
376 | wdev->wext.ibss.ssid_len = len; | 389 | wdev->wext.ibss.ssid_len = len; |
377 | 390 | ||
391 | mutex_lock(&rdev->devlist_mtx); | ||
378 | wdev_lock(wdev); | 392 | wdev_lock(wdev); |
379 | err = cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev); | 393 | err = cfg80211_ibss_wext_join(rdev, wdev); |
380 | wdev_unlock(wdev); | 394 | wdev_unlock(wdev); |
395 | mutex_unlock(&rdev->devlist_mtx); | ||
381 | 396 | ||
382 | return err; | 397 | return err; |
383 | } | 398 | } |
@@ -414,6 +429,7 @@ int cfg80211_ibss_wext_siwap(struct net_device *dev, | |||
414 | struct sockaddr *ap_addr, char *extra) | 429 | struct sockaddr *ap_addr, char *extra) |
415 | { | 430 | { |
416 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 431 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
432 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | ||
417 | u8 *bssid = ap_addr->sa_data; | 433 | u8 *bssid = ap_addr->sa_data; |
418 | int err; | 434 | int err; |
419 | 435 | ||
@@ -421,7 +437,7 @@ int cfg80211_ibss_wext_siwap(struct net_device *dev, | |||
421 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) | 437 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) |
422 | return -EINVAL; | 438 | return -EINVAL; |
423 | 439 | ||
424 | if (!wiphy_to_dev(wdev->wiphy)->ops->join_ibss) | 440 | if (!rdev->ops->join_ibss) |
425 | return -EOPNOTSUPP; | 441 | return -EOPNOTSUPP; |
426 | 442 | ||
427 | if (ap_addr->sa_family != ARPHRD_ETHER) | 443 | if (ap_addr->sa_family != ARPHRD_ETHER) |
@@ -443,8 +459,7 @@ int cfg80211_ibss_wext_siwap(struct net_device *dev, | |||
443 | wdev_lock(wdev); | 459 | wdev_lock(wdev); |
444 | err = 0; | 460 | err = 0; |
445 | if (wdev->ssid_len) | 461 | if (wdev->ssid_len) |
446 | err = __cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy), | 462 | err = __cfg80211_leave_ibss(rdev, dev, true); |
447 | dev, true); | ||
448 | wdev_unlock(wdev); | 463 | wdev_unlock(wdev); |
449 | 464 | ||
450 | if (err) | 465 | if (err) |
@@ -456,9 +471,11 @@ int cfg80211_ibss_wext_siwap(struct net_device *dev, | |||
456 | } else | 471 | } else |
457 | wdev->wext.ibss.bssid = NULL; | 472 | wdev->wext.ibss.bssid = NULL; |
458 | 473 | ||
474 | mutex_lock(&rdev->devlist_mtx); | ||
459 | wdev_lock(wdev); | 475 | wdev_lock(wdev); |
460 | err = cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev); | 476 | err = cfg80211_ibss_wext_join(rdev, wdev); |
461 | wdev_unlock(wdev); | 477 | wdev_unlock(wdev); |
478 | mutex_unlock(&rdev->devlist_mtx); | ||
462 | 479 | ||
463 | return err; | 480 | return err; |
464 | } | 481 | } |