aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/wext-sme.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/wext-sme.c')
-rw-r--r--net/wireless/wext-sme.c65
1 files changed, 36 insertions, 29 deletions
diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c
index e4a054aceb5..fe1a5363912 100644
--- a/net/wireless/wext-sme.c
+++ b/net/wireless/wext-sme.c
@@ -52,25 +52,31 @@ int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
52 52
53int cfg80211_mgd_wext_siwfreq(struct net_device *dev, 53int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
54 struct iw_request_info *info, 54 struct iw_request_info *info,
55 struct iw_freq *freq, char *extra) 55 struct iw_freq *wextfreq, char *extra)
56{ 56{
57 struct wireless_dev *wdev = dev->ieee80211_ptr; 57 struct wireless_dev *wdev = dev->ieee80211_ptr;
58 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 58 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
59 struct ieee80211_channel *chan; 59 struct ieee80211_channel *chan = NULL;
60 int err; 60 int err, freq;
61 61
62 /* call only for station! */ 62 /* call only for station! */
63 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION)) 63 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
64 return -EINVAL; 64 return -EINVAL;
65 65
66 chan = cfg80211_wext_freq(wdev->wiphy, freq); 66 freq = cfg80211_wext_freq(wdev->wiphy, wextfreq);
67 if (chan && IS_ERR(chan)) 67 if (freq < 0)
68 return PTR_ERR(chan); 68 return freq;
69 69
70 if (chan && (chan->flags & IEEE80211_CHAN_DISABLED)) 70 if (freq) {
71 return -EINVAL; 71 chan = ieee80211_get_channel(wdev->wiphy, freq);
72 if (!chan)
73 return -EINVAL;
74 if (chan->flags & IEEE80211_CHAN_DISABLED)
75 return -EINVAL;
76 }
72 77
73 cfg80211_lock_rdev(rdev); 78 cfg80211_lock_rdev(rdev);
79 mutex_lock(&rdev->devlist_mtx);
74 wdev_lock(wdev); 80 wdev_lock(wdev);
75 81
76 if (wdev->sme_state != CFG80211_SME_IDLE) { 82 if (wdev->sme_state != CFG80211_SME_IDLE) {
@@ -84,9 +90,8 @@ int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
84 /* if SSID set, we'll try right again, avoid event */ 90 /* if SSID set, we'll try right again, avoid event */
85 if (wdev->wext.connect.ssid_len) 91 if (wdev->wext.connect.ssid_len)
86 event = false; 92 event = false;
87 err = __cfg80211_disconnect(wiphy_to_dev(wdev->wiphy), 93 err = __cfg80211_disconnect(rdev, dev,
88 dev, WLAN_REASON_DEAUTH_LEAVING, 94 WLAN_REASON_DEAUTH_LEAVING, event);
89 event);
90 if (err) 95 if (err)
91 goto out; 96 goto out;
92 } 97 }
@@ -95,17 +100,15 @@ int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
95 wdev->wext.connect.channel = chan; 100 wdev->wext.connect.channel = chan;
96 101
97 /* SSID is not set, we just want to switch channel */ 102 /* SSID is not set, we just want to switch channel */
98 if (wdev->wext.connect.ssid_len && chan) { 103 if (chan && !wdev->wext.connect.ssid_len) {
99 err = -EOPNOTSUPP; 104 err = rdev_set_freq(rdev, freq, NL80211_CHAN_NO_HT);
100 if (rdev->ops->set_channel)
101 err = rdev->ops->set_channel(wdev->wiphy, chan,
102 NL80211_CHAN_NO_HT);
103 goto out; 105 goto out;
104 } 106 }
105 107
106 err = cfg80211_mgd_wext_connect(wiphy_to_dev(wdev->wiphy), wdev); 108 err = cfg80211_mgd_wext_connect(rdev, wdev);
107 out: 109 out:
108 wdev_unlock(wdev); 110 wdev_unlock(wdev);
111 mutex_unlock(&rdev->devlist_mtx);
109 cfg80211_unlock_rdev(rdev); 112 cfg80211_unlock_rdev(rdev);
110 return err; 113 return err;
111} 114}
@@ -143,6 +146,7 @@ int cfg80211_mgd_wext_siwessid(struct net_device *dev,
143 struct iw_point *data, char *ssid) 146 struct iw_point *data, char *ssid)
144{ 147{
145 struct wireless_dev *wdev = dev->ieee80211_ptr; 148 struct wireless_dev *wdev = dev->ieee80211_ptr;
149 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
146 size_t len = data->length; 150 size_t len = data->length;
147 int err; 151 int err;
148 152
@@ -157,7 +161,8 @@ int cfg80211_mgd_wext_siwessid(struct net_device *dev,
157 if (len > 0 && ssid[len - 1] == '\0') 161 if (len > 0 && ssid[len - 1] == '\0')
158 len--; 162 len--;
159 163
160 cfg80211_lock_rdev(wiphy_to_dev(wdev->wiphy)); 164 cfg80211_lock_rdev(rdev);
165 mutex_lock(&rdev->devlist_mtx);
161 wdev_lock(wdev); 166 wdev_lock(wdev);
162 167
163 err = 0; 168 err = 0;
@@ -173,9 +178,8 @@ int cfg80211_mgd_wext_siwessid(struct net_device *dev,
173 /* if SSID set now, we'll try to connect, avoid event */ 178 /* if SSID set now, we'll try to connect, avoid event */
174 if (len) 179 if (len)
175 event = false; 180 event = false;
176 err = __cfg80211_disconnect(wiphy_to_dev(wdev->wiphy), 181 err = __cfg80211_disconnect(rdev, dev,
177 dev, WLAN_REASON_DEAUTH_LEAVING, 182 WLAN_REASON_DEAUTH_LEAVING, event);
178 event);
179 if (err) 183 if (err)
180 goto out; 184 goto out;
181 } 185 }
@@ -186,10 +190,11 @@ int cfg80211_mgd_wext_siwessid(struct net_device *dev,
186 190
187 wdev->wext.connect.crypto.control_port = false; 191 wdev->wext.connect.crypto.control_port = false;
188 192
189 err = cfg80211_mgd_wext_connect(wiphy_to_dev(wdev->wiphy), wdev); 193 err = cfg80211_mgd_wext_connect(rdev, wdev);
190 out: 194 out:
191 wdev_unlock(wdev); 195 wdev_unlock(wdev);
192 cfg80211_unlock_rdev(wiphy_to_dev(wdev->wiphy)); 196 mutex_unlock(&rdev->devlist_mtx);
197 cfg80211_unlock_rdev(rdev);
193 return err; 198 return err;
194} 199}
195 200
@@ -230,6 +235,7 @@ int cfg80211_mgd_wext_siwap(struct net_device *dev,
230 struct sockaddr *ap_addr, char *extra) 235 struct sockaddr *ap_addr, char *extra)
231{ 236{
232 struct wireless_dev *wdev = dev->ieee80211_ptr; 237 struct wireless_dev *wdev = dev->ieee80211_ptr;
238 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
233 u8 *bssid = ap_addr->sa_data; 239 u8 *bssid = ap_addr->sa_data;
234 int err; 240 int err;
235 241
@@ -244,7 +250,8 @@ int cfg80211_mgd_wext_siwap(struct net_device *dev,
244 if (is_zero_ether_addr(bssid) || is_broadcast_ether_addr(bssid)) 250 if (is_zero_ether_addr(bssid) || is_broadcast_ether_addr(bssid))
245 bssid = NULL; 251 bssid = NULL;
246 252
247 cfg80211_lock_rdev(wiphy_to_dev(wdev->wiphy)); 253 cfg80211_lock_rdev(rdev);
254 mutex_lock(&rdev->devlist_mtx);
248 wdev_lock(wdev); 255 wdev_lock(wdev);
249 256
250 if (wdev->sme_state != CFG80211_SME_IDLE) { 257 if (wdev->sme_state != CFG80211_SME_IDLE) {
@@ -258,9 +265,8 @@ int cfg80211_mgd_wext_siwap(struct net_device *dev,
258 compare_ether_addr(bssid, wdev->wext.connect.bssid) == 0) 265 compare_ether_addr(bssid, wdev->wext.connect.bssid) == 0)
259 goto out; 266 goto out;
260 267
261 err = __cfg80211_disconnect(wiphy_to_dev(wdev->wiphy), 268 err = __cfg80211_disconnect(rdev, dev,
262 dev, WLAN_REASON_DEAUTH_LEAVING, 269 WLAN_REASON_DEAUTH_LEAVING, false);
263 false);
264 if (err) 270 if (err)
265 goto out; 271 goto out;
266 } 272 }
@@ -271,10 +277,11 @@ int cfg80211_mgd_wext_siwap(struct net_device *dev,
271 } else 277 } else
272 wdev->wext.connect.bssid = NULL; 278 wdev->wext.connect.bssid = NULL;
273 279
274 err = cfg80211_mgd_wext_connect(wiphy_to_dev(wdev->wiphy), wdev); 280 err = cfg80211_mgd_wext_connect(rdev, wdev);
275 out: 281 out:
276 wdev_unlock(wdev); 282 wdev_unlock(wdev);
277 cfg80211_unlock_rdev(wiphy_to_dev(wdev->wiphy)); 283 mutex_unlock(&rdev->devlist_mtx);
284 cfg80211_unlock_rdev(rdev);
278 return err; 285 return err;
279} 286}
280 287