]> Pileus Git - ~andy/linux/blob - net/wireless/sme.c
Merge branch 'core-rcu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[~andy/linux] / net / wireless / sme.c
1 /*
2  * SME code for cfg80211's connect emulation.
3  *
4  * Copyright 2009       Johannes Berg <johannes@sipsolutions.net>
5  * Copyright (C) 2009   Intel Corporation. All rights reserved.
6  */
7
8 #include <linux/etherdevice.h>
9 #include <linux/if_arp.h>
10 #include <linux/slab.h>
11 #include <linux/workqueue.h>
12 #include <linux/wireless.h>
13 #include <linux/export.h>
14 #include <net/iw_handler.h>
15 #include <net/cfg80211.h>
16 #include <net/rtnetlink.h>
17 #include "nl80211.h"
18 #include "reg.h"
19 #include "rdev-ops.h"
20
21 struct cfg80211_conn {
22         struct cfg80211_connect_params params;
23         /* these are sub-states of the _CONNECTING sme_state */
24         enum {
25                 CFG80211_CONN_IDLE,
26                 CFG80211_CONN_SCANNING,
27                 CFG80211_CONN_SCAN_AGAIN,
28                 CFG80211_CONN_AUTHENTICATE_NEXT,
29                 CFG80211_CONN_AUTHENTICATING,
30                 CFG80211_CONN_ASSOCIATE_NEXT,
31                 CFG80211_CONN_ASSOCIATING,
32                 CFG80211_CONN_DEAUTH_ASSOC_FAIL,
33         } state;
34         u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN];
35         u8 *ie;
36         size_t ie_len;
37         bool auto_auth, prev_bssid_valid;
38 };
39
40 static bool cfg80211_is_all_idle(void)
41 {
42         struct cfg80211_registered_device *rdev;
43         struct wireless_dev *wdev;
44         bool is_all_idle = true;
45
46         mutex_lock(&cfg80211_mutex);
47
48         /*
49          * All devices must be idle as otherwise if you are actively
50          * scanning some new beacon hints could be learned and would
51          * count as new regulatory hints.
52          */
53         list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
54                 cfg80211_lock_rdev(rdev);
55                 list_for_each_entry(wdev, &rdev->wdev_list, list) {
56                         wdev_lock(wdev);
57                         if (wdev->sme_state != CFG80211_SME_IDLE)
58                                 is_all_idle = false;
59                         wdev_unlock(wdev);
60                 }
61                 cfg80211_unlock_rdev(rdev);
62         }
63
64         mutex_unlock(&cfg80211_mutex);
65
66         return is_all_idle;
67 }
68
69 static void disconnect_work(struct work_struct *work)
70 {
71         if (!cfg80211_is_all_idle())
72                 return;
73
74         regulatory_hint_disconnect();
75 }
76
77 static DECLARE_WORK(cfg80211_disconnect_work, disconnect_work);
78
79 static int cfg80211_conn_scan(struct wireless_dev *wdev)
80 {
81         struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
82         struct cfg80211_scan_request *request;
83         int n_channels, err;
84
85         ASSERT_RTNL();
86         ASSERT_RDEV_LOCK(rdev);
87         ASSERT_WDEV_LOCK(wdev);
88         lockdep_assert_held(&rdev->sched_scan_mtx);
89
90         if (rdev->scan_req)
91                 return -EBUSY;
92
93         if (wdev->conn->params.channel) {
94                 n_channels = 1;
95         } else {
96                 enum ieee80211_band band;
97                 n_channels = 0;
98
99                 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
100                         if (!wdev->wiphy->bands[band])
101                                 continue;
102                         n_channels += wdev->wiphy->bands[band]->n_channels;
103                 }
104         }
105         request = kzalloc(sizeof(*request) + sizeof(request->ssids[0]) +
106                           sizeof(request->channels[0]) * n_channels,
107                           GFP_KERNEL);
108         if (!request)
109                 return -ENOMEM;
110
111         if (wdev->conn->params.channel)
112                 request->channels[0] = wdev->conn->params.channel;
113         else {
114                 int i = 0, j;
115                 enum ieee80211_band band;
116                 struct ieee80211_supported_band *bands;
117                 struct ieee80211_channel *channel;
118
119                 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
120                         bands = wdev->wiphy->bands[band];
121                         if (!bands)
122                                 continue;
123                         for (j = 0; j < bands->n_channels; j++) {
124                                 channel = &bands->channels[j];
125                                 if (channel->flags & IEEE80211_CHAN_DISABLED)
126                                         continue;
127                                 request->channels[i++] = channel;
128                         }
129                         request->rates[band] = (1 << bands->n_bitrates) - 1;
130                 }
131                 n_channels = i;
132         }
133         request->n_channels = n_channels;
134         request->ssids = (void *)&request->channels[n_channels];
135         request->n_ssids = 1;
136
137         memcpy(request->ssids[0].ssid, wdev->conn->params.ssid,
138                 wdev->conn->params.ssid_len);
139         request->ssids[0].ssid_len = wdev->conn->params.ssid_len;
140
141         request->wdev = wdev;
142         request->wiphy = &rdev->wiphy;
143         request->scan_start = jiffies;
144
145         rdev->scan_req = request;
146
147         err = rdev_scan(rdev, request);
148         if (!err) {
149                 wdev->conn->state = CFG80211_CONN_SCANNING;
150                 nl80211_send_scan_start(rdev, wdev);
151                 dev_hold(wdev->netdev);
152         } else {
153                 rdev->scan_req = NULL;
154                 kfree(request);
155         }
156         return err;
157 }
158
159 static int cfg80211_conn_do_work(struct wireless_dev *wdev)
160 {
161         struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
162         struct cfg80211_connect_params *params;
163         const u8 *prev_bssid = NULL;
164         int err;
165
166         ASSERT_WDEV_LOCK(wdev);
167
168         if (!wdev->conn)
169                 return 0;
170
171         params = &wdev->conn->params;
172
173         switch (wdev->conn->state) {
174         case CFG80211_CONN_SCAN_AGAIN:
175                 return cfg80211_conn_scan(wdev);
176         case CFG80211_CONN_AUTHENTICATE_NEXT:
177                 BUG_ON(!rdev->ops->auth);
178                 wdev->conn->state = CFG80211_CONN_AUTHENTICATING;
179                 return __cfg80211_mlme_auth(rdev, wdev->netdev,
180                                             params->channel, params->auth_type,
181                                             params->bssid,
182                                             params->ssid, params->ssid_len,
183                                             NULL, 0,
184                                             params->key, params->key_len,
185                                             params->key_idx, NULL, 0);
186         case CFG80211_CONN_ASSOCIATE_NEXT:
187                 BUG_ON(!rdev->ops->assoc);
188                 wdev->conn->state = CFG80211_CONN_ASSOCIATING;
189                 if (wdev->conn->prev_bssid_valid)
190                         prev_bssid = wdev->conn->prev_bssid;
191                 err = __cfg80211_mlme_assoc(rdev, wdev->netdev,
192                                             params->channel, params->bssid,
193                                             prev_bssid,
194                                             params->ssid, params->ssid_len,
195                                             params->ie, params->ie_len,
196                                             params->mfp != NL80211_MFP_NO,
197                                             &params->crypto,
198                                             params->flags, &params->ht_capa,
199                                             &params->ht_capa_mask);
200                 if (err)
201                         __cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
202                                                NULL, 0,
203                                                WLAN_REASON_DEAUTH_LEAVING,
204                                                false);
205                 return err;
206         case CFG80211_CONN_DEAUTH_ASSOC_FAIL:
207                 __cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
208                                        NULL, 0,
209                                        WLAN_REASON_DEAUTH_LEAVING, false);
210                 /* return an error so that we call __cfg80211_connect_result() */
211                 return -EINVAL;
212         default:
213                 return 0;
214         }
215 }
216
217 void cfg80211_conn_work(struct work_struct *work)
218 {
219         struct cfg80211_registered_device *rdev =
220                 container_of(work, struct cfg80211_registered_device, conn_work);
221         struct wireless_dev *wdev;
222         u8 bssid_buf[ETH_ALEN], *bssid = NULL;
223
224         rtnl_lock();
225         cfg80211_lock_rdev(rdev);
226         mutex_lock(&rdev->devlist_mtx);
227         mutex_lock(&rdev->sched_scan_mtx);
228
229         list_for_each_entry(wdev, &rdev->wdev_list, list) {
230                 wdev_lock(wdev);
231                 if (!netif_running(wdev->netdev)) {
232                         wdev_unlock(wdev);
233                         continue;
234                 }
235                 if (wdev->sme_state != CFG80211_SME_CONNECTING) {
236                         wdev_unlock(wdev);
237                         continue;
238                 }
239                 if (wdev->conn->params.bssid) {
240                         memcpy(bssid_buf, wdev->conn->params.bssid, ETH_ALEN);
241                         bssid = bssid_buf;
242                 }
243                 if (cfg80211_conn_do_work(wdev))
244                         __cfg80211_connect_result(
245                                         wdev->netdev, bssid,
246                                         NULL, 0, NULL, 0,
247                                         WLAN_STATUS_UNSPECIFIED_FAILURE,
248                                         false, NULL);
249                 wdev_unlock(wdev);
250         }
251
252         mutex_unlock(&rdev->sched_scan_mtx);
253         mutex_unlock(&rdev->devlist_mtx);
254         cfg80211_unlock_rdev(rdev);
255         rtnl_unlock();
256 }
257
258 static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev)
259 {
260         struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
261         struct cfg80211_bss *bss;
262         u16 capa = WLAN_CAPABILITY_ESS;
263
264         ASSERT_WDEV_LOCK(wdev);
265
266         if (wdev->conn->params.privacy)
267                 capa |= WLAN_CAPABILITY_PRIVACY;
268
269         bss = cfg80211_get_bss(wdev->wiphy, wdev->conn->params.channel,
270                                wdev->conn->params.bssid,
271                                wdev->conn->params.ssid,
272                                wdev->conn->params.ssid_len,
273                                WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_PRIVACY,
274                                capa);
275         if (!bss)
276                 return NULL;
277
278         memcpy(wdev->conn->bssid, bss->bssid, ETH_ALEN);
279         wdev->conn->params.bssid = wdev->conn->bssid;
280         wdev->conn->params.channel = bss->channel;
281         wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
282         schedule_work(&rdev->conn_work);
283
284         return bss;
285 }
286
287 static void __cfg80211_sme_scan_done(struct net_device *dev)
288 {
289         struct wireless_dev *wdev = dev->ieee80211_ptr;
290         struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
291         struct cfg80211_bss *bss;
292
293         ASSERT_WDEV_LOCK(wdev);
294
295         if (wdev->sme_state != CFG80211_SME_CONNECTING)
296                 return;
297
298         if (!wdev->conn)
299                 return;
300
301         if (wdev->conn->state != CFG80211_CONN_SCANNING &&
302             wdev->conn->state != CFG80211_CONN_SCAN_AGAIN)
303                 return;
304
305         bss = cfg80211_get_conn_bss(wdev);
306         if (bss) {
307                 cfg80211_put_bss(&rdev->wiphy, bss);
308         } else {
309                 /* not found */
310                 if (wdev->conn->state == CFG80211_CONN_SCAN_AGAIN)
311                         schedule_work(&rdev->conn_work);
312                 else
313                         __cfg80211_connect_result(
314                                         wdev->netdev,
315                                         wdev->conn->params.bssid,
316                                         NULL, 0, NULL, 0,
317                                         WLAN_STATUS_UNSPECIFIED_FAILURE,
318                                         false, NULL);
319         }
320 }
321
322 void cfg80211_sme_scan_done(struct net_device *dev)
323 {
324         struct wireless_dev *wdev = dev->ieee80211_ptr;
325
326         wdev_lock(wdev);
327         __cfg80211_sme_scan_done(dev);
328         wdev_unlock(wdev);
329 }
330
331 void cfg80211_sme_rx_auth(struct net_device *dev,
332                           const u8 *buf, size_t len)
333 {
334         struct wireless_dev *wdev = dev->ieee80211_ptr;
335         struct wiphy *wiphy = wdev->wiphy;
336         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
337         struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
338         u16 status_code = le16_to_cpu(mgmt->u.auth.status_code);
339
340         ASSERT_WDEV_LOCK(wdev);
341
342         /* should only RX auth frames when connecting */
343         if (wdev->sme_state != CFG80211_SME_CONNECTING)
344                 return;
345
346         if (WARN_ON(!wdev->conn))
347                 return;
348
349         if (status_code == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG &&
350             wdev->conn->auto_auth &&
351             wdev->conn->params.auth_type != NL80211_AUTHTYPE_NETWORK_EAP) {
352                 /* select automatically between only open, shared, leap */
353                 switch (wdev->conn->params.auth_type) {
354                 case NL80211_AUTHTYPE_OPEN_SYSTEM:
355                         if (wdev->connect_keys)
356                                 wdev->conn->params.auth_type =
357                                         NL80211_AUTHTYPE_SHARED_KEY;
358                         else
359                                 wdev->conn->params.auth_type =
360                                         NL80211_AUTHTYPE_NETWORK_EAP;
361                         break;
362                 case NL80211_AUTHTYPE_SHARED_KEY:
363                         wdev->conn->params.auth_type =
364                                 NL80211_AUTHTYPE_NETWORK_EAP;
365                         break;
366                 default:
367                         /* huh? */
368                         wdev->conn->params.auth_type =
369                                 NL80211_AUTHTYPE_OPEN_SYSTEM;
370                         break;
371                 }
372                 wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
373                 schedule_work(&rdev->conn_work);
374         } else if (status_code != WLAN_STATUS_SUCCESS) {
375                 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0,
376                                           status_code, false, NULL);
377         } else if (wdev->sme_state == CFG80211_SME_CONNECTING &&
378                  wdev->conn->state == CFG80211_CONN_AUTHENTICATING) {
379                 wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT;
380                 schedule_work(&rdev->conn_work);
381         }
382 }
383
384 bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev)
385 {
386         struct wiphy *wiphy = wdev->wiphy;
387         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
388
389         if (WARN_ON(!wdev->conn))
390                 return false;
391
392         if (!wdev->conn->prev_bssid_valid)
393                 return false;
394
395         /*
396          * Some stupid APs don't accept reassoc, so we
397          * need to fall back to trying regular assoc.
398          */
399         wdev->conn->prev_bssid_valid = false;
400         wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT;
401         schedule_work(&rdev->conn_work);
402
403         return true;
404 }
405
406 void cfg80211_sme_failed_assoc(struct wireless_dev *wdev)
407 {
408         struct wiphy *wiphy = wdev->wiphy;
409         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
410
411         wdev->conn->state = CFG80211_CONN_DEAUTH_ASSOC_FAIL;
412         schedule_work(&rdev->conn_work);
413 }
414
415 void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
416                                const u8 *req_ie, size_t req_ie_len,
417                                const u8 *resp_ie, size_t resp_ie_len,
418                                u16 status, bool wextev,
419                                struct cfg80211_bss *bss)
420 {
421         struct wireless_dev *wdev = dev->ieee80211_ptr;
422         const u8 *country_ie;
423 #ifdef CONFIG_CFG80211_WEXT
424         union iwreq_data wrqu;
425 #endif
426
427         ASSERT_WDEV_LOCK(wdev);
428
429         if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION &&
430                     wdev->iftype != NL80211_IFTYPE_P2P_CLIENT))
431                 return;
432
433         if (wdev->sme_state != CFG80211_SME_CONNECTING)
434                 return;
435
436         nl80211_send_connect_result(wiphy_to_dev(wdev->wiphy), dev,
437                                     bssid, req_ie, req_ie_len,
438                                     resp_ie, resp_ie_len,
439                                     status, GFP_KERNEL);
440
441 #ifdef CONFIG_CFG80211_WEXT
442         if (wextev) {
443                 if (req_ie && status == WLAN_STATUS_SUCCESS) {
444                         memset(&wrqu, 0, sizeof(wrqu));
445                         wrqu.data.length = req_ie_len;
446                         wireless_send_event(dev, IWEVASSOCREQIE, &wrqu, req_ie);
447                 }
448
449                 if (resp_ie && status == WLAN_STATUS_SUCCESS) {
450                         memset(&wrqu, 0, sizeof(wrqu));
451                         wrqu.data.length = resp_ie_len;
452                         wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, resp_ie);
453                 }
454
455                 memset(&wrqu, 0, sizeof(wrqu));
456                 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
457                 if (bssid && status == WLAN_STATUS_SUCCESS) {
458                         memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
459                         memcpy(wdev->wext.prev_bssid, bssid, ETH_ALEN);
460                         wdev->wext.prev_bssid_valid = true;
461                 }
462                 wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
463         }
464 #endif
465
466         if (wdev->current_bss) {
467                 cfg80211_unhold_bss(wdev->current_bss);
468                 cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub);
469                 wdev->current_bss = NULL;
470         }
471
472         if (wdev->conn)
473                 wdev->conn->state = CFG80211_CONN_IDLE;
474
475         if (status != WLAN_STATUS_SUCCESS) {
476                 wdev->sme_state = CFG80211_SME_IDLE;
477                 if (wdev->conn)
478                         kfree(wdev->conn->ie);
479                 kfree(wdev->conn);
480                 wdev->conn = NULL;
481                 kfree(wdev->connect_keys);
482                 wdev->connect_keys = NULL;
483                 wdev->ssid_len = 0;
484                 cfg80211_put_bss(wdev->wiphy, bss);
485                 return;
486         }
487
488         if (!bss)
489                 bss = cfg80211_get_bss(wdev->wiphy,
490                                        wdev->conn ? wdev->conn->params.channel :
491                                        NULL,
492                                        bssid,
493                                        wdev->ssid, wdev->ssid_len,
494                                        WLAN_CAPABILITY_ESS,
495                                        WLAN_CAPABILITY_ESS);
496
497         if (WARN_ON(!bss))
498                 return;
499
500         cfg80211_hold_bss(bss_from_pub(bss));
501         wdev->current_bss = bss_from_pub(bss);
502
503         wdev->sme_state = CFG80211_SME_CONNECTED;
504         cfg80211_upload_connect_keys(wdev);
505
506         rcu_read_lock();
507         country_ie = ieee80211_bss_get_ie(bss, WLAN_EID_COUNTRY);
508         if (!country_ie) {
509                 rcu_read_unlock();
510                 return;
511         }
512
513         country_ie = kmemdup(country_ie, 2 + country_ie[1], GFP_ATOMIC);
514         rcu_read_unlock();
515
516         if (!country_ie)
517                 return;
518
519         /*
520          * ieee80211_bss_get_ie() ensures we can access:
521          * - country_ie + 2, the start of the country ie data, and
522          * - and country_ie[1] which is the IE length
523          */
524         regulatory_hint_11d(wdev->wiphy, bss->channel->band,
525                             country_ie + 2, country_ie[1]);
526         kfree(country_ie);
527 }
528
529 void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
530                              const u8 *req_ie, size_t req_ie_len,
531                              const u8 *resp_ie, size_t resp_ie_len,
532                              u16 status, gfp_t gfp)
533 {
534         struct wireless_dev *wdev = dev->ieee80211_ptr;
535         struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
536         struct cfg80211_event *ev;
537         unsigned long flags;
538
539         CFG80211_DEV_WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTING);
540
541         ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len, gfp);
542         if (!ev)
543                 return;
544
545         ev->type = EVENT_CONNECT_RESULT;
546         if (bssid)
547                 memcpy(ev->cr.bssid, bssid, ETH_ALEN);
548         if (req_ie_len) {
549                 ev->cr.req_ie = ((u8 *)ev) + sizeof(*ev);
550                 ev->cr.req_ie_len = req_ie_len;
551                 memcpy((void *)ev->cr.req_ie, req_ie, req_ie_len);
552         }
553         if (resp_ie_len) {
554                 ev->cr.resp_ie = ((u8 *)ev) + sizeof(*ev) + req_ie_len;
555                 ev->cr.resp_ie_len = resp_ie_len;
556                 memcpy((void *)ev->cr.resp_ie, resp_ie, resp_ie_len);
557         }
558         ev->cr.status = status;
559
560         spin_lock_irqsave(&wdev->event_lock, flags);
561         list_add_tail(&ev->list, &wdev->event_list);
562         spin_unlock_irqrestore(&wdev->event_lock, flags);
563         queue_work(cfg80211_wq, &rdev->event_work);
564 }
565 EXPORT_SYMBOL(cfg80211_connect_result);
566
567 void __cfg80211_roamed(struct wireless_dev *wdev,
568                        struct cfg80211_bss *bss,
569                        const u8 *req_ie, size_t req_ie_len,
570                        const u8 *resp_ie, size_t resp_ie_len)
571 {
572 #ifdef CONFIG_CFG80211_WEXT
573         union iwreq_data wrqu;
574 #endif
575         ASSERT_WDEV_LOCK(wdev);
576
577         if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION &&
578                     wdev->iftype != NL80211_IFTYPE_P2P_CLIENT))
579                 goto out;
580
581         if (wdev->sme_state != CFG80211_SME_CONNECTED)
582                 goto out;
583
584         /* internal error -- how did we get to CONNECTED w/o BSS? */
585         if (WARN_ON(!wdev->current_bss)) {
586                 goto out;
587         }
588
589         cfg80211_unhold_bss(wdev->current_bss);
590         cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub);
591         wdev->current_bss = NULL;
592
593         cfg80211_hold_bss(bss_from_pub(bss));
594         wdev->current_bss = bss_from_pub(bss);
595
596         nl80211_send_roamed(wiphy_to_dev(wdev->wiphy), wdev->netdev, bss->bssid,
597                             req_ie, req_ie_len, resp_ie, resp_ie_len,
598                             GFP_KERNEL);
599
600 #ifdef CONFIG_CFG80211_WEXT
601         if (req_ie) {
602                 memset(&wrqu, 0, sizeof(wrqu));
603                 wrqu.data.length = req_ie_len;
604                 wireless_send_event(wdev->netdev, IWEVASSOCREQIE,
605                                     &wrqu, req_ie);
606         }
607
608         if (resp_ie) {
609                 memset(&wrqu, 0, sizeof(wrqu));
610                 wrqu.data.length = resp_ie_len;
611                 wireless_send_event(wdev->netdev, IWEVASSOCRESPIE,
612                                     &wrqu, resp_ie);
613         }
614
615         memset(&wrqu, 0, sizeof(wrqu));
616         wrqu.ap_addr.sa_family = ARPHRD_ETHER;
617         memcpy(wrqu.ap_addr.sa_data, bss->bssid, ETH_ALEN);
618         memcpy(wdev->wext.prev_bssid, bss->bssid, ETH_ALEN);
619         wdev->wext.prev_bssid_valid = true;
620         wireless_send_event(wdev->netdev, SIOCGIWAP, &wrqu, NULL);
621 #endif
622
623         return;
624 out:
625         cfg80211_put_bss(wdev->wiphy, bss);
626 }
627
628 void cfg80211_roamed(struct net_device *dev,
629                      struct ieee80211_channel *channel,
630                      const u8 *bssid,
631                      const u8 *req_ie, size_t req_ie_len,
632                      const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp)
633 {
634         struct wireless_dev *wdev = dev->ieee80211_ptr;
635         struct cfg80211_bss *bss;
636
637         CFG80211_DEV_WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTED);
638
639         bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, wdev->ssid,
640                                wdev->ssid_len, WLAN_CAPABILITY_ESS,
641                                WLAN_CAPABILITY_ESS);
642         if (WARN_ON(!bss))
643                 return;
644
645         cfg80211_roamed_bss(dev, bss, req_ie, req_ie_len, resp_ie,
646                             resp_ie_len, gfp);
647 }
648 EXPORT_SYMBOL(cfg80211_roamed);
649
650 void cfg80211_roamed_bss(struct net_device *dev,
651                          struct cfg80211_bss *bss, const u8 *req_ie,
652                          size_t req_ie_len, const u8 *resp_ie,
653                          size_t resp_ie_len, gfp_t gfp)
654 {
655         struct wireless_dev *wdev = dev->ieee80211_ptr;
656         struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
657         struct cfg80211_event *ev;
658         unsigned long flags;
659
660         CFG80211_DEV_WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTED);
661
662         if (WARN_ON(!bss))
663                 return;
664
665         ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len, gfp);
666         if (!ev) {
667                 cfg80211_put_bss(wdev->wiphy, bss);
668                 return;
669         }
670
671         ev->type = EVENT_ROAMED;
672         ev->rm.req_ie = ((u8 *)ev) + sizeof(*ev);
673         ev->rm.req_ie_len = req_ie_len;
674         memcpy((void *)ev->rm.req_ie, req_ie, req_ie_len);
675         ev->rm.resp_ie = ((u8 *)ev) + sizeof(*ev) + req_ie_len;
676         ev->rm.resp_ie_len = resp_ie_len;
677         memcpy((void *)ev->rm.resp_ie, resp_ie, resp_ie_len);
678         ev->rm.bss = bss;
679
680         spin_lock_irqsave(&wdev->event_lock, flags);
681         list_add_tail(&ev->list, &wdev->event_list);
682         spin_unlock_irqrestore(&wdev->event_lock, flags);
683         queue_work(cfg80211_wq, &rdev->event_work);
684 }
685 EXPORT_SYMBOL(cfg80211_roamed_bss);
686
687 void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
688                              size_t ie_len, u16 reason, bool from_ap)
689 {
690         struct wireless_dev *wdev = dev->ieee80211_ptr;
691         struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
692         int i;
693 #ifdef CONFIG_CFG80211_WEXT
694         union iwreq_data wrqu;
695 #endif
696
697         ASSERT_WDEV_LOCK(wdev);
698
699         if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION &&
700                     wdev->iftype != NL80211_IFTYPE_P2P_CLIENT))
701                 return;
702
703         if (wdev->sme_state != CFG80211_SME_CONNECTED)
704                 return;
705
706         if (wdev->current_bss) {
707                 cfg80211_unhold_bss(wdev->current_bss);
708                 cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub);
709         }
710
711         wdev->current_bss = NULL;
712         wdev->sme_state = CFG80211_SME_IDLE;
713         wdev->ssid_len = 0;
714
715         if (wdev->conn) {
716                 kfree(wdev->conn->ie);
717                 wdev->conn->ie = NULL;
718                 kfree(wdev->conn);
719                 wdev->conn = NULL;
720         }
721
722         nl80211_send_disconnected(rdev, dev, reason, ie, ie_len, from_ap);
723
724         /*
725          * Delete all the keys ... pairwise keys can't really
726          * exist any more anyway, but default keys might.
727          */
728         if (rdev->ops->del_key)
729                 for (i = 0; i < 6; i++)
730                         rdev_del_key(rdev, dev, i, false, NULL);
731
732 #ifdef CONFIG_CFG80211_WEXT
733         memset(&wrqu, 0, sizeof(wrqu));
734         wrqu.ap_addr.sa_family = ARPHRD_ETHER;
735         wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
736         wdev->wext.connect.ssid_len = 0;
737 #endif
738
739         schedule_work(&cfg80211_disconnect_work);
740 }
741
742 void cfg80211_disconnected(struct net_device *dev, u16 reason,
743                            u8 *ie, size_t ie_len, gfp_t gfp)
744 {
745         struct wireless_dev *wdev = dev->ieee80211_ptr;
746         struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
747         struct cfg80211_event *ev;
748         unsigned long flags;
749
750         CFG80211_DEV_WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTED);
751
752         ev = kzalloc(sizeof(*ev) + ie_len, gfp);
753         if (!ev)
754                 return;
755
756         ev->type = EVENT_DISCONNECTED;
757         ev->dc.ie = ((u8 *)ev) + sizeof(*ev);
758         ev->dc.ie_len = ie_len;
759         memcpy((void *)ev->dc.ie, ie, ie_len);
760         ev->dc.reason = reason;
761
762         spin_lock_irqsave(&wdev->event_lock, flags);
763         list_add_tail(&ev->list, &wdev->event_list);
764         spin_unlock_irqrestore(&wdev->event_lock, flags);
765         queue_work(cfg80211_wq, &rdev->event_work);
766 }
767 EXPORT_SYMBOL(cfg80211_disconnected);
768
769 int __cfg80211_connect(struct cfg80211_registered_device *rdev,
770                        struct net_device *dev,
771                        struct cfg80211_connect_params *connect,
772                        struct cfg80211_cached_keys *connkeys,
773                        const u8 *prev_bssid)
774 {
775         struct wireless_dev *wdev = dev->ieee80211_ptr;
776         struct cfg80211_bss *bss = NULL;
777         int err;
778
779         ASSERT_WDEV_LOCK(wdev);
780
781         if (wdev->sme_state != CFG80211_SME_IDLE)
782                 return -EALREADY;
783
784         if (WARN_ON(wdev->connect_keys)) {
785                 kfree(wdev->connect_keys);
786                 wdev->connect_keys = NULL;
787         }
788
789         cfg80211_oper_and_ht_capa(&connect->ht_capa_mask,
790                                   rdev->wiphy.ht_capa_mod_mask);
791
792         if (connkeys && connkeys->def >= 0) {
793                 int idx;
794                 u32 cipher;
795
796                 idx = connkeys->def;
797                 cipher = connkeys->params[idx].cipher;
798                 /* If given a WEP key we may need it for shared key auth */
799                 if (cipher == WLAN_CIPHER_SUITE_WEP40 ||
800                     cipher == WLAN_CIPHER_SUITE_WEP104) {
801                         connect->key_idx = idx;
802                         connect->key = connkeys->params[idx].key;
803                         connect->key_len = connkeys->params[idx].key_len;
804
805                         /*
806                          * If ciphers are not set (e.g. when going through
807                          * iwconfig), we have to set them appropriately here.
808                          */
809                         if (connect->crypto.cipher_group == 0)
810                                 connect->crypto.cipher_group = cipher;
811
812                         if (connect->crypto.n_ciphers_pairwise == 0) {
813                                 connect->crypto.n_ciphers_pairwise = 1;
814                                 connect->crypto.ciphers_pairwise[0] = cipher;
815                         }
816                 }
817         }
818
819         if (!rdev->ops->connect) {
820                 if (!rdev->ops->auth || !rdev->ops->assoc)
821                         return -EOPNOTSUPP;
822
823                 if (WARN_ON(wdev->conn))
824                         return -EINPROGRESS;
825
826                 wdev->conn = kzalloc(sizeof(*wdev->conn), GFP_KERNEL);
827                 if (!wdev->conn)
828                         return -ENOMEM;
829
830                 /*
831                  * Copy all parameters, and treat explicitly IEs, BSSID, SSID.
832                  */
833                 memcpy(&wdev->conn->params, connect, sizeof(*connect));
834                 if (connect->bssid) {
835                         wdev->conn->params.bssid = wdev->conn->bssid;
836                         memcpy(wdev->conn->bssid, connect->bssid, ETH_ALEN);
837                 }
838
839                 if (connect->ie) {
840                         wdev->conn->ie = kmemdup(connect->ie, connect->ie_len,
841                                                 GFP_KERNEL);
842                         wdev->conn->params.ie = wdev->conn->ie;
843                         if (!wdev->conn->ie) {
844                                 kfree(wdev->conn);
845                                 wdev->conn = NULL;
846                                 return -ENOMEM;
847                         }
848                 }
849
850                 if (connect->auth_type == NL80211_AUTHTYPE_AUTOMATIC) {
851                         wdev->conn->auto_auth = true;
852                         /* start with open system ... should mostly work */
853                         wdev->conn->params.auth_type =
854                                 NL80211_AUTHTYPE_OPEN_SYSTEM;
855                 } else {
856                         wdev->conn->auto_auth = false;
857                 }
858
859                 memcpy(wdev->ssid, connect->ssid, connect->ssid_len);
860                 wdev->ssid_len = connect->ssid_len;
861                 wdev->conn->params.ssid = wdev->ssid;
862                 wdev->conn->params.ssid_len = connect->ssid_len;
863
864                 /* see if we have the bss already */
865                 bss = cfg80211_get_conn_bss(wdev);
866
867                 wdev->sme_state = CFG80211_SME_CONNECTING;
868                 wdev->connect_keys = connkeys;
869
870                 if (prev_bssid) {
871                         memcpy(wdev->conn->prev_bssid, prev_bssid, ETH_ALEN);
872                         wdev->conn->prev_bssid_valid = true;
873                 }
874
875                 /* we're good if we have a matching bss struct */
876                 if (bss) {
877                         wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
878                         err = cfg80211_conn_do_work(wdev);
879                         cfg80211_put_bss(wdev->wiphy, bss);
880                 } else {
881                         /* otherwise we'll need to scan for the AP first */
882                         err = cfg80211_conn_scan(wdev);
883                         /*
884                          * If we can't scan right now, then we need to scan again
885                          * after the current scan finished, since the parameters
886                          * changed (unless we find a good AP anyway).
887                          */
888                         if (err == -EBUSY) {
889                                 err = 0;
890                                 wdev->conn->state = CFG80211_CONN_SCAN_AGAIN;
891                         }
892                 }
893                 if (err) {
894                         kfree(wdev->conn->ie);
895                         kfree(wdev->conn);
896                         wdev->conn = NULL;
897                         wdev->sme_state = CFG80211_SME_IDLE;
898                         wdev->connect_keys = NULL;
899                         wdev->ssid_len = 0;
900                 }
901
902                 return err;
903         } else {
904                 wdev->sme_state = CFG80211_SME_CONNECTING;
905                 wdev->connect_keys = connkeys;
906                 err = rdev_connect(rdev, dev, connect);
907                 if (err) {
908                         wdev->connect_keys = NULL;
909                         wdev->sme_state = CFG80211_SME_IDLE;
910                         return err;
911                 }
912
913                 memcpy(wdev->ssid, connect->ssid, connect->ssid_len);
914                 wdev->ssid_len = connect->ssid_len;
915
916                 return 0;
917         }
918 }
919
920 int cfg80211_connect(struct cfg80211_registered_device *rdev,
921                      struct net_device *dev,
922                      struct cfg80211_connect_params *connect,
923                      struct cfg80211_cached_keys *connkeys)
924 {
925         int err;
926
927         mutex_lock(&rdev->devlist_mtx);
928         /* might request scan - scan_mtx -> wdev_mtx dependency */
929         mutex_lock(&rdev->sched_scan_mtx);
930         wdev_lock(dev->ieee80211_ptr);
931         err = __cfg80211_connect(rdev, dev, connect, connkeys, NULL);
932         wdev_unlock(dev->ieee80211_ptr);
933         mutex_unlock(&rdev->sched_scan_mtx);
934         mutex_unlock(&rdev->devlist_mtx);
935
936         return err;
937 }
938
939 int __cfg80211_disconnect(struct cfg80211_registered_device *rdev,
940                           struct net_device *dev, u16 reason, bool wextev)
941 {
942         struct wireless_dev *wdev = dev->ieee80211_ptr;
943         int err;
944
945         ASSERT_WDEV_LOCK(wdev);
946
947         if (wdev->sme_state == CFG80211_SME_IDLE)
948                 return -EINVAL;
949
950         kfree(wdev->connect_keys);
951         wdev->connect_keys = NULL;
952
953         if (!rdev->ops->disconnect) {
954                 if (!rdev->ops->deauth)
955                         return -EOPNOTSUPP;
956
957                 /* was it connected by userspace SME? */
958                 if (!wdev->conn) {
959                         cfg80211_mlme_down(rdev, dev);
960                         return 0;
961                 }
962
963                 if (wdev->sme_state == CFG80211_SME_CONNECTING &&
964                     (wdev->conn->state == CFG80211_CONN_SCANNING ||
965                      wdev->conn->state == CFG80211_CONN_SCAN_AGAIN)) {
966                         wdev->sme_state = CFG80211_SME_IDLE;
967                         kfree(wdev->conn->ie);
968                         kfree(wdev->conn);
969                         wdev->conn = NULL;
970                         wdev->ssid_len = 0;
971                         return 0;
972                 }
973
974                 /* wdev->conn->params.bssid must be set if > SCANNING */
975                 err = __cfg80211_mlme_deauth(rdev, dev,
976                                              wdev->conn->params.bssid,
977                                              NULL, 0, reason, false);
978                 if (err)
979                         return err;
980         } else {
981                 err = rdev_disconnect(rdev, dev, reason);
982                 if (err)
983                         return err;
984         }
985
986         if (wdev->sme_state == CFG80211_SME_CONNECTED)
987                 __cfg80211_disconnected(dev, NULL, 0, 0, false);
988         else if (wdev->sme_state == CFG80211_SME_CONNECTING)
989                 __cfg80211_connect_result(dev, NULL, NULL, 0, NULL, 0,
990                                           WLAN_STATUS_UNSPECIFIED_FAILURE,
991                                           wextev, NULL);
992
993         return 0;
994 }
995
996 int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
997                         struct net_device *dev,
998                         u16 reason, bool wextev)
999 {
1000         int err;
1001
1002         wdev_lock(dev->ieee80211_ptr);
1003         err = __cfg80211_disconnect(rdev, dev, reason, wextev);
1004         wdev_unlock(dev->ieee80211_ptr);
1005
1006         return err;
1007 }
1008
1009 void cfg80211_sme_disassoc(struct net_device *dev,
1010                            struct cfg80211_internal_bss *bss)
1011 {
1012         struct wireless_dev *wdev = dev->ieee80211_ptr;
1013         struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
1014         u8 bssid[ETH_ALEN];
1015
1016         ASSERT_WDEV_LOCK(wdev);
1017
1018         if (!wdev->conn)
1019                 return;
1020
1021         if (wdev->conn->state == CFG80211_CONN_IDLE)
1022                 return;
1023
1024         /*
1025          * Ok, so the association was made by this SME -- we don't
1026          * want it any more so deauthenticate too.
1027          */
1028
1029         memcpy(bssid, bss->pub.bssid, ETH_ALEN);
1030
1031         __cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0,
1032                                WLAN_REASON_DEAUTH_LEAVING, false);
1033 }