diff options
Diffstat (limited to 'net/wireless/sme.c')
-rw-r--r-- | net/wireless/sme.c | 90 |
1 files changed, 38 insertions, 52 deletions
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 6459bb7c21f7..532a0007ce82 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
@@ -5,6 +5,7 @@ | |||
5 | * | 5 | * |
6 | * Copyright 2009 Johannes Berg <johannes@sipsolutions.net> | 6 | * Copyright 2009 Johannes Berg <johannes@sipsolutions.net> |
7 | * Copyright (C) 2009 Intel Corporation. All rights reserved. | 7 | * Copyright (C) 2009 Intel Corporation. All rights reserved. |
8 | * Copyright 2017 Intel Deutschland GmbH | ||
8 | */ | 9 | */ |
9 | 10 | ||
10 | #include <linux/etherdevice.h> | 11 | #include <linux/etherdevice.h> |
@@ -870,9 +871,7 @@ EXPORT_SYMBOL(cfg80211_connect_done); | |||
870 | 871 | ||
871 | /* Consumes bss object one way or another */ | 872 | /* Consumes bss object one way or another */ |
872 | void __cfg80211_roamed(struct wireless_dev *wdev, | 873 | void __cfg80211_roamed(struct wireless_dev *wdev, |
873 | struct cfg80211_bss *bss, | 874 | struct cfg80211_roam_info *info) |
874 | const u8 *req_ie, size_t req_ie_len, | ||
875 | const u8 *resp_ie, size_t resp_ie_len) | ||
876 | { | 875 | { |
877 | #ifdef CONFIG_CFG80211_WEXT | 876 | #ifdef CONFIG_CFG80211_WEXT |
878 | union iwreq_data wrqu; | 877 | union iwreq_data wrqu; |
@@ -890,97 +889,84 @@ void __cfg80211_roamed(struct wireless_dev *wdev, | |||
890 | cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub); | 889 | cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub); |
891 | wdev->current_bss = NULL; | 890 | wdev->current_bss = NULL; |
892 | 891 | ||
893 | cfg80211_hold_bss(bss_from_pub(bss)); | 892 | if (WARN_ON(!info->bss)) |
894 | wdev->current_bss = bss_from_pub(bss); | 893 | return; |
894 | |||
895 | cfg80211_hold_bss(bss_from_pub(info->bss)); | ||
896 | wdev->current_bss = bss_from_pub(info->bss); | ||
895 | 897 | ||
896 | nl80211_send_roamed(wiphy_to_rdev(wdev->wiphy), | 898 | nl80211_send_roamed(wiphy_to_rdev(wdev->wiphy), |
897 | wdev->netdev, bss->bssid, | 899 | wdev->netdev, info, GFP_KERNEL); |
898 | req_ie, req_ie_len, resp_ie, resp_ie_len, | ||
899 | GFP_KERNEL); | ||
900 | 900 | ||
901 | #ifdef CONFIG_CFG80211_WEXT | 901 | #ifdef CONFIG_CFG80211_WEXT |
902 | if (req_ie) { | 902 | if (info->req_ie) { |
903 | memset(&wrqu, 0, sizeof(wrqu)); | 903 | memset(&wrqu, 0, sizeof(wrqu)); |
904 | wrqu.data.length = req_ie_len; | 904 | wrqu.data.length = info->req_ie_len; |
905 | wireless_send_event(wdev->netdev, IWEVASSOCREQIE, | 905 | wireless_send_event(wdev->netdev, IWEVASSOCREQIE, |
906 | &wrqu, req_ie); | 906 | &wrqu, info->req_ie); |
907 | } | 907 | } |
908 | 908 | ||
909 | if (resp_ie) { | 909 | if (info->resp_ie) { |
910 | memset(&wrqu, 0, sizeof(wrqu)); | 910 | memset(&wrqu, 0, sizeof(wrqu)); |
911 | wrqu.data.length = resp_ie_len; | 911 | wrqu.data.length = info->resp_ie_len; |
912 | wireless_send_event(wdev->netdev, IWEVASSOCRESPIE, | 912 | wireless_send_event(wdev->netdev, IWEVASSOCRESPIE, |
913 | &wrqu, resp_ie); | 913 | &wrqu, info->resp_ie); |
914 | } | 914 | } |
915 | 915 | ||
916 | memset(&wrqu, 0, sizeof(wrqu)); | 916 | memset(&wrqu, 0, sizeof(wrqu)); |
917 | wrqu.ap_addr.sa_family = ARPHRD_ETHER; | 917 | wrqu.ap_addr.sa_family = ARPHRD_ETHER; |
918 | memcpy(wrqu.ap_addr.sa_data, bss->bssid, ETH_ALEN); | 918 | memcpy(wrqu.ap_addr.sa_data, info->bss->bssid, ETH_ALEN); |
919 | memcpy(wdev->wext.prev_bssid, bss->bssid, ETH_ALEN); | 919 | memcpy(wdev->wext.prev_bssid, info->bss->bssid, ETH_ALEN); |
920 | wdev->wext.prev_bssid_valid = true; | 920 | wdev->wext.prev_bssid_valid = true; |
921 | wireless_send_event(wdev->netdev, SIOCGIWAP, &wrqu, NULL); | 921 | wireless_send_event(wdev->netdev, SIOCGIWAP, &wrqu, NULL); |
922 | #endif | 922 | #endif |
923 | 923 | ||
924 | return; | 924 | return; |
925 | out: | 925 | out: |
926 | cfg80211_put_bss(wdev->wiphy, bss); | 926 | cfg80211_put_bss(wdev->wiphy, info->bss); |
927 | } | ||
928 | |||
929 | void cfg80211_roamed(struct net_device *dev, | ||
930 | struct ieee80211_channel *channel, | ||
931 | const u8 *bssid, | ||
932 | const u8 *req_ie, size_t req_ie_len, | ||
933 | const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp) | ||
934 | { | ||
935 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
936 | struct cfg80211_bss *bss; | ||
937 | |||
938 | bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, wdev->ssid, | ||
939 | wdev->ssid_len, | ||
940 | wdev->conn_bss_type, IEEE80211_PRIVACY_ANY); | ||
941 | if (WARN_ON(!bss)) | ||
942 | return; | ||
943 | |||
944 | cfg80211_roamed_bss(dev, bss, req_ie, req_ie_len, resp_ie, | ||
945 | resp_ie_len, gfp); | ||
946 | } | 927 | } |
947 | EXPORT_SYMBOL(cfg80211_roamed); | ||
948 | 928 | ||
949 | /* Consumes bss object one way or another */ | 929 | /* Consumes info->bss object one way or another */ |
950 | void cfg80211_roamed_bss(struct net_device *dev, | 930 | void cfg80211_roamed(struct net_device *dev, struct cfg80211_roam_info *info, |
951 | struct cfg80211_bss *bss, const u8 *req_ie, | 931 | gfp_t gfp) |
952 | size_t req_ie_len, const u8 *resp_ie, | ||
953 | size_t resp_ie_len, gfp_t gfp) | ||
954 | { | 932 | { |
955 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 933 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
956 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); | 934 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
957 | struct cfg80211_event *ev; | 935 | struct cfg80211_event *ev; |
958 | unsigned long flags; | 936 | unsigned long flags; |
959 | 937 | ||
960 | if (WARN_ON(!bss)) | 938 | if (!info->bss) { |
939 | info->bss = cfg80211_get_bss(wdev->wiphy, info->channel, | ||
940 | info->bssid, wdev->ssid, | ||
941 | wdev->ssid_len, | ||
942 | wdev->conn_bss_type, | ||
943 | IEEE80211_PRIVACY_ANY); | ||
944 | } | ||
945 | |||
946 | if (WARN_ON(!info->bss)) | ||
961 | return; | 947 | return; |
962 | 948 | ||
963 | ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len, gfp); | 949 | ev = kzalloc(sizeof(*ev) + info->req_ie_len + info->resp_ie_len, gfp); |
964 | if (!ev) { | 950 | if (!ev) { |
965 | cfg80211_put_bss(wdev->wiphy, bss); | 951 | cfg80211_put_bss(wdev->wiphy, info->bss); |
966 | return; | 952 | return; |
967 | } | 953 | } |
968 | 954 | ||
969 | ev->type = EVENT_ROAMED; | 955 | ev->type = EVENT_ROAMED; |
970 | ev->rm.req_ie = ((u8 *)ev) + sizeof(*ev); | 956 | ev->rm.req_ie = ((u8 *)ev) + sizeof(*ev); |
971 | ev->rm.req_ie_len = req_ie_len; | 957 | ev->rm.req_ie_len = info->req_ie_len; |
972 | memcpy((void *)ev->rm.req_ie, req_ie, req_ie_len); | 958 | memcpy((void *)ev->rm.req_ie, info->req_ie, info->req_ie_len); |
973 | ev->rm.resp_ie = ((u8 *)ev) + sizeof(*ev) + req_ie_len; | 959 | ev->rm.resp_ie = ((u8 *)ev) + sizeof(*ev) + info->req_ie_len; |
974 | ev->rm.resp_ie_len = resp_ie_len; | 960 | ev->rm.resp_ie_len = info->resp_ie_len; |
975 | memcpy((void *)ev->rm.resp_ie, resp_ie, resp_ie_len); | 961 | memcpy((void *)ev->rm.resp_ie, info->resp_ie, info->resp_ie_len); |
976 | ev->rm.bss = bss; | 962 | ev->rm.bss = info->bss; |
977 | 963 | ||
978 | spin_lock_irqsave(&wdev->event_lock, flags); | 964 | spin_lock_irqsave(&wdev->event_lock, flags); |
979 | list_add_tail(&ev->list, &wdev->event_list); | 965 | list_add_tail(&ev->list, &wdev->event_list); |
980 | spin_unlock_irqrestore(&wdev->event_lock, flags); | 966 | spin_unlock_irqrestore(&wdev->event_lock, flags); |
981 | queue_work(cfg80211_wq, &rdev->event_work); | 967 | queue_work(cfg80211_wq, &rdev->event_work); |
982 | } | 968 | } |
983 | EXPORT_SYMBOL(cfg80211_roamed_bss); | 969 | EXPORT_SYMBOL(cfg80211_roamed); |
984 | 970 | ||
985 | void __cfg80211_disconnected(struct net_device *dev, const u8 *ie, | 971 | void __cfg80211_disconnected(struct net_device *dev, const u8 *ie, |
986 | size_t ie_len, u16 reason, bool from_ap) | 972 | size_t ie_len, u16 reason, bool from_ap) |