diff options
| author | David S. Miller <davem@davemloft.net> | 2009-11-24 18:01:29 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2009-11-24 18:01:29 -0500 |
| commit | 4ba3eb034fb6fd1990ccc5a6d71d5abcda37b905 (patch) | |
| tree | 0789ba36d96dba330416a1e6a9a68e891a78802a /net/wireless/mlme.c | |
| parent | 35700212b45ea9f98fa682cfc1bc1a67c9ccc34b (diff) | |
| parent | 18b6c9a2213d3b6e0212e8b225abf95f7564206a (diff) | |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'net/wireless/mlme.c')
| -rw-r--r-- | net/wireless/mlme.c | 56 |
1 files changed, 43 insertions, 13 deletions
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 2610b746effa..1001db4912f7 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
| @@ -243,21 +243,12 @@ void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len) | |||
| 243 | } | 243 | } |
| 244 | EXPORT_SYMBOL(cfg80211_send_disassoc); | 244 | EXPORT_SYMBOL(cfg80211_send_disassoc); |
| 245 | 245 | ||
| 246 | void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr) | 246 | static void __cfg80211_auth_remove(struct wireless_dev *wdev, const u8 *addr) |
| 247 | { | 247 | { |
| 248 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
| 249 | struct wiphy *wiphy = wdev->wiphy; | ||
| 250 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | ||
| 251 | int i; | 248 | int i; |
| 252 | bool done = false; | 249 | bool done = false; |
| 253 | 250 | ||
| 254 | wdev_lock(wdev); | 251 | ASSERT_WDEV_LOCK(wdev); |
| 255 | |||
| 256 | nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL); | ||
| 257 | if (wdev->sme_state == CFG80211_SME_CONNECTING) | ||
| 258 | __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0, | ||
| 259 | WLAN_STATUS_UNSPECIFIED_FAILURE, | ||
| 260 | false, NULL); | ||
| 261 | 252 | ||
| 262 | for (i = 0; addr && i < MAX_AUTH_BSSES; i++) { | 253 | for (i = 0; addr && i < MAX_AUTH_BSSES; i++) { |
| 263 | if (wdev->authtry_bsses[i] && | 254 | if (wdev->authtry_bsses[i] && |
| @@ -272,6 +263,29 @@ void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr) | |||
| 272 | } | 263 | } |
| 273 | 264 | ||
| 274 | WARN_ON(!done); | 265 | WARN_ON(!done); |
| 266 | } | ||
| 267 | |||
| 268 | void __cfg80211_auth_canceled(struct net_device *dev, const u8 *addr) | ||
| 269 | { | ||
| 270 | __cfg80211_auth_remove(dev->ieee80211_ptr, addr); | ||
| 271 | } | ||
| 272 | EXPORT_SYMBOL(__cfg80211_auth_canceled); | ||
| 273 | |||
| 274 | void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr) | ||
| 275 | { | ||
| 276 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
| 277 | struct wiphy *wiphy = wdev->wiphy; | ||
| 278 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | ||
| 279 | |||
| 280 | wdev_lock(wdev); | ||
| 281 | |||
| 282 | nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL); | ||
| 283 | if (wdev->sme_state == CFG80211_SME_CONNECTING) | ||
| 284 | __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0, | ||
| 285 | WLAN_STATUS_UNSPECIFIED_FAILURE, | ||
| 286 | false, NULL); | ||
| 287 | |||
| 288 | __cfg80211_auth_remove(wdev, addr); | ||
| 275 | 289 | ||
| 276 | wdev_unlock(wdev); | 290 | wdev_unlock(wdev); |
| 277 | } | 291 | } |
| @@ -446,12 +460,23 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, | |||
| 446 | struct cfg80211_assoc_request req; | 460 | struct cfg80211_assoc_request req; |
| 447 | struct cfg80211_internal_bss *bss; | 461 | struct cfg80211_internal_bss *bss; |
| 448 | int i, err, slot = -1; | 462 | int i, err, slot = -1; |
| 463 | bool was_connected = false; | ||
| 449 | 464 | ||
| 450 | ASSERT_WDEV_LOCK(wdev); | 465 | ASSERT_WDEV_LOCK(wdev); |
| 451 | 466 | ||
| 452 | memset(&req, 0, sizeof(req)); | 467 | memset(&req, 0, sizeof(req)); |
| 453 | 468 | ||
| 454 | if (wdev->current_bss) | 469 | if (wdev->current_bss && prev_bssid && |
| 470 | memcmp(wdev->current_bss->pub.bssid, prev_bssid, ETH_ALEN) == 0) { | ||
| 471 | /* | ||
| 472 | * Trying to reassociate: Allow this to proceed and let the old | ||
| 473 | * association to be dropped when the new one is completed. | ||
| 474 | */ | ||
| 475 | if (wdev->sme_state == CFG80211_SME_CONNECTED) { | ||
| 476 | was_connected = true; | ||
| 477 | wdev->sme_state = CFG80211_SME_CONNECTING; | ||
| 478 | } | ||
| 479 | } else if (wdev->current_bss) | ||
| 455 | return -EALREADY; | 480 | return -EALREADY; |
| 456 | 481 | ||
| 457 | req.ie = ie; | 482 | req.ie = ie; |
| @@ -461,8 +486,11 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, | |||
| 461 | req.prev_bssid = prev_bssid; | 486 | req.prev_bssid = prev_bssid; |
| 462 | req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, | 487 | req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, |
| 463 | WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); | 488 | WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); |
| 464 | if (!req.bss) | 489 | if (!req.bss) { |
| 490 | if (was_connected) | ||
| 491 | wdev->sme_state = CFG80211_SME_CONNECTED; | ||
| 465 | return -ENOENT; | 492 | return -ENOENT; |
| 493 | } | ||
| 466 | 494 | ||
| 467 | bss = bss_from_pub(req.bss); | 495 | bss = bss_from_pub(req.bss); |
| 468 | 496 | ||
| @@ -480,6 +508,8 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, | |||
| 480 | 508 | ||
| 481 | err = rdev->ops->assoc(&rdev->wiphy, dev, &req); | 509 | err = rdev->ops->assoc(&rdev->wiphy, dev, &req); |
| 482 | out: | 510 | out: |
| 511 | if (err && was_connected) | ||
| 512 | wdev->sme_state = CFG80211_SME_CONNECTED; | ||
| 483 | /* still a reference in wdev->auth_bsses[slot] */ | 513 | /* still a reference in wdev->auth_bsses[slot] */ |
| 484 | cfg80211_put_bss(req.bss); | 514 | cfg80211_put_bss(req.bss); |
| 485 | return err; | 515 | return err; |
