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>
21 struct cfg80211_conn
{
22 struct cfg80211_connect_params params
;
23 /* these are sub-states of the _CONNECTING sme_state */
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
,
34 u8 bssid
[ETH_ALEN
], prev_bssid
[ETH_ALEN
];
37 bool auto_auth
, prev_bssid_valid
;
40 static bool cfg80211_is_all_idle(void)
42 struct cfg80211_registered_device
*rdev
;
43 struct wireless_dev
*wdev
;
44 bool is_all_idle
= true;
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 list_for_each_entry(wdev
, &rdev
->wdev_list
, list
) {
54 if (wdev
->sme_state
!= CFG80211_SME_IDLE
)
63 static void disconnect_work(struct work_struct
*work
)
66 if (cfg80211_is_all_idle())
67 regulatory_hint_disconnect();
71 static DECLARE_WORK(cfg80211_disconnect_work
, disconnect_work
);
73 static int cfg80211_conn_scan(struct wireless_dev
*wdev
)
75 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
76 struct cfg80211_scan_request
*request
;
80 ASSERT_RDEV_LOCK(rdev
);
81 ASSERT_WDEV_LOCK(wdev
);
86 if (wdev
->conn
->params
.channel
) {
89 enum ieee80211_band band
;
92 for (band
= 0; band
< IEEE80211_NUM_BANDS
; band
++) {
93 if (!wdev
->wiphy
->bands
[band
])
95 n_channels
+= wdev
->wiphy
->bands
[band
]->n_channels
;
98 request
= kzalloc(sizeof(*request
) + sizeof(request
->ssids
[0]) +
99 sizeof(request
->channels
[0]) * n_channels
,
104 if (wdev
->conn
->params
.channel
)
105 request
->channels
[0] = wdev
->conn
->params
.channel
;
108 enum ieee80211_band band
;
109 struct ieee80211_supported_band
*bands
;
110 struct ieee80211_channel
*channel
;
112 for (band
= 0; band
< IEEE80211_NUM_BANDS
; band
++) {
113 bands
= wdev
->wiphy
->bands
[band
];
116 for (j
= 0; j
< bands
->n_channels
; j
++) {
117 channel
= &bands
->channels
[j
];
118 if (channel
->flags
& IEEE80211_CHAN_DISABLED
)
120 request
->channels
[i
++] = channel
;
122 request
->rates
[band
] = (1 << bands
->n_bitrates
) - 1;
126 request
->n_channels
= n_channels
;
127 request
->ssids
= (void *)&request
->channels
[n_channels
];
128 request
->n_ssids
= 1;
130 memcpy(request
->ssids
[0].ssid
, wdev
->conn
->params
.ssid
,
131 wdev
->conn
->params
.ssid_len
);
132 request
->ssids
[0].ssid_len
= wdev
->conn
->params
.ssid_len
;
134 request
->wdev
= wdev
;
135 request
->wiphy
= &rdev
->wiphy
;
136 request
->scan_start
= jiffies
;
138 rdev
->scan_req
= request
;
140 err
= rdev_scan(rdev
, request
);
142 wdev
->conn
->state
= CFG80211_CONN_SCANNING
;
143 nl80211_send_scan_start(rdev
, wdev
);
144 dev_hold(wdev
->netdev
);
146 rdev
->scan_req
= NULL
;
152 static int cfg80211_conn_do_work(struct wireless_dev
*wdev
)
154 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
155 struct cfg80211_connect_params
*params
;
156 struct cfg80211_assoc_request req
= {};
159 ASSERT_WDEV_LOCK(wdev
);
164 params
= &wdev
->conn
->params
;
166 switch (wdev
->conn
->state
) {
167 case CFG80211_CONN_SCAN_AGAIN
:
168 return cfg80211_conn_scan(wdev
);
169 case CFG80211_CONN_AUTHENTICATE_NEXT
:
170 BUG_ON(!rdev
->ops
->auth
);
171 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATING
;
172 return cfg80211_mlme_auth(rdev
, wdev
->netdev
,
173 params
->channel
, params
->auth_type
,
175 params
->ssid
, params
->ssid_len
,
177 params
->key
, params
->key_len
,
178 params
->key_idx
, NULL
, 0);
179 case CFG80211_CONN_ASSOCIATE_NEXT
:
180 BUG_ON(!rdev
->ops
->assoc
);
181 wdev
->conn
->state
= CFG80211_CONN_ASSOCIATING
;
182 if (wdev
->conn
->prev_bssid_valid
)
183 req
.prev_bssid
= wdev
->conn
->prev_bssid
;
185 req
.ie_len
= params
->ie_len
;
186 req
.use_mfp
= params
->mfp
!= NL80211_MFP_NO
;
187 req
.crypto
= params
->crypto
;
188 req
.flags
= params
->flags
;
189 req
.ht_capa
= params
->ht_capa
;
190 req
.ht_capa_mask
= params
->ht_capa_mask
;
191 req
.vht_capa
= params
->vht_capa
;
192 req
.vht_capa_mask
= params
->vht_capa_mask
;
194 err
= cfg80211_mlme_assoc(rdev
, wdev
->netdev
, params
->channel
,
195 params
->bssid
, params
->ssid
,
196 params
->ssid_len
, &req
);
198 cfg80211_mlme_deauth(rdev
, wdev
->netdev
, params
->bssid
,
200 WLAN_REASON_DEAUTH_LEAVING
,
203 case CFG80211_CONN_DEAUTH_ASSOC_FAIL
:
204 cfg80211_mlme_deauth(rdev
, wdev
->netdev
, params
->bssid
,
206 WLAN_REASON_DEAUTH_LEAVING
, false);
207 /* return an error so that we call __cfg80211_connect_result() */
214 void cfg80211_conn_work(struct work_struct
*work
)
216 struct cfg80211_registered_device
*rdev
=
217 container_of(work
, struct cfg80211_registered_device
, conn_work
);
218 struct wireless_dev
*wdev
;
219 u8 bssid_buf
[ETH_ALEN
], *bssid
= NULL
;
223 list_for_each_entry(wdev
, &rdev
->wdev_list
, list
) {
228 if (!netif_running(wdev
->netdev
)) {
232 if (wdev
->sme_state
!= CFG80211_SME_CONNECTING
|| !wdev
->conn
) {
236 if (wdev
->conn
->params
.bssid
) {
237 memcpy(bssid_buf
, wdev
->conn
->params
.bssid
, ETH_ALEN
);
240 if (cfg80211_conn_do_work(wdev
))
241 __cfg80211_connect_result(
244 WLAN_STATUS_UNSPECIFIED_FAILURE
,
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(&rdev
->wiphy
, 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
;
321 __cfg80211_sme_scan_done(dev
);
325 void cfg80211_sme_rx_auth(struct net_device
*dev
,
326 const u8
*buf
, size_t len
)
328 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
329 struct wiphy
*wiphy
= wdev
->wiphy
;
330 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
331 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*)buf
;
332 u16 status_code
= le16_to_cpu(mgmt
->u
.auth
.status_code
);
334 ASSERT_WDEV_LOCK(wdev
);
336 /* should only RX auth frames when connecting */
337 if (wdev
->sme_state
!= CFG80211_SME_CONNECTING
)
340 if (WARN_ON(!wdev
->conn
))
343 if (status_code
== WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
&&
344 wdev
->conn
->auto_auth
&&
345 wdev
->conn
->params
.auth_type
!= NL80211_AUTHTYPE_NETWORK_EAP
) {
346 /* select automatically between only open, shared, leap */
347 switch (wdev
->conn
->params
.auth_type
) {
348 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
349 if (wdev
->connect_keys
)
350 wdev
->conn
->params
.auth_type
=
351 NL80211_AUTHTYPE_SHARED_KEY
;
353 wdev
->conn
->params
.auth_type
=
354 NL80211_AUTHTYPE_NETWORK_EAP
;
356 case NL80211_AUTHTYPE_SHARED_KEY
:
357 wdev
->conn
->params
.auth_type
=
358 NL80211_AUTHTYPE_NETWORK_EAP
;
362 wdev
->conn
->params
.auth_type
=
363 NL80211_AUTHTYPE_OPEN_SYSTEM
;
366 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATE_NEXT
;
367 schedule_work(&rdev
->conn_work
);
368 } else if (status_code
!= WLAN_STATUS_SUCCESS
) {
369 __cfg80211_connect_result(dev
, mgmt
->bssid
, NULL
, 0, NULL
, 0,
370 status_code
, false, NULL
);
371 } else if (wdev
->sme_state
== CFG80211_SME_CONNECTING
&&
372 wdev
->conn
->state
== CFG80211_CONN_AUTHENTICATING
) {
373 wdev
->conn
->state
= CFG80211_CONN_ASSOCIATE_NEXT
;
374 schedule_work(&rdev
->conn_work
);
378 bool cfg80211_sme_failed_reassoc(struct wireless_dev
*wdev
)
380 struct wiphy
*wiphy
= wdev
->wiphy
;
381 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
383 if (WARN_ON(!wdev
->conn
))
386 if (!wdev
->conn
->prev_bssid_valid
)
390 * Some stupid APs don't accept reassoc, so we
391 * need to fall back to trying regular assoc.
393 wdev
->conn
->prev_bssid_valid
= false;
394 wdev
->conn
->state
= CFG80211_CONN_ASSOCIATE_NEXT
;
395 schedule_work(&rdev
->conn_work
);
400 void cfg80211_sme_failed_assoc(struct wireless_dev
*wdev
)
402 struct wiphy
*wiphy
= wdev
->wiphy
;
403 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
405 wdev
->conn
->state
= CFG80211_CONN_DEAUTH_ASSOC_FAIL
;
406 schedule_work(&rdev
->conn_work
);
409 void __cfg80211_connect_result(struct net_device
*dev
, const u8
*bssid
,
410 const u8
*req_ie
, size_t req_ie_len
,
411 const u8
*resp_ie
, size_t resp_ie_len
,
412 u16 status
, bool wextev
,
413 struct cfg80211_bss
*bss
)
415 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
416 const u8
*country_ie
;
417 #ifdef CONFIG_CFG80211_WEXT
418 union iwreq_data wrqu
;
421 ASSERT_WDEV_LOCK(wdev
);
423 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_STATION
&&
424 wdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
))
427 if (wdev
->sme_state
!= CFG80211_SME_CONNECTING
)
430 nl80211_send_connect_result(wiphy_to_dev(wdev
->wiphy
), dev
,
431 bssid
, req_ie
, req_ie_len
,
432 resp_ie
, resp_ie_len
,
435 #ifdef CONFIG_CFG80211_WEXT
437 if (req_ie
&& status
== WLAN_STATUS_SUCCESS
) {
438 memset(&wrqu
, 0, sizeof(wrqu
));
439 wrqu
.data
.length
= req_ie_len
;
440 wireless_send_event(dev
, IWEVASSOCREQIE
, &wrqu
, req_ie
);
443 if (resp_ie
&& status
== WLAN_STATUS_SUCCESS
) {
444 memset(&wrqu
, 0, sizeof(wrqu
));
445 wrqu
.data
.length
= resp_ie_len
;
446 wireless_send_event(dev
, IWEVASSOCRESPIE
, &wrqu
, resp_ie
);
449 memset(&wrqu
, 0, sizeof(wrqu
));
450 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
451 if (bssid
&& status
== WLAN_STATUS_SUCCESS
) {
452 memcpy(wrqu
.ap_addr
.sa_data
, bssid
, ETH_ALEN
);
453 memcpy(wdev
->wext
.prev_bssid
, bssid
, ETH_ALEN
);
454 wdev
->wext
.prev_bssid_valid
= true;
456 wireless_send_event(dev
, SIOCGIWAP
, &wrqu
, NULL
);
460 if (wdev
->current_bss
) {
461 cfg80211_unhold_bss(wdev
->current_bss
);
462 cfg80211_put_bss(wdev
->wiphy
, &wdev
->current_bss
->pub
);
463 wdev
->current_bss
= NULL
;
467 wdev
->conn
->state
= CFG80211_CONN_IDLE
;
469 if (status
!= WLAN_STATUS_SUCCESS
) {
470 wdev
->sme_state
= CFG80211_SME_IDLE
;
472 kfree(wdev
->conn
->ie
);
475 kfree(wdev
->connect_keys
);
476 wdev
->connect_keys
= NULL
;
478 cfg80211_put_bss(wdev
->wiphy
, bss
);
483 bss
= cfg80211_get_bss(wdev
->wiphy
,
484 wdev
->conn
? wdev
->conn
->params
.channel
:
487 wdev
->ssid
, wdev
->ssid_len
,
489 WLAN_CAPABILITY_ESS
);
494 cfg80211_hold_bss(bss_from_pub(bss
));
495 wdev
->current_bss
= bss_from_pub(bss
);
497 wdev
->sme_state
= CFG80211_SME_CONNECTED
;
498 cfg80211_upload_connect_keys(wdev
);
501 country_ie
= ieee80211_bss_get_ie(bss
, WLAN_EID_COUNTRY
);
507 country_ie
= kmemdup(country_ie
, 2 + country_ie
[1], GFP_ATOMIC
);
514 * ieee80211_bss_get_ie() ensures we can access:
515 * - country_ie + 2, the start of the country ie data, and
516 * - and country_ie[1] which is the IE length
518 regulatory_hint_11d(wdev
->wiphy
, bss
->channel
->band
,
519 country_ie
+ 2, country_ie
[1]);
523 void cfg80211_connect_result(struct net_device
*dev
, const u8
*bssid
,
524 const u8
*req_ie
, size_t req_ie_len
,
525 const u8
*resp_ie
, size_t resp_ie_len
,
526 u16 status
, gfp_t gfp
)
528 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
529 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
530 struct cfg80211_event
*ev
;
533 CFG80211_DEV_WARN_ON(wdev
->sme_state
!= CFG80211_SME_CONNECTING
);
535 ev
= kzalloc(sizeof(*ev
) + req_ie_len
+ resp_ie_len
, gfp
);
539 ev
->type
= EVENT_CONNECT_RESULT
;
541 memcpy(ev
->cr
.bssid
, bssid
, ETH_ALEN
);
543 ev
->cr
.req_ie
= ((u8
*)ev
) + sizeof(*ev
);
544 ev
->cr
.req_ie_len
= req_ie_len
;
545 memcpy((void *)ev
->cr
.req_ie
, req_ie
, req_ie_len
);
548 ev
->cr
.resp_ie
= ((u8
*)ev
) + sizeof(*ev
) + req_ie_len
;
549 ev
->cr
.resp_ie_len
= resp_ie_len
;
550 memcpy((void *)ev
->cr
.resp_ie
, resp_ie
, resp_ie_len
);
552 ev
->cr
.status
= status
;
554 spin_lock_irqsave(&wdev
->event_lock
, flags
);
555 list_add_tail(&ev
->list
, &wdev
->event_list
);
556 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
557 queue_work(cfg80211_wq
, &rdev
->event_work
);
559 EXPORT_SYMBOL(cfg80211_connect_result
);
561 void __cfg80211_roamed(struct wireless_dev
*wdev
,
562 struct cfg80211_bss
*bss
,
563 const u8
*req_ie
, size_t req_ie_len
,
564 const u8
*resp_ie
, size_t resp_ie_len
)
566 #ifdef CONFIG_CFG80211_WEXT
567 union iwreq_data wrqu
;
569 ASSERT_WDEV_LOCK(wdev
);
571 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_STATION
&&
572 wdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
))
575 if (wdev
->sme_state
!= CFG80211_SME_CONNECTED
)
578 /* internal error -- how did we get to CONNECTED w/o BSS? */
579 if (WARN_ON(!wdev
->current_bss
)) {
583 cfg80211_unhold_bss(wdev
->current_bss
);
584 cfg80211_put_bss(wdev
->wiphy
, &wdev
->current_bss
->pub
);
585 wdev
->current_bss
= NULL
;
587 cfg80211_hold_bss(bss_from_pub(bss
));
588 wdev
->current_bss
= bss_from_pub(bss
);
590 nl80211_send_roamed(wiphy_to_dev(wdev
->wiphy
), wdev
->netdev
, bss
->bssid
,
591 req_ie
, req_ie_len
, resp_ie
, resp_ie_len
,
594 #ifdef CONFIG_CFG80211_WEXT
596 memset(&wrqu
, 0, sizeof(wrqu
));
597 wrqu
.data
.length
= req_ie_len
;
598 wireless_send_event(wdev
->netdev
, IWEVASSOCREQIE
,
603 memset(&wrqu
, 0, sizeof(wrqu
));
604 wrqu
.data
.length
= resp_ie_len
;
605 wireless_send_event(wdev
->netdev
, IWEVASSOCRESPIE
,
609 memset(&wrqu
, 0, sizeof(wrqu
));
610 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
611 memcpy(wrqu
.ap_addr
.sa_data
, bss
->bssid
, ETH_ALEN
);
612 memcpy(wdev
->wext
.prev_bssid
, bss
->bssid
, ETH_ALEN
);
613 wdev
->wext
.prev_bssid_valid
= true;
614 wireless_send_event(wdev
->netdev
, SIOCGIWAP
, &wrqu
, NULL
);
619 cfg80211_put_bss(wdev
->wiphy
, bss
);
622 void cfg80211_roamed(struct net_device
*dev
,
623 struct ieee80211_channel
*channel
,
625 const u8
*req_ie
, size_t req_ie_len
,
626 const u8
*resp_ie
, size_t resp_ie_len
, gfp_t gfp
)
628 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
629 struct cfg80211_bss
*bss
;
631 CFG80211_DEV_WARN_ON(wdev
->sme_state
!= CFG80211_SME_CONNECTED
);
633 bss
= cfg80211_get_bss(wdev
->wiphy
, channel
, bssid
, wdev
->ssid
,
634 wdev
->ssid_len
, WLAN_CAPABILITY_ESS
,
635 WLAN_CAPABILITY_ESS
);
639 cfg80211_roamed_bss(dev
, bss
, req_ie
, req_ie_len
, resp_ie
,
642 EXPORT_SYMBOL(cfg80211_roamed
);
644 void cfg80211_roamed_bss(struct net_device
*dev
,
645 struct cfg80211_bss
*bss
, const u8
*req_ie
,
646 size_t req_ie_len
, const u8
*resp_ie
,
647 size_t resp_ie_len
, gfp_t gfp
)
649 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
650 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
651 struct cfg80211_event
*ev
;
654 CFG80211_DEV_WARN_ON(wdev
->sme_state
!= CFG80211_SME_CONNECTED
);
659 ev
= kzalloc(sizeof(*ev
) + req_ie_len
+ resp_ie_len
, gfp
);
661 cfg80211_put_bss(wdev
->wiphy
, bss
);
665 ev
->type
= EVENT_ROAMED
;
666 ev
->rm
.req_ie
= ((u8
*)ev
) + sizeof(*ev
);
667 ev
->rm
.req_ie_len
= req_ie_len
;
668 memcpy((void *)ev
->rm
.req_ie
, req_ie
, req_ie_len
);
669 ev
->rm
.resp_ie
= ((u8
*)ev
) + sizeof(*ev
) + req_ie_len
;
670 ev
->rm
.resp_ie_len
= resp_ie_len
;
671 memcpy((void *)ev
->rm
.resp_ie
, resp_ie
, resp_ie_len
);
674 spin_lock_irqsave(&wdev
->event_lock
, flags
);
675 list_add_tail(&ev
->list
, &wdev
->event_list
);
676 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
677 queue_work(cfg80211_wq
, &rdev
->event_work
);
679 EXPORT_SYMBOL(cfg80211_roamed_bss
);
681 void __cfg80211_disconnected(struct net_device
*dev
, const u8
*ie
,
682 size_t ie_len
, u16 reason
, bool from_ap
)
684 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
685 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
687 #ifdef CONFIG_CFG80211_WEXT
688 union iwreq_data wrqu
;
691 ASSERT_WDEV_LOCK(wdev
);
693 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_STATION
&&
694 wdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
))
697 if (wdev
->sme_state
!= CFG80211_SME_CONNECTED
)
700 if (wdev
->current_bss
) {
701 cfg80211_unhold_bss(wdev
->current_bss
);
702 cfg80211_put_bss(wdev
->wiphy
, &wdev
->current_bss
->pub
);
705 wdev
->current_bss
= NULL
;
706 wdev
->sme_state
= CFG80211_SME_IDLE
;
710 kfree(wdev
->conn
->ie
);
711 wdev
->conn
->ie
= NULL
;
716 nl80211_send_disconnected(rdev
, dev
, reason
, ie
, ie_len
, from_ap
);
719 * Delete all the keys ... pairwise keys can't really
720 * exist any more anyway, but default keys might.
722 if (rdev
->ops
->del_key
)
723 for (i
= 0; i
< 6; i
++)
724 rdev_del_key(rdev
, dev
, i
, false, NULL
);
726 #ifdef CONFIG_CFG80211_WEXT
727 memset(&wrqu
, 0, sizeof(wrqu
));
728 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
729 wireless_send_event(dev
, SIOCGIWAP
, &wrqu
, NULL
);
730 wdev
->wext
.connect
.ssid_len
= 0;
733 schedule_work(&cfg80211_disconnect_work
);
736 void cfg80211_disconnected(struct net_device
*dev
, u16 reason
,
737 u8
*ie
, size_t ie_len
, gfp_t gfp
)
739 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
740 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
741 struct cfg80211_event
*ev
;
744 CFG80211_DEV_WARN_ON(wdev
->sme_state
!= CFG80211_SME_CONNECTED
);
746 ev
= kzalloc(sizeof(*ev
) + ie_len
, gfp
);
750 ev
->type
= EVENT_DISCONNECTED
;
751 ev
->dc
.ie
= ((u8
*)ev
) + sizeof(*ev
);
752 ev
->dc
.ie_len
= ie_len
;
753 memcpy((void *)ev
->dc
.ie
, ie
, ie_len
);
754 ev
->dc
.reason
= reason
;
756 spin_lock_irqsave(&wdev
->event_lock
, flags
);
757 list_add_tail(&ev
->list
, &wdev
->event_list
);
758 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
759 queue_work(cfg80211_wq
, &rdev
->event_work
);
761 EXPORT_SYMBOL(cfg80211_disconnected
);
763 int cfg80211_connect(struct cfg80211_registered_device
*rdev
,
764 struct net_device
*dev
,
765 struct cfg80211_connect_params
*connect
,
766 struct cfg80211_cached_keys
*connkeys
,
767 const u8
*prev_bssid
)
769 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
770 struct cfg80211_bss
*bss
= NULL
;
773 ASSERT_WDEV_LOCK(wdev
);
775 if (wdev
->sme_state
!= CFG80211_SME_IDLE
)
778 if (WARN_ON(wdev
->connect_keys
)) {
779 kfree(wdev
->connect_keys
);
780 wdev
->connect_keys
= NULL
;
783 cfg80211_oper_and_ht_capa(&connect
->ht_capa_mask
,
784 rdev
->wiphy
.ht_capa_mod_mask
);
786 if (connkeys
&& connkeys
->def
>= 0) {
791 cipher
= connkeys
->params
[idx
].cipher
;
792 /* If given a WEP key we may need it for shared key auth */
793 if (cipher
== WLAN_CIPHER_SUITE_WEP40
||
794 cipher
== WLAN_CIPHER_SUITE_WEP104
) {
795 connect
->key_idx
= idx
;
796 connect
->key
= connkeys
->params
[idx
].key
;
797 connect
->key_len
= connkeys
->params
[idx
].key_len
;
800 * If ciphers are not set (e.g. when going through
801 * iwconfig), we have to set them appropriately here.
803 if (connect
->crypto
.cipher_group
== 0)
804 connect
->crypto
.cipher_group
= cipher
;
806 if (connect
->crypto
.n_ciphers_pairwise
== 0) {
807 connect
->crypto
.n_ciphers_pairwise
= 1;
808 connect
->crypto
.ciphers_pairwise
[0] = cipher
;
813 if (!rdev
->ops
->connect
) {
814 if (!rdev
->ops
->auth
|| !rdev
->ops
->assoc
)
817 if (WARN_ON(wdev
->conn
))
820 wdev
->conn
= kzalloc(sizeof(*wdev
->conn
), GFP_KERNEL
);
825 * Copy all parameters, and treat explicitly IEs, BSSID, SSID.
827 memcpy(&wdev
->conn
->params
, connect
, sizeof(*connect
));
828 if (connect
->bssid
) {
829 wdev
->conn
->params
.bssid
= wdev
->conn
->bssid
;
830 memcpy(wdev
->conn
->bssid
, connect
->bssid
, ETH_ALEN
);
834 wdev
->conn
->ie
= kmemdup(connect
->ie
, connect
->ie_len
,
836 wdev
->conn
->params
.ie
= wdev
->conn
->ie
;
837 if (!wdev
->conn
->ie
) {
844 if (connect
->auth_type
== NL80211_AUTHTYPE_AUTOMATIC
) {
845 wdev
->conn
->auto_auth
= true;
846 /* start with open system ... should mostly work */
847 wdev
->conn
->params
.auth_type
=
848 NL80211_AUTHTYPE_OPEN_SYSTEM
;
850 wdev
->conn
->auto_auth
= false;
853 memcpy(wdev
->ssid
, connect
->ssid
, connect
->ssid_len
);
854 wdev
->ssid_len
= connect
->ssid_len
;
855 wdev
->conn
->params
.ssid
= wdev
->ssid
;
856 wdev
->conn
->params
.ssid_len
= connect
->ssid_len
;
858 /* see if we have the bss already */
859 bss
= cfg80211_get_conn_bss(wdev
);
861 wdev
->sme_state
= CFG80211_SME_CONNECTING
;
862 wdev
->connect_keys
= connkeys
;
865 memcpy(wdev
->conn
->prev_bssid
, prev_bssid
, ETH_ALEN
);
866 wdev
->conn
->prev_bssid_valid
= true;
869 /* we're good if we have a matching bss struct */
871 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATE_NEXT
;
872 err
= cfg80211_conn_do_work(wdev
);
873 cfg80211_put_bss(wdev
->wiphy
, bss
);
875 /* otherwise we'll need to scan for the AP first */
876 err
= cfg80211_conn_scan(wdev
);
878 * If we can't scan right now, then we need to scan again
879 * after the current scan finished, since the parameters
880 * changed (unless we find a good AP anyway).
884 wdev
->conn
->state
= CFG80211_CONN_SCAN_AGAIN
;
888 kfree(wdev
->conn
->ie
);
891 wdev
->sme_state
= CFG80211_SME_IDLE
;
892 wdev
->connect_keys
= NULL
;
898 wdev
->sme_state
= CFG80211_SME_CONNECTING
;
899 wdev
->connect_keys
= connkeys
;
900 err
= rdev_connect(rdev
, dev
, connect
);
902 wdev
->connect_keys
= NULL
;
903 wdev
->sme_state
= CFG80211_SME_IDLE
;
907 memcpy(wdev
->ssid
, connect
->ssid
, connect
->ssid_len
);
908 wdev
->ssid_len
= connect
->ssid_len
;
914 int cfg80211_disconnect(struct cfg80211_registered_device
*rdev
,
915 struct net_device
*dev
, u16 reason
, bool wextev
)
917 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
920 ASSERT_WDEV_LOCK(wdev
);
922 if (wdev
->sme_state
== CFG80211_SME_IDLE
)
925 kfree(wdev
->connect_keys
);
926 wdev
->connect_keys
= NULL
;
928 if (!rdev
->ops
->disconnect
) {
929 if (!rdev
->ops
->deauth
)
932 /* was it connected by userspace SME? */
934 cfg80211_mlme_down(rdev
, dev
);
938 if (wdev
->sme_state
== CFG80211_SME_CONNECTING
&&
939 (wdev
->conn
->state
== CFG80211_CONN_SCANNING
||
940 wdev
->conn
->state
== CFG80211_CONN_SCAN_AGAIN
)) {
941 wdev
->sme_state
= CFG80211_SME_IDLE
;
942 kfree(wdev
->conn
->ie
);
949 /* wdev->conn->params.bssid must be set if > SCANNING */
950 err
= cfg80211_mlme_deauth(rdev
, dev
,
951 wdev
->conn
->params
.bssid
,
952 NULL
, 0, reason
, false);
956 err
= rdev_disconnect(rdev
, dev
, reason
);
962 if (wdev
->sme_state
== CFG80211_SME_CONNECTED
)
963 __cfg80211_disconnected(dev
, NULL
, 0, 0, false);
964 else if (wdev
->sme_state
== CFG80211_SME_CONNECTING
)
965 __cfg80211_connect_result(dev
, NULL
, NULL
, 0, NULL
, 0,
966 WLAN_STATUS_UNSPECIFIED_FAILURE
,
972 void cfg80211_sme_disassoc(struct net_device
*dev
,
973 struct cfg80211_internal_bss
*bss
)
975 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
976 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
979 ASSERT_WDEV_LOCK(wdev
);
984 if (wdev
->conn
->state
== CFG80211_CONN_IDLE
)
988 * Ok, so the association was made by this SME -- we don't
989 * want it any more so deauthenticate too.
992 memcpy(bssid
, bss
->pub
.bssid
, ETH_ALEN
);
994 cfg80211_mlme_deauth(rdev
, dev
, bssid
, NULL
, 0,
995 WLAN_REASON_DEAUTH_LEAVING
, false);