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;
46 mutex_lock(&cfg80211_mutex
);
49 * All devices must be idle as otherwise if you are actively
50 * scanning some new beacon hints could be learned and would
51 * count as new regulatory hints.
53 list_for_each_entry(rdev
, &cfg80211_rdev_list
, list
) {
54 cfg80211_lock_rdev(rdev
);
55 list_for_each_entry(wdev
, &rdev
->wdev_list
, list
) {
57 if (wdev
->sme_state
!= CFG80211_SME_IDLE
)
61 cfg80211_unlock_rdev(rdev
);
64 mutex_unlock(&cfg80211_mutex
);
69 static void disconnect_work(struct work_struct
*work
)
71 if (!cfg80211_is_all_idle())
74 regulatory_hint_disconnect();
77 static DECLARE_WORK(cfg80211_disconnect_work
, disconnect_work
);
79 static int cfg80211_conn_scan(struct wireless_dev
*wdev
)
81 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
82 struct cfg80211_scan_request
*request
;
86 ASSERT_RDEV_LOCK(rdev
);
87 ASSERT_WDEV_LOCK(wdev
);
88 lockdep_assert_held(&rdev
->sched_scan_mtx
);
93 if (wdev
->conn
->params
.channel
) {
96 enum ieee80211_band band
;
99 for (band
= 0; band
< IEEE80211_NUM_BANDS
; band
++) {
100 if (!wdev
->wiphy
->bands
[band
])
102 n_channels
+= wdev
->wiphy
->bands
[band
]->n_channels
;
105 request
= kzalloc(sizeof(*request
) + sizeof(request
->ssids
[0]) +
106 sizeof(request
->channels
[0]) * n_channels
,
111 if (wdev
->conn
->params
.channel
)
112 request
->channels
[0] = wdev
->conn
->params
.channel
;
115 enum ieee80211_band band
;
116 struct ieee80211_supported_band
*bands
;
117 struct ieee80211_channel
*channel
;
119 for (band
= 0; band
< IEEE80211_NUM_BANDS
; band
++) {
120 bands
= wdev
->wiphy
->bands
[band
];
123 for (j
= 0; j
< bands
->n_channels
; j
++) {
124 channel
= &bands
->channels
[j
];
125 if (channel
->flags
& IEEE80211_CHAN_DISABLED
)
127 request
->channels
[i
++] = channel
;
129 request
->rates
[band
] = (1 << bands
->n_bitrates
) - 1;
133 request
->n_channels
= n_channels
;
134 request
->ssids
= (void *)&request
->channels
[n_channels
];
135 request
->n_ssids
= 1;
137 memcpy(request
->ssids
[0].ssid
, wdev
->conn
->params
.ssid
,
138 wdev
->conn
->params
.ssid_len
);
139 request
->ssids
[0].ssid_len
= wdev
->conn
->params
.ssid_len
;
141 request
->wdev
= wdev
;
142 request
->wiphy
= &rdev
->wiphy
;
143 request
->scan_start
= jiffies
;
145 rdev
->scan_req
= request
;
147 err
= rdev_scan(rdev
, request
);
149 wdev
->conn
->state
= CFG80211_CONN_SCANNING
;
150 nl80211_send_scan_start(rdev
, wdev
);
151 dev_hold(wdev
->netdev
);
153 rdev
->scan_req
= NULL
;
159 static int cfg80211_conn_do_work(struct wireless_dev
*wdev
)
161 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
162 struct cfg80211_connect_params
*params
;
163 struct cfg80211_assoc_request req
= {};
166 ASSERT_WDEV_LOCK(wdev
);
171 params
= &wdev
->conn
->params
;
173 switch (wdev
->conn
->state
) {
174 case CFG80211_CONN_SCAN_AGAIN
:
175 return cfg80211_conn_scan(wdev
);
176 case CFG80211_CONN_AUTHENTICATE_NEXT
:
177 BUG_ON(!rdev
->ops
->auth
);
178 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATING
;
179 return __cfg80211_mlme_auth(rdev
, wdev
->netdev
,
180 params
->channel
, params
->auth_type
,
182 params
->ssid
, params
->ssid_len
,
184 params
->key
, params
->key_len
,
185 params
->key_idx
, NULL
, 0);
186 case CFG80211_CONN_ASSOCIATE_NEXT
:
187 BUG_ON(!rdev
->ops
->assoc
);
188 wdev
->conn
->state
= CFG80211_CONN_ASSOCIATING
;
189 if (wdev
->conn
->prev_bssid_valid
)
190 req
.prev_bssid
= wdev
->conn
->prev_bssid
;
192 req
.ie_len
= params
->ie_len
;
193 req
.use_mfp
= params
->mfp
!= NL80211_MFP_NO
;
194 req
.crypto
= params
->crypto
;
195 req
.flags
= params
->flags
;
196 req
.ht_capa
= params
->ht_capa
;
197 req
.ht_capa_mask
= params
->ht_capa_mask
;
198 req
.vht_capa
= params
->vht_capa
;
199 req
.vht_capa_mask
= params
->vht_capa_mask
;
201 err
= __cfg80211_mlme_assoc(rdev
, wdev
->netdev
, params
->channel
,
202 params
->bssid
, params
->ssid
,
203 params
->ssid_len
, &req
);
205 __cfg80211_mlme_deauth(rdev
, wdev
->netdev
, params
->bssid
,
207 WLAN_REASON_DEAUTH_LEAVING
,
210 case CFG80211_CONN_DEAUTH_ASSOC_FAIL
:
211 __cfg80211_mlme_deauth(rdev
, wdev
->netdev
, params
->bssid
,
213 WLAN_REASON_DEAUTH_LEAVING
, false);
214 /* return an error so that we call __cfg80211_connect_result() */
221 void cfg80211_conn_work(struct work_struct
*work
)
223 struct cfg80211_registered_device
*rdev
=
224 container_of(work
, struct cfg80211_registered_device
, conn_work
);
225 struct wireless_dev
*wdev
;
226 u8 bssid_buf
[ETH_ALEN
], *bssid
= NULL
;
229 cfg80211_lock_rdev(rdev
);
230 mutex_lock(&rdev
->devlist_mtx
);
231 mutex_lock(&rdev
->sched_scan_mtx
);
233 list_for_each_entry(wdev
, &rdev
->wdev_list
, list
) {
238 if (!netif_running(wdev
->netdev
)) {
242 if (wdev
->sme_state
!= CFG80211_SME_CONNECTING
|| !wdev
->conn
) {
246 if (wdev
->conn
->params
.bssid
) {
247 memcpy(bssid_buf
, wdev
->conn
->params
.bssid
, ETH_ALEN
);
250 if (cfg80211_conn_do_work(wdev
))
251 __cfg80211_connect_result(
254 WLAN_STATUS_UNSPECIFIED_FAILURE
,
259 mutex_unlock(&rdev
->sched_scan_mtx
);
260 mutex_unlock(&rdev
->devlist_mtx
);
261 cfg80211_unlock_rdev(rdev
);
265 static struct cfg80211_bss
*cfg80211_get_conn_bss(struct wireless_dev
*wdev
)
267 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
268 struct cfg80211_bss
*bss
;
269 u16 capa
= WLAN_CAPABILITY_ESS
;
271 ASSERT_WDEV_LOCK(wdev
);
273 if (wdev
->conn
->params
.privacy
)
274 capa
|= WLAN_CAPABILITY_PRIVACY
;
276 bss
= cfg80211_get_bss(wdev
->wiphy
, wdev
->conn
->params
.channel
,
277 wdev
->conn
->params
.bssid
,
278 wdev
->conn
->params
.ssid
,
279 wdev
->conn
->params
.ssid_len
,
280 WLAN_CAPABILITY_ESS
| WLAN_CAPABILITY_PRIVACY
,
285 memcpy(wdev
->conn
->bssid
, bss
->bssid
, ETH_ALEN
);
286 wdev
->conn
->params
.bssid
= wdev
->conn
->bssid
;
287 wdev
->conn
->params
.channel
= bss
->channel
;
288 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATE_NEXT
;
289 schedule_work(&rdev
->conn_work
);
294 static void __cfg80211_sme_scan_done(struct net_device
*dev
)
296 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
297 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
298 struct cfg80211_bss
*bss
;
300 ASSERT_WDEV_LOCK(wdev
);
302 if (wdev
->sme_state
!= CFG80211_SME_CONNECTING
)
308 if (wdev
->conn
->state
!= CFG80211_CONN_SCANNING
&&
309 wdev
->conn
->state
!= CFG80211_CONN_SCAN_AGAIN
)
312 bss
= cfg80211_get_conn_bss(wdev
);
314 cfg80211_put_bss(&rdev
->wiphy
, bss
);
317 if (wdev
->conn
->state
== CFG80211_CONN_SCAN_AGAIN
)
318 schedule_work(&rdev
->conn_work
);
320 __cfg80211_connect_result(
322 wdev
->conn
->params
.bssid
,
324 WLAN_STATUS_UNSPECIFIED_FAILURE
,
329 void cfg80211_sme_scan_done(struct net_device
*dev
)
331 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
334 __cfg80211_sme_scan_done(dev
);
338 void cfg80211_sme_rx_auth(struct net_device
*dev
,
339 const u8
*buf
, size_t len
)
341 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
342 struct wiphy
*wiphy
= wdev
->wiphy
;
343 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
344 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*)buf
;
345 u16 status_code
= le16_to_cpu(mgmt
->u
.auth
.status_code
);
347 ASSERT_WDEV_LOCK(wdev
);
349 /* should only RX auth frames when connecting */
350 if (wdev
->sme_state
!= CFG80211_SME_CONNECTING
)
353 if (WARN_ON(!wdev
->conn
))
356 if (status_code
== WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
&&
357 wdev
->conn
->auto_auth
&&
358 wdev
->conn
->params
.auth_type
!= NL80211_AUTHTYPE_NETWORK_EAP
) {
359 /* select automatically between only open, shared, leap */
360 switch (wdev
->conn
->params
.auth_type
) {
361 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
362 if (wdev
->connect_keys
)
363 wdev
->conn
->params
.auth_type
=
364 NL80211_AUTHTYPE_SHARED_KEY
;
366 wdev
->conn
->params
.auth_type
=
367 NL80211_AUTHTYPE_NETWORK_EAP
;
369 case NL80211_AUTHTYPE_SHARED_KEY
:
370 wdev
->conn
->params
.auth_type
=
371 NL80211_AUTHTYPE_NETWORK_EAP
;
375 wdev
->conn
->params
.auth_type
=
376 NL80211_AUTHTYPE_OPEN_SYSTEM
;
379 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATE_NEXT
;
380 schedule_work(&rdev
->conn_work
);
381 } else if (status_code
!= WLAN_STATUS_SUCCESS
) {
382 __cfg80211_connect_result(dev
, mgmt
->bssid
, NULL
, 0, NULL
, 0,
383 status_code
, false, NULL
);
384 } else if (wdev
->sme_state
== CFG80211_SME_CONNECTING
&&
385 wdev
->conn
->state
== CFG80211_CONN_AUTHENTICATING
) {
386 wdev
->conn
->state
= CFG80211_CONN_ASSOCIATE_NEXT
;
387 schedule_work(&rdev
->conn_work
);
391 bool cfg80211_sme_failed_reassoc(struct wireless_dev
*wdev
)
393 struct wiphy
*wiphy
= wdev
->wiphy
;
394 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
396 if (WARN_ON(!wdev
->conn
))
399 if (!wdev
->conn
->prev_bssid_valid
)
403 * Some stupid APs don't accept reassoc, so we
404 * need to fall back to trying regular assoc.
406 wdev
->conn
->prev_bssid_valid
= false;
407 wdev
->conn
->state
= CFG80211_CONN_ASSOCIATE_NEXT
;
408 schedule_work(&rdev
->conn_work
);
413 void cfg80211_sme_failed_assoc(struct wireless_dev
*wdev
)
415 struct wiphy
*wiphy
= wdev
->wiphy
;
416 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
418 wdev
->conn
->state
= CFG80211_CONN_DEAUTH_ASSOC_FAIL
;
419 schedule_work(&rdev
->conn_work
);
422 void __cfg80211_connect_result(struct net_device
*dev
, const u8
*bssid
,
423 const u8
*req_ie
, size_t req_ie_len
,
424 const u8
*resp_ie
, size_t resp_ie_len
,
425 u16 status
, bool wextev
,
426 struct cfg80211_bss
*bss
)
428 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
429 const u8
*country_ie
;
430 #ifdef CONFIG_CFG80211_WEXT
431 union iwreq_data wrqu
;
434 ASSERT_WDEV_LOCK(wdev
);
436 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_STATION
&&
437 wdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
))
440 if (wdev
->sme_state
!= CFG80211_SME_CONNECTING
)
443 nl80211_send_connect_result(wiphy_to_dev(wdev
->wiphy
), dev
,
444 bssid
, req_ie
, req_ie_len
,
445 resp_ie
, resp_ie_len
,
448 #ifdef CONFIG_CFG80211_WEXT
450 if (req_ie
&& status
== WLAN_STATUS_SUCCESS
) {
451 memset(&wrqu
, 0, sizeof(wrqu
));
452 wrqu
.data
.length
= req_ie_len
;
453 wireless_send_event(dev
, IWEVASSOCREQIE
, &wrqu
, req_ie
);
456 if (resp_ie
&& status
== WLAN_STATUS_SUCCESS
) {
457 memset(&wrqu
, 0, sizeof(wrqu
));
458 wrqu
.data
.length
= resp_ie_len
;
459 wireless_send_event(dev
, IWEVASSOCRESPIE
, &wrqu
, resp_ie
);
462 memset(&wrqu
, 0, sizeof(wrqu
));
463 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
464 if (bssid
&& status
== WLAN_STATUS_SUCCESS
) {
465 memcpy(wrqu
.ap_addr
.sa_data
, bssid
, ETH_ALEN
);
466 memcpy(wdev
->wext
.prev_bssid
, bssid
, ETH_ALEN
);
467 wdev
->wext
.prev_bssid_valid
= true;
469 wireless_send_event(dev
, SIOCGIWAP
, &wrqu
, NULL
);
473 if (wdev
->current_bss
) {
474 cfg80211_unhold_bss(wdev
->current_bss
);
475 cfg80211_put_bss(wdev
->wiphy
, &wdev
->current_bss
->pub
);
476 wdev
->current_bss
= NULL
;
480 wdev
->conn
->state
= CFG80211_CONN_IDLE
;
482 if (status
!= WLAN_STATUS_SUCCESS
) {
483 wdev
->sme_state
= CFG80211_SME_IDLE
;
485 kfree(wdev
->conn
->ie
);
488 kfree(wdev
->connect_keys
);
489 wdev
->connect_keys
= NULL
;
491 cfg80211_put_bss(wdev
->wiphy
, bss
);
496 bss
= cfg80211_get_bss(wdev
->wiphy
,
497 wdev
->conn
? wdev
->conn
->params
.channel
:
500 wdev
->ssid
, wdev
->ssid_len
,
502 WLAN_CAPABILITY_ESS
);
507 cfg80211_hold_bss(bss_from_pub(bss
));
508 wdev
->current_bss
= bss_from_pub(bss
);
510 wdev
->sme_state
= CFG80211_SME_CONNECTED
;
511 cfg80211_upload_connect_keys(wdev
);
514 country_ie
= ieee80211_bss_get_ie(bss
, WLAN_EID_COUNTRY
);
520 country_ie
= kmemdup(country_ie
, 2 + country_ie
[1], GFP_ATOMIC
);
527 * ieee80211_bss_get_ie() ensures we can access:
528 * - country_ie + 2, the start of the country ie data, and
529 * - and country_ie[1] which is the IE length
531 regulatory_hint_11d(wdev
->wiphy
, bss
->channel
->band
,
532 country_ie
+ 2, country_ie
[1]);
536 void cfg80211_connect_result(struct net_device
*dev
, const u8
*bssid
,
537 const u8
*req_ie
, size_t req_ie_len
,
538 const u8
*resp_ie
, size_t resp_ie_len
,
539 u16 status
, gfp_t gfp
)
541 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
542 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
543 struct cfg80211_event
*ev
;
546 CFG80211_DEV_WARN_ON(wdev
->sme_state
!= CFG80211_SME_CONNECTING
);
548 ev
= kzalloc(sizeof(*ev
) + req_ie_len
+ resp_ie_len
, gfp
);
552 ev
->type
= EVENT_CONNECT_RESULT
;
554 memcpy(ev
->cr
.bssid
, bssid
, ETH_ALEN
);
556 ev
->cr
.req_ie
= ((u8
*)ev
) + sizeof(*ev
);
557 ev
->cr
.req_ie_len
= req_ie_len
;
558 memcpy((void *)ev
->cr
.req_ie
, req_ie
, req_ie_len
);
561 ev
->cr
.resp_ie
= ((u8
*)ev
) + sizeof(*ev
) + req_ie_len
;
562 ev
->cr
.resp_ie_len
= resp_ie_len
;
563 memcpy((void *)ev
->cr
.resp_ie
, resp_ie
, resp_ie_len
);
565 ev
->cr
.status
= status
;
567 spin_lock_irqsave(&wdev
->event_lock
, flags
);
568 list_add_tail(&ev
->list
, &wdev
->event_list
);
569 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
570 queue_work(cfg80211_wq
, &rdev
->event_work
);
572 EXPORT_SYMBOL(cfg80211_connect_result
);
574 void __cfg80211_roamed(struct wireless_dev
*wdev
,
575 struct cfg80211_bss
*bss
,
576 const u8
*req_ie
, size_t req_ie_len
,
577 const u8
*resp_ie
, size_t resp_ie_len
)
579 #ifdef CONFIG_CFG80211_WEXT
580 union iwreq_data wrqu
;
582 ASSERT_WDEV_LOCK(wdev
);
584 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_STATION
&&
585 wdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
))
588 if (wdev
->sme_state
!= CFG80211_SME_CONNECTED
)
591 /* internal error -- how did we get to CONNECTED w/o BSS? */
592 if (WARN_ON(!wdev
->current_bss
)) {
596 cfg80211_unhold_bss(wdev
->current_bss
);
597 cfg80211_put_bss(wdev
->wiphy
, &wdev
->current_bss
->pub
);
598 wdev
->current_bss
= NULL
;
600 cfg80211_hold_bss(bss_from_pub(bss
));
601 wdev
->current_bss
= bss_from_pub(bss
);
603 nl80211_send_roamed(wiphy_to_dev(wdev
->wiphy
), wdev
->netdev
, bss
->bssid
,
604 req_ie
, req_ie_len
, resp_ie
, resp_ie_len
,
607 #ifdef CONFIG_CFG80211_WEXT
609 memset(&wrqu
, 0, sizeof(wrqu
));
610 wrqu
.data
.length
= req_ie_len
;
611 wireless_send_event(wdev
->netdev
, IWEVASSOCREQIE
,
616 memset(&wrqu
, 0, sizeof(wrqu
));
617 wrqu
.data
.length
= resp_ie_len
;
618 wireless_send_event(wdev
->netdev
, IWEVASSOCRESPIE
,
622 memset(&wrqu
, 0, sizeof(wrqu
));
623 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
624 memcpy(wrqu
.ap_addr
.sa_data
, bss
->bssid
, ETH_ALEN
);
625 memcpy(wdev
->wext
.prev_bssid
, bss
->bssid
, ETH_ALEN
);
626 wdev
->wext
.prev_bssid_valid
= true;
627 wireless_send_event(wdev
->netdev
, SIOCGIWAP
, &wrqu
, NULL
);
632 cfg80211_put_bss(wdev
->wiphy
, bss
);
635 void cfg80211_roamed(struct net_device
*dev
,
636 struct ieee80211_channel
*channel
,
638 const u8
*req_ie
, size_t req_ie_len
,
639 const u8
*resp_ie
, size_t resp_ie_len
, gfp_t gfp
)
641 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
642 struct cfg80211_bss
*bss
;
644 CFG80211_DEV_WARN_ON(wdev
->sme_state
!= CFG80211_SME_CONNECTED
);
646 bss
= cfg80211_get_bss(wdev
->wiphy
, channel
, bssid
, wdev
->ssid
,
647 wdev
->ssid_len
, WLAN_CAPABILITY_ESS
,
648 WLAN_CAPABILITY_ESS
);
652 cfg80211_roamed_bss(dev
, bss
, req_ie
, req_ie_len
, resp_ie
,
655 EXPORT_SYMBOL(cfg80211_roamed
);
657 void cfg80211_roamed_bss(struct net_device
*dev
,
658 struct cfg80211_bss
*bss
, const u8
*req_ie
,
659 size_t req_ie_len
, const u8
*resp_ie
,
660 size_t resp_ie_len
, gfp_t gfp
)
662 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
663 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
664 struct cfg80211_event
*ev
;
667 CFG80211_DEV_WARN_ON(wdev
->sme_state
!= CFG80211_SME_CONNECTED
);
672 ev
= kzalloc(sizeof(*ev
) + req_ie_len
+ resp_ie_len
, gfp
);
674 cfg80211_put_bss(wdev
->wiphy
, bss
);
678 ev
->type
= EVENT_ROAMED
;
679 ev
->rm
.req_ie
= ((u8
*)ev
) + sizeof(*ev
);
680 ev
->rm
.req_ie_len
= req_ie_len
;
681 memcpy((void *)ev
->rm
.req_ie
, req_ie
, req_ie_len
);
682 ev
->rm
.resp_ie
= ((u8
*)ev
) + sizeof(*ev
) + req_ie_len
;
683 ev
->rm
.resp_ie_len
= resp_ie_len
;
684 memcpy((void *)ev
->rm
.resp_ie
, resp_ie
, resp_ie_len
);
687 spin_lock_irqsave(&wdev
->event_lock
, flags
);
688 list_add_tail(&ev
->list
, &wdev
->event_list
);
689 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
690 queue_work(cfg80211_wq
, &rdev
->event_work
);
692 EXPORT_SYMBOL(cfg80211_roamed_bss
);
694 void __cfg80211_disconnected(struct net_device
*dev
, const u8
*ie
,
695 size_t ie_len
, u16 reason
, bool from_ap
)
697 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
698 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
700 #ifdef CONFIG_CFG80211_WEXT
701 union iwreq_data wrqu
;
704 ASSERT_WDEV_LOCK(wdev
);
706 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_STATION
&&
707 wdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
))
710 if (wdev
->sme_state
!= CFG80211_SME_CONNECTED
)
713 if (wdev
->current_bss
) {
714 cfg80211_unhold_bss(wdev
->current_bss
);
715 cfg80211_put_bss(wdev
->wiphy
, &wdev
->current_bss
->pub
);
718 wdev
->current_bss
= NULL
;
719 wdev
->sme_state
= CFG80211_SME_IDLE
;
723 kfree(wdev
->conn
->ie
);
724 wdev
->conn
->ie
= NULL
;
729 nl80211_send_disconnected(rdev
, dev
, reason
, ie
, ie_len
, from_ap
);
732 * Delete all the keys ... pairwise keys can't really
733 * exist any more anyway, but default keys might.
735 if (rdev
->ops
->del_key
)
736 for (i
= 0; i
< 6; i
++)
737 rdev_del_key(rdev
, dev
, i
, false, NULL
);
739 #ifdef CONFIG_CFG80211_WEXT
740 memset(&wrqu
, 0, sizeof(wrqu
));
741 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
742 wireless_send_event(dev
, SIOCGIWAP
, &wrqu
, NULL
);
743 wdev
->wext
.connect
.ssid_len
= 0;
746 schedule_work(&cfg80211_disconnect_work
);
749 void cfg80211_disconnected(struct net_device
*dev
, u16 reason
,
750 u8
*ie
, size_t ie_len
, gfp_t gfp
)
752 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
753 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
754 struct cfg80211_event
*ev
;
757 CFG80211_DEV_WARN_ON(wdev
->sme_state
!= CFG80211_SME_CONNECTED
);
759 ev
= kzalloc(sizeof(*ev
) + ie_len
, gfp
);
763 ev
->type
= EVENT_DISCONNECTED
;
764 ev
->dc
.ie
= ((u8
*)ev
) + sizeof(*ev
);
765 ev
->dc
.ie_len
= ie_len
;
766 memcpy((void *)ev
->dc
.ie
, ie
, ie_len
);
767 ev
->dc
.reason
= reason
;
769 spin_lock_irqsave(&wdev
->event_lock
, flags
);
770 list_add_tail(&ev
->list
, &wdev
->event_list
);
771 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
772 queue_work(cfg80211_wq
, &rdev
->event_work
);
774 EXPORT_SYMBOL(cfg80211_disconnected
);
776 int __cfg80211_connect(struct cfg80211_registered_device
*rdev
,
777 struct net_device
*dev
,
778 struct cfg80211_connect_params
*connect
,
779 struct cfg80211_cached_keys
*connkeys
,
780 const u8
*prev_bssid
)
782 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
783 struct cfg80211_bss
*bss
= NULL
;
786 ASSERT_WDEV_LOCK(wdev
);
788 if (wdev
->sme_state
!= CFG80211_SME_IDLE
)
791 if (WARN_ON(wdev
->connect_keys
)) {
792 kfree(wdev
->connect_keys
);
793 wdev
->connect_keys
= NULL
;
796 cfg80211_oper_and_ht_capa(&connect
->ht_capa_mask
,
797 rdev
->wiphy
.ht_capa_mod_mask
);
799 if (connkeys
&& connkeys
->def
>= 0) {
804 cipher
= connkeys
->params
[idx
].cipher
;
805 /* If given a WEP key we may need it for shared key auth */
806 if (cipher
== WLAN_CIPHER_SUITE_WEP40
||
807 cipher
== WLAN_CIPHER_SUITE_WEP104
) {
808 connect
->key_idx
= idx
;
809 connect
->key
= connkeys
->params
[idx
].key
;
810 connect
->key_len
= connkeys
->params
[idx
].key_len
;
813 * If ciphers are not set (e.g. when going through
814 * iwconfig), we have to set them appropriately here.
816 if (connect
->crypto
.cipher_group
== 0)
817 connect
->crypto
.cipher_group
= cipher
;
819 if (connect
->crypto
.n_ciphers_pairwise
== 0) {
820 connect
->crypto
.n_ciphers_pairwise
= 1;
821 connect
->crypto
.ciphers_pairwise
[0] = cipher
;
826 if (!rdev
->ops
->connect
) {
827 if (!rdev
->ops
->auth
|| !rdev
->ops
->assoc
)
830 if (WARN_ON(wdev
->conn
))
833 wdev
->conn
= kzalloc(sizeof(*wdev
->conn
), GFP_KERNEL
);
838 * Copy all parameters, and treat explicitly IEs, BSSID, SSID.
840 memcpy(&wdev
->conn
->params
, connect
, sizeof(*connect
));
841 if (connect
->bssid
) {
842 wdev
->conn
->params
.bssid
= wdev
->conn
->bssid
;
843 memcpy(wdev
->conn
->bssid
, connect
->bssid
, ETH_ALEN
);
847 wdev
->conn
->ie
= kmemdup(connect
->ie
, connect
->ie_len
,
849 wdev
->conn
->params
.ie
= wdev
->conn
->ie
;
850 if (!wdev
->conn
->ie
) {
857 if (connect
->auth_type
== NL80211_AUTHTYPE_AUTOMATIC
) {
858 wdev
->conn
->auto_auth
= true;
859 /* start with open system ... should mostly work */
860 wdev
->conn
->params
.auth_type
=
861 NL80211_AUTHTYPE_OPEN_SYSTEM
;
863 wdev
->conn
->auto_auth
= false;
866 memcpy(wdev
->ssid
, connect
->ssid
, connect
->ssid_len
);
867 wdev
->ssid_len
= connect
->ssid_len
;
868 wdev
->conn
->params
.ssid
= wdev
->ssid
;
869 wdev
->conn
->params
.ssid_len
= connect
->ssid_len
;
871 /* see if we have the bss already */
872 bss
= cfg80211_get_conn_bss(wdev
);
874 wdev
->sme_state
= CFG80211_SME_CONNECTING
;
875 wdev
->connect_keys
= connkeys
;
878 memcpy(wdev
->conn
->prev_bssid
, prev_bssid
, ETH_ALEN
);
879 wdev
->conn
->prev_bssid_valid
= true;
882 /* we're good if we have a matching bss struct */
884 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATE_NEXT
;
885 err
= cfg80211_conn_do_work(wdev
);
886 cfg80211_put_bss(wdev
->wiphy
, bss
);
888 /* otherwise we'll need to scan for the AP first */
889 err
= cfg80211_conn_scan(wdev
);
891 * If we can't scan right now, then we need to scan again
892 * after the current scan finished, since the parameters
893 * changed (unless we find a good AP anyway).
897 wdev
->conn
->state
= CFG80211_CONN_SCAN_AGAIN
;
901 kfree(wdev
->conn
->ie
);
904 wdev
->sme_state
= CFG80211_SME_IDLE
;
905 wdev
->connect_keys
= NULL
;
911 wdev
->sme_state
= CFG80211_SME_CONNECTING
;
912 wdev
->connect_keys
= connkeys
;
913 err
= rdev_connect(rdev
, dev
, connect
);
915 wdev
->connect_keys
= NULL
;
916 wdev
->sme_state
= CFG80211_SME_IDLE
;
920 memcpy(wdev
->ssid
, connect
->ssid
, connect
->ssid_len
);
921 wdev
->ssid_len
= connect
->ssid_len
;
927 int cfg80211_connect(struct cfg80211_registered_device
*rdev
,
928 struct net_device
*dev
,
929 struct cfg80211_connect_params
*connect
,
930 struct cfg80211_cached_keys
*connkeys
)
934 mutex_lock(&rdev
->devlist_mtx
);
935 /* might request scan - scan_mtx -> wdev_mtx dependency */
936 mutex_lock(&rdev
->sched_scan_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
->sched_scan_mtx
);
941 mutex_unlock(&rdev
->devlist_mtx
);
946 int __cfg80211_disconnect(struct cfg80211_registered_device
*rdev
,
947 struct net_device
*dev
, u16 reason
, bool wextev
)
949 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
952 ASSERT_WDEV_LOCK(wdev
);
954 if (wdev
->sme_state
== CFG80211_SME_IDLE
)
957 kfree(wdev
->connect_keys
);
958 wdev
->connect_keys
= NULL
;
960 if (!rdev
->ops
->disconnect
) {
961 if (!rdev
->ops
->deauth
)
964 /* was it connected by userspace SME? */
966 cfg80211_mlme_down(rdev
, dev
);
970 if (wdev
->sme_state
== CFG80211_SME_CONNECTING
&&
971 (wdev
->conn
->state
== CFG80211_CONN_SCANNING
||
972 wdev
->conn
->state
== CFG80211_CONN_SCAN_AGAIN
)) {
973 wdev
->sme_state
= CFG80211_SME_IDLE
;
974 kfree(wdev
->conn
->ie
);
981 /* wdev->conn->params.bssid must be set if > SCANNING */
982 err
= __cfg80211_mlme_deauth(rdev
, dev
,
983 wdev
->conn
->params
.bssid
,
984 NULL
, 0, reason
, false);
988 err
= rdev_disconnect(rdev
, dev
, reason
);
994 if (wdev
->sme_state
== CFG80211_SME_CONNECTED
)
995 __cfg80211_disconnected(dev
, NULL
, 0, 0, false);
996 else if (wdev
->sme_state
== CFG80211_SME_CONNECTING
)
997 __cfg80211_connect_result(dev
, NULL
, NULL
, 0, NULL
, 0,
998 WLAN_STATUS_UNSPECIFIED_FAILURE
,
1004 int cfg80211_disconnect(struct cfg80211_registered_device
*rdev
,
1005 struct net_device
*dev
,
1006 u16 reason
, bool wextev
)
1010 wdev_lock(dev
->ieee80211_ptr
);
1011 err
= __cfg80211_disconnect(rdev
, dev
, reason
, wextev
);
1012 wdev_unlock(dev
->ieee80211_ptr
);
1017 void cfg80211_sme_disassoc(struct net_device
*dev
,
1018 struct cfg80211_internal_bss
*bss
)
1020 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
1021 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
1024 ASSERT_WDEV_LOCK(wdev
);
1029 if (wdev
->conn
->state
== CFG80211_CONN_IDLE
)
1033 * Ok, so the association was made by this SME -- we don't
1034 * want it any more so deauthenticate too.
1037 memcpy(bssid
, bss
->pub
.bssid
, ETH_ALEN
);
1039 __cfg80211_mlme_deauth(rdev
, dev
, bssid
, NULL
, 0,
1040 WLAN_REASON_DEAUTH_LEAVING
, false);