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 <linux/export.h>
14 #include <net/iw_handler.h>
15 #include <net/cfg80211.h>
16 #include <net/rtnetlink.h>
20 struct cfg80211_conn
{
21 struct cfg80211_connect_params params
;
22 /* these are sub-states of the _CONNECTING sme_state */
25 CFG80211_CONN_SCANNING
,
26 CFG80211_CONN_SCAN_AGAIN
,
27 CFG80211_CONN_AUTHENTICATE_NEXT
,
28 CFG80211_CONN_AUTHENTICATING
,
29 CFG80211_CONN_ASSOCIATE_NEXT
,
30 CFG80211_CONN_ASSOCIATING
,
31 CFG80211_CONN_DEAUTH_ASSOC_FAIL
,
33 u8 bssid
[ETH_ALEN
], prev_bssid
[ETH_ALEN
];
36 bool auto_auth
, prev_bssid_valid
;
39 static bool cfg80211_is_all_idle(void)
41 struct cfg80211_registered_device
*rdev
;
42 struct wireless_dev
*wdev
;
43 bool is_all_idle
= true;
45 mutex_lock(&cfg80211_mutex
);
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.
52 list_for_each_entry(rdev
, &cfg80211_rdev_list
, list
) {
53 cfg80211_lock_rdev(rdev
);
54 list_for_each_entry(wdev
, &rdev
->netdev_list
, list
) {
56 if (wdev
->sme_state
!= CFG80211_SME_IDLE
)
60 cfg80211_unlock_rdev(rdev
);
63 mutex_unlock(&cfg80211_mutex
);
68 static void disconnect_work(struct work_struct
*work
)
70 if (!cfg80211_is_all_idle())
73 regulatory_hint_disconnect();
76 static DECLARE_WORK(cfg80211_disconnect_work
, disconnect_work
);
78 static int cfg80211_conn_scan(struct wireless_dev
*wdev
)
80 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
81 struct cfg80211_scan_request
*request
;
85 ASSERT_RDEV_LOCK(rdev
);
86 ASSERT_WDEV_LOCK(wdev
);
91 if (wdev
->conn
->params
.channel
) {
94 enum ieee80211_band band
;
97 for (band
= 0; band
< IEEE80211_NUM_BANDS
; band
++) {
98 if (!wdev
->wiphy
->bands
[band
])
100 n_channels
+= wdev
->wiphy
->bands
[band
]->n_channels
;
103 request
= kzalloc(sizeof(*request
) + sizeof(request
->ssids
[0]) +
104 sizeof(request
->channels
[0]) * n_channels
,
109 if (wdev
->conn
->params
.channel
)
110 request
->channels
[0] = wdev
->conn
->params
.channel
;
113 enum ieee80211_band band
;
114 struct ieee80211_supported_band
*bands
;
115 struct ieee80211_channel
*channel
;
117 for (band
= 0; band
< IEEE80211_NUM_BANDS
; band
++) {
118 bands
= wdev
->wiphy
->bands
[band
];
121 for (j
= 0; j
< bands
->n_channels
; j
++) {
122 channel
= &bands
->channels
[j
];
123 if (channel
->flags
& IEEE80211_CHAN_DISABLED
)
125 request
->channels
[i
++] = channel
;
127 request
->rates
[band
] = (1 << bands
->n_bitrates
) - 1;
131 request
->n_channels
= n_channels
;
132 request
->ssids
= (void *)&request
->channels
[n_channels
];
133 request
->n_ssids
= 1;
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
;
139 request
->dev
= wdev
->netdev
;
140 request
->wiphy
= &rdev
->wiphy
;
142 rdev
->scan_req
= request
;
144 err
= rdev
->ops
->scan(wdev
->wiphy
, wdev
->netdev
, request
);
146 wdev
->conn
->state
= CFG80211_CONN_SCANNING
;
147 nl80211_send_scan_start(rdev
, wdev
->netdev
);
148 dev_hold(wdev
->netdev
);
150 rdev
->scan_req
= NULL
;
156 static int cfg80211_conn_do_work(struct wireless_dev
*wdev
)
158 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
159 struct cfg80211_connect_params
*params
;
160 const u8
*prev_bssid
= NULL
;
163 ASSERT_WDEV_LOCK(wdev
);
168 params
= &wdev
->conn
->params
;
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
,
179 params
->ssid
, params
->ssid_len
,
181 params
->key
, params
->key_len
,
182 params
->key_idx
, false);
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
,
191 params
->ssid
, params
->ssid_len
,
192 params
->ie
, params
->ie_len
,
193 false, ¶ms
->crypto
,
194 params
->flags
, ¶ms
->ht_capa
,
195 ¶ms
->ht_capa_mask
);
197 __cfg80211_mlme_deauth(rdev
, wdev
->netdev
, params
->bssid
,
199 WLAN_REASON_DEAUTH_LEAVING
,
202 case CFG80211_CONN_DEAUTH_ASSOC_FAIL
:
203 __cfg80211_mlme_deauth(rdev
, wdev
->netdev
, params
->bssid
,
205 WLAN_REASON_DEAUTH_LEAVING
, false);
206 /* return an error so that we call __cfg80211_connect_result() */
213 void cfg80211_conn_work(struct work_struct
*work
)
215 struct cfg80211_registered_device
*rdev
=
216 container_of(work
, struct cfg80211_registered_device
, conn_work
);
217 struct wireless_dev
*wdev
;
218 u8 bssid_buf
[ETH_ALEN
], *bssid
= NULL
;
221 cfg80211_lock_rdev(rdev
);
222 mutex_lock(&rdev
->devlist_mtx
);
224 list_for_each_entry(wdev
, &rdev
->netdev_list
, list
) {
226 if (!netif_running(wdev
->netdev
)) {
230 if (wdev
->sme_state
!= CFG80211_SME_CONNECTING
) {
234 if (wdev
->conn
->params
.bssid
) {
235 memcpy(bssid_buf
, wdev
->conn
->params
.bssid
, ETH_ALEN
);
238 if (cfg80211_conn_do_work(wdev
))
239 __cfg80211_connect_result(
242 WLAN_STATUS_UNSPECIFIED_FAILURE
,
247 mutex_unlock(&rdev
->devlist_mtx
);
248 cfg80211_unlock_rdev(rdev
);
252 static struct cfg80211_bss
*cfg80211_get_conn_bss(struct wireless_dev
*wdev
)
254 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
255 struct cfg80211_bss
*bss
;
256 u16 capa
= WLAN_CAPABILITY_ESS
;
258 ASSERT_WDEV_LOCK(wdev
);
260 if (wdev
->conn
->params
.privacy
)
261 capa
|= WLAN_CAPABILITY_PRIVACY
;
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
,
267 WLAN_CAPABILITY_ESS
| WLAN_CAPABILITY_PRIVACY
,
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
);
281 static void __cfg80211_sme_scan_done(struct net_device
*dev
)
283 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
284 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
285 struct cfg80211_bss
*bss
;
287 ASSERT_WDEV_LOCK(wdev
);
289 if (wdev
->sme_state
!= CFG80211_SME_CONNECTING
)
295 if (wdev
->conn
->state
!= CFG80211_CONN_SCANNING
&&
296 wdev
->conn
->state
!= CFG80211_CONN_SCAN_AGAIN
)
299 bss
= cfg80211_get_conn_bss(wdev
);
301 cfg80211_put_bss(bss
);
304 if (wdev
->conn
->state
== CFG80211_CONN_SCAN_AGAIN
)
305 schedule_work(&rdev
->conn_work
);
307 __cfg80211_connect_result(
309 wdev
->conn
->params
.bssid
,
311 WLAN_STATUS_UNSPECIFIED_FAILURE
,
316 void cfg80211_sme_scan_done(struct net_device
*dev
)
318 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
320 mutex_lock(&wiphy_to_dev(wdev
->wiphy
)->devlist_mtx
);
322 __cfg80211_sme_scan_done(dev
);
324 mutex_unlock(&wiphy_to_dev(wdev
->wiphy
)->devlist_mtx
);
327 void cfg80211_sme_rx_auth(struct net_device
*dev
,
328 const u8
*buf
, size_t len
)
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
);
336 ASSERT_WDEV_LOCK(wdev
);
338 /* should only RX auth frames when connecting */
339 if (wdev
->sme_state
!= CFG80211_SME_CONNECTING
)
342 if (WARN_ON(!wdev
->conn
))
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
) {
350 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
351 if (wdev
->connect_keys
)
352 wdev
->conn
->params
.auth_type
=
353 NL80211_AUTHTYPE_SHARED_KEY
;
355 wdev
->conn
->params
.auth_type
=
356 NL80211_AUTHTYPE_NETWORK_EAP
;
358 case NL80211_AUTHTYPE_SHARED_KEY
:
359 wdev
->conn
->params
.auth_type
=
360 NL80211_AUTHTYPE_NETWORK_EAP
;
364 wdev
->conn
->params
.auth_type
=
365 NL80211_AUTHTYPE_OPEN_SYSTEM
;
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
);
380 bool cfg80211_sme_failed_reassoc(struct wireless_dev
*wdev
)
382 struct wiphy
*wiphy
= wdev
->wiphy
;
383 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
385 if (WARN_ON(!wdev
->conn
))
388 if (!wdev
->conn
->prev_bssid_valid
)
392 * Some stupid APs don't accept reassoc, so we
393 * need to fall back to trying regular assoc.
395 wdev
->conn
->prev_bssid_valid
= false;
396 wdev
->conn
->state
= CFG80211_CONN_ASSOCIATE_NEXT
;
397 schedule_work(&rdev
->conn_work
);
402 void cfg80211_sme_failed_assoc(struct wireless_dev
*wdev
)
404 struct wiphy
*wiphy
= wdev
->wiphy
;
405 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
407 wdev
->conn
->state
= CFG80211_CONN_DEAUTH_ASSOC_FAIL
;
408 schedule_work(&rdev
->conn_work
);
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
)
417 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
419 #ifdef CONFIG_CFG80211_WEXT
420 union iwreq_data wrqu
;
423 ASSERT_WDEV_LOCK(wdev
);
425 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_STATION
&&
426 wdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
))
429 if (wdev
->sme_state
!= CFG80211_SME_CONNECTING
)
432 nl80211_send_connect_result(wiphy_to_dev(wdev
->wiphy
), dev
,
433 bssid
, req_ie
, req_ie_len
,
434 resp_ie
, resp_ie_len
,
437 #ifdef CONFIG_CFG80211_WEXT
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
);
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
);
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;
458 wireless_send_event(dev
, SIOCGIWAP
, &wrqu
, NULL
);
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
;
469 wdev
->conn
->state
= CFG80211_CONN_IDLE
;
471 if (status
!= WLAN_STATUS_SUCCESS
) {
472 wdev
->sme_state
= CFG80211_SME_IDLE
;
474 kfree(wdev
->conn
->ie
);
477 kfree(wdev
->connect_keys
);
478 wdev
->connect_keys
= NULL
;
484 bss
= cfg80211_get_bss(wdev
->wiphy
,
485 wdev
->conn
? wdev
->conn
->params
.channel
:
488 wdev
->ssid
, wdev
->ssid_len
,
490 WLAN_CAPABILITY_ESS
);
495 cfg80211_hold_bss(bss_from_pub(bss
));
496 wdev
->current_bss
= bss_from_pub(bss
);
498 wdev
->sme_state
= CFG80211_SME_CONNECTED
;
499 cfg80211_upload_connect_keys(wdev
);
501 country_ie
= (u8
*) ieee80211_bss_get_ie(bss
, WLAN_EID_COUNTRY
);
507 * ieee80211_bss_get_ie() ensures we can access:
508 * - country_ie + 2, the start of the country ie data, and
509 * - and country_ie[1] which is the IE length
511 regulatory_hint_11d(wdev
->wiphy
,
517 void cfg80211_connect_result(struct net_device
*dev
, const u8
*bssid
,
518 const u8
*req_ie
, size_t req_ie_len
,
519 const u8
*resp_ie
, size_t resp_ie_len
,
520 u16 status
, gfp_t gfp
)
522 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
523 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
524 struct cfg80211_event
*ev
;
527 CFG80211_DEV_WARN_ON(wdev
->sme_state
!= CFG80211_SME_CONNECTING
);
529 ev
= kzalloc(sizeof(*ev
) + req_ie_len
+ resp_ie_len
, gfp
);
533 ev
->type
= EVENT_CONNECT_RESULT
;
535 memcpy(ev
->cr
.bssid
, bssid
, ETH_ALEN
);
537 ev
->cr
.req_ie
= ((u8
*)ev
) + sizeof(*ev
);
538 ev
->cr
.req_ie_len
= req_ie_len
;
539 memcpy((void *)ev
->cr
.req_ie
, req_ie
, req_ie_len
);
542 ev
->cr
.resp_ie
= ((u8
*)ev
) + sizeof(*ev
) + req_ie_len
;
543 ev
->cr
.resp_ie_len
= resp_ie_len
;
544 memcpy((void *)ev
->cr
.resp_ie
, resp_ie
, resp_ie_len
);
546 ev
->cr
.status
= status
;
548 spin_lock_irqsave(&wdev
->event_lock
, flags
);
549 list_add_tail(&ev
->list
, &wdev
->event_list
);
550 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
551 queue_work(cfg80211_wq
, &rdev
->event_work
);
553 EXPORT_SYMBOL(cfg80211_connect_result
);
555 void __cfg80211_roamed(struct wireless_dev
*wdev
,
556 struct cfg80211_bss
*bss
,
557 const u8
*req_ie
, size_t req_ie_len
,
558 const u8
*resp_ie
, size_t resp_ie_len
)
560 #ifdef CONFIG_CFG80211_WEXT
561 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 cfg80211_hold_bss(bss_from_pub(bss
));
582 wdev
->current_bss
= bss_from_pub(bss
);
584 nl80211_send_roamed(wiphy_to_dev(wdev
->wiphy
), wdev
->netdev
, bss
->bssid
,
585 req_ie
, req_ie_len
, resp_ie
, resp_ie_len
,
588 #ifdef CONFIG_CFG80211_WEXT
590 memset(&wrqu
, 0, sizeof(wrqu
));
591 wrqu
.data
.length
= req_ie_len
;
592 wireless_send_event(wdev
->netdev
, IWEVASSOCREQIE
,
597 memset(&wrqu
, 0, sizeof(wrqu
));
598 wrqu
.data
.length
= resp_ie_len
;
599 wireless_send_event(wdev
->netdev
, IWEVASSOCRESPIE
,
603 memset(&wrqu
, 0, sizeof(wrqu
));
604 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
605 memcpy(wrqu
.ap_addr
.sa_data
, bss
->bssid
, ETH_ALEN
);
606 memcpy(wdev
->wext
.prev_bssid
, bss
->bssid
, ETH_ALEN
);
607 wdev
->wext
.prev_bssid_valid
= true;
608 wireless_send_event(wdev
->netdev
, SIOCGIWAP
, &wrqu
, NULL
);
613 cfg80211_put_bss(bss
);
616 void cfg80211_roamed(struct net_device
*dev
,
617 struct ieee80211_channel
*channel
,
619 const u8
*req_ie
, size_t req_ie_len
,
620 const u8
*resp_ie
, size_t resp_ie_len
, gfp_t gfp
)
622 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
623 struct cfg80211_bss
*bss
;
625 CFG80211_DEV_WARN_ON(wdev
->sme_state
!= CFG80211_SME_CONNECTED
);
627 bss
= cfg80211_get_bss(wdev
->wiphy
, channel
, bssid
, wdev
->ssid
,
628 wdev
->ssid_len
, WLAN_CAPABILITY_ESS
,
629 WLAN_CAPABILITY_ESS
);
633 cfg80211_roamed_bss(dev
, bss
, req_ie
, req_ie_len
, resp_ie
,
636 EXPORT_SYMBOL(cfg80211_roamed
);
638 void cfg80211_roamed_bss(struct net_device
*dev
,
639 struct cfg80211_bss
*bss
, const u8
*req_ie
,
640 size_t req_ie_len
, const u8
*resp_ie
,
641 size_t resp_ie_len
, gfp_t gfp
)
643 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
644 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
645 struct cfg80211_event
*ev
;
648 CFG80211_DEV_WARN_ON(wdev
->sme_state
!= CFG80211_SME_CONNECTED
);
653 ev
= kzalloc(sizeof(*ev
) + req_ie_len
+ resp_ie_len
, gfp
);
655 cfg80211_put_bss(bss
);
659 ev
->type
= EVENT_ROAMED
;
660 ev
->rm
.req_ie
= ((u8
*)ev
) + sizeof(*ev
);
661 ev
->rm
.req_ie_len
= req_ie_len
;
662 memcpy((void *)ev
->rm
.req_ie
, req_ie
, req_ie_len
);
663 ev
->rm
.resp_ie
= ((u8
*)ev
) + sizeof(*ev
) + req_ie_len
;
664 ev
->rm
.resp_ie_len
= resp_ie_len
;
665 memcpy((void *)ev
->rm
.resp_ie
, resp_ie
, resp_ie_len
);
668 spin_lock_irqsave(&wdev
->event_lock
, flags
);
669 list_add_tail(&ev
->list
, &wdev
->event_list
);
670 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
671 queue_work(cfg80211_wq
, &rdev
->event_work
);
673 EXPORT_SYMBOL(cfg80211_roamed_bss
);
675 void __cfg80211_disconnected(struct net_device
*dev
, const u8
*ie
,
676 size_t ie_len
, u16 reason
, bool from_ap
)
678 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
679 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
681 #ifdef CONFIG_CFG80211_WEXT
682 union iwreq_data wrqu
;
685 ASSERT_WDEV_LOCK(wdev
);
687 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_STATION
&&
688 wdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
))
691 if (wdev
->sme_state
!= CFG80211_SME_CONNECTED
)
694 if (wdev
->current_bss
) {
695 cfg80211_unhold_bss(wdev
->current_bss
);
696 cfg80211_put_bss(&wdev
->current_bss
->pub
);
699 wdev
->current_bss
= NULL
;
700 wdev
->sme_state
= CFG80211_SME_IDLE
;
707 kfree(wdev
->conn
->ie
);
708 wdev
->conn
->ie
= NULL
;
713 * If this disconnect was due to a disassoc, we
714 * we might still have an auth BSS around. For
715 * the userspace SME that's currently expected,
716 * but for the kernel SME (nl80211 CONNECT or
717 * wireless extensions) we want to clear up all
720 for (i
= 0; i
< MAX_AUTH_BSSES
; i
++) {
721 if (!wdev
->auth_bsses
[i
])
723 bssid
= wdev
->auth_bsses
[i
]->pub
.bssid
;
724 ret
= __cfg80211_mlme_deauth(rdev
, dev
, bssid
, NULL
, 0,
725 WLAN_REASON_DEAUTH_LEAVING
,
727 WARN(ret
, "deauth failed: %d\n", ret
);
731 nl80211_send_disconnected(rdev
, dev
, reason
, ie
, ie_len
, from_ap
);
734 * Delete all the keys ... pairwise keys can't really
735 * exist any more anyway, but default keys might.
737 if (rdev
->ops
->del_key
)
738 for (i
= 0; i
< 6; i
++)
739 rdev
->ops
->del_key(wdev
->wiphy
, dev
, i
, false, NULL
);
741 #ifdef CONFIG_CFG80211_WEXT
742 memset(&wrqu
, 0, sizeof(wrqu
));
743 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
744 wireless_send_event(dev
, SIOCGIWAP
, &wrqu
, NULL
);
745 wdev
->wext
.connect
.ssid_len
= 0;
748 schedule_work(&cfg80211_disconnect_work
);
751 void cfg80211_disconnected(struct net_device
*dev
, u16 reason
,
752 u8
*ie
, size_t ie_len
, gfp_t gfp
)
754 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
755 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
756 struct cfg80211_event
*ev
;
759 CFG80211_DEV_WARN_ON(wdev
->sme_state
!= CFG80211_SME_CONNECTED
);
761 ev
= kzalloc(sizeof(*ev
) + ie_len
, gfp
);
765 ev
->type
= EVENT_DISCONNECTED
;
766 ev
->dc
.ie
= ((u8
*)ev
) + sizeof(*ev
);
767 ev
->dc
.ie_len
= ie_len
;
768 memcpy((void *)ev
->dc
.ie
, ie
, ie_len
);
769 ev
->dc
.reason
= reason
;
771 spin_lock_irqsave(&wdev
->event_lock
, flags
);
772 list_add_tail(&ev
->list
, &wdev
->event_list
);
773 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
774 queue_work(cfg80211_wq
, &rdev
->event_work
);
776 EXPORT_SYMBOL(cfg80211_disconnected
);
778 int __cfg80211_connect(struct cfg80211_registered_device
*rdev
,
779 struct net_device
*dev
,
780 struct cfg80211_connect_params
*connect
,
781 struct cfg80211_cached_keys
*connkeys
,
782 const u8
*prev_bssid
)
784 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
785 struct cfg80211_bss
*bss
= NULL
;
788 ASSERT_WDEV_LOCK(wdev
);
790 if (wdev
->sme_state
!= CFG80211_SME_IDLE
)
793 if (WARN_ON(wdev
->connect_keys
)) {
794 kfree(wdev
->connect_keys
);
795 wdev
->connect_keys
= NULL
;
798 cfg80211_oper_and_ht_capa(&connect
->ht_capa_mask
,
799 rdev
->wiphy
.ht_capa_mod_mask
);
801 if (connkeys
&& connkeys
->def
>= 0) {
806 cipher
= connkeys
->params
[idx
].cipher
;
807 /* If given a WEP key we may need it for shared key auth */
808 if (cipher
== WLAN_CIPHER_SUITE_WEP40
||
809 cipher
== WLAN_CIPHER_SUITE_WEP104
) {
810 connect
->key_idx
= idx
;
811 connect
->key
= connkeys
->params
[idx
].key
;
812 connect
->key_len
= connkeys
->params
[idx
].key_len
;
815 * If ciphers are not set (e.g. when going through
816 * iwconfig), we have to set them appropriately here.
818 if (connect
->crypto
.cipher_group
== 0)
819 connect
->crypto
.cipher_group
= cipher
;
821 if (connect
->crypto
.n_ciphers_pairwise
== 0) {
822 connect
->crypto
.n_ciphers_pairwise
= 1;
823 connect
->crypto
.ciphers_pairwise
[0] = cipher
;
828 if (!rdev
->ops
->connect
) {
829 if (!rdev
->ops
->auth
|| !rdev
->ops
->assoc
)
832 if (WARN_ON(wdev
->conn
))
835 wdev
->conn
= kzalloc(sizeof(*wdev
->conn
), GFP_KERNEL
);
840 * Copy all parameters, and treat explicitly IEs, BSSID, SSID.
842 memcpy(&wdev
->conn
->params
, connect
, sizeof(*connect
));
843 if (connect
->bssid
) {
844 wdev
->conn
->params
.bssid
= wdev
->conn
->bssid
;
845 memcpy(wdev
->conn
->bssid
, connect
->bssid
, ETH_ALEN
);
849 wdev
->conn
->ie
= kmemdup(connect
->ie
, connect
->ie_len
,
851 wdev
->conn
->params
.ie
= wdev
->conn
->ie
;
852 if (!wdev
->conn
->ie
) {
859 if (connect
->auth_type
== NL80211_AUTHTYPE_AUTOMATIC
) {
860 wdev
->conn
->auto_auth
= true;
861 /* start with open system ... should mostly work */
862 wdev
->conn
->params
.auth_type
=
863 NL80211_AUTHTYPE_OPEN_SYSTEM
;
865 wdev
->conn
->auto_auth
= false;
868 memcpy(wdev
->ssid
, connect
->ssid
, connect
->ssid_len
);
869 wdev
->ssid_len
= connect
->ssid_len
;
870 wdev
->conn
->params
.ssid
= wdev
->ssid
;
871 wdev
->conn
->params
.ssid_len
= connect
->ssid_len
;
873 /* see if we have the bss already */
874 bss
= cfg80211_get_conn_bss(wdev
);
876 wdev
->sme_state
= CFG80211_SME_CONNECTING
;
877 wdev
->connect_keys
= connkeys
;
880 memcpy(wdev
->conn
->prev_bssid
, prev_bssid
, ETH_ALEN
);
881 wdev
->conn
->prev_bssid_valid
= true;
884 /* we're good if we have a matching bss struct */
886 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATE_NEXT
;
887 err
= cfg80211_conn_do_work(wdev
);
888 cfg80211_put_bss(bss
);
890 /* otherwise we'll need to scan for the AP first */
891 err
= cfg80211_conn_scan(wdev
);
893 * If we can't scan right now, then we need to scan again
894 * after the current scan finished, since the parameters
895 * changed (unless we find a good AP anyway).
899 wdev
->conn
->state
= CFG80211_CONN_SCAN_AGAIN
;
903 kfree(wdev
->conn
->ie
);
906 wdev
->sme_state
= CFG80211_SME_IDLE
;
907 wdev
->connect_keys
= NULL
;
913 wdev
->sme_state
= CFG80211_SME_CONNECTING
;
914 wdev
->connect_keys
= connkeys
;
915 err
= rdev
->ops
->connect(&rdev
->wiphy
, dev
, connect
);
917 wdev
->connect_keys
= NULL
;
918 wdev
->sme_state
= CFG80211_SME_IDLE
;
922 memcpy(wdev
->ssid
, connect
->ssid
, connect
->ssid_len
);
923 wdev
->ssid_len
= connect
->ssid_len
;
929 int cfg80211_connect(struct cfg80211_registered_device
*rdev
,
930 struct net_device
*dev
,
931 struct cfg80211_connect_params
*connect
,
932 struct cfg80211_cached_keys
*connkeys
)
936 mutex_lock(&rdev
->devlist_mtx
);
937 wdev_lock(dev
->ieee80211_ptr
);
938 err
= __cfg80211_connect(rdev
, dev
, connect
, connkeys
, NULL
);
939 wdev_unlock(dev
->ieee80211_ptr
);
940 mutex_unlock(&rdev
->devlist_mtx
);
945 int __cfg80211_disconnect(struct cfg80211_registered_device
*rdev
,
946 struct net_device
*dev
, u16 reason
, bool wextev
)
948 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
951 ASSERT_WDEV_LOCK(wdev
);
953 if (wdev
->sme_state
== CFG80211_SME_IDLE
)
956 kfree(wdev
->connect_keys
);
957 wdev
->connect_keys
= NULL
;
959 if (!rdev
->ops
->disconnect
) {
960 if (!rdev
->ops
->deauth
)
963 /* was it connected by userspace SME? */
965 cfg80211_mlme_down(rdev
, dev
);
969 if (wdev
->sme_state
== CFG80211_SME_CONNECTING
&&
970 (wdev
->conn
->state
== CFG80211_CONN_SCANNING
||
971 wdev
->conn
->state
== CFG80211_CONN_SCAN_AGAIN
)) {
972 wdev
->sme_state
= CFG80211_SME_IDLE
;
973 kfree(wdev
->conn
->ie
);
980 /* wdev->conn->params.bssid must be set if > SCANNING */
981 err
= __cfg80211_mlme_deauth(rdev
, dev
,
982 wdev
->conn
->params
.bssid
,
983 NULL
, 0, reason
, false);
987 err
= rdev
->ops
->disconnect(&rdev
->wiphy
, dev
, reason
);
992 if (wdev
->sme_state
== CFG80211_SME_CONNECTED
)
993 __cfg80211_disconnected(dev
, NULL
, 0, 0, false);
994 else if (wdev
->sme_state
== CFG80211_SME_CONNECTING
)
995 __cfg80211_connect_result(dev
, NULL
, NULL
, 0, NULL
, 0,
996 WLAN_STATUS_UNSPECIFIED_FAILURE
,
1002 int cfg80211_disconnect(struct cfg80211_registered_device
*rdev
,
1003 struct net_device
*dev
,
1004 u16 reason
, bool wextev
)
1008 wdev_lock(dev
->ieee80211_ptr
);
1009 err
= __cfg80211_disconnect(rdev
, dev
, reason
, wextev
);
1010 wdev_unlock(dev
->ieee80211_ptr
);
1015 void cfg80211_sme_disassoc(struct net_device
*dev
, int idx
)
1017 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
1018 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
1021 ASSERT_WDEV_LOCK(wdev
);
1026 if (wdev
->conn
->state
== CFG80211_CONN_IDLE
)
1030 * Ok, so the association was made by this SME -- we don't
1031 * want it any more so deauthenticate too.
1034 if (!wdev
->auth_bsses
[idx
])
1037 memcpy(bssid
, wdev
->auth_bsses
[idx
]->pub
.bssid
, ETH_ALEN
);
1038 if (__cfg80211_mlme_deauth(rdev
, dev
, bssid
,
1039 NULL
, 0, WLAN_REASON_DEAUTH_LEAVING
,
1041 /* whatever -- assume gone anyway */
1042 cfg80211_unhold_bss(wdev
->auth_bsses
[idx
]);
1043 cfg80211_put_bss(&wdev
->auth_bsses
[idx
]->pub
);
1044 wdev
->auth_bsses
[idx
] = NULL
;