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_ASSOCIATE_NEXT
,
38 CFG80211_CONN_ASSOCIATING
,
40 CFG80211_CONN_CONNECTED
,
42 u8 bssid
[ETH_ALEN
], prev_bssid
[ETH_ALEN
];
45 bool auto_auth
, prev_bssid_valid
;
48 static void cfg80211_sme_free(struct wireless_dev
*wdev
)
53 kfree(wdev
->conn
->ie
);
58 static int cfg80211_conn_scan(struct wireless_dev
*wdev
)
60 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
61 struct cfg80211_scan_request
*request
;
65 ASSERT_RDEV_LOCK(rdev
);
66 ASSERT_WDEV_LOCK(wdev
);
71 if (wdev
->conn
->params
.channel
) {
74 enum ieee80211_band band
;
77 for (band
= 0; band
< IEEE80211_NUM_BANDS
; band
++) {
78 if (!wdev
->wiphy
->bands
[band
])
80 n_channels
+= wdev
->wiphy
->bands
[band
]->n_channels
;
83 request
= kzalloc(sizeof(*request
) + sizeof(request
->ssids
[0]) +
84 sizeof(request
->channels
[0]) * n_channels
,
89 if (wdev
->conn
->params
.channel
)
90 request
->channels
[0] = wdev
->conn
->params
.channel
;
93 enum ieee80211_band band
;
94 struct ieee80211_supported_band
*bands
;
95 struct ieee80211_channel
*channel
;
97 for (band
= 0; band
< IEEE80211_NUM_BANDS
; band
++) {
98 bands
= wdev
->wiphy
->bands
[band
];
101 for (j
= 0; j
< bands
->n_channels
; j
++) {
102 channel
= &bands
->channels
[j
];
103 if (channel
->flags
& IEEE80211_CHAN_DISABLED
)
105 request
->channels
[i
++] = channel
;
107 request
->rates
[band
] = (1 << bands
->n_bitrates
) - 1;
111 request
->n_channels
= n_channels
;
112 request
->ssids
= (void *)&request
->channels
[n_channels
];
113 request
->n_ssids
= 1;
115 memcpy(request
->ssids
[0].ssid
, wdev
->conn
->params
.ssid
,
116 wdev
->conn
->params
.ssid_len
);
117 request
->ssids
[0].ssid_len
= wdev
->conn
->params
.ssid_len
;
119 request
->wdev
= wdev
;
120 request
->wiphy
= &rdev
->wiphy
;
121 request
->scan_start
= jiffies
;
123 rdev
->scan_req
= request
;
125 err
= rdev_scan(rdev
, request
);
127 wdev
->conn
->state
= CFG80211_CONN_SCANNING
;
128 nl80211_send_scan_start(rdev
, wdev
);
129 dev_hold(wdev
->netdev
);
131 rdev
->scan_req
= NULL
;
137 static int cfg80211_conn_do_work(struct wireless_dev
*wdev
)
139 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
140 struct cfg80211_connect_params
*params
;
141 struct cfg80211_assoc_request req
= {};
144 ASSERT_WDEV_LOCK(wdev
);
149 params
= &wdev
->conn
->params
;
151 switch (wdev
->conn
->state
) {
152 case CFG80211_CONN_SCANNING
:
153 /* didn't find it during scan ... */
155 case CFG80211_CONN_SCAN_AGAIN
:
156 return cfg80211_conn_scan(wdev
);
157 case CFG80211_CONN_AUTHENTICATE_NEXT
:
158 BUG_ON(!rdev
->ops
->auth
);
159 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATING
;
160 return cfg80211_mlme_auth(rdev
, wdev
->netdev
,
161 params
->channel
, params
->auth_type
,
163 params
->ssid
, params
->ssid_len
,
165 params
->key
, params
->key_len
,
166 params
->key_idx
, NULL
, 0);
167 case CFG80211_CONN_ASSOCIATE_NEXT
:
168 BUG_ON(!rdev
->ops
->assoc
);
169 wdev
->conn
->state
= CFG80211_CONN_ASSOCIATING
;
170 if (wdev
->conn
->prev_bssid_valid
)
171 req
.prev_bssid
= wdev
->conn
->prev_bssid
;
173 req
.ie_len
= params
->ie_len
;
174 req
.use_mfp
= params
->mfp
!= NL80211_MFP_NO
;
175 req
.crypto
= params
->crypto
;
176 req
.flags
= params
->flags
;
177 req
.ht_capa
= params
->ht_capa
;
178 req
.ht_capa_mask
= params
->ht_capa_mask
;
179 req
.vht_capa
= params
->vht_capa
;
180 req
.vht_capa_mask
= params
->vht_capa_mask
;
182 err
= cfg80211_mlme_assoc(rdev
, wdev
->netdev
, params
->channel
,
183 params
->bssid
, params
->ssid
,
184 params
->ssid_len
, &req
);
186 cfg80211_mlme_deauth(rdev
, wdev
->netdev
, params
->bssid
,
188 WLAN_REASON_DEAUTH_LEAVING
,
191 case CFG80211_CONN_DEAUTH
:
192 cfg80211_mlme_deauth(rdev
, wdev
->netdev
, params
->bssid
,
194 WLAN_REASON_DEAUTH_LEAVING
, false);
201 void cfg80211_conn_work(struct work_struct
*work
)
203 struct cfg80211_registered_device
*rdev
=
204 container_of(work
, struct cfg80211_registered_device
, conn_work
);
205 struct wireless_dev
*wdev
;
206 u8 bssid_buf
[ETH_ALEN
], *bssid
= NULL
;
210 list_for_each_entry(wdev
, &rdev
->wdev_list
, list
) {
215 if (!netif_running(wdev
->netdev
)) {
220 wdev
->conn
->state
== CFG80211_CONN_CONNECTED
) {
224 if (wdev
->conn
->params
.bssid
) {
225 memcpy(bssid_buf
, wdev
->conn
->params
.bssid
, ETH_ALEN
);
228 if (cfg80211_conn_do_work(wdev
)) {
229 __cfg80211_connect_result(
232 WLAN_STATUS_UNSPECIFIED_FAILURE
,
234 cfg80211_sme_free(wdev
);
242 /* Returned bss is reference counted and must be cleaned up appropriately. */
243 static struct cfg80211_bss
*cfg80211_get_conn_bss(struct wireless_dev
*wdev
)
245 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
246 struct cfg80211_bss
*bss
;
247 u16 capa
= WLAN_CAPABILITY_ESS
;
249 ASSERT_WDEV_LOCK(wdev
);
251 if (wdev
->conn
->params
.privacy
)
252 capa
|= WLAN_CAPABILITY_PRIVACY
;
254 bss
= cfg80211_get_bss(wdev
->wiphy
, wdev
->conn
->params
.channel
,
255 wdev
->conn
->params
.bssid
,
256 wdev
->conn
->params
.ssid
,
257 wdev
->conn
->params
.ssid_len
,
258 WLAN_CAPABILITY_ESS
| WLAN_CAPABILITY_PRIVACY
,
263 memcpy(wdev
->conn
->bssid
, bss
->bssid
, ETH_ALEN
);
264 wdev
->conn
->params
.bssid
= wdev
->conn
->bssid
;
265 wdev
->conn
->params
.channel
= bss
->channel
;
266 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATE_NEXT
;
267 schedule_work(&rdev
->conn_work
);
272 static void __cfg80211_sme_scan_done(struct net_device
*dev
)
274 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
275 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
276 struct cfg80211_bss
*bss
;
278 ASSERT_WDEV_LOCK(wdev
);
283 if (wdev
->conn
->state
!= CFG80211_CONN_SCANNING
&&
284 wdev
->conn
->state
!= CFG80211_CONN_SCAN_AGAIN
)
287 bss
= cfg80211_get_conn_bss(wdev
);
289 cfg80211_put_bss(&rdev
->wiphy
, bss
);
291 schedule_work(&rdev
->conn_work
);
294 void cfg80211_sme_scan_done(struct net_device
*dev
)
296 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
299 __cfg80211_sme_scan_done(dev
);
303 void cfg80211_sme_rx_auth(struct wireless_dev
*wdev
, const u8
*buf
, size_t len
)
305 struct wiphy
*wiphy
= wdev
->wiphy
;
306 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
307 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*)buf
;
308 u16 status_code
= le16_to_cpu(mgmt
->u
.auth
.status_code
);
310 ASSERT_WDEV_LOCK(wdev
);
312 if (!wdev
->conn
|| wdev
->conn
->state
== CFG80211_CONN_CONNECTED
)
315 if (status_code
== WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
&&
316 wdev
->conn
->auto_auth
&&
317 wdev
->conn
->params
.auth_type
!= NL80211_AUTHTYPE_NETWORK_EAP
) {
318 /* select automatically between only open, shared, leap */
319 switch (wdev
->conn
->params
.auth_type
) {
320 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
321 if (wdev
->connect_keys
)
322 wdev
->conn
->params
.auth_type
=
323 NL80211_AUTHTYPE_SHARED_KEY
;
325 wdev
->conn
->params
.auth_type
=
326 NL80211_AUTHTYPE_NETWORK_EAP
;
328 case NL80211_AUTHTYPE_SHARED_KEY
:
329 wdev
->conn
->params
.auth_type
=
330 NL80211_AUTHTYPE_NETWORK_EAP
;
334 wdev
->conn
->params
.auth_type
=
335 NL80211_AUTHTYPE_OPEN_SYSTEM
;
338 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATE_NEXT
;
339 schedule_work(&rdev
->conn_work
);
340 } else if (status_code
!= WLAN_STATUS_SUCCESS
) {
341 __cfg80211_connect_result(wdev
->netdev
, mgmt
->bssid
,
343 status_code
, false, NULL
);
344 } else if (wdev
->conn
->state
== CFG80211_CONN_AUTHENTICATING
) {
345 wdev
->conn
->state
= CFG80211_CONN_ASSOCIATE_NEXT
;
346 schedule_work(&rdev
->conn_work
);
350 bool cfg80211_sme_rx_assoc_resp(struct wireless_dev
*wdev
, u16 status
)
352 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
357 if (status
== WLAN_STATUS_SUCCESS
) {
358 wdev
->conn
->state
= CFG80211_CONN_CONNECTED
;
362 if (wdev
->conn
->prev_bssid_valid
) {
364 * Some stupid APs don't accept reassoc, so we
365 * need to fall back to trying regular assoc;
366 * return true so no event is sent to userspace.
368 wdev
->conn
->prev_bssid_valid
= false;
369 wdev
->conn
->state
= CFG80211_CONN_ASSOCIATE_NEXT
;
370 schedule_work(&rdev
->conn_work
);
374 wdev
->conn
->state
= CFG80211_CONN_DEAUTH
;
375 schedule_work(&rdev
->conn_work
);
379 void cfg80211_sme_deauth(struct wireless_dev
*wdev
)
381 cfg80211_sme_free(wdev
);
384 void cfg80211_sme_auth_timeout(struct wireless_dev
*wdev
)
386 cfg80211_sme_free(wdev
);
389 void cfg80211_sme_disassoc(struct wireless_dev
*wdev
)
391 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
396 wdev
->conn
->state
= CFG80211_CONN_DEAUTH
;
397 schedule_work(&rdev
->conn_work
);
400 void cfg80211_sme_assoc_timeout(struct wireless_dev
*wdev
)
402 cfg80211_sme_disassoc(wdev
);
405 static int cfg80211_sme_connect(struct wireless_dev
*wdev
,
406 struct cfg80211_connect_params
*connect
,
407 const u8
*prev_bssid
)
409 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
410 struct cfg80211_bss
*bss
;
413 if (!rdev
->ops
->auth
|| !rdev
->ops
->assoc
)
416 if (wdev
->current_bss
)
419 if (WARN_ON(wdev
->conn
))
422 wdev
->conn
= kzalloc(sizeof(*wdev
->conn
), GFP_KERNEL
);
427 * Copy all parameters, and treat explicitly IEs, BSSID, SSID.
429 memcpy(&wdev
->conn
->params
, connect
, sizeof(*connect
));
430 if (connect
->bssid
) {
431 wdev
->conn
->params
.bssid
= wdev
->conn
->bssid
;
432 memcpy(wdev
->conn
->bssid
, connect
->bssid
, ETH_ALEN
);
436 wdev
->conn
->ie
= kmemdup(connect
->ie
, connect
->ie_len
,
438 wdev
->conn
->params
.ie
= wdev
->conn
->ie
;
439 if (!wdev
->conn
->ie
) {
446 if (connect
->auth_type
== NL80211_AUTHTYPE_AUTOMATIC
) {
447 wdev
->conn
->auto_auth
= true;
448 /* start with open system ... should mostly work */
449 wdev
->conn
->params
.auth_type
=
450 NL80211_AUTHTYPE_OPEN_SYSTEM
;
452 wdev
->conn
->auto_auth
= false;
455 wdev
->conn
->params
.ssid
= wdev
->ssid
;
456 wdev
->conn
->params
.ssid_len
= connect
->ssid_len
;
458 /* see if we have the bss already */
459 bss
= cfg80211_get_conn_bss(wdev
);
462 memcpy(wdev
->conn
->prev_bssid
, prev_bssid
, ETH_ALEN
);
463 wdev
->conn
->prev_bssid_valid
= true;
466 /* we're good if we have a matching bss struct */
468 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATE_NEXT
;
469 err
= cfg80211_conn_do_work(wdev
);
470 cfg80211_put_bss(wdev
->wiphy
, bss
);
472 /* otherwise we'll need to scan for the AP first */
473 err
= cfg80211_conn_scan(wdev
);
476 * If we can't scan right now, then we need to scan again
477 * after the current scan finished, since the parameters
478 * changed (unless we find a good AP anyway).
482 wdev
->conn
->state
= CFG80211_CONN_SCAN_AGAIN
;
487 cfg80211_sme_free(wdev
);
492 static int cfg80211_sme_disconnect(struct wireless_dev
*wdev
, u16 reason
)
494 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
500 if (!rdev
->ops
->deauth
)
503 if (wdev
->conn
->state
== CFG80211_CONN_SCANNING
||
504 wdev
->conn
->state
== CFG80211_CONN_SCAN_AGAIN
) {
509 /* wdev->conn->params.bssid must be set if > SCANNING */
510 err
= cfg80211_mlme_deauth(rdev
, wdev
->netdev
,
511 wdev
->conn
->params
.bssid
,
512 NULL
, 0, reason
, false);
514 cfg80211_sme_free(wdev
);
519 * code shared for in-device and software SME
522 static bool cfg80211_is_all_idle(void)
524 struct cfg80211_registered_device
*rdev
;
525 struct wireless_dev
*wdev
;
526 bool is_all_idle
= true;
529 * All devices must be idle as otherwise if you are actively
530 * scanning some new beacon hints could be learned and would
531 * count as new regulatory hints.
533 list_for_each_entry(rdev
, &cfg80211_rdev_list
, list
) {
534 list_for_each_entry(wdev
, &rdev
->wdev_list
, list
) {
536 if (wdev
->conn
|| wdev
->current_bss
)
545 static void disconnect_work(struct work_struct
*work
)
548 if (cfg80211_is_all_idle())
549 regulatory_hint_disconnect();
553 static DECLARE_WORK(cfg80211_disconnect_work
, disconnect_work
);
557 * API calls for drivers implementing connect/disconnect and
561 /* This method must consume bss one way or another */
562 void __cfg80211_connect_result(struct net_device
*dev
, const u8
*bssid
,
563 const u8
*req_ie
, size_t req_ie_len
,
564 const u8
*resp_ie
, size_t resp_ie_len
,
565 u16 status
, bool wextev
,
566 struct cfg80211_bss
*bss
)
568 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
569 const u8
*country_ie
;
570 #ifdef CONFIG_CFG80211_WEXT
571 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
)) {
578 cfg80211_put_bss(wdev
->wiphy
, bss
);
582 nl80211_send_connect_result(wiphy_to_dev(wdev
->wiphy
), dev
,
583 bssid
, req_ie
, req_ie_len
,
584 resp_ie
, resp_ie_len
,
587 #ifdef CONFIG_CFG80211_WEXT
589 if (req_ie
&& status
== WLAN_STATUS_SUCCESS
) {
590 memset(&wrqu
, 0, sizeof(wrqu
));
591 wrqu
.data
.length
= req_ie_len
;
592 wireless_send_event(dev
, IWEVASSOCREQIE
, &wrqu
, req_ie
);
595 if (resp_ie
&& status
== WLAN_STATUS_SUCCESS
) {
596 memset(&wrqu
, 0, sizeof(wrqu
));
597 wrqu
.data
.length
= resp_ie_len
;
598 wireless_send_event(dev
, IWEVASSOCRESPIE
, &wrqu
, resp_ie
);
601 memset(&wrqu
, 0, sizeof(wrqu
));
602 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
603 if (bssid
&& status
== WLAN_STATUS_SUCCESS
) {
604 memcpy(wrqu
.ap_addr
.sa_data
, bssid
, ETH_ALEN
);
605 memcpy(wdev
->wext
.prev_bssid
, bssid
, ETH_ALEN
);
606 wdev
->wext
.prev_bssid_valid
= true;
608 wireless_send_event(dev
, SIOCGIWAP
, &wrqu
, NULL
);
612 if (wdev
->current_bss
) {
613 cfg80211_unhold_bss(wdev
->current_bss
);
614 cfg80211_put_bss(wdev
->wiphy
, &wdev
->current_bss
->pub
);
615 wdev
->current_bss
= NULL
;
618 if (status
!= WLAN_STATUS_SUCCESS
) {
619 kfree(wdev
->connect_keys
);
620 wdev
->connect_keys
= NULL
;
623 cfg80211_unhold_bss(bss_from_pub(bss
));
624 cfg80211_put_bss(wdev
->wiphy
, bss
);
630 WARN_ON_ONCE(!wiphy_to_dev(wdev
->wiphy
)->ops
->connect
);
631 bss
= cfg80211_get_bss(wdev
->wiphy
, NULL
, bssid
,
632 wdev
->ssid
, wdev
->ssid_len
,
634 WLAN_CAPABILITY_ESS
);
637 cfg80211_hold_bss(bss_from_pub(bss
));
640 wdev
->current_bss
= bss_from_pub(bss
);
642 cfg80211_upload_connect_keys(wdev
);
645 country_ie
= ieee80211_bss_get_ie(bss
, WLAN_EID_COUNTRY
);
651 country_ie
= kmemdup(country_ie
, 2 + country_ie
[1], GFP_ATOMIC
);
658 * ieee80211_bss_get_ie() ensures we can access:
659 * - country_ie + 2, the start of the country ie data, and
660 * - and country_ie[1] which is the IE length
662 regulatory_hint_11d(wdev
->wiphy
, bss
->channel
->band
,
663 country_ie
+ 2, country_ie
[1]);
667 void cfg80211_connect_result(struct net_device
*dev
, const u8
*bssid
,
668 const u8
*req_ie
, size_t req_ie_len
,
669 const u8
*resp_ie
, size_t resp_ie_len
,
670 u16 status
, gfp_t gfp
)
672 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
673 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
674 struct cfg80211_event
*ev
;
677 ev
= kzalloc(sizeof(*ev
) + req_ie_len
+ resp_ie_len
, gfp
);
681 ev
->type
= EVENT_CONNECT_RESULT
;
683 memcpy(ev
->cr
.bssid
, bssid
, ETH_ALEN
);
685 ev
->cr
.req_ie
= ((u8
*)ev
) + sizeof(*ev
);
686 ev
->cr
.req_ie_len
= req_ie_len
;
687 memcpy((void *)ev
->cr
.req_ie
, req_ie
, req_ie_len
);
690 ev
->cr
.resp_ie
= ((u8
*)ev
) + sizeof(*ev
) + req_ie_len
;
691 ev
->cr
.resp_ie_len
= resp_ie_len
;
692 memcpy((void *)ev
->cr
.resp_ie
, resp_ie
, resp_ie_len
);
694 ev
->cr
.status
= status
;
696 spin_lock_irqsave(&wdev
->event_lock
, flags
);
697 list_add_tail(&ev
->list
, &wdev
->event_list
);
698 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
699 queue_work(cfg80211_wq
, &rdev
->event_work
);
701 EXPORT_SYMBOL(cfg80211_connect_result
);
703 /* Consumes bss object one way or another */
704 void __cfg80211_roamed(struct wireless_dev
*wdev
,
705 struct cfg80211_bss
*bss
,
706 const u8
*req_ie
, size_t req_ie_len
,
707 const u8
*resp_ie
, size_t resp_ie_len
)
709 #ifdef CONFIG_CFG80211_WEXT
710 union iwreq_data wrqu
;
712 ASSERT_WDEV_LOCK(wdev
);
714 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_STATION
&&
715 wdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
))
718 if (WARN_ON(!wdev
->current_bss
))
721 cfg80211_unhold_bss(wdev
->current_bss
);
722 cfg80211_put_bss(wdev
->wiphy
, &wdev
->current_bss
->pub
);
723 wdev
->current_bss
= NULL
;
725 cfg80211_hold_bss(bss_from_pub(bss
));
726 wdev
->current_bss
= bss_from_pub(bss
);
728 nl80211_send_roamed(wiphy_to_dev(wdev
->wiphy
), wdev
->netdev
, bss
->bssid
,
729 req_ie
, req_ie_len
, resp_ie
, resp_ie_len
,
732 #ifdef CONFIG_CFG80211_WEXT
734 memset(&wrqu
, 0, sizeof(wrqu
));
735 wrqu
.data
.length
= req_ie_len
;
736 wireless_send_event(wdev
->netdev
, IWEVASSOCREQIE
,
741 memset(&wrqu
, 0, sizeof(wrqu
));
742 wrqu
.data
.length
= resp_ie_len
;
743 wireless_send_event(wdev
->netdev
, IWEVASSOCRESPIE
,
747 memset(&wrqu
, 0, sizeof(wrqu
));
748 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
749 memcpy(wrqu
.ap_addr
.sa_data
, bss
->bssid
, ETH_ALEN
);
750 memcpy(wdev
->wext
.prev_bssid
, bss
->bssid
, ETH_ALEN
);
751 wdev
->wext
.prev_bssid_valid
= true;
752 wireless_send_event(wdev
->netdev
, SIOCGIWAP
, &wrqu
, NULL
);
757 cfg80211_put_bss(wdev
->wiphy
, bss
);
760 void cfg80211_roamed(struct net_device
*dev
,
761 struct ieee80211_channel
*channel
,
763 const u8
*req_ie
, size_t req_ie_len
,
764 const u8
*resp_ie
, size_t resp_ie_len
, gfp_t gfp
)
766 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
767 struct cfg80211_bss
*bss
;
769 bss
= cfg80211_get_bss(wdev
->wiphy
, channel
, bssid
, wdev
->ssid
,
770 wdev
->ssid_len
, WLAN_CAPABILITY_ESS
,
771 WLAN_CAPABILITY_ESS
);
775 cfg80211_roamed_bss(dev
, bss
, req_ie
, req_ie_len
, resp_ie
,
778 EXPORT_SYMBOL(cfg80211_roamed
);
780 /* Consumes bss object one way or another */
781 void cfg80211_roamed_bss(struct net_device
*dev
,
782 struct cfg80211_bss
*bss
, const u8
*req_ie
,
783 size_t req_ie_len
, const u8
*resp_ie
,
784 size_t resp_ie_len
, gfp_t gfp
)
786 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
787 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
788 struct cfg80211_event
*ev
;
794 ev
= kzalloc(sizeof(*ev
) + req_ie_len
+ resp_ie_len
, gfp
);
796 cfg80211_put_bss(wdev
->wiphy
, bss
);
800 ev
->type
= EVENT_ROAMED
;
801 ev
->rm
.req_ie
= ((u8
*)ev
) + sizeof(*ev
);
802 ev
->rm
.req_ie_len
= req_ie_len
;
803 memcpy((void *)ev
->rm
.req_ie
, req_ie
, req_ie_len
);
804 ev
->rm
.resp_ie
= ((u8
*)ev
) + sizeof(*ev
) + req_ie_len
;
805 ev
->rm
.resp_ie_len
= resp_ie_len
;
806 memcpy((void *)ev
->rm
.resp_ie
, resp_ie
, resp_ie_len
);
809 spin_lock_irqsave(&wdev
->event_lock
, flags
);
810 list_add_tail(&ev
->list
, &wdev
->event_list
);
811 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
812 queue_work(cfg80211_wq
, &rdev
->event_work
);
814 EXPORT_SYMBOL(cfg80211_roamed_bss
);
816 void __cfg80211_disconnected(struct net_device
*dev
, const u8
*ie
,
817 size_t ie_len
, u16 reason
, bool from_ap
)
819 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
820 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
822 #ifdef CONFIG_CFG80211_WEXT
823 union iwreq_data wrqu
;
826 ASSERT_WDEV_LOCK(wdev
);
828 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_STATION
&&
829 wdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
))
832 if (wdev
->current_bss
) {
833 cfg80211_unhold_bss(wdev
->current_bss
);
834 cfg80211_put_bss(wdev
->wiphy
, &wdev
->current_bss
->pub
);
837 wdev
->current_bss
= NULL
;
840 nl80211_send_disconnected(rdev
, dev
, reason
, ie
, ie_len
, from_ap
);
843 * Delete all the keys ... pairwise keys can't really
844 * exist any more anyway, but default keys might.
846 if (rdev
->ops
->del_key
)
847 for (i
= 0; i
< 6; i
++)
848 rdev_del_key(rdev
, dev
, i
, false, NULL
);
850 #ifdef CONFIG_CFG80211_WEXT
851 memset(&wrqu
, 0, sizeof(wrqu
));
852 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
853 wireless_send_event(dev
, SIOCGIWAP
, &wrqu
, NULL
);
854 wdev
->wext
.connect
.ssid_len
= 0;
857 schedule_work(&cfg80211_disconnect_work
);
860 void cfg80211_disconnected(struct net_device
*dev
, u16 reason
,
861 u8
*ie
, size_t ie_len
, gfp_t gfp
)
863 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
864 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
865 struct cfg80211_event
*ev
;
868 ev
= kzalloc(sizeof(*ev
) + ie_len
, gfp
);
872 ev
->type
= EVENT_DISCONNECTED
;
873 ev
->dc
.ie
= ((u8
*)ev
) + sizeof(*ev
);
874 ev
->dc
.ie_len
= ie_len
;
875 memcpy((void *)ev
->dc
.ie
, ie
, ie_len
);
876 ev
->dc
.reason
= reason
;
878 spin_lock_irqsave(&wdev
->event_lock
, flags
);
879 list_add_tail(&ev
->list
, &wdev
->event_list
);
880 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
881 queue_work(cfg80211_wq
, &rdev
->event_work
);
883 EXPORT_SYMBOL(cfg80211_disconnected
);
886 * API calls for nl80211/wext compatibility code
888 int cfg80211_connect(struct cfg80211_registered_device
*rdev
,
889 struct net_device
*dev
,
890 struct cfg80211_connect_params
*connect
,
891 struct cfg80211_cached_keys
*connkeys
,
892 const u8
*prev_bssid
)
894 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
897 ASSERT_WDEV_LOCK(wdev
);
899 if (WARN_ON(wdev
->connect_keys
)) {
900 kfree(wdev
->connect_keys
);
901 wdev
->connect_keys
= NULL
;
904 cfg80211_oper_and_ht_capa(&connect
->ht_capa_mask
,
905 rdev
->wiphy
.ht_capa_mod_mask
);
907 if (connkeys
&& connkeys
->def
>= 0) {
912 cipher
= connkeys
->params
[idx
].cipher
;
913 /* If given a WEP key we may need it for shared key auth */
914 if (cipher
== WLAN_CIPHER_SUITE_WEP40
||
915 cipher
== WLAN_CIPHER_SUITE_WEP104
) {
916 connect
->key_idx
= idx
;
917 connect
->key
= connkeys
->params
[idx
].key
;
918 connect
->key_len
= connkeys
->params
[idx
].key_len
;
921 * If ciphers are not set (e.g. when going through
922 * iwconfig), we have to set them appropriately here.
924 if (connect
->crypto
.cipher_group
== 0)
925 connect
->crypto
.cipher_group
= cipher
;
927 if (connect
->crypto
.n_ciphers_pairwise
== 0) {
928 connect
->crypto
.n_ciphers_pairwise
= 1;
929 connect
->crypto
.ciphers_pairwise
[0] = cipher
;
934 wdev
->connect_keys
= connkeys
;
935 memcpy(wdev
->ssid
, connect
->ssid
, connect
->ssid_len
);
936 wdev
->ssid_len
= connect
->ssid_len
;
938 if (!rdev
->ops
->connect
)
939 err
= cfg80211_sme_connect(wdev
, connect
, prev_bssid
);
941 err
= rdev_connect(rdev
, dev
, connect
);
944 wdev
->connect_keys
= NULL
;
952 int cfg80211_disconnect(struct cfg80211_registered_device
*rdev
,
953 struct net_device
*dev
, u16 reason
, bool wextev
)
955 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
958 ASSERT_WDEV_LOCK(wdev
);
960 kfree(wdev
->connect_keys
);
961 wdev
->connect_keys
= NULL
;
964 err
= cfg80211_sme_disconnect(wdev
, reason
);
965 } else if (!rdev
->ops
->disconnect
) {
966 cfg80211_mlme_down(rdev
, dev
);
969 err
= rdev_disconnect(rdev
, dev
, reason
);