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
);
92 if (wdev
->conn
->params
.channel
) {
95 enum ieee80211_band band
;
98 for (band
= 0; band
< IEEE80211_NUM_BANDS
; band
++) {
99 if (!wdev
->wiphy
->bands
[band
])
101 n_channels
+= wdev
->wiphy
->bands
[band
]->n_channels
;
104 request
= kzalloc(sizeof(*request
) + sizeof(request
->ssids
[0]) +
105 sizeof(request
->channels
[0]) * n_channels
,
110 if (wdev
->conn
->params
.channel
)
111 request
->channels
[0] = wdev
->conn
->params
.channel
;
114 enum ieee80211_band band
;
115 struct ieee80211_supported_band
*bands
;
116 struct ieee80211_channel
*channel
;
118 for (band
= 0; band
< IEEE80211_NUM_BANDS
; band
++) {
119 bands
= wdev
->wiphy
->bands
[band
];
122 for (j
= 0; j
< bands
->n_channels
; j
++) {
123 channel
= &bands
->channels
[j
];
124 if (channel
->flags
& IEEE80211_CHAN_DISABLED
)
126 request
->channels
[i
++] = channel
;
128 request
->rates
[band
] = (1 << bands
->n_bitrates
) - 1;
132 request
->n_channels
= n_channels
;
133 request
->ssids
= (void *)&request
->channels
[n_channels
];
134 request
->n_ssids
= 1;
136 memcpy(request
->ssids
[0].ssid
, wdev
->conn
->params
.ssid
,
137 wdev
->conn
->params
.ssid_len
);
138 request
->ssids
[0].ssid_len
= wdev
->conn
->params
.ssid_len
;
140 request
->wdev
= wdev
;
141 request
->wiphy
= &rdev
->wiphy
;
142 request
->scan_start
= jiffies
;
144 rdev
->scan_req
= request
;
146 err
= rdev_scan(rdev
, request
);
148 wdev
->conn
->state
= CFG80211_CONN_SCANNING
;
149 nl80211_send_scan_start(rdev
, wdev
);
150 dev_hold(wdev
->netdev
);
152 rdev
->scan_req
= NULL
;
158 static int cfg80211_conn_do_work(struct wireless_dev
*wdev
)
160 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
161 struct cfg80211_connect_params
*params
;
162 const u8
*prev_bssid
= NULL
;
165 ASSERT_WDEV_LOCK(wdev
);
170 params
= &wdev
->conn
->params
;
172 switch (wdev
->conn
->state
) {
173 case CFG80211_CONN_SCAN_AGAIN
:
174 return cfg80211_conn_scan(wdev
);
175 case CFG80211_CONN_AUTHENTICATE_NEXT
:
176 BUG_ON(!rdev
->ops
->auth
);
177 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATING
;
178 return __cfg80211_mlme_auth(rdev
, wdev
->netdev
,
179 params
->channel
, params
->auth_type
,
181 params
->ssid
, params
->ssid_len
,
183 params
->key
, params
->key_len
,
184 params
->key_idx
, NULL
, 0);
185 case CFG80211_CONN_ASSOCIATE_NEXT
:
186 BUG_ON(!rdev
->ops
->assoc
);
187 wdev
->conn
->state
= CFG80211_CONN_ASSOCIATING
;
188 if (wdev
->conn
->prev_bssid_valid
)
189 prev_bssid
= wdev
->conn
->prev_bssid
;
190 err
= __cfg80211_mlme_assoc(rdev
, wdev
->netdev
,
191 params
->channel
, params
->bssid
,
193 params
->ssid
, params
->ssid_len
,
194 params
->ie
, params
->ie_len
,
195 params
->mfp
!= NL80211_MFP_NO
,
197 params
->flags
, ¶ms
->ht_capa
,
198 ¶ms
->ht_capa_mask
);
200 __cfg80211_mlme_deauth(rdev
, wdev
->netdev
, params
->bssid
,
202 WLAN_REASON_DEAUTH_LEAVING
,
205 case CFG80211_CONN_DEAUTH_ASSOC_FAIL
:
206 __cfg80211_mlme_deauth(rdev
, wdev
->netdev
, params
->bssid
,
208 WLAN_REASON_DEAUTH_LEAVING
, false);
209 /* return an error so that we call __cfg80211_connect_result() */
216 void cfg80211_conn_work(struct work_struct
*work
)
218 struct cfg80211_registered_device
*rdev
=
219 container_of(work
, struct cfg80211_registered_device
, conn_work
);
220 struct wireless_dev
*wdev
;
221 u8 bssid_buf
[ETH_ALEN
], *bssid
= NULL
;
224 cfg80211_lock_rdev(rdev
);
225 mutex_lock(&rdev
->devlist_mtx
);
227 list_for_each_entry(wdev
, &rdev
->wdev_list
, list
) {
229 if (!netif_running(wdev
->netdev
)) {
233 if (wdev
->sme_state
!= CFG80211_SME_CONNECTING
) {
237 if (wdev
->conn
->params
.bssid
) {
238 memcpy(bssid_buf
, wdev
->conn
->params
.bssid
, ETH_ALEN
);
241 if (cfg80211_conn_do_work(wdev
))
242 __cfg80211_connect_result(
245 WLAN_STATUS_UNSPECIFIED_FAILURE
,
250 mutex_unlock(&rdev
->devlist_mtx
);
251 cfg80211_unlock_rdev(rdev
);
255 static struct cfg80211_bss
*cfg80211_get_conn_bss(struct wireless_dev
*wdev
)
257 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
258 struct cfg80211_bss
*bss
;
259 u16 capa
= WLAN_CAPABILITY_ESS
;
261 ASSERT_WDEV_LOCK(wdev
);
263 if (wdev
->conn
->params
.privacy
)
264 capa
|= WLAN_CAPABILITY_PRIVACY
;
266 bss
= cfg80211_get_bss(wdev
->wiphy
, wdev
->conn
->params
.channel
,
267 wdev
->conn
->params
.bssid
,
268 wdev
->conn
->params
.ssid
,
269 wdev
->conn
->params
.ssid_len
,
270 WLAN_CAPABILITY_ESS
| WLAN_CAPABILITY_PRIVACY
,
275 memcpy(wdev
->conn
->bssid
, bss
->bssid
, ETH_ALEN
);
276 wdev
->conn
->params
.bssid
= wdev
->conn
->bssid
;
277 wdev
->conn
->params
.channel
= bss
->channel
;
278 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATE_NEXT
;
279 schedule_work(&rdev
->conn_work
);
284 static void __cfg80211_sme_scan_done(struct net_device
*dev
)
286 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
287 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
288 struct cfg80211_bss
*bss
;
290 ASSERT_WDEV_LOCK(wdev
);
292 if (wdev
->sme_state
!= CFG80211_SME_CONNECTING
)
298 if (wdev
->conn
->state
!= CFG80211_CONN_SCANNING
&&
299 wdev
->conn
->state
!= CFG80211_CONN_SCAN_AGAIN
)
302 bss
= cfg80211_get_conn_bss(wdev
);
304 cfg80211_put_bss(&rdev
->wiphy
, bss
);
307 if (wdev
->conn
->state
== CFG80211_CONN_SCAN_AGAIN
)
308 schedule_work(&rdev
->conn_work
);
310 __cfg80211_connect_result(
312 wdev
->conn
->params
.bssid
,
314 WLAN_STATUS_UNSPECIFIED_FAILURE
,
319 void cfg80211_sme_scan_done(struct net_device
*dev
)
321 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
323 mutex_lock(&wiphy_to_dev(wdev
->wiphy
)->devlist_mtx
);
325 __cfg80211_sme_scan_done(dev
);
327 mutex_unlock(&wiphy_to_dev(wdev
->wiphy
)->devlist_mtx
);
330 void cfg80211_sme_rx_auth(struct net_device
*dev
,
331 const u8
*buf
, size_t len
)
333 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
334 struct wiphy
*wiphy
= wdev
->wiphy
;
335 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
336 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*)buf
;
337 u16 status_code
= le16_to_cpu(mgmt
->u
.auth
.status_code
);
339 ASSERT_WDEV_LOCK(wdev
);
341 /* should only RX auth frames when connecting */
342 if (wdev
->sme_state
!= CFG80211_SME_CONNECTING
)
345 if (WARN_ON(!wdev
->conn
))
348 if (status_code
== WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
&&
349 wdev
->conn
->auto_auth
&&
350 wdev
->conn
->params
.auth_type
!= NL80211_AUTHTYPE_NETWORK_EAP
) {
351 /* select automatically between only open, shared, leap */
352 switch (wdev
->conn
->params
.auth_type
) {
353 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
354 if (wdev
->connect_keys
)
355 wdev
->conn
->params
.auth_type
=
356 NL80211_AUTHTYPE_SHARED_KEY
;
358 wdev
->conn
->params
.auth_type
=
359 NL80211_AUTHTYPE_NETWORK_EAP
;
361 case NL80211_AUTHTYPE_SHARED_KEY
:
362 wdev
->conn
->params
.auth_type
=
363 NL80211_AUTHTYPE_NETWORK_EAP
;
367 wdev
->conn
->params
.auth_type
=
368 NL80211_AUTHTYPE_OPEN_SYSTEM
;
371 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATE_NEXT
;
372 schedule_work(&rdev
->conn_work
);
373 } else if (status_code
!= WLAN_STATUS_SUCCESS
) {
374 __cfg80211_connect_result(dev
, mgmt
->bssid
, NULL
, 0, NULL
, 0,
375 status_code
, false, NULL
);
376 } else if (wdev
->sme_state
== CFG80211_SME_CONNECTING
&&
377 wdev
->conn
->state
== CFG80211_CONN_AUTHENTICATING
) {
378 wdev
->conn
->state
= CFG80211_CONN_ASSOCIATE_NEXT
;
379 schedule_work(&rdev
->conn_work
);
383 bool cfg80211_sme_failed_reassoc(struct wireless_dev
*wdev
)
385 struct wiphy
*wiphy
= wdev
->wiphy
;
386 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
388 if (WARN_ON(!wdev
->conn
))
391 if (!wdev
->conn
->prev_bssid_valid
)
395 * Some stupid APs don't accept reassoc, so we
396 * need to fall back to trying regular assoc.
398 wdev
->conn
->prev_bssid_valid
= false;
399 wdev
->conn
->state
= CFG80211_CONN_ASSOCIATE_NEXT
;
400 schedule_work(&rdev
->conn_work
);
405 void cfg80211_sme_failed_assoc(struct wireless_dev
*wdev
)
407 struct wiphy
*wiphy
= wdev
->wiphy
;
408 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
410 wdev
->conn
->state
= CFG80211_CONN_DEAUTH_ASSOC_FAIL
;
411 schedule_work(&rdev
->conn_work
);
414 void __cfg80211_connect_result(struct net_device
*dev
, const u8
*bssid
,
415 const u8
*req_ie
, size_t req_ie_len
,
416 const u8
*resp_ie
, size_t resp_ie_len
,
417 u16 status
, bool wextev
,
418 struct cfg80211_bss
*bss
)
420 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
421 const u8
*country_ie
;
422 #ifdef CONFIG_CFG80211_WEXT
423 union iwreq_data wrqu
;
426 ASSERT_WDEV_LOCK(wdev
);
428 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_STATION
&&
429 wdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
))
432 if (wdev
->sme_state
!= CFG80211_SME_CONNECTING
)
435 nl80211_send_connect_result(wiphy_to_dev(wdev
->wiphy
), dev
,
436 bssid
, req_ie
, req_ie_len
,
437 resp_ie
, resp_ie_len
,
440 #ifdef CONFIG_CFG80211_WEXT
442 if (req_ie
&& status
== WLAN_STATUS_SUCCESS
) {
443 memset(&wrqu
, 0, sizeof(wrqu
));
444 wrqu
.data
.length
= req_ie_len
;
445 wireless_send_event(dev
, IWEVASSOCREQIE
, &wrqu
, req_ie
);
448 if (resp_ie
&& status
== WLAN_STATUS_SUCCESS
) {
449 memset(&wrqu
, 0, sizeof(wrqu
));
450 wrqu
.data
.length
= resp_ie_len
;
451 wireless_send_event(dev
, IWEVASSOCRESPIE
, &wrqu
, resp_ie
);
454 memset(&wrqu
, 0, sizeof(wrqu
));
455 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
456 if (bssid
&& status
== WLAN_STATUS_SUCCESS
) {
457 memcpy(wrqu
.ap_addr
.sa_data
, bssid
, ETH_ALEN
);
458 memcpy(wdev
->wext
.prev_bssid
, bssid
, ETH_ALEN
);
459 wdev
->wext
.prev_bssid_valid
= true;
461 wireless_send_event(dev
, SIOCGIWAP
, &wrqu
, NULL
);
465 if (wdev
->current_bss
) {
466 cfg80211_unhold_bss(wdev
->current_bss
);
467 cfg80211_put_bss(wdev
->wiphy
, &wdev
->current_bss
->pub
);
468 wdev
->current_bss
= NULL
;
472 wdev
->conn
->state
= CFG80211_CONN_IDLE
;
474 if (status
!= WLAN_STATUS_SUCCESS
) {
475 wdev
->sme_state
= CFG80211_SME_IDLE
;
477 kfree(wdev
->conn
->ie
);
480 kfree(wdev
->connect_keys
);
481 wdev
->connect_keys
= NULL
;
483 cfg80211_put_bss(wdev
->wiphy
, bss
);
488 bss
= cfg80211_get_bss(wdev
->wiphy
,
489 wdev
->conn
? wdev
->conn
->params
.channel
:
492 wdev
->ssid
, wdev
->ssid_len
,
494 WLAN_CAPABILITY_ESS
);
499 cfg80211_hold_bss(bss_from_pub(bss
));
500 wdev
->current_bss
= bss_from_pub(bss
);
502 wdev
->sme_state
= CFG80211_SME_CONNECTED
;
503 cfg80211_upload_connect_keys(wdev
);
506 country_ie
= ieee80211_bss_get_ie(bss
, WLAN_EID_COUNTRY
);
512 country_ie
= kmemdup(country_ie
, 2 + country_ie
[1], GFP_ATOMIC
);
519 * ieee80211_bss_get_ie() ensures we can access:
520 * - country_ie + 2, the start of the country ie data, and
521 * - and country_ie[1] which is the IE length
523 regulatory_hint_11d(wdev
->wiphy
, bss
->channel
->band
,
524 country_ie
+ 2, country_ie
[1]);
528 void cfg80211_connect_result(struct net_device
*dev
, const u8
*bssid
,
529 const u8
*req_ie
, size_t req_ie_len
,
530 const u8
*resp_ie
, size_t resp_ie_len
,
531 u16 status
, gfp_t gfp
)
533 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
534 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
535 struct cfg80211_event
*ev
;
538 CFG80211_DEV_WARN_ON(wdev
->sme_state
!= CFG80211_SME_CONNECTING
);
540 ev
= kzalloc(sizeof(*ev
) + req_ie_len
+ resp_ie_len
, gfp
);
544 ev
->type
= EVENT_CONNECT_RESULT
;
546 memcpy(ev
->cr
.bssid
, bssid
, ETH_ALEN
);
548 ev
->cr
.req_ie
= ((u8
*)ev
) + sizeof(*ev
);
549 ev
->cr
.req_ie_len
= req_ie_len
;
550 memcpy((void *)ev
->cr
.req_ie
, req_ie
, req_ie_len
);
553 ev
->cr
.resp_ie
= ((u8
*)ev
) + sizeof(*ev
) + req_ie_len
;
554 ev
->cr
.resp_ie_len
= resp_ie_len
;
555 memcpy((void *)ev
->cr
.resp_ie
, resp_ie
, resp_ie_len
);
557 ev
->cr
.status
= status
;
559 spin_lock_irqsave(&wdev
->event_lock
, flags
);
560 list_add_tail(&ev
->list
, &wdev
->event_list
);
561 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
562 queue_work(cfg80211_wq
, &rdev
->event_work
);
564 EXPORT_SYMBOL(cfg80211_connect_result
);
566 void __cfg80211_roamed(struct wireless_dev
*wdev
,
567 struct cfg80211_bss
*bss
,
568 const u8
*req_ie
, size_t req_ie_len
,
569 const u8
*resp_ie
, size_t resp_ie_len
)
571 #ifdef CONFIG_CFG80211_WEXT
572 union iwreq_data wrqu
;
574 ASSERT_WDEV_LOCK(wdev
);
576 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_STATION
&&
577 wdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
))
580 if (wdev
->sme_state
!= CFG80211_SME_CONNECTED
)
583 /* internal error -- how did we get to CONNECTED w/o BSS? */
584 if (WARN_ON(!wdev
->current_bss
)) {
588 cfg80211_unhold_bss(wdev
->current_bss
);
589 cfg80211_put_bss(wdev
->wiphy
, &wdev
->current_bss
->pub
);
590 wdev
->current_bss
= NULL
;
592 cfg80211_hold_bss(bss_from_pub(bss
));
593 wdev
->current_bss
= bss_from_pub(bss
);
595 nl80211_send_roamed(wiphy_to_dev(wdev
->wiphy
), wdev
->netdev
, bss
->bssid
,
596 req_ie
, req_ie_len
, resp_ie
, resp_ie_len
,
599 #ifdef CONFIG_CFG80211_WEXT
601 memset(&wrqu
, 0, sizeof(wrqu
));
602 wrqu
.data
.length
= req_ie_len
;
603 wireless_send_event(wdev
->netdev
, IWEVASSOCREQIE
,
608 memset(&wrqu
, 0, sizeof(wrqu
));
609 wrqu
.data
.length
= resp_ie_len
;
610 wireless_send_event(wdev
->netdev
, IWEVASSOCRESPIE
,
614 memset(&wrqu
, 0, sizeof(wrqu
));
615 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
616 memcpy(wrqu
.ap_addr
.sa_data
, bss
->bssid
, ETH_ALEN
);
617 memcpy(wdev
->wext
.prev_bssid
, bss
->bssid
, ETH_ALEN
);
618 wdev
->wext
.prev_bssid_valid
= true;
619 wireless_send_event(wdev
->netdev
, SIOCGIWAP
, &wrqu
, NULL
);
624 cfg80211_put_bss(wdev
->wiphy
, bss
);
627 void cfg80211_roamed(struct net_device
*dev
,
628 struct ieee80211_channel
*channel
,
630 const u8
*req_ie
, size_t req_ie_len
,
631 const u8
*resp_ie
, size_t resp_ie_len
, gfp_t gfp
)
633 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
634 struct cfg80211_bss
*bss
;
636 CFG80211_DEV_WARN_ON(wdev
->sme_state
!= CFG80211_SME_CONNECTED
);
638 bss
= cfg80211_get_bss(wdev
->wiphy
, channel
, bssid
, wdev
->ssid
,
639 wdev
->ssid_len
, WLAN_CAPABILITY_ESS
,
640 WLAN_CAPABILITY_ESS
);
644 cfg80211_roamed_bss(dev
, bss
, req_ie
, req_ie_len
, resp_ie
,
647 EXPORT_SYMBOL(cfg80211_roamed
);
649 void cfg80211_roamed_bss(struct net_device
*dev
,
650 struct cfg80211_bss
*bss
, const u8
*req_ie
,
651 size_t req_ie_len
, const u8
*resp_ie
,
652 size_t resp_ie_len
, gfp_t gfp
)
654 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
655 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
656 struct cfg80211_event
*ev
;
659 CFG80211_DEV_WARN_ON(wdev
->sme_state
!= CFG80211_SME_CONNECTED
);
664 ev
= kzalloc(sizeof(*ev
) + req_ie_len
+ resp_ie_len
, gfp
);
666 cfg80211_put_bss(wdev
->wiphy
, bss
);
670 ev
->type
= EVENT_ROAMED
;
671 ev
->rm
.req_ie
= ((u8
*)ev
) + sizeof(*ev
);
672 ev
->rm
.req_ie_len
= req_ie_len
;
673 memcpy((void *)ev
->rm
.req_ie
, req_ie
, req_ie_len
);
674 ev
->rm
.resp_ie
= ((u8
*)ev
) + sizeof(*ev
) + req_ie_len
;
675 ev
->rm
.resp_ie_len
= resp_ie_len
;
676 memcpy((void *)ev
->rm
.resp_ie
, resp_ie
, resp_ie_len
);
679 spin_lock_irqsave(&wdev
->event_lock
, flags
);
680 list_add_tail(&ev
->list
, &wdev
->event_list
);
681 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
682 queue_work(cfg80211_wq
, &rdev
->event_work
);
684 EXPORT_SYMBOL(cfg80211_roamed_bss
);
686 void __cfg80211_disconnected(struct net_device
*dev
, const u8
*ie
,
687 size_t ie_len
, u16 reason
, bool from_ap
)
689 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
690 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
692 #ifdef CONFIG_CFG80211_WEXT
693 union iwreq_data wrqu
;
696 ASSERT_WDEV_LOCK(wdev
);
698 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_STATION
&&
699 wdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
))
702 if (wdev
->sme_state
!= CFG80211_SME_CONNECTED
)
705 if (wdev
->current_bss
) {
706 cfg80211_unhold_bss(wdev
->current_bss
);
707 cfg80211_put_bss(wdev
->wiphy
, &wdev
->current_bss
->pub
);
710 wdev
->current_bss
= NULL
;
711 wdev
->sme_state
= CFG80211_SME_IDLE
;
715 kfree(wdev
->conn
->ie
);
716 wdev
->conn
->ie
= NULL
;
721 nl80211_send_disconnected(rdev
, dev
, reason
, ie
, ie_len
, from_ap
);
724 * Delete all the keys ... pairwise keys can't really
725 * exist any more anyway, but default keys might.
727 if (rdev
->ops
->del_key
)
728 for (i
= 0; i
< 6; i
++)
729 rdev_del_key(rdev
, dev
, i
, false, NULL
);
731 #ifdef CONFIG_CFG80211_WEXT
732 memset(&wrqu
, 0, sizeof(wrqu
));
733 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
734 wireless_send_event(dev
, SIOCGIWAP
, &wrqu
, NULL
);
735 wdev
->wext
.connect
.ssid_len
= 0;
738 schedule_work(&cfg80211_disconnect_work
);
741 void cfg80211_disconnected(struct net_device
*dev
, u16 reason
,
742 u8
*ie
, size_t ie_len
, gfp_t gfp
)
744 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
745 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
746 struct cfg80211_event
*ev
;
749 CFG80211_DEV_WARN_ON(wdev
->sme_state
!= CFG80211_SME_CONNECTED
);
751 ev
= kzalloc(sizeof(*ev
) + ie_len
, gfp
);
755 ev
->type
= EVENT_DISCONNECTED
;
756 ev
->dc
.ie
= ((u8
*)ev
) + sizeof(*ev
);
757 ev
->dc
.ie_len
= ie_len
;
758 memcpy((void *)ev
->dc
.ie
, ie
, ie_len
);
759 ev
->dc
.reason
= reason
;
761 spin_lock_irqsave(&wdev
->event_lock
, flags
);
762 list_add_tail(&ev
->list
, &wdev
->event_list
);
763 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
764 queue_work(cfg80211_wq
, &rdev
->event_work
);
766 EXPORT_SYMBOL(cfg80211_disconnected
);
768 int __cfg80211_connect(struct cfg80211_registered_device
*rdev
,
769 struct net_device
*dev
,
770 struct cfg80211_connect_params
*connect
,
771 struct cfg80211_cached_keys
*connkeys
,
772 const u8
*prev_bssid
)
774 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
775 struct cfg80211_bss
*bss
= NULL
;
778 ASSERT_WDEV_LOCK(wdev
);
780 if (wdev
->sme_state
!= CFG80211_SME_IDLE
)
783 if (WARN_ON(wdev
->connect_keys
)) {
784 kfree(wdev
->connect_keys
);
785 wdev
->connect_keys
= NULL
;
788 cfg80211_oper_and_ht_capa(&connect
->ht_capa_mask
,
789 rdev
->wiphy
.ht_capa_mod_mask
);
791 if (connkeys
&& connkeys
->def
>= 0) {
796 cipher
= connkeys
->params
[idx
].cipher
;
797 /* If given a WEP key we may need it for shared key auth */
798 if (cipher
== WLAN_CIPHER_SUITE_WEP40
||
799 cipher
== WLAN_CIPHER_SUITE_WEP104
) {
800 connect
->key_idx
= idx
;
801 connect
->key
= connkeys
->params
[idx
].key
;
802 connect
->key_len
= connkeys
->params
[idx
].key_len
;
805 * If ciphers are not set (e.g. when going through
806 * iwconfig), we have to set them appropriately here.
808 if (connect
->crypto
.cipher_group
== 0)
809 connect
->crypto
.cipher_group
= cipher
;
811 if (connect
->crypto
.n_ciphers_pairwise
== 0) {
812 connect
->crypto
.n_ciphers_pairwise
= 1;
813 connect
->crypto
.ciphers_pairwise
[0] = cipher
;
818 if (!rdev
->ops
->connect
) {
819 if (!rdev
->ops
->auth
|| !rdev
->ops
->assoc
)
822 if (WARN_ON(wdev
->conn
))
825 wdev
->conn
= kzalloc(sizeof(*wdev
->conn
), GFP_KERNEL
);
830 * Copy all parameters, and treat explicitly IEs, BSSID, SSID.
832 memcpy(&wdev
->conn
->params
, connect
, sizeof(*connect
));
833 if (connect
->bssid
) {
834 wdev
->conn
->params
.bssid
= wdev
->conn
->bssid
;
835 memcpy(wdev
->conn
->bssid
, connect
->bssid
, ETH_ALEN
);
839 wdev
->conn
->ie
= kmemdup(connect
->ie
, connect
->ie_len
,
841 wdev
->conn
->params
.ie
= wdev
->conn
->ie
;
842 if (!wdev
->conn
->ie
) {
849 if (connect
->auth_type
== NL80211_AUTHTYPE_AUTOMATIC
) {
850 wdev
->conn
->auto_auth
= true;
851 /* start with open system ... should mostly work */
852 wdev
->conn
->params
.auth_type
=
853 NL80211_AUTHTYPE_OPEN_SYSTEM
;
855 wdev
->conn
->auto_auth
= false;
858 memcpy(wdev
->ssid
, connect
->ssid
, connect
->ssid_len
);
859 wdev
->ssid_len
= connect
->ssid_len
;
860 wdev
->conn
->params
.ssid
= wdev
->ssid
;
861 wdev
->conn
->params
.ssid_len
= connect
->ssid_len
;
863 /* see if we have the bss already */
864 bss
= cfg80211_get_conn_bss(wdev
);
866 wdev
->sme_state
= CFG80211_SME_CONNECTING
;
867 wdev
->connect_keys
= connkeys
;
870 memcpy(wdev
->conn
->prev_bssid
, prev_bssid
, ETH_ALEN
);
871 wdev
->conn
->prev_bssid_valid
= true;
874 /* we're good if we have a matching bss struct */
876 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATE_NEXT
;
877 err
= cfg80211_conn_do_work(wdev
);
878 cfg80211_put_bss(wdev
->wiphy
, bss
);
880 /* otherwise we'll need to scan for the AP first */
881 err
= cfg80211_conn_scan(wdev
);
883 * If we can't scan right now, then we need to scan again
884 * after the current scan finished, since the parameters
885 * changed (unless we find a good AP anyway).
889 wdev
->conn
->state
= CFG80211_CONN_SCAN_AGAIN
;
893 kfree(wdev
->conn
->ie
);
896 wdev
->sme_state
= CFG80211_SME_IDLE
;
897 wdev
->connect_keys
= NULL
;
903 wdev
->sme_state
= CFG80211_SME_CONNECTING
;
904 wdev
->connect_keys
= connkeys
;
905 err
= rdev_connect(rdev
, dev
, connect
);
907 wdev
->connect_keys
= NULL
;
908 wdev
->sme_state
= CFG80211_SME_IDLE
;
912 memcpy(wdev
->ssid
, connect
->ssid
, connect
->ssid_len
);
913 wdev
->ssid_len
= connect
->ssid_len
;
919 int cfg80211_connect(struct cfg80211_registered_device
*rdev
,
920 struct net_device
*dev
,
921 struct cfg80211_connect_params
*connect
,
922 struct cfg80211_cached_keys
*connkeys
)
926 mutex_lock(&rdev
->devlist_mtx
);
927 wdev_lock(dev
->ieee80211_ptr
);
928 err
= __cfg80211_connect(rdev
, dev
, connect
, connkeys
, NULL
);
929 wdev_unlock(dev
->ieee80211_ptr
);
930 mutex_unlock(&rdev
->devlist_mtx
);
935 int __cfg80211_disconnect(struct cfg80211_registered_device
*rdev
,
936 struct net_device
*dev
, u16 reason
, bool wextev
)
938 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
941 ASSERT_WDEV_LOCK(wdev
);
943 if (wdev
->sme_state
== CFG80211_SME_IDLE
)
946 kfree(wdev
->connect_keys
);
947 wdev
->connect_keys
= NULL
;
949 if (!rdev
->ops
->disconnect
) {
950 if (!rdev
->ops
->deauth
)
953 /* was it connected by userspace SME? */
955 cfg80211_mlme_down(rdev
, dev
);
959 if (wdev
->sme_state
== CFG80211_SME_CONNECTING
&&
960 (wdev
->conn
->state
== CFG80211_CONN_SCANNING
||
961 wdev
->conn
->state
== CFG80211_CONN_SCAN_AGAIN
)) {
962 wdev
->sme_state
= CFG80211_SME_IDLE
;
963 kfree(wdev
->conn
->ie
);
970 /* wdev->conn->params.bssid must be set if > SCANNING */
971 err
= __cfg80211_mlme_deauth(rdev
, dev
,
972 wdev
->conn
->params
.bssid
,
973 NULL
, 0, reason
, false);
977 err
= rdev_disconnect(rdev
, dev
, reason
);
982 if (wdev
->sme_state
== CFG80211_SME_CONNECTED
)
983 __cfg80211_disconnected(dev
, NULL
, 0, 0, false);
984 else if (wdev
->sme_state
== CFG80211_SME_CONNECTING
)
985 __cfg80211_connect_result(dev
, NULL
, NULL
, 0, NULL
, 0,
986 WLAN_STATUS_UNSPECIFIED_FAILURE
,
992 int cfg80211_disconnect(struct cfg80211_registered_device
*rdev
,
993 struct net_device
*dev
,
994 u16 reason
, bool wextev
)
998 wdev_lock(dev
->ieee80211_ptr
);
999 err
= __cfg80211_disconnect(rdev
, dev
, reason
, wextev
);
1000 wdev_unlock(dev
->ieee80211_ptr
);
1005 void cfg80211_sme_disassoc(struct net_device
*dev
,
1006 struct cfg80211_internal_bss
*bss
)
1008 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
1009 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
1012 ASSERT_WDEV_LOCK(wdev
);
1017 if (wdev
->conn
->state
== CFG80211_CONN_IDLE
)
1021 * Ok, so the association was made by this SME -- we don't
1022 * want it any more so deauthenticate too.
1025 memcpy(bssid
, bss
->pub
.bssid
, ETH_ALEN
);
1027 __cfg80211_mlme_deauth(rdev
, dev
, bssid
, NULL
, 0,
1028 WLAN_REASON_DEAUTH_LEAVING
, false);