2 * SME code for cfg80211
3 * both driver SME event handling and the SME implementation
4 * (for nl80211's connect() and wext)
6 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
7 * Copyright (C) 2009 Intel Corporation. All rights reserved.
10 #include <linux/etherdevice.h>
11 #include <linux/if_arp.h>
12 #include <linux/slab.h>
13 #include <linux/workqueue.h>
14 #include <linux/wireless.h>
15 #include <linux/export.h>
16 #include <net/iw_handler.h>
17 #include <net/cfg80211.h>
18 #include <net/rtnetlink.h>
24 * Software SME in cfg80211, using auth/assoc/deauth calls to the
25 * driver. This is is for implementing nl80211's connect/disconnect
26 * and wireless extensions (if configured.)
29 struct cfg80211_conn
{
30 struct cfg80211_connect_params params
;
31 /* these are sub-states of the _CONNECTING sme_state */
33 CFG80211_CONN_SCANNING
,
34 CFG80211_CONN_SCAN_AGAIN
,
35 CFG80211_CONN_AUTHENTICATE_NEXT
,
36 CFG80211_CONN_AUTHENTICATING
,
37 CFG80211_CONN_AUTH_FAILED
,
38 CFG80211_CONN_ASSOCIATE_NEXT
,
39 CFG80211_CONN_ASSOCIATING
,
40 CFG80211_CONN_ASSOC_FAILED
,
42 CFG80211_CONN_CONNECTED
,
44 u8 bssid
[ETH_ALEN
], prev_bssid
[ETH_ALEN
];
47 bool auto_auth
, prev_bssid_valid
;
50 static void cfg80211_sme_free(struct wireless_dev
*wdev
)
55 kfree(wdev
->conn
->ie
);
60 static int cfg80211_conn_scan(struct wireless_dev
*wdev
)
62 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
63 struct cfg80211_scan_request
*request
;
67 ASSERT_WDEV_LOCK(wdev
);
69 if (rdev
->scan_req
|| rdev
->scan_msg
)
72 if (wdev
->conn
->params
.channel
)
75 n_channels
= ieee80211_get_num_supported_channels(wdev
->wiphy
);
77 request
= kzalloc(sizeof(*request
) + sizeof(request
->ssids
[0]) +
78 sizeof(request
->channels
[0]) * n_channels
,
83 if (wdev
->conn
->params
.channel
)
84 request
->channels
[0] = wdev
->conn
->params
.channel
;
87 enum ieee80211_band band
;
88 struct ieee80211_supported_band
*bands
;
89 struct ieee80211_channel
*channel
;
91 for (band
= 0; band
< IEEE80211_NUM_BANDS
; band
++) {
92 bands
= wdev
->wiphy
->bands
[band
];
95 for (j
= 0; j
< bands
->n_channels
; j
++) {
96 channel
= &bands
->channels
[j
];
97 if (channel
->flags
& IEEE80211_CHAN_DISABLED
)
99 request
->channels
[i
++] = channel
;
101 request
->rates
[band
] = (1 << bands
->n_bitrates
) - 1;
105 request
->n_channels
= n_channels
;
106 request
->ssids
= (void *)&request
->channels
[n_channels
];
107 request
->n_ssids
= 1;
109 memcpy(request
->ssids
[0].ssid
, wdev
->conn
->params
.ssid
,
110 wdev
->conn
->params
.ssid_len
);
111 request
->ssids
[0].ssid_len
= wdev
->conn
->params
.ssid_len
;
113 request
->wdev
= wdev
;
114 request
->wiphy
= &rdev
->wiphy
;
115 request
->scan_start
= jiffies
;
117 rdev
->scan_req
= request
;
119 err
= rdev_scan(rdev
, request
);
121 wdev
->conn
->state
= CFG80211_CONN_SCANNING
;
122 nl80211_send_scan_start(rdev
, wdev
);
123 dev_hold(wdev
->netdev
);
125 rdev
->scan_req
= NULL
;
131 static int cfg80211_conn_do_work(struct wireless_dev
*wdev
)
133 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
134 struct cfg80211_connect_params
*params
;
135 struct cfg80211_assoc_request req
= {};
138 ASSERT_WDEV_LOCK(wdev
);
143 params
= &wdev
->conn
->params
;
145 switch (wdev
->conn
->state
) {
146 case CFG80211_CONN_SCANNING
:
147 /* didn't find it during scan ... */
149 case CFG80211_CONN_SCAN_AGAIN
:
150 return cfg80211_conn_scan(wdev
);
151 case CFG80211_CONN_AUTHENTICATE_NEXT
:
152 BUG_ON(!rdev
->ops
->auth
);
153 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATING
;
154 return cfg80211_mlme_auth(rdev
, wdev
->netdev
,
155 params
->channel
, params
->auth_type
,
157 params
->ssid
, params
->ssid_len
,
159 params
->key
, params
->key_len
,
160 params
->key_idx
, NULL
, 0);
161 case CFG80211_CONN_AUTH_FAILED
:
163 case CFG80211_CONN_ASSOCIATE_NEXT
:
164 BUG_ON(!rdev
->ops
->assoc
);
165 wdev
->conn
->state
= CFG80211_CONN_ASSOCIATING
;
166 if (wdev
->conn
->prev_bssid_valid
)
167 req
.prev_bssid
= wdev
->conn
->prev_bssid
;
169 req
.ie_len
= params
->ie_len
;
170 req
.use_mfp
= params
->mfp
!= NL80211_MFP_NO
;
171 req
.crypto
= params
->crypto
;
172 req
.flags
= params
->flags
;
173 req
.ht_capa
= params
->ht_capa
;
174 req
.ht_capa_mask
= params
->ht_capa_mask
;
175 req
.vht_capa
= params
->vht_capa
;
176 req
.vht_capa_mask
= params
->vht_capa_mask
;
178 err
= cfg80211_mlme_assoc(rdev
, wdev
->netdev
, params
->channel
,
179 params
->bssid
, params
->ssid
,
180 params
->ssid_len
, &req
);
182 cfg80211_mlme_deauth(rdev
, wdev
->netdev
, params
->bssid
,
184 WLAN_REASON_DEAUTH_LEAVING
,
187 case CFG80211_CONN_ASSOC_FAILED
:
188 cfg80211_mlme_deauth(rdev
, wdev
->netdev
, params
->bssid
,
190 WLAN_REASON_DEAUTH_LEAVING
, false);
192 case CFG80211_CONN_DEAUTH
:
193 cfg80211_mlme_deauth(rdev
, wdev
->netdev
, params
->bssid
,
195 WLAN_REASON_DEAUTH_LEAVING
, false);
196 /* free directly, disconnected event already sent */
197 cfg80211_sme_free(wdev
);
204 void cfg80211_conn_work(struct work_struct
*work
)
206 struct cfg80211_registered_device
*rdev
=
207 container_of(work
, struct cfg80211_registered_device
, conn_work
);
208 struct wireless_dev
*wdev
;
209 u8 bssid_buf
[ETH_ALEN
], *bssid
= NULL
;
213 list_for_each_entry(wdev
, &rdev
->wdev_list
, list
) {
218 if (!netif_running(wdev
->netdev
)) {
223 wdev
->conn
->state
== CFG80211_CONN_CONNECTED
) {
227 if (wdev
->conn
->params
.bssid
) {
228 memcpy(bssid_buf
, wdev
->conn
->params
.bssid
, ETH_ALEN
);
231 if (cfg80211_conn_do_work(wdev
)) {
232 __cfg80211_connect_result(
235 WLAN_STATUS_UNSPECIFIED_FAILURE
,
244 /* Returned bss is reference counted and must be cleaned up appropriately. */
245 static struct cfg80211_bss
*cfg80211_get_conn_bss(struct wireless_dev
*wdev
)
247 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
248 struct cfg80211_bss
*bss
;
249 u16 capa
= WLAN_CAPABILITY_ESS
;
251 ASSERT_WDEV_LOCK(wdev
);
253 if (wdev
->conn
->params
.privacy
)
254 capa
|= WLAN_CAPABILITY_PRIVACY
;
256 bss
= cfg80211_get_bss(wdev
->wiphy
, wdev
->conn
->params
.channel
,
257 wdev
->conn
->params
.bssid
,
258 wdev
->conn
->params
.ssid
,
259 wdev
->conn
->params
.ssid_len
,
260 WLAN_CAPABILITY_ESS
| WLAN_CAPABILITY_PRIVACY
,
265 memcpy(wdev
->conn
->bssid
, bss
->bssid
, ETH_ALEN
);
266 wdev
->conn
->params
.bssid
= wdev
->conn
->bssid
;
267 wdev
->conn
->params
.channel
= bss
->channel
;
268 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATE_NEXT
;
269 schedule_work(&rdev
->conn_work
);
274 static void __cfg80211_sme_scan_done(struct net_device
*dev
)
276 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
277 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
278 struct cfg80211_bss
*bss
;
280 ASSERT_WDEV_LOCK(wdev
);
285 if (wdev
->conn
->state
!= CFG80211_CONN_SCANNING
&&
286 wdev
->conn
->state
!= CFG80211_CONN_SCAN_AGAIN
)
289 bss
= cfg80211_get_conn_bss(wdev
);
291 cfg80211_put_bss(&rdev
->wiphy
, bss
);
293 schedule_work(&rdev
->conn_work
);
296 void cfg80211_sme_scan_done(struct net_device
*dev
)
298 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
301 __cfg80211_sme_scan_done(dev
);
305 void cfg80211_sme_rx_auth(struct wireless_dev
*wdev
, const u8
*buf
, size_t len
)
307 struct wiphy
*wiphy
= wdev
->wiphy
;
308 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
309 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*)buf
;
310 u16 status_code
= le16_to_cpu(mgmt
->u
.auth
.status_code
);
312 ASSERT_WDEV_LOCK(wdev
);
314 if (!wdev
->conn
|| wdev
->conn
->state
== CFG80211_CONN_CONNECTED
)
317 if (status_code
== WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
&&
318 wdev
->conn
->auto_auth
&&
319 wdev
->conn
->params
.auth_type
!= NL80211_AUTHTYPE_NETWORK_EAP
) {
320 /* select automatically between only open, shared, leap */
321 switch (wdev
->conn
->params
.auth_type
) {
322 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
323 if (wdev
->connect_keys
)
324 wdev
->conn
->params
.auth_type
=
325 NL80211_AUTHTYPE_SHARED_KEY
;
327 wdev
->conn
->params
.auth_type
=
328 NL80211_AUTHTYPE_NETWORK_EAP
;
330 case NL80211_AUTHTYPE_SHARED_KEY
:
331 wdev
->conn
->params
.auth_type
=
332 NL80211_AUTHTYPE_NETWORK_EAP
;
336 wdev
->conn
->params
.auth_type
=
337 NL80211_AUTHTYPE_OPEN_SYSTEM
;
340 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATE_NEXT
;
341 schedule_work(&rdev
->conn_work
);
342 } else if (status_code
!= WLAN_STATUS_SUCCESS
) {
343 __cfg80211_connect_result(wdev
->netdev
, mgmt
->bssid
,
345 status_code
, false, NULL
);
346 } else if (wdev
->conn
->state
== CFG80211_CONN_AUTHENTICATING
) {
347 wdev
->conn
->state
= CFG80211_CONN_ASSOCIATE_NEXT
;
348 schedule_work(&rdev
->conn_work
);
352 bool cfg80211_sme_rx_assoc_resp(struct wireless_dev
*wdev
, u16 status
)
354 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
359 if (status
== WLAN_STATUS_SUCCESS
) {
360 wdev
->conn
->state
= CFG80211_CONN_CONNECTED
;
364 if (wdev
->conn
->prev_bssid_valid
) {
366 * Some stupid APs don't accept reassoc, so we
367 * need to fall back to trying regular assoc;
368 * return true so no event is sent to userspace.
370 wdev
->conn
->prev_bssid_valid
= false;
371 wdev
->conn
->state
= CFG80211_CONN_ASSOCIATE_NEXT
;
372 schedule_work(&rdev
->conn_work
);
376 wdev
->conn
->state
= CFG80211_CONN_ASSOC_FAILED
;
377 schedule_work(&rdev
->conn_work
);
381 void cfg80211_sme_deauth(struct wireless_dev
*wdev
)
383 cfg80211_sme_free(wdev
);
386 void cfg80211_sme_auth_timeout(struct wireless_dev
*wdev
)
388 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
393 wdev
->conn
->state
= CFG80211_CONN_AUTH_FAILED
;
394 schedule_work(&rdev
->conn_work
);
397 void cfg80211_sme_disassoc(struct wireless_dev
*wdev
)
399 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
404 wdev
->conn
->state
= CFG80211_CONN_DEAUTH
;
405 schedule_work(&rdev
->conn_work
);
408 void cfg80211_sme_assoc_timeout(struct wireless_dev
*wdev
)
410 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
415 wdev
->conn
->state
= CFG80211_CONN_ASSOC_FAILED
;
416 schedule_work(&rdev
->conn_work
);
419 static int cfg80211_sme_connect(struct wireless_dev
*wdev
,
420 struct cfg80211_connect_params
*connect
,
421 const u8
*prev_bssid
)
423 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
424 struct cfg80211_bss
*bss
;
427 if (!rdev
->ops
->auth
|| !rdev
->ops
->assoc
)
430 if (wdev
->current_bss
)
433 if (WARN_ON(wdev
->conn
))
436 wdev
->conn
= kzalloc(sizeof(*wdev
->conn
), GFP_KERNEL
);
441 * Copy all parameters, and treat explicitly IEs, BSSID, SSID.
443 memcpy(&wdev
->conn
->params
, connect
, sizeof(*connect
));
444 if (connect
->bssid
) {
445 wdev
->conn
->params
.bssid
= wdev
->conn
->bssid
;
446 memcpy(wdev
->conn
->bssid
, connect
->bssid
, ETH_ALEN
);
450 wdev
->conn
->ie
= kmemdup(connect
->ie
, connect
->ie_len
,
452 wdev
->conn
->params
.ie
= wdev
->conn
->ie
;
453 if (!wdev
->conn
->ie
) {
460 if (connect
->auth_type
== NL80211_AUTHTYPE_AUTOMATIC
) {
461 wdev
->conn
->auto_auth
= true;
462 /* start with open system ... should mostly work */
463 wdev
->conn
->params
.auth_type
=
464 NL80211_AUTHTYPE_OPEN_SYSTEM
;
466 wdev
->conn
->auto_auth
= false;
469 wdev
->conn
->params
.ssid
= wdev
->ssid
;
470 wdev
->conn
->params
.ssid_len
= connect
->ssid_len
;
472 /* see if we have the bss already */
473 bss
= cfg80211_get_conn_bss(wdev
);
476 memcpy(wdev
->conn
->prev_bssid
, prev_bssid
, ETH_ALEN
);
477 wdev
->conn
->prev_bssid_valid
= true;
480 /* we're good if we have a matching bss struct */
482 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATE_NEXT
;
483 err
= cfg80211_conn_do_work(wdev
);
484 cfg80211_put_bss(wdev
->wiphy
, bss
);
486 /* otherwise we'll need to scan for the AP first */
487 err
= cfg80211_conn_scan(wdev
);
490 * If we can't scan right now, then we need to scan again
491 * after the current scan finished, since the parameters
492 * changed (unless we find a good AP anyway).
496 wdev
->conn
->state
= CFG80211_CONN_SCAN_AGAIN
;
501 cfg80211_sme_free(wdev
);
506 static int cfg80211_sme_disconnect(struct wireless_dev
*wdev
, u16 reason
)
508 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
514 if (!rdev
->ops
->deauth
)
517 if (wdev
->conn
->state
== CFG80211_CONN_SCANNING
||
518 wdev
->conn
->state
== CFG80211_CONN_SCAN_AGAIN
) {
523 /* wdev->conn->params.bssid must be set if > SCANNING */
524 err
= cfg80211_mlme_deauth(rdev
, wdev
->netdev
,
525 wdev
->conn
->params
.bssid
,
526 NULL
, 0, reason
, false);
528 cfg80211_sme_free(wdev
);
533 * code shared for in-device and software SME
536 static bool cfg80211_is_all_idle(void)
538 struct cfg80211_registered_device
*rdev
;
539 struct wireless_dev
*wdev
;
540 bool is_all_idle
= true;
543 * All devices must be idle as otherwise if you are actively
544 * scanning some new beacon hints could be learned and would
545 * count as new regulatory hints.
547 list_for_each_entry(rdev
, &cfg80211_rdev_list
, list
) {
548 list_for_each_entry(wdev
, &rdev
->wdev_list
, list
) {
550 if (wdev
->conn
|| wdev
->current_bss
)
559 static void disconnect_work(struct work_struct
*work
)
562 if (cfg80211_is_all_idle())
563 regulatory_hint_disconnect();
567 static DECLARE_WORK(cfg80211_disconnect_work
, disconnect_work
);
571 * API calls for drivers implementing connect/disconnect and
575 /* This method must consume bss one way or another */
576 void __cfg80211_connect_result(struct net_device
*dev
, const u8
*bssid
,
577 const u8
*req_ie
, size_t req_ie_len
,
578 const u8
*resp_ie
, size_t resp_ie_len
,
579 u16 status
, bool wextev
,
580 struct cfg80211_bss
*bss
)
582 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
583 const u8
*country_ie
;
584 #ifdef CONFIG_CFG80211_WEXT
585 union iwreq_data wrqu
;
588 ASSERT_WDEV_LOCK(wdev
);
590 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_STATION
&&
591 wdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
)) {
592 cfg80211_put_bss(wdev
->wiphy
, bss
);
596 nl80211_send_connect_result(wiphy_to_dev(wdev
->wiphy
), dev
,
597 bssid
, req_ie
, req_ie_len
,
598 resp_ie
, resp_ie_len
,
601 #ifdef CONFIG_CFG80211_WEXT
603 if (req_ie
&& status
== WLAN_STATUS_SUCCESS
) {
604 memset(&wrqu
, 0, sizeof(wrqu
));
605 wrqu
.data
.length
= req_ie_len
;
606 wireless_send_event(dev
, IWEVASSOCREQIE
, &wrqu
, req_ie
);
609 if (resp_ie
&& status
== WLAN_STATUS_SUCCESS
) {
610 memset(&wrqu
, 0, sizeof(wrqu
));
611 wrqu
.data
.length
= resp_ie_len
;
612 wireless_send_event(dev
, IWEVASSOCRESPIE
, &wrqu
, resp_ie
);
615 memset(&wrqu
, 0, sizeof(wrqu
));
616 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
617 if (bssid
&& status
== WLAN_STATUS_SUCCESS
) {
618 memcpy(wrqu
.ap_addr
.sa_data
, bssid
, ETH_ALEN
);
619 memcpy(wdev
->wext
.prev_bssid
, bssid
, ETH_ALEN
);
620 wdev
->wext
.prev_bssid_valid
= true;
622 wireless_send_event(dev
, SIOCGIWAP
, &wrqu
, NULL
);
626 if (!bss
&& (status
== WLAN_STATUS_SUCCESS
)) {
627 WARN_ON_ONCE(!wiphy_to_dev(wdev
->wiphy
)->ops
->connect
);
628 bss
= cfg80211_get_bss(wdev
->wiphy
, NULL
, bssid
,
629 wdev
->ssid
, wdev
->ssid_len
,
631 WLAN_CAPABILITY_ESS
);
633 cfg80211_hold_bss(bss_from_pub(bss
));
636 if (wdev
->current_bss
) {
637 cfg80211_unhold_bss(wdev
->current_bss
);
638 cfg80211_put_bss(wdev
->wiphy
, &wdev
->current_bss
->pub
);
639 wdev
->current_bss
= NULL
;
642 if (status
!= WLAN_STATUS_SUCCESS
) {
643 kfree(wdev
->connect_keys
);
644 wdev
->connect_keys
= NULL
;
647 cfg80211_unhold_bss(bss_from_pub(bss
));
648 cfg80211_put_bss(wdev
->wiphy
, bss
);
650 cfg80211_sme_free(wdev
);
657 wdev
->current_bss
= bss_from_pub(bss
);
659 cfg80211_upload_connect_keys(wdev
);
662 country_ie
= ieee80211_bss_get_ie(bss
, WLAN_EID_COUNTRY
);
668 country_ie
= kmemdup(country_ie
, 2 + country_ie
[1], GFP_ATOMIC
);
675 * ieee80211_bss_get_ie() ensures we can access:
676 * - country_ie + 2, the start of the country ie data, and
677 * - and country_ie[1] which is the IE length
679 regulatory_hint_country_ie(wdev
->wiphy
, bss
->channel
->band
,
680 country_ie
+ 2, country_ie
[1]);
684 void cfg80211_connect_result(struct net_device
*dev
, const u8
*bssid
,
685 const u8
*req_ie
, size_t req_ie_len
,
686 const u8
*resp_ie
, size_t resp_ie_len
,
687 u16 status
, gfp_t gfp
)
689 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
690 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
691 struct cfg80211_event
*ev
;
694 ev
= kzalloc(sizeof(*ev
) + req_ie_len
+ resp_ie_len
, gfp
);
698 ev
->type
= EVENT_CONNECT_RESULT
;
700 memcpy(ev
->cr
.bssid
, bssid
, ETH_ALEN
);
702 ev
->cr
.req_ie
= ((u8
*)ev
) + sizeof(*ev
);
703 ev
->cr
.req_ie_len
= req_ie_len
;
704 memcpy((void *)ev
->cr
.req_ie
, req_ie
, req_ie_len
);
707 ev
->cr
.resp_ie
= ((u8
*)ev
) + sizeof(*ev
) + req_ie_len
;
708 ev
->cr
.resp_ie_len
= resp_ie_len
;
709 memcpy((void *)ev
->cr
.resp_ie
, resp_ie
, resp_ie_len
);
711 ev
->cr
.status
= status
;
713 spin_lock_irqsave(&wdev
->event_lock
, flags
);
714 list_add_tail(&ev
->list
, &wdev
->event_list
);
715 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
716 queue_work(cfg80211_wq
, &rdev
->event_work
);
718 EXPORT_SYMBOL(cfg80211_connect_result
);
720 /* Consumes bss object one way or another */
721 void __cfg80211_roamed(struct wireless_dev
*wdev
,
722 struct cfg80211_bss
*bss
,
723 const u8
*req_ie
, size_t req_ie_len
,
724 const u8
*resp_ie
, size_t resp_ie_len
)
726 #ifdef CONFIG_CFG80211_WEXT
727 union iwreq_data wrqu
;
729 ASSERT_WDEV_LOCK(wdev
);
731 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_STATION
&&
732 wdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
))
735 if (WARN_ON(!wdev
->current_bss
))
738 cfg80211_unhold_bss(wdev
->current_bss
);
739 cfg80211_put_bss(wdev
->wiphy
, &wdev
->current_bss
->pub
);
740 wdev
->current_bss
= NULL
;
742 cfg80211_hold_bss(bss_from_pub(bss
));
743 wdev
->current_bss
= bss_from_pub(bss
);
745 nl80211_send_roamed(wiphy_to_dev(wdev
->wiphy
), wdev
->netdev
, bss
->bssid
,
746 req_ie
, req_ie_len
, resp_ie
, resp_ie_len
,
749 #ifdef CONFIG_CFG80211_WEXT
751 memset(&wrqu
, 0, sizeof(wrqu
));
752 wrqu
.data
.length
= req_ie_len
;
753 wireless_send_event(wdev
->netdev
, IWEVASSOCREQIE
,
758 memset(&wrqu
, 0, sizeof(wrqu
));
759 wrqu
.data
.length
= resp_ie_len
;
760 wireless_send_event(wdev
->netdev
, IWEVASSOCRESPIE
,
764 memset(&wrqu
, 0, sizeof(wrqu
));
765 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
766 memcpy(wrqu
.ap_addr
.sa_data
, bss
->bssid
, ETH_ALEN
);
767 memcpy(wdev
->wext
.prev_bssid
, bss
->bssid
, ETH_ALEN
);
768 wdev
->wext
.prev_bssid_valid
= true;
769 wireless_send_event(wdev
->netdev
, SIOCGIWAP
, &wrqu
, NULL
);
774 cfg80211_put_bss(wdev
->wiphy
, bss
);
777 void cfg80211_roamed(struct net_device
*dev
,
778 struct ieee80211_channel
*channel
,
780 const u8
*req_ie
, size_t req_ie_len
,
781 const u8
*resp_ie
, size_t resp_ie_len
, gfp_t gfp
)
783 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
784 struct cfg80211_bss
*bss
;
786 bss
= cfg80211_get_bss(wdev
->wiphy
, channel
, bssid
, wdev
->ssid
,
787 wdev
->ssid_len
, WLAN_CAPABILITY_ESS
,
788 WLAN_CAPABILITY_ESS
);
792 cfg80211_roamed_bss(dev
, bss
, req_ie
, req_ie_len
, resp_ie
,
795 EXPORT_SYMBOL(cfg80211_roamed
);
797 /* Consumes bss object one way or another */
798 void cfg80211_roamed_bss(struct net_device
*dev
,
799 struct cfg80211_bss
*bss
, const u8
*req_ie
,
800 size_t req_ie_len
, const u8
*resp_ie
,
801 size_t resp_ie_len
, gfp_t gfp
)
803 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
804 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
805 struct cfg80211_event
*ev
;
811 ev
= kzalloc(sizeof(*ev
) + req_ie_len
+ resp_ie_len
, gfp
);
813 cfg80211_put_bss(wdev
->wiphy
, bss
);
817 ev
->type
= EVENT_ROAMED
;
818 ev
->rm
.req_ie
= ((u8
*)ev
) + sizeof(*ev
);
819 ev
->rm
.req_ie_len
= req_ie_len
;
820 memcpy((void *)ev
->rm
.req_ie
, req_ie
, req_ie_len
);
821 ev
->rm
.resp_ie
= ((u8
*)ev
) + sizeof(*ev
) + req_ie_len
;
822 ev
->rm
.resp_ie_len
= resp_ie_len
;
823 memcpy((void *)ev
->rm
.resp_ie
, resp_ie
, resp_ie_len
);
826 spin_lock_irqsave(&wdev
->event_lock
, flags
);
827 list_add_tail(&ev
->list
, &wdev
->event_list
);
828 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
829 queue_work(cfg80211_wq
, &rdev
->event_work
);
831 EXPORT_SYMBOL(cfg80211_roamed_bss
);
833 void __cfg80211_disconnected(struct net_device
*dev
, const u8
*ie
,
834 size_t ie_len
, u16 reason
, bool from_ap
)
836 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
837 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
839 #ifdef CONFIG_CFG80211_WEXT
840 union iwreq_data wrqu
;
843 ASSERT_WDEV_LOCK(wdev
);
845 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_STATION
&&
846 wdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
))
849 if (wdev
->current_bss
) {
850 cfg80211_unhold_bss(wdev
->current_bss
);
851 cfg80211_put_bss(wdev
->wiphy
, &wdev
->current_bss
->pub
);
854 wdev
->current_bss
= NULL
;
857 nl80211_send_disconnected(rdev
, dev
, reason
, ie
, ie_len
, from_ap
);
860 * Delete all the keys ... pairwise keys can't really
861 * exist any more anyway, but default keys might.
863 if (rdev
->ops
->del_key
)
864 for (i
= 0; i
< 6; i
++)
865 rdev_del_key(rdev
, dev
, i
, false, NULL
);
867 rdev_set_qos_map(rdev
, dev
, NULL
);
869 #ifdef CONFIG_CFG80211_WEXT
870 memset(&wrqu
, 0, sizeof(wrqu
));
871 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
872 wireless_send_event(dev
, SIOCGIWAP
, &wrqu
, NULL
);
873 wdev
->wext
.connect
.ssid_len
= 0;
876 schedule_work(&cfg80211_disconnect_work
);
879 void cfg80211_disconnected(struct net_device
*dev
, u16 reason
,
880 u8
*ie
, size_t ie_len
, gfp_t gfp
)
882 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
883 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
884 struct cfg80211_event
*ev
;
887 ev
= kzalloc(sizeof(*ev
) + ie_len
, gfp
);
891 ev
->type
= EVENT_DISCONNECTED
;
892 ev
->dc
.ie
= ((u8
*)ev
) + sizeof(*ev
);
893 ev
->dc
.ie_len
= ie_len
;
894 memcpy((void *)ev
->dc
.ie
, ie
, ie_len
);
895 ev
->dc
.reason
= reason
;
897 spin_lock_irqsave(&wdev
->event_lock
, flags
);
898 list_add_tail(&ev
->list
, &wdev
->event_list
);
899 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
900 queue_work(cfg80211_wq
, &rdev
->event_work
);
902 EXPORT_SYMBOL(cfg80211_disconnected
);
905 * API calls for nl80211/wext compatibility code
907 int cfg80211_connect(struct cfg80211_registered_device
*rdev
,
908 struct net_device
*dev
,
909 struct cfg80211_connect_params
*connect
,
910 struct cfg80211_cached_keys
*connkeys
,
911 const u8
*prev_bssid
)
913 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
916 ASSERT_WDEV_LOCK(wdev
);
918 if (WARN_ON(wdev
->connect_keys
)) {
919 kfree(wdev
->connect_keys
);
920 wdev
->connect_keys
= NULL
;
923 cfg80211_oper_and_ht_capa(&connect
->ht_capa_mask
,
924 rdev
->wiphy
.ht_capa_mod_mask
);
926 if (connkeys
&& connkeys
->def
>= 0) {
931 cipher
= connkeys
->params
[idx
].cipher
;
932 /* If given a WEP key we may need it for shared key auth */
933 if (cipher
== WLAN_CIPHER_SUITE_WEP40
||
934 cipher
== WLAN_CIPHER_SUITE_WEP104
) {
935 connect
->key_idx
= idx
;
936 connect
->key
= connkeys
->params
[idx
].key
;
937 connect
->key_len
= connkeys
->params
[idx
].key_len
;
940 * If ciphers are not set (e.g. when going through
941 * iwconfig), we have to set them appropriately here.
943 if (connect
->crypto
.cipher_group
== 0)
944 connect
->crypto
.cipher_group
= cipher
;
946 if (connect
->crypto
.n_ciphers_pairwise
== 0) {
947 connect
->crypto
.n_ciphers_pairwise
= 1;
948 connect
->crypto
.ciphers_pairwise
[0] = cipher
;
953 wdev
->connect_keys
= connkeys
;
954 memcpy(wdev
->ssid
, connect
->ssid
, connect
->ssid_len
);
955 wdev
->ssid_len
= connect
->ssid_len
;
957 if (!rdev
->ops
->connect
)
958 err
= cfg80211_sme_connect(wdev
, connect
, prev_bssid
);
960 err
= rdev_connect(rdev
, dev
, connect
);
963 wdev
->connect_keys
= NULL
;
971 int cfg80211_disconnect(struct cfg80211_registered_device
*rdev
,
972 struct net_device
*dev
, u16 reason
, bool wextev
)
974 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
977 ASSERT_WDEV_LOCK(wdev
);
979 kfree(wdev
->connect_keys
);
980 wdev
->connect_keys
= NULL
;
983 err
= cfg80211_sme_disconnect(wdev
, reason
);
984 else if (!rdev
->ops
->disconnect
)
985 cfg80211_mlme_down(rdev
, dev
);
986 else if (wdev
->current_bss
)
987 err
= rdev_disconnect(rdev
, dev
, reason
);