aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorIlan Peer <ilan.peer@intel.com>2014-02-25 08:33:38 -0500
committerJohannes Berg <johannes.berg@intel.com>2014-02-25 11:34:18 -0500
commit7c8d5e03acc680eb433b0d5dbacbb6cc9db663a1 (patch)
tree59b267fcc15a04dcd69c9e3c45e5d51f0fe745c0 /net
parent31559f35c5724976fd975e5d7e90cdb693b8dd27 (diff)
cfg80211: send stop AP event only due to internal reason
Commit "nl80211: send event when AP operation is stopped" added an event to notify user space that an AP interface has been stopped, to handle cases such as suspend etc. The event is sent regardless if the stop AP flow was triggered by user space or due to internal state change. This might cause issues with wpa_supplicant/hostapd flows that consider stop AP flow as a synchronous one, e.g., AP/GO channel change in the absence of CSA support. In such cases, the flow will restart the AP immediately after the stop AP flow is done, and only handle the stop AP event after the current flow is done, and as a result stop the AP again. Change the current implementation to only send the event in case the stop AP was triggered due to an internal reason. Signed-off-by: Ilan Peer <ilan.peer@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r--net/wireless/ap.c9
-rw-r--r--net/wireless/core.c2
-rw-r--r--net/wireless/core.h2
-rw-r--r--net/wireless/nl80211.c2
-rw-r--r--net/wireless/util.c2
5 files changed, 9 insertions, 8 deletions
diff --git a/net/wireless/ap.c b/net/wireless/ap.c
index 68602be07cc1..3e02ade508d8 100644
--- a/net/wireless/ap.c
+++ b/net/wireless/ap.c
@@ -7,7 +7,7 @@
7 7
8 8
9static int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, 9static int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
10 struct net_device *dev) 10 struct net_device *dev, bool notify)
11{ 11{
12 struct wireless_dev *wdev = dev->ieee80211_ptr; 12 struct wireless_dev *wdev = dev->ieee80211_ptr;
13 int err; 13 int err;
@@ -30,20 +30,21 @@ static int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
30 memset(&wdev->chandef, 0, sizeof(wdev->chandef)); 30 memset(&wdev->chandef, 0, sizeof(wdev->chandef));
31 wdev->ssid_len = 0; 31 wdev->ssid_len = 0;
32 rdev_set_qos_map(rdev, dev, NULL); 32 rdev_set_qos_map(rdev, dev, NULL);
33 nl80211_send_ap_stopped(wdev); 33 if (notify)
34 nl80211_send_ap_stopped(wdev);
34 } 35 }
35 36
36 return err; 37 return err;
37} 38}
38 39
39int cfg80211_stop_ap(struct cfg80211_registered_device *rdev, 40int cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
40 struct net_device *dev) 41 struct net_device *dev, bool notify)
41{ 42{
42 struct wireless_dev *wdev = dev->ieee80211_ptr; 43 struct wireless_dev *wdev = dev->ieee80211_ptr;
43 int err; 44 int err;
44 45
45 wdev_lock(wdev); 46 wdev_lock(wdev);
46 err = __cfg80211_stop_ap(rdev, dev); 47 err = __cfg80211_stop_ap(rdev, dev, notify);
47 wdev_unlock(wdev); 48 wdev_unlock(wdev);
48 49
49 return err; 50 return err;
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 76ae6a605abb..276cf938f764 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -783,7 +783,7 @@ void cfg80211_leave(struct cfg80211_registered_device *rdev,
783 break; 783 break;
784 case NL80211_IFTYPE_AP: 784 case NL80211_IFTYPE_AP:
785 case NL80211_IFTYPE_P2P_GO: 785 case NL80211_IFTYPE_P2P_GO:
786 cfg80211_stop_ap(rdev, dev); 786 cfg80211_stop_ap(rdev, dev, true);
787 break; 787 break;
788 default: 788 default:
789 break; 789 break;
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 64fde38c1a7e..3975ffa8feb2 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -283,7 +283,7 @@ int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev,
283 283
284/* AP */ 284/* AP */
285int cfg80211_stop_ap(struct cfg80211_registered_device *rdev, 285int cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
286 struct net_device *dev); 286 struct net_device *dev, bool notify);
287 287
288/* MLME */ 288/* MLME */
289int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, 289int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 8fa02a3fa7f7..052c1bf8ffac 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3332,7 +3332,7 @@ static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info)
3332 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 3332 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3333 struct net_device *dev = info->user_ptr[1]; 3333 struct net_device *dev = info->user_ptr[1];
3334 3334
3335 return cfg80211_stop_ap(rdev, dev); 3335 return cfg80211_stop_ap(rdev, dev, false);
3336} 3336}
3337 3337
3338static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = { 3338static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 57b3ce7a6b92..dadc934d987f 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -886,7 +886,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
886 886
887 switch (otype) { 887 switch (otype) {
888 case NL80211_IFTYPE_AP: 888 case NL80211_IFTYPE_AP:
889 cfg80211_stop_ap(rdev, dev); 889 cfg80211_stop_ap(rdev, dev, true);
890 break; 890 break;
891 case NL80211_IFTYPE_ADHOC: 891 case NL80211_IFTYPE_ADHOC:
892 cfg80211_leave_ibss(rdev, dev, false); 892 cfg80211_leave_ibss(rdev, dev, false);