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