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