diff options
Diffstat (limited to 'net/wireless/mlme.c')
-rw-r--r-- | net/wireless/mlme.c | 49 |
1 files changed, 29 insertions, 20 deletions
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 1cdb1d5e6b0f..904a7f368325 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
@@ -457,20 +457,14 @@ int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, | |||
457 | .reason_code = reason, | 457 | .reason_code = reason, |
458 | .ie = ie, | 458 | .ie = ie, |
459 | .ie_len = ie_len, | 459 | .ie_len = ie_len, |
460 | .local_state_change = local_state_change, | ||
460 | }; | 461 | }; |
461 | 462 | ||
462 | ASSERT_WDEV_LOCK(wdev); | 463 | ASSERT_WDEV_LOCK(wdev); |
463 | 464 | ||
464 | if (local_state_change) { | 465 | if (local_state_change && (!wdev->current_bss || |
465 | if (wdev->current_bss && | 466 | !ether_addr_equal(wdev->current_bss->pub.bssid, bssid))) |
466 | ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) { | ||
467 | cfg80211_unhold_bss(wdev->current_bss); | ||
468 | cfg80211_put_bss(&wdev->current_bss->pub); | ||
469 | wdev->current_bss = NULL; | ||
470 | } | ||
471 | |||
472 | return 0; | 467 | return 0; |
473 | } | ||
474 | 468 | ||
475 | return rdev->ops->deauth(&rdev->wiphy, dev, &req); | 469 | return rdev->ops->deauth(&rdev->wiphy, dev, &req); |
476 | } | 470 | } |
@@ -612,10 +606,21 @@ void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp) | |||
612 | } | 606 | } |
613 | EXPORT_SYMBOL(cfg80211_del_sta); | 607 | EXPORT_SYMBOL(cfg80211_del_sta); |
614 | 608 | ||
609 | void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr, | ||
610 | enum nl80211_connect_failed_reason reason, | ||
611 | gfp_t gfp) | ||
612 | { | ||
613 | struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; | ||
614 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | ||
615 | |||
616 | nl80211_send_conn_failed_event(rdev, dev, mac_addr, reason, gfp); | ||
617 | } | ||
618 | EXPORT_SYMBOL(cfg80211_conn_failed); | ||
619 | |||
615 | struct cfg80211_mgmt_registration { | 620 | struct cfg80211_mgmt_registration { |
616 | struct list_head list; | 621 | struct list_head list; |
617 | 622 | ||
618 | u32 nlpid; | 623 | u32 nlportid; |
619 | 624 | ||
620 | int match_len; | 625 | int match_len; |
621 | 626 | ||
@@ -624,7 +629,7 @@ struct cfg80211_mgmt_registration { | |||
624 | u8 match[]; | 629 | u8 match[]; |
625 | }; | 630 | }; |
626 | 631 | ||
627 | int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid, | 632 | int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_portid, |
628 | u16 frame_type, const u8 *match_data, | 633 | u16 frame_type, const u8 *match_data, |
629 | int match_len) | 634 | int match_len) |
630 | { | 635 | { |
@@ -672,7 +677,7 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid, | |||
672 | 677 | ||
673 | memcpy(nreg->match, match_data, match_len); | 678 | memcpy(nreg->match, match_data, match_len); |
674 | nreg->match_len = match_len; | 679 | nreg->match_len = match_len; |
675 | nreg->nlpid = snd_pid; | 680 | nreg->nlportid = snd_portid; |
676 | nreg->frame_type = cpu_to_le16(frame_type); | 681 | nreg->frame_type = cpu_to_le16(frame_type); |
677 | list_add(&nreg->list, &wdev->mgmt_registrations); | 682 | list_add(&nreg->list, &wdev->mgmt_registrations); |
678 | 683 | ||
@@ -685,7 +690,7 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid, | |||
685 | return err; | 690 | return err; |
686 | } | 691 | } |
687 | 692 | ||
688 | void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid) | 693 | void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlportid) |
689 | { | 694 | { |
690 | struct wiphy *wiphy = wdev->wiphy; | 695 | struct wiphy *wiphy = wdev->wiphy; |
691 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 696 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
@@ -694,7 +699,7 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid) | |||
694 | spin_lock_bh(&wdev->mgmt_registrations_lock); | 699 | spin_lock_bh(&wdev->mgmt_registrations_lock); |
695 | 700 | ||
696 | list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) { | 701 | list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) { |
697 | if (reg->nlpid != nlpid) | 702 | if (reg->nlportid != nlportid) |
698 | continue; | 703 | continue; |
699 | 704 | ||
700 | if (rdev->ops->mgmt_frame_register) { | 705 | if (rdev->ops->mgmt_frame_register) { |
@@ -710,8 +715,8 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid) | |||
710 | 715 | ||
711 | spin_unlock_bh(&wdev->mgmt_registrations_lock); | 716 | spin_unlock_bh(&wdev->mgmt_registrations_lock); |
712 | 717 | ||
713 | if (nlpid == wdev->ap_unexpected_nlpid) | 718 | if (nlportid == wdev->ap_unexpected_nlportid) |
714 | wdev->ap_unexpected_nlpid = 0; | 719 | wdev->ap_unexpected_nlportid = 0; |
715 | } | 720 | } |
716 | 721 | ||
717 | void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev) | 722 | void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev) |
@@ -736,7 +741,6 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, | |||
736 | const u8 *buf, size_t len, bool no_cck, | 741 | const u8 *buf, size_t len, bool no_cck, |
737 | bool dont_wait_for_ack, u64 *cookie) | 742 | bool dont_wait_for_ack, u64 *cookie) |
738 | { | 743 | { |
739 | struct net_device *dev = wdev->netdev; | ||
740 | const struct ieee80211_mgmt *mgmt; | 744 | const struct ieee80211_mgmt *mgmt; |
741 | u16 stype; | 745 | u16 stype; |
742 | 746 | ||
@@ -796,7 +800,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, | |||
796 | case NL80211_IFTYPE_AP: | 800 | case NL80211_IFTYPE_AP: |
797 | case NL80211_IFTYPE_P2P_GO: | 801 | case NL80211_IFTYPE_P2P_GO: |
798 | case NL80211_IFTYPE_AP_VLAN: | 802 | case NL80211_IFTYPE_AP_VLAN: |
799 | if (!ether_addr_equal(mgmt->bssid, dev->dev_addr)) | 803 | if (!ether_addr_equal(mgmt->bssid, wdev_address(wdev))) |
800 | err = -EINVAL; | 804 | err = -EINVAL; |
801 | break; | 805 | break; |
802 | case NL80211_IFTYPE_MESH_POINT: | 806 | case NL80211_IFTYPE_MESH_POINT: |
@@ -809,6 +813,11 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, | |||
809 | * cfg80211 doesn't track the stations | 813 | * cfg80211 doesn't track the stations |
810 | */ | 814 | */ |
811 | break; | 815 | break; |
816 | case NL80211_IFTYPE_P2P_DEVICE: | ||
817 | /* | ||
818 | * fall through, P2P device only supports | ||
819 | * public action frames | ||
820 | */ | ||
812 | default: | 821 | default: |
813 | err = -EOPNOTSUPP; | 822 | err = -EOPNOTSUPP; |
814 | break; | 823 | break; |
@@ -819,7 +828,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, | |||
819 | return err; | 828 | return err; |
820 | } | 829 | } |
821 | 830 | ||
822 | if (!ether_addr_equal(mgmt->sa, dev->dev_addr)) | 831 | if (!ether_addr_equal(mgmt->sa, wdev_address(wdev))) |
823 | return -EINVAL; | 832 | return -EINVAL; |
824 | 833 | ||
825 | /* Transmit the Action frame as requested by user space */ | 834 | /* Transmit the Action frame as requested by user space */ |
@@ -868,7 +877,7 @@ bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm, | |||
868 | /* found match! */ | 877 | /* found match! */ |
869 | 878 | ||
870 | /* Indicate the received Action frame to user space */ | 879 | /* Indicate the received Action frame to user space */ |
871 | if (nl80211_send_mgmt(rdev, wdev, reg->nlpid, | 880 | if (nl80211_send_mgmt(rdev, wdev, reg->nlportid, |
872 | freq, sig_mbm, | 881 | freq, sig_mbm, |
873 | buf, len, gfp)) | 882 | buf, len, gfp)) |
874 | continue; | 883 | continue; |