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