2 * SME code for cfg80211's connect emulation.
4 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
5 * Copyright (C) 2009 Intel Corporation. All rights reserved.
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>
19 struct cfg80211_conn
{
20 struct cfg80211_connect_params params
;
21 /* these are sub-states of the _CONNECTING sme_state */
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
,
32 u8 bssid
[ETH_ALEN
], prev_bssid
[ETH_ALEN
];
35 bool auto_auth
, prev_bssid_valid
;
38 static bool cfg80211_is_all_idle(void)
40 struct cfg80211_registered_device
*rdev
;
41 struct wireless_dev
*wdev
;
42 bool is_all_idle
= true;
44 mutex_lock(&cfg80211_mutex
);
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.
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
) {
55 if (wdev
->sme_state
!= CFG80211_SME_IDLE
)
59 cfg80211_unlock_rdev(rdev
);
62 mutex_unlock(&cfg80211_mutex
);
67 static void disconnect_work(struct work_struct
*work
)
69 if (!cfg80211_is_all_idle())
72 regulatory_hint_disconnect();
75 static DECLARE_WORK(cfg80211_disconnect_work
, disconnect_work
);
77 static int cfg80211_conn_scan(struct wireless_dev
*wdev
)
79 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
80 struct cfg80211_scan_request
*request
;
84 ASSERT_RDEV_LOCK(rdev
);
85 ASSERT_WDEV_LOCK(wdev
);
90 if (wdev
->conn
->params
.channel
) {
93 enum ieee80211_band band
;
96 for (band
= 0; band
< IEEE80211_NUM_BANDS
; band
++) {
97 if (!wdev
->wiphy
->bands
[band
])
99 n_channels
+= wdev
->wiphy
->bands
[band
]->n_channels
;
102 request
= kzalloc(sizeof(*request
) + sizeof(request
->ssids
[0]) +
103 sizeof(request
->channels
[0]) * n_channels
,
108 if (wdev
->conn
->params
.channel
)
109 request
->channels
[0] = wdev
->conn
->params
.channel
;
112 enum ieee80211_band band
;
113 struct ieee80211_supported_band
*bands
;
114 struct ieee80211_channel
*channel
;
116 for (band
= 0; band
< IEEE80211_NUM_BANDS
; band
++) {
117 bands
= wdev
->wiphy
->bands
[band
];
120 for (j
= 0; j
< bands
->n_channels
; j
++) {
121 channel
= &bands
->channels
[j
];
122 if (channel
->flags
& IEEE80211_CHAN_DISABLED
)
124 request
->channels
[i
++] = channel
;
126 request
->rates
[band
] = (1 << bands
->n_bitrates
) - 1;
130 request
->n_channels
= n_channels
;
131 request
->ssids
= (void *)&request
->channels
[n_channels
];
132 request
->n_ssids
= 1;
134 memcpy(request
->ssids
[0].ssid
, wdev
->conn
->params
.ssid
,
135 wdev
->conn
->params
.ssid_len
);
136 request
->ssids
[0].ssid_len
= wdev
->conn
->params
.ssid_len
;
138 request
->dev
= wdev
->netdev
;
139 request
->wiphy
= &rdev
->wiphy
;
141 rdev
->scan_req
= request
;
143 err
= rdev
->ops
->scan(wdev
->wiphy
, wdev
->netdev
, request
);
145 wdev
->conn
->state
= CFG80211_CONN_SCANNING
;
146 nl80211_send_scan_start(rdev
, wdev
->netdev
);
147 dev_hold(wdev
->netdev
);
149 rdev
->scan_req
= NULL
;
155 static int cfg80211_conn_do_work(struct wireless_dev
*wdev
)
157 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
158 struct cfg80211_connect_params
*params
;
159 const u8
*prev_bssid
= NULL
;
162 ASSERT_WDEV_LOCK(wdev
);
167 params
= &wdev
->conn
->params
;
169 switch (wdev
->conn
->state
) {
170 case CFG80211_CONN_SCAN_AGAIN
:
171 return cfg80211_conn_scan(wdev
);
172 case CFG80211_CONN_AUTHENTICATE_NEXT
:
173 BUG_ON(!rdev
->ops
->auth
);
174 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATING
;
175 return __cfg80211_mlme_auth(rdev
, wdev
->netdev
,
176 params
->channel
, params
->auth_type
,
178 params
->ssid
, params
->ssid_len
,
180 params
->key
, params
->key_len
,
181 params
->key_idx
, false);
182 case CFG80211_CONN_ASSOCIATE_NEXT
:
183 BUG_ON(!rdev
->ops
->assoc
);
184 wdev
->conn
->state
= CFG80211_CONN_ASSOCIATING
;
185 if (wdev
->conn
->prev_bssid_valid
)
186 prev_bssid
= wdev
->conn
->prev_bssid
;
187 err
= __cfg80211_mlme_assoc(rdev
, wdev
->netdev
,
188 params
->channel
, params
->bssid
,
190 params
->ssid
, params
->ssid_len
,
191 params
->ie
, params
->ie_len
,
192 false, ¶ms
->crypto
);
194 __cfg80211_mlme_deauth(rdev
, wdev
->netdev
, params
->bssid
,
196 WLAN_REASON_DEAUTH_LEAVING
,
199 case CFG80211_CONN_DEAUTH_ASSOC_FAIL
:
200 __cfg80211_mlme_deauth(rdev
, wdev
->netdev
, params
->bssid
,
202 WLAN_REASON_DEAUTH_LEAVING
, false);
203 /* return an error so that we call __cfg80211_connect_result() */
210 void cfg80211_conn_work(struct work_struct
*work
)
212 struct cfg80211_registered_device
*rdev
=
213 container_of(work
, struct cfg80211_registered_device
, conn_work
);
214 struct wireless_dev
*wdev
;
215 u8 bssid_buf
[ETH_ALEN
], *bssid
= NULL
;
218 cfg80211_lock_rdev(rdev
);
219 mutex_lock(&rdev
->devlist_mtx
);
221 list_for_each_entry(wdev
, &rdev
->netdev_list
, list
) {
223 if (!netif_running(wdev
->netdev
)) {
227 if (wdev
->sme_state
!= CFG80211_SME_CONNECTING
) {
231 if (wdev
->conn
->params
.bssid
) {
232 memcpy(bssid_buf
, wdev
->conn
->params
.bssid
, ETH_ALEN
);
235 if (cfg80211_conn_do_work(wdev
))
236 __cfg80211_connect_result(
239 WLAN_STATUS_UNSPECIFIED_FAILURE
,
244 mutex_unlock(&rdev
->devlist_mtx
);
245 cfg80211_unlock_rdev(rdev
);
249 static struct cfg80211_bss
*cfg80211_get_conn_bss(struct wireless_dev
*wdev
)
251 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
252 struct cfg80211_bss
*bss
;
253 u16 capa
= WLAN_CAPABILITY_ESS
;
255 ASSERT_WDEV_LOCK(wdev
);
257 if (wdev
->conn
->params
.privacy
)
258 capa
|= WLAN_CAPABILITY_PRIVACY
;
260 bss
= cfg80211_get_bss(wdev
->wiphy
, wdev
->conn
->params
.channel
,
261 wdev
->conn
->params
.bssid
,
262 wdev
->conn
->params
.ssid
,
263 wdev
->conn
->params
.ssid_len
,
264 WLAN_CAPABILITY_ESS
| WLAN_CAPABILITY_PRIVACY
,
269 memcpy(wdev
->conn
->bssid
, bss
->bssid
, ETH_ALEN
);
270 wdev
->conn
->params
.bssid
= wdev
->conn
->bssid
;
271 wdev
->conn
->params
.channel
= bss
->channel
;
272 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATE_NEXT
;
273 schedule_work(&rdev
->conn_work
);
278 static void __cfg80211_sme_scan_done(struct net_device
*dev
)
280 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
281 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
282 struct cfg80211_bss
*bss
;
284 ASSERT_WDEV_LOCK(wdev
);
286 if (wdev
->sme_state
!= CFG80211_SME_CONNECTING
)
292 if (wdev
->conn
->state
!= CFG80211_CONN_SCANNING
&&
293 wdev
->conn
->state
!= CFG80211_CONN_SCAN_AGAIN
)
296 bss
= cfg80211_get_conn_bss(wdev
);
298 cfg80211_put_bss(bss
);
301 if (wdev
->conn
->state
== CFG80211_CONN_SCAN_AGAIN
)
302 schedule_work(&rdev
->conn_work
);
304 __cfg80211_connect_result(
306 wdev
->conn
->params
.bssid
,
308 WLAN_STATUS_UNSPECIFIED_FAILURE
,
313 void cfg80211_sme_scan_done(struct net_device
*dev
)
315 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
317 mutex_lock(&wiphy_to_dev(wdev
->wiphy
)->devlist_mtx
);
319 __cfg80211_sme_scan_done(dev
);
321 mutex_unlock(&wiphy_to_dev(wdev
->wiphy
)->devlist_mtx
);
324 void cfg80211_sme_rx_auth(struct net_device
*dev
,
325 const u8
*buf
, size_t len
)
327 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
328 struct wiphy
*wiphy
= wdev
->wiphy
;
329 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
330 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*)buf
;
331 u16 status_code
= le16_to_cpu(mgmt
->u
.auth
.status_code
);
333 ASSERT_WDEV_LOCK(wdev
);
335 /* should only RX auth frames when connecting */
336 if (wdev
->sme_state
!= CFG80211_SME_CONNECTING
)
339 if (WARN_ON(!wdev
->conn
))
342 if (status_code
== WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
&&
343 wdev
->conn
->auto_auth
&&
344 wdev
->conn
->params
.auth_type
!= NL80211_AUTHTYPE_NETWORK_EAP
) {
345 /* select automatically between only open, shared, leap */
346 switch (wdev
->conn
->params
.auth_type
) {
347 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
348 if (wdev
->connect_keys
)
349 wdev
->conn
->params
.auth_type
=
350 NL80211_AUTHTYPE_SHARED_KEY
;
352 wdev
->conn
->params
.auth_type
=
353 NL80211_AUTHTYPE_NETWORK_EAP
;
355 case NL80211_AUTHTYPE_SHARED_KEY
:
356 wdev
->conn
->params
.auth_type
=
357 NL80211_AUTHTYPE_NETWORK_EAP
;
361 wdev
->conn
->params
.auth_type
=
362 NL80211_AUTHTYPE_OPEN_SYSTEM
;
365 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATE_NEXT
;
366 schedule_work(&rdev
->conn_work
);
367 } else if (status_code
!= WLAN_STATUS_SUCCESS
) {
368 __cfg80211_connect_result(dev
, mgmt
->bssid
, NULL
, 0, NULL
, 0,
369 status_code
, false, NULL
);
370 } else if (wdev
->sme_state
== CFG80211_SME_CONNECTING
&&
371 wdev
->conn
->state
== CFG80211_CONN_AUTHENTICATING
) {
372 wdev
->conn
->state
= CFG80211_CONN_ASSOCIATE_NEXT
;
373 schedule_work(&rdev
->conn_work
);
377 bool cfg80211_sme_failed_reassoc(struct wireless_dev
*wdev
)
379 struct wiphy
*wiphy
= wdev
->wiphy
;
380 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
382 if (WARN_ON(!wdev
->conn
))
385 if (!wdev
->conn
->prev_bssid_valid
)
389 * Some stupid APs don't accept reassoc, so we
390 * need to fall back to trying regular assoc.
392 wdev
->conn
->prev_bssid_valid
= false;
393 wdev
->conn
->state
= CFG80211_CONN_ASSOCIATE_NEXT
;
394 schedule_work(&rdev
->conn_work
);
399 void cfg80211_sme_failed_assoc(struct wireless_dev
*wdev
)
401 struct wiphy
*wiphy
= wdev
->wiphy
;
402 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
404 wdev
->conn
->state
= CFG80211_CONN_DEAUTH_ASSOC_FAIL
;
405 schedule_work(&rdev
->conn_work
);
408 void __cfg80211_connect_result(struct net_device
*dev
, const u8
*bssid
,
409 const u8
*req_ie
, size_t req_ie_len
,
410 const u8
*resp_ie
, size_t resp_ie_len
,
411 u16 status
, bool wextev
,
412 struct cfg80211_bss
*bss
)
414 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
416 #ifdef CONFIG_CFG80211_WEXT
417 union iwreq_data wrqu
;
420 ASSERT_WDEV_LOCK(wdev
);
422 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_STATION
&&
423 wdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
))
426 if (wdev
->sme_state
!= CFG80211_SME_CONNECTING
)
429 nl80211_send_connect_result(wiphy_to_dev(wdev
->wiphy
), dev
,
430 bssid
, req_ie
, req_ie_len
,
431 resp_ie
, resp_ie_len
,
434 #ifdef CONFIG_CFG80211_WEXT
436 if (req_ie
&& status
== WLAN_STATUS_SUCCESS
) {
437 memset(&wrqu
, 0, sizeof(wrqu
));
438 wrqu
.data
.length
= req_ie_len
;
439 wireless_send_event(dev
, IWEVASSOCREQIE
, &wrqu
, req_ie
);
442 if (resp_ie
&& status
== WLAN_STATUS_SUCCESS
) {
443 memset(&wrqu
, 0, sizeof(wrqu
));
444 wrqu
.data
.length
= resp_ie_len
;
445 wireless_send_event(dev
, IWEVASSOCRESPIE
, &wrqu
, resp_ie
);
448 memset(&wrqu
, 0, sizeof(wrqu
));
449 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
450 if (bssid
&& status
== WLAN_STATUS_SUCCESS
) {
451 memcpy(wrqu
.ap_addr
.sa_data
, bssid
, ETH_ALEN
);
452 memcpy(wdev
->wext
.prev_bssid
, bssid
, ETH_ALEN
);
453 wdev
->wext
.prev_bssid_valid
= true;
455 wireless_send_event(dev
, SIOCGIWAP
, &wrqu
, NULL
);
459 if (wdev
->current_bss
) {
460 cfg80211_unhold_bss(wdev
->current_bss
);
461 cfg80211_put_bss(&wdev
->current_bss
->pub
);
462 wdev
->current_bss
= NULL
;
466 wdev
->conn
->state
= CFG80211_CONN_IDLE
;
468 if (status
!= WLAN_STATUS_SUCCESS
) {
469 wdev
->sme_state
= CFG80211_SME_IDLE
;
471 kfree(wdev
->conn
->ie
);
474 kfree(wdev
->connect_keys
);
475 wdev
->connect_keys
= NULL
;
481 bss
= cfg80211_get_bss(wdev
->wiphy
,
482 wdev
->conn
? wdev
->conn
->params
.channel
:
485 wdev
->ssid
, wdev
->ssid_len
,
487 WLAN_CAPABILITY_ESS
);
492 cfg80211_hold_bss(bss_from_pub(bss
));
493 wdev
->current_bss
= bss_from_pub(bss
);
495 wdev
->sme_state
= CFG80211_SME_CONNECTED
;
496 cfg80211_upload_connect_keys(wdev
);
498 country_ie
= (u8
*) ieee80211_bss_get_ie(bss
, WLAN_EID_COUNTRY
);
504 * ieee80211_bss_get_ie() ensures we can access:
505 * - country_ie + 2, the start of the country ie data, and
506 * - and country_ie[1] which is the IE length
508 regulatory_hint_11d(wdev
->wiphy
,
514 void cfg80211_connect_result(struct net_device
*dev
, const u8
*bssid
,
515 const u8
*req_ie
, size_t req_ie_len
,
516 const u8
*resp_ie
, size_t resp_ie_len
,
517 u16 status
, gfp_t gfp
)
519 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
520 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
521 struct cfg80211_event
*ev
;
524 CFG80211_DEV_WARN_ON(wdev
->sme_state
!= CFG80211_SME_CONNECTING
);
526 ev
= kzalloc(sizeof(*ev
) + req_ie_len
+ resp_ie_len
, gfp
);
530 ev
->type
= EVENT_CONNECT_RESULT
;
532 memcpy(ev
->cr
.bssid
, bssid
, ETH_ALEN
);
534 ev
->cr
.req_ie
= ((u8
*)ev
) + sizeof(*ev
);
535 ev
->cr
.req_ie_len
= req_ie_len
;
536 memcpy((void *)ev
->cr
.req_ie
, req_ie
, req_ie_len
);
539 ev
->cr
.resp_ie
= ((u8
*)ev
) + sizeof(*ev
) + req_ie_len
;
540 ev
->cr
.resp_ie_len
= resp_ie_len
;
541 memcpy((void *)ev
->cr
.resp_ie
, resp_ie
, resp_ie_len
);
543 ev
->cr
.status
= status
;
545 spin_lock_irqsave(&wdev
->event_lock
, flags
);
546 list_add_tail(&ev
->list
, &wdev
->event_list
);
547 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
548 queue_work(cfg80211_wq
, &rdev
->event_work
);
550 EXPORT_SYMBOL(cfg80211_connect_result
);
552 void __cfg80211_roamed(struct wireless_dev
*wdev
,
553 struct ieee80211_channel
*channel
,
555 const u8
*req_ie
, size_t req_ie_len
,
556 const u8
*resp_ie
, size_t resp_ie_len
)
558 struct cfg80211_bss
*bss
;
559 #ifdef CONFIG_CFG80211_WEXT
560 union iwreq_data wrqu
;
563 ASSERT_WDEV_LOCK(wdev
);
565 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_STATION
&&
566 wdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
))
569 if (wdev
->sme_state
!= CFG80211_SME_CONNECTED
)
572 /* internal error -- how did we get to CONNECTED w/o BSS? */
573 if (WARN_ON(!wdev
->current_bss
)) {
577 cfg80211_unhold_bss(wdev
->current_bss
);
578 cfg80211_put_bss(&wdev
->current_bss
->pub
);
579 wdev
->current_bss
= NULL
;
581 bss
= cfg80211_get_bss(wdev
->wiphy
, channel
, bssid
,
582 wdev
->ssid
, wdev
->ssid_len
,
583 WLAN_CAPABILITY_ESS
, WLAN_CAPABILITY_ESS
);
588 cfg80211_hold_bss(bss_from_pub(bss
));
589 wdev
->current_bss
= bss_from_pub(bss
);
591 nl80211_send_roamed(wiphy_to_dev(wdev
->wiphy
), wdev
->netdev
, bssid
,
592 req_ie
, req_ie_len
, resp_ie
, resp_ie_len
,
595 #ifdef CONFIG_CFG80211_WEXT
597 memset(&wrqu
, 0, sizeof(wrqu
));
598 wrqu
.data
.length
= req_ie_len
;
599 wireless_send_event(wdev
->netdev
, IWEVASSOCREQIE
,
604 memset(&wrqu
, 0, sizeof(wrqu
));
605 wrqu
.data
.length
= resp_ie_len
;
606 wireless_send_event(wdev
->netdev
, IWEVASSOCRESPIE
,
610 memset(&wrqu
, 0, sizeof(wrqu
));
611 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
612 memcpy(wrqu
.ap_addr
.sa_data
, bssid
, ETH_ALEN
);
613 memcpy(wdev
->wext
.prev_bssid
, bssid
, ETH_ALEN
);
614 wdev
->wext
.prev_bssid_valid
= true;
615 wireless_send_event(wdev
->netdev
, SIOCGIWAP
, &wrqu
, NULL
);
619 void cfg80211_roamed(struct net_device
*dev
,
620 struct ieee80211_channel
*channel
,
622 const u8
*req_ie
, size_t req_ie_len
,
623 const u8
*resp_ie
, size_t resp_ie_len
, gfp_t gfp
)
625 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
626 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
627 struct cfg80211_event
*ev
;
630 CFG80211_DEV_WARN_ON(wdev
->sme_state
!= CFG80211_SME_CONNECTED
);
632 ev
= kzalloc(sizeof(*ev
) + req_ie_len
+ resp_ie_len
, gfp
);
636 ev
->type
= EVENT_ROAMED
;
637 ev
->rm
.channel
= channel
;
638 memcpy(ev
->rm
.bssid
, bssid
, ETH_ALEN
);
639 ev
->rm
.req_ie
= ((u8
*)ev
) + sizeof(*ev
);
640 ev
->rm
.req_ie_len
= req_ie_len
;
641 memcpy((void *)ev
->rm
.req_ie
, req_ie
, req_ie_len
);
642 ev
->rm
.resp_ie
= ((u8
*)ev
) + sizeof(*ev
) + req_ie_len
;
643 ev
->rm
.resp_ie_len
= resp_ie_len
;
644 memcpy((void *)ev
->rm
.resp_ie
, resp_ie
, resp_ie_len
);
646 spin_lock_irqsave(&wdev
->event_lock
, flags
);
647 list_add_tail(&ev
->list
, &wdev
->event_list
);
648 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
649 queue_work(cfg80211_wq
, &rdev
->event_work
);
651 EXPORT_SYMBOL(cfg80211_roamed
);
653 void __cfg80211_disconnected(struct net_device
*dev
, const u8
*ie
,
654 size_t ie_len
, u16 reason
, bool from_ap
)
656 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
657 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
659 #ifdef CONFIG_CFG80211_WEXT
660 union iwreq_data wrqu
;
663 ASSERT_WDEV_LOCK(wdev
);
665 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_STATION
&&
666 wdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
))
669 if (wdev
->sme_state
!= CFG80211_SME_CONNECTED
)
672 if (wdev
->current_bss
) {
673 cfg80211_unhold_bss(wdev
->current_bss
);
674 cfg80211_put_bss(&wdev
->current_bss
->pub
);
677 wdev
->current_bss
= NULL
;
678 wdev
->sme_state
= CFG80211_SME_IDLE
;
685 kfree(wdev
->conn
->ie
);
686 wdev
->conn
->ie
= NULL
;
691 * If this disconnect was due to a disassoc, we
692 * we might still have an auth BSS around. For
693 * the userspace SME that's currently expected,
694 * but for the kernel SME (nl80211 CONNECT or
695 * wireless extensions) we want to clear up all
698 for (i
= 0; i
< MAX_AUTH_BSSES
; i
++) {
699 if (!wdev
->auth_bsses
[i
])
701 bssid
= wdev
->auth_bsses
[i
]->pub
.bssid
;
702 ret
= __cfg80211_mlme_deauth(rdev
, dev
, bssid
, NULL
, 0,
703 WLAN_REASON_DEAUTH_LEAVING
,
705 WARN(ret
, "deauth failed: %d\n", ret
);
709 nl80211_send_disconnected(rdev
, dev
, reason
, ie
, ie_len
, from_ap
);
712 * Delete all the keys ... pairwise keys can't really
713 * exist any more anyway, but default keys might.
715 if (rdev
->ops
->del_key
)
716 for (i
= 0; i
< 6; i
++)
717 rdev
->ops
->del_key(wdev
->wiphy
, dev
, i
, false, NULL
);
719 #ifdef CONFIG_CFG80211_WEXT
720 memset(&wrqu
, 0, sizeof(wrqu
));
721 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
722 wireless_send_event(dev
, SIOCGIWAP
, &wrqu
, NULL
);
723 wdev
->wext
.connect
.ssid_len
= 0;
726 schedule_work(&cfg80211_disconnect_work
);
729 void cfg80211_disconnected(struct net_device
*dev
, u16 reason
,
730 u8
*ie
, size_t ie_len
, gfp_t gfp
)
732 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
733 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
734 struct cfg80211_event
*ev
;
737 CFG80211_DEV_WARN_ON(wdev
->sme_state
!= CFG80211_SME_CONNECTED
);
739 ev
= kzalloc(sizeof(*ev
) + ie_len
, gfp
);
743 ev
->type
= EVENT_DISCONNECTED
;
744 ev
->dc
.ie
= ((u8
*)ev
) + sizeof(*ev
);
745 ev
->dc
.ie_len
= ie_len
;
746 memcpy((void *)ev
->dc
.ie
, ie
, ie_len
);
747 ev
->dc
.reason
= reason
;
749 spin_lock_irqsave(&wdev
->event_lock
, flags
);
750 list_add_tail(&ev
->list
, &wdev
->event_list
);
751 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
752 queue_work(cfg80211_wq
, &rdev
->event_work
);
754 EXPORT_SYMBOL(cfg80211_disconnected
);
756 int __cfg80211_connect(struct cfg80211_registered_device
*rdev
,
757 struct net_device
*dev
,
758 struct cfg80211_connect_params
*connect
,
759 struct cfg80211_cached_keys
*connkeys
,
760 const u8
*prev_bssid
)
762 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
763 struct cfg80211_bss
*bss
= NULL
;
766 ASSERT_WDEV_LOCK(wdev
);
768 if (wdev
->sme_state
!= CFG80211_SME_IDLE
)
771 if (WARN_ON(wdev
->connect_keys
)) {
772 kfree(wdev
->connect_keys
);
773 wdev
->connect_keys
= NULL
;
776 if (connkeys
&& connkeys
->def
>= 0) {
781 cipher
= connkeys
->params
[idx
].cipher
;
782 /* If given a WEP key we may need it for shared key auth */
783 if (cipher
== WLAN_CIPHER_SUITE_WEP40
||
784 cipher
== WLAN_CIPHER_SUITE_WEP104
) {
785 connect
->key_idx
= idx
;
786 connect
->key
= connkeys
->params
[idx
].key
;
787 connect
->key_len
= connkeys
->params
[idx
].key_len
;
790 * If ciphers are not set (e.g. when going through
791 * iwconfig), we have to set them appropriately here.
793 if (connect
->crypto
.cipher_group
== 0)
794 connect
->crypto
.cipher_group
= cipher
;
796 if (connect
->crypto
.n_ciphers_pairwise
== 0) {
797 connect
->crypto
.n_ciphers_pairwise
= 1;
798 connect
->crypto
.ciphers_pairwise
[0] = cipher
;
803 if (!rdev
->ops
->connect
) {
804 if (!rdev
->ops
->auth
|| !rdev
->ops
->assoc
)
807 if (WARN_ON(wdev
->conn
))
810 wdev
->conn
= kzalloc(sizeof(*wdev
->conn
), GFP_KERNEL
);
815 * Copy all parameters, and treat explicitly IEs, BSSID, SSID.
817 memcpy(&wdev
->conn
->params
, connect
, sizeof(*connect
));
818 if (connect
->bssid
) {
819 wdev
->conn
->params
.bssid
= wdev
->conn
->bssid
;
820 memcpy(wdev
->conn
->bssid
, connect
->bssid
, ETH_ALEN
);
824 wdev
->conn
->ie
= kmemdup(connect
->ie
, connect
->ie_len
,
826 wdev
->conn
->params
.ie
= wdev
->conn
->ie
;
827 if (!wdev
->conn
->ie
) {
834 if (connect
->auth_type
== NL80211_AUTHTYPE_AUTOMATIC
) {
835 wdev
->conn
->auto_auth
= true;
836 /* start with open system ... should mostly work */
837 wdev
->conn
->params
.auth_type
=
838 NL80211_AUTHTYPE_OPEN_SYSTEM
;
840 wdev
->conn
->auto_auth
= false;
843 memcpy(wdev
->ssid
, connect
->ssid
, connect
->ssid_len
);
844 wdev
->ssid_len
= connect
->ssid_len
;
845 wdev
->conn
->params
.ssid
= wdev
->ssid
;
846 wdev
->conn
->params
.ssid_len
= connect
->ssid_len
;
848 /* see if we have the bss already */
849 bss
= cfg80211_get_conn_bss(wdev
);
851 wdev
->sme_state
= CFG80211_SME_CONNECTING
;
852 wdev
->connect_keys
= connkeys
;
855 memcpy(wdev
->conn
->prev_bssid
, prev_bssid
, ETH_ALEN
);
856 wdev
->conn
->prev_bssid_valid
= true;
859 /* we're good if we have a matching bss struct */
861 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATE_NEXT
;
862 err
= cfg80211_conn_do_work(wdev
);
863 cfg80211_put_bss(bss
);
865 /* otherwise we'll need to scan for the AP first */
866 err
= cfg80211_conn_scan(wdev
);
868 * If we can't scan right now, then we need to scan again
869 * after the current scan finished, since the parameters
870 * changed (unless we find a good AP anyway).
874 wdev
->conn
->state
= CFG80211_CONN_SCAN_AGAIN
;
878 kfree(wdev
->conn
->ie
);
881 wdev
->sme_state
= CFG80211_SME_IDLE
;
882 wdev
->connect_keys
= NULL
;
888 wdev
->sme_state
= CFG80211_SME_CONNECTING
;
889 wdev
->connect_keys
= connkeys
;
890 err
= rdev
->ops
->connect(&rdev
->wiphy
, dev
, connect
);
892 wdev
->connect_keys
= NULL
;
893 wdev
->sme_state
= CFG80211_SME_IDLE
;
897 memcpy(wdev
->ssid
, connect
->ssid
, connect
->ssid_len
);
898 wdev
->ssid_len
= connect
->ssid_len
;
904 int cfg80211_connect(struct cfg80211_registered_device
*rdev
,
905 struct net_device
*dev
,
906 struct cfg80211_connect_params
*connect
,
907 struct cfg80211_cached_keys
*connkeys
)
911 mutex_lock(&rdev
->devlist_mtx
);
912 wdev_lock(dev
->ieee80211_ptr
);
913 err
= __cfg80211_connect(rdev
, dev
, connect
, connkeys
, NULL
);
914 wdev_unlock(dev
->ieee80211_ptr
);
915 mutex_unlock(&rdev
->devlist_mtx
);
920 int __cfg80211_disconnect(struct cfg80211_registered_device
*rdev
,
921 struct net_device
*dev
, u16 reason
, bool wextev
)
923 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
926 ASSERT_WDEV_LOCK(wdev
);
928 if (wdev
->sme_state
== CFG80211_SME_IDLE
)
931 kfree(wdev
->connect_keys
);
932 wdev
->connect_keys
= NULL
;
934 if (!rdev
->ops
->disconnect
) {
935 if (!rdev
->ops
->deauth
)
938 /* was it connected by userspace SME? */
940 cfg80211_mlme_down(rdev
, dev
);
944 if (wdev
->sme_state
== CFG80211_SME_CONNECTING
&&
945 (wdev
->conn
->state
== CFG80211_CONN_SCANNING
||
946 wdev
->conn
->state
== CFG80211_CONN_SCAN_AGAIN
)) {
947 wdev
->sme_state
= CFG80211_SME_IDLE
;
948 kfree(wdev
->conn
->ie
);
955 /* wdev->conn->params.bssid must be set if > SCANNING */
956 err
= __cfg80211_mlme_deauth(rdev
, dev
,
957 wdev
->conn
->params
.bssid
,
958 NULL
, 0, reason
, false);
962 err
= rdev
->ops
->disconnect(&rdev
->wiphy
, dev
, reason
);
967 if (wdev
->sme_state
== CFG80211_SME_CONNECTED
)
968 __cfg80211_disconnected(dev
, NULL
, 0, 0, false);
969 else if (wdev
->sme_state
== CFG80211_SME_CONNECTING
)
970 __cfg80211_connect_result(dev
, NULL
, NULL
, 0, NULL
, 0,
971 WLAN_STATUS_UNSPECIFIED_FAILURE
,
977 int cfg80211_disconnect(struct cfg80211_registered_device
*rdev
,
978 struct net_device
*dev
,
979 u16 reason
, bool wextev
)
983 wdev_lock(dev
->ieee80211_ptr
);
984 err
= __cfg80211_disconnect(rdev
, dev
, reason
, wextev
);
985 wdev_unlock(dev
->ieee80211_ptr
);
990 void cfg80211_sme_disassoc(struct net_device
*dev
, int idx
)
992 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
993 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
996 ASSERT_WDEV_LOCK(wdev
);
1001 if (wdev
->conn
->state
== CFG80211_CONN_IDLE
)
1005 * Ok, so the association was made by this SME -- we don't
1006 * want it any more so deauthenticate too.
1009 if (!wdev
->auth_bsses
[idx
])
1012 memcpy(bssid
, wdev
->auth_bsses
[idx
]->pub
.bssid
, ETH_ALEN
);
1013 if (__cfg80211_mlme_deauth(rdev
, dev
, bssid
,
1014 NULL
, 0, WLAN_REASON_DEAUTH_LEAVING
,
1016 /* whatever -- assume gone anyway */
1017 cfg80211_unhold_bss(wdev
->auth_bsses
[idx
]);
1018 cfg80211_put_bss(&wdev
->auth_bsses
[idx
]->pub
);
1019 wdev
->auth_bsses
[idx
] = NULL
;