diff options
Diffstat (limited to 'net/wireless/mlme.c')
-rw-r--r-- | net/wireless/mlme.c | 53 |
1 files changed, 42 insertions, 11 deletions
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 62bc8855e123..48ead6f0426d 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
9 | #include <linux/netdevice.h> | 9 | #include <linux/netdevice.h> |
10 | #include <linux/nl80211.h> | 10 | #include <linux/nl80211.h> |
11 | #include <linux/slab.h> | ||
11 | #include <linux/wireless.h> | 12 | #include <linux/wireless.h> |
12 | #include <net/cfg80211.h> | 13 | #include <net/cfg80211.h> |
13 | #include <net/iw_handler.h> | 14 | #include <net/iw_handler.h> |
@@ -377,7 +378,8 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, | |||
377 | const u8 *bssid, | 378 | const u8 *bssid, |
378 | const u8 *ssid, int ssid_len, | 379 | const u8 *ssid, int ssid_len, |
379 | const u8 *ie, int ie_len, | 380 | const u8 *ie, int ie_len, |
380 | const u8 *key, int key_len, int key_idx) | 381 | const u8 *key, int key_len, int key_idx, |
382 | bool local_state_change) | ||
381 | { | 383 | { |
382 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 384 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
383 | struct cfg80211_auth_request req; | 385 | struct cfg80211_auth_request req; |
@@ -407,6 +409,7 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, | |||
407 | 409 | ||
408 | memset(&req, 0, sizeof(req)); | 410 | memset(&req, 0, sizeof(req)); |
409 | 411 | ||
412 | req.local_state_change = local_state_change; | ||
410 | req.ie = ie; | 413 | req.ie = ie; |
411 | req.ie_len = ie_len; | 414 | req.ie_len = ie_len; |
412 | req.auth_type = auth_type; | 415 | req.auth_type = auth_type; |
@@ -433,12 +436,18 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, | |||
433 | goto out; | 436 | goto out; |
434 | } | 437 | } |
435 | 438 | ||
436 | wdev->authtry_bsses[slot] = bss; | 439 | if (local_state_change) |
440 | wdev->auth_bsses[slot] = bss; | ||
441 | else | ||
442 | wdev->authtry_bsses[slot] = bss; | ||
437 | cfg80211_hold_bss(bss); | 443 | cfg80211_hold_bss(bss); |
438 | 444 | ||
439 | err = rdev->ops->auth(&rdev->wiphy, dev, &req); | 445 | err = rdev->ops->auth(&rdev->wiphy, dev, &req); |
440 | if (err) { | 446 | if (err) { |
441 | wdev->authtry_bsses[slot] = NULL; | 447 | if (local_state_change) |
448 | wdev->auth_bsses[slot] = NULL; | ||
449 | else | ||
450 | wdev->authtry_bsses[slot] = NULL; | ||
442 | cfg80211_unhold_bss(bss); | 451 | cfg80211_unhold_bss(bss); |
443 | } | 452 | } |
444 | 453 | ||
@@ -453,14 +462,15 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, | |||
453 | enum nl80211_auth_type auth_type, const u8 *bssid, | 462 | enum nl80211_auth_type auth_type, const u8 *bssid, |
454 | const u8 *ssid, int ssid_len, | 463 | const u8 *ssid, int ssid_len, |
455 | const u8 *ie, int ie_len, | 464 | const u8 *ie, int ie_len, |
456 | const u8 *key, int key_len, int key_idx) | 465 | const u8 *key, int key_len, int key_idx, |
466 | bool local_state_change) | ||
457 | { | 467 | { |
458 | int err; | 468 | int err; |
459 | 469 | ||
460 | wdev_lock(dev->ieee80211_ptr); | 470 | wdev_lock(dev->ieee80211_ptr); |
461 | err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, | 471 | err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, |
462 | ssid, ssid_len, ie, ie_len, | 472 | ssid, ssid_len, ie, ie_len, |
463 | key, key_len, key_idx); | 473 | key, key_len, key_idx, local_state_change); |
464 | wdev_unlock(dev->ieee80211_ptr); | 474 | wdev_unlock(dev->ieee80211_ptr); |
465 | 475 | ||
466 | return err; | 476 | return err; |
@@ -554,7 +564,8 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, | |||
554 | 564 | ||
555 | int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, | 565 | int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, |
556 | struct net_device *dev, const u8 *bssid, | 566 | struct net_device *dev, const u8 *bssid, |
557 | const u8 *ie, int ie_len, u16 reason) | 567 | const u8 *ie, int ie_len, u16 reason, |
568 | bool local_state_change) | ||
558 | { | 569 | { |
559 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 570 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
560 | struct cfg80211_deauth_request req; | 571 | struct cfg80211_deauth_request req; |
@@ -564,6 +575,7 @@ int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, | |||
564 | 575 | ||
565 | memset(&req, 0, sizeof(req)); | 576 | memset(&req, 0, sizeof(req)); |
566 | req.reason_code = reason; | 577 | req.reason_code = reason; |
578 | req.local_state_change = local_state_change; | ||
567 | req.ie = ie; | 579 | req.ie = ie; |
568 | req.ie_len = ie_len; | 580 | req.ie_len = ie_len; |
569 | if (wdev->current_bss && | 581 | if (wdev->current_bss && |
@@ -590,13 +602,15 @@ int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, | |||
590 | 602 | ||
591 | int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, | 603 | int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, |
592 | struct net_device *dev, const u8 *bssid, | 604 | struct net_device *dev, const u8 *bssid, |
593 | const u8 *ie, int ie_len, u16 reason) | 605 | const u8 *ie, int ie_len, u16 reason, |
606 | bool local_state_change) | ||
594 | { | 607 | { |
595 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 608 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
596 | int err; | 609 | int err; |
597 | 610 | ||
598 | wdev_lock(wdev); | 611 | wdev_lock(wdev); |
599 | err = __cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason); | 612 | err = __cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason, |
613 | local_state_change); | ||
600 | wdev_unlock(wdev); | 614 | wdev_unlock(wdev); |
601 | 615 | ||
602 | return err; | 616 | return err; |
@@ -604,7 +618,8 @@ int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, | |||
604 | 618 | ||
605 | static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, | 619 | static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, |
606 | struct net_device *dev, const u8 *bssid, | 620 | struct net_device *dev, const u8 *bssid, |
607 | const u8 *ie, int ie_len, u16 reason) | 621 | const u8 *ie, int ie_len, u16 reason, |
622 | bool local_state_change) | ||
608 | { | 623 | { |
609 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 624 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
610 | struct cfg80211_disassoc_request req; | 625 | struct cfg80211_disassoc_request req; |
@@ -619,6 +634,7 @@ static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, | |||
619 | 634 | ||
620 | memset(&req, 0, sizeof(req)); | 635 | memset(&req, 0, sizeof(req)); |
621 | req.reason_code = reason; | 636 | req.reason_code = reason; |
637 | req.local_state_change = local_state_change; | ||
622 | req.ie = ie; | 638 | req.ie = ie; |
623 | req.ie_len = ie_len; | 639 | req.ie_len = ie_len; |
624 | if (memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) | 640 | if (memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) |
@@ -631,13 +647,15 @@ static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, | |||
631 | 647 | ||
632 | int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, | 648 | int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, |
633 | struct net_device *dev, const u8 *bssid, | 649 | struct net_device *dev, const u8 *bssid, |
634 | const u8 *ie, int ie_len, u16 reason) | 650 | const u8 *ie, int ie_len, u16 reason, |
651 | bool local_state_change) | ||
635 | { | 652 | { |
636 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 653 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
637 | int err; | 654 | int err; |
638 | 655 | ||
639 | wdev_lock(wdev); | 656 | wdev_lock(wdev); |
640 | err = __cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason); | 657 | err = __cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason, |
658 | local_state_change); | ||
641 | wdev_unlock(wdev); | 659 | wdev_unlock(wdev); |
642 | 660 | ||
643 | return err; | 661 | return err; |
@@ -894,3 +912,16 @@ void cfg80211_action_tx_status(struct net_device *dev, u64 cookie, | |||
894 | nl80211_send_action_tx_status(rdev, dev, cookie, buf, len, ack, gfp); | 912 | nl80211_send_action_tx_status(rdev, dev, cookie, buf, len, ack, gfp); |
895 | } | 913 | } |
896 | EXPORT_SYMBOL(cfg80211_action_tx_status); | 914 | EXPORT_SYMBOL(cfg80211_action_tx_status); |
915 | |||
916 | void cfg80211_cqm_rssi_notify(struct net_device *dev, | ||
917 | enum nl80211_cqm_rssi_threshold_event rssi_event, | ||
918 | gfp_t gfp) | ||
919 | { | ||
920 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
921 | struct wiphy *wiphy = wdev->wiphy; | ||
922 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | ||
923 | |||
924 | /* Indicate roaming trigger event to user space */ | ||
925 | nl80211_send_cqm_rssi_notify(rdev, dev, rssi_event, gfp); | ||
926 | } | ||
927 | EXPORT_SYMBOL(cfg80211_cqm_rssi_notify); | ||