aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2015-05-22 10:22:20 -0400
committerJohannes Berg <johannes.berg@intel.com>2015-05-26 09:21:27 -0400
commit80279fb7ba5b71981a60988b0307afa43f78f6b1 (patch)
treef209256191424c26c5e72fedb36ec90a398b19c3 /net/wireless
parentc5a71688e1e56e155fb79b8d699322f4f0793cc8 (diff)
cfg80211: properly send NL80211_ATTR_DISCONNECTED_BY_AP in disconnect
When we disconnect from the AP, drivers call cfg80211_disconnect(). This doesn't know whether the disconnection was initiated locally or by the AP though, which can cause problems with the supplicant, for example with WPS. This issue obviously doesn't show up with any mac80211 based driver since mac80211 doesn't call this function. Fix this by requiring drivers to indicate whether the disconnect is locally generated or not. I've tried to update the drivers, but may not have gotten the values correct, and some drivers may currently not be able to report correct values. In case of doubt I left it at false, which is the current behaviour. For libertas, make adjustments as indicated by Dan Williams. Reported-by: Matthieu Mauger <matthieux.mauger@intel.com> Tested-by: Matthieu Mauger <matthieux.mauger@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/core.h1
-rw-r--r--net/wireless/sme.c4
-rw-r--r--net/wireless/util.c3
3 files changed, 6 insertions, 2 deletions
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 801cd49c5a0c..311eef26bf88 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -222,6 +222,7 @@ struct cfg80211_event {
222 const u8 *ie; 222 const u8 *ie;
223 size_t ie_len; 223 size_t ie_len;
224 u16 reason; 224 u16 reason;
225 bool locally_generated;
225 } dc; 226 } dc;
226 struct { 227 struct {
227 u8 bssid[ETH_ALEN]; 228 u8 bssid[ETH_ALEN];
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index d11454f87bac..8020b5b094d4 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -938,7 +938,8 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
938} 938}
939 939
940void cfg80211_disconnected(struct net_device *dev, u16 reason, 940void cfg80211_disconnected(struct net_device *dev, u16 reason,
941 const u8 *ie, size_t ie_len, gfp_t gfp) 941 const u8 *ie, size_t ie_len,
942 bool locally_generated, gfp_t gfp)
942{ 943{
943 struct wireless_dev *wdev = dev->ieee80211_ptr; 944 struct wireless_dev *wdev = dev->ieee80211_ptr;
944 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); 945 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
@@ -954,6 +955,7 @@ void cfg80211_disconnected(struct net_device *dev, u16 reason,
954 ev->dc.ie_len = ie_len; 955 ev->dc.ie_len = ie_len;
955 memcpy((void *)ev->dc.ie, ie, ie_len); 956 memcpy((void *)ev->dc.ie, ie, ie_len);
956 ev->dc.reason = reason; 957 ev->dc.reason = reason;
958 ev->dc.locally_generated = locally_generated;
957 959
958 spin_lock_irqsave(&wdev->event_lock, flags); 960 spin_lock_irqsave(&wdev->event_lock, flags);
959 list_add_tail(&ev->list, &wdev->event_list); 961 list_add_tail(&ev->list, &wdev->event_list);
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 70051ab52f4f..4cb34557b873 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -887,7 +887,8 @@ void cfg80211_process_wdev_events(struct wireless_dev *wdev)
887 case EVENT_DISCONNECTED: 887 case EVENT_DISCONNECTED:
888 __cfg80211_disconnected(wdev->netdev, 888 __cfg80211_disconnected(wdev->netdev,
889 ev->dc.ie, ev->dc.ie_len, 889 ev->dc.ie, ev->dc.ie_len,
890 ev->dc.reason, true); 890 ev->dc.reason,
891 !ev->dc.locally_generated);
891 break; 892 break;
892 case EVENT_IBSS_JOINED: 893 case EVENT_IBSS_JOINED:
893 __cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid, 894 __cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid,