aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/mlme.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/mlme.c')
-rw-r--r--net/wireless/mlme.c49
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}
613EXPORT_SYMBOL(cfg80211_del_sta); 607EXPORT_SYMBOL(cfg80211_del_sta);
614 608
609void 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}
618EXPORT_SYMBOL(cfg80211_conn_failed);
619
615struct cfg80211_mgmt_registration { 620struct 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
627int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid, 632int 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
688void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid) 693void 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
717void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev) 722void 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;