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_TIMEOUT
,
38 CFG80211_CONN_ASSOCIATE_NEXT
,
39 CFG80211_CONN_ASSOCIATING
,
40 CFG80211_CONN_ASSOC_FAILED
,
41 CFG80211_CONN_ASSOC_FAILED_TIMEOUT
,
43 CFG80211_CONN_ABANDON
,
44 CFG80211_CONN_CONNECTED
,
46 u8 bssid
[ETH_ALEN
], prev_bssid
[ETH_ALEN
];
49 bool auto_auth
, prev_bssid_valid
;
52 static void cfg80211_sme_free(struct wireless_dev
*wdev
)
57 kfree(wdev
->conn
->ie
);
62 static int cfg80211_conn_scan(struct wireless_dev
*wdev
)
64 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
65 struct cfg80211_scan_request
*request
;
69 ASSERT_WDEV_LOCK(wdev
);
71 if (rdev
->scan_req
|| rdev
->scan_msg
)
74 if (wdev
->conn
->params
.channel
)
77 n_channels
= ieee80211_get_num_supported_channels(wdev
->wiphy
);
79 request
= kzalloc(sizeof(*request
) + sizeof(request
->ssids
[0]) +
80 sizeof(request
->channels
[0]) * n_channels
,
85 if (wdev
->conn
->params
.channel
) {
86 enum nl80211_band band
= wdev
->conn
->params
.channel
->band
;
87 struct ieee80211_supported_band
*sband
=
88 wdev
->wiphy
->bands
[band
];
94 request
->channels
[0] = wdev
->conn
->params
.channel
;
95 request
->rates
[band
] = (1 << sband
->n_bitrates
) - 1;
98 enum nl80211_band band
;
99 struct ieee80211_supported_band
*bands
;
100 struct ieee80211_channel
*channel
;
102 for (band
= 0; band
< NUM_NL80211_BANDS
; band
++) {
103 bands
= wdev
->wiphy
->bands
[band
];
106 for (j
= 0; j
< bands
->n_channels
; j
++) {
107 channel
= &bands
->channels
[j
];
108 if (channel
->flags
& IEEE80211_CHAN_DISABLED
)
110 request
->channels
[i
++] = channel
;
112 request
->rates
[band
] = (1 << bands
->n_bitrates
) - 1;
116 request
->n_channels
= n_channels
;
117 request
->ssids
= (void *)&request
->channels
[n_channels
];
118 request
->n_ssids
= 1;
120 memcpy(request
->ssids
[0].ssid
, wdev
->conn
->params
.ssid
,
121 wdev
->conn
->params
.ssid_len
);
122 request
->ssids
[0].ssid_len
= wdev
->conn
->params
.ssid_len
;
124 eth_broadcast_addr(request
->bssid
);
126 request
->wdev
= wdev
;
127 request
->wiphy
= &rdev
->wiphy
;
128 request
->scan_start
= jiffies
;
130 rdev
->scan_req
= request
;
132 err
= rdev_scan(rdev
, request
);
134 wdev
->conn
->state
= CFG80211_CONN_SCANNING
;
135 nl80211_send_scan_start(rdev
, wdev
);
136 dev_hold(wdev
->netdev
);
138 rdev
->scan_req
= NULL
;
144 static int cfg80211_conn_do_work(struct wireless_dev
*wdev
,
145 enum nl80211_timeout_reason
*treason
)
147 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
148 struct cfg80211_connect_params
*params
;
149 struct cfg80211_assoc_request req
= {};
152 ASSERT_WDEV_LOCK(wdev
);
157 params
= &wdev
->conn
->params
;
159 switch (wdev
->conn
->state
) {
160 case CFG80211_CONN_SCANNING
:
161 /* didn't find it during scan ... */
163 case CFG80211_CONN_SCAN_AGAIN
:
164 return cfg80211_conn_scan(wdev
);
165 case CFG80211_CONN_AUTHENTICATE_NEXT
:
166 if (WARN_ON(!rdev
->ops
->auth
))
168 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATING
;
169 return cfg80211_mlme_auth(rdev
, wdev
->netdev
,
170 params
->channel
, params
->auth_type
,
172 params
->ssid
, params
->ssid_len
,
174 params
->key
, params
->key_len
,
175 params
->key_idx
, NULL
, 0);
176 case CFG80211_CONN_AUTH_FAILED_TIMEOUT
:
177 *treason
= NL80211_TIMEOUT_AUTH
;
179 case CFG80211_CONN_ASSOCIATE_NEXT
:
180 if (WARN_ON(!rdev
->ops
->assoc
))
182 wdev
->conn
->state
= CFG80211_CONN_ASSOCIATING
;
183 if (wdev
->conn
->prev_bssid_valid
)
184 req
.prev_bssid
= wdev
->conn
->prev_bssid
;
186 req
.ie_len
= params
->ie_len
;
187 req
.use_mfp
= params
->mfp
!= NL80211_MFP_NO
;
188 req
.crypto
= params
->crypto
;
189 req
.flags
= params
->flags
;
190 req
.ht_capa
= params
->ht_capa
;
191 req
.ht_capa_mask
= params
->ht_capa_mask
;
192 req
.vht_capa
= params
->vht_capa
;
193 req
.vht_capa_mask
= params
->vht_capa_mask
;
195 err
= cfg80211_mlme_assoc(rdev
, wdev
->netdev
, params
->channel
,
196 params
->bssid
, params
->ssid
,
197 params
->ssid_len
, &req
);
199 cfg80211_mlme_deauth(rdev
, wdev
->netdev
, params
->bssid
,
201 WLAN_REASON_DEAUTH_LEAVING
,
204 case CFG80211_CONN_ASSOC_FAILED_TIMEOUT
:
205 *treason
= NL80211_TIMEOUT_ASSOC
;
207 case CFG80211_CONN_ASSOC_FAILED
:
208 cfg80211_mlme_deauth(rdev
, wdev
->netdev
, params
->bssid
,
210 WLAN_REASON_DEAUTH_LEAVING
, false);
212 case CFG80211_CONN_DEAUTH
:
213 cfg80211_mlme_deauth(rdev
, wdev
->netdev
, params
->bssid
,
215 WLAN_REASON_DEAUTH_LEAVING
, false);
217 case CFG80211_CONN_ABANDON
:
218 /* free directly, disconnected event already sent */
219 cfg80211_sme_free(wdev
);
226 void cfg80211_conn_work(struct work_struct
*work
)
228 struct cfg80211_registered_device
*rdev
=
229 container_of(work
, struct cfg80211_registered_device
, conn_work
);
230 struct wireless_dev
*wdev
;
231 u8 bssid_buf
[ETH_ALEN
], *bssid
= NULL
;
232 enum nl80211_timeout_reason treason
;
236 list_for_each_entry(wdev
, &rdev
->wiphy
.wdev_list
, list
) {
241 if (!netif_running(wdev
->netdev
)) {
246 wdev
->conn
->state
== CFG80211_CONN_CONNECTED
) {
250 if (wdev
->conn
->params
.bssid
) {
251 memcpy(bssid_buf
, wdev
->conn
->params
.bssid
, ETH_ALEN
);
254 treason
= NL80211_TIMEOUT_UNSPECIFIED
;
255 if (cfg80211_conn_do_work(wdev
, &treason
)) {
256 __cfg80211_connect_result(
258 NULL
, 0, NULL
, 0, -1, false, NULL
,
267 /* Returned bss is reference counted and must be cleaned up appropriately. */
268 static struct cfg80211_bss
*cfg80211_get_conn_bss(struct wireless_dev
*wdev
)
270 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
271 struct cfg80211_bss
*bss
;
273 ASSERT_WDEV_LOCK(wdev
);
275 bss
= cfg80211_get_bss(wdev
->wiphy
, wdev
->conn
->params
.channel
,
276 wdev
->conn
->params
.bssid
,
277 wdev
->conn
->params
.ssid
,
278 wdev
->conn
->params
.ssid_len
,
280 IEEE80211_PRIVACY(wdev
->conn
->params
.privacy
));
284 memcpy(wdev
->conn
->bssid
, bss
->bssid
, ETH_ALEN
);
285 wdev
->conn
->params
.bssid
= wdev
->conn
->bssid
;
286 wdev
->conn
->params
.channel
= bss
->channel
;
287 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATE_NEXT
;
288 schedule_work(&rdev
->conn_work
);
293 static void __cfg80211_sme_scan_done(struct net_device
*dev
)
295 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
296 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
297 struct cfg80211_bss
*bss
;
299 ASSERT_WDEV_LOCK(wdev
);
304 if (wdev
->conn
->state
!= CFG80211_CONN_SCANNING
&&
305 wdev
->conn
->state
!= CFG80211_CONN_SCAN_AGAIN
)
308 bss
= cfg80211_get_conn_bss(wdev
);
310 cfg80211_put_bss(&rdev
->wiphy
, bss
);
312 schedule_work(&rdev
->conn_work
);
315 void cfg80211_sme_scan_done(struct net_device
*dev
)
317 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
320 __cfg80211_sme_scan_done(dev
);
324 void cfg80211_sme_rx_auth(struct wireless_dev
*wdev
, const u8
*buf
, size_t len
)
326 struct wiphy
*wiphy
= wdev
->wiphy
;
327 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wiphy
);
328 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*)buf
;
329 u16 status_code
= le16_to_cpu(mgmt
->u
.auth
.status_code
);
331 ASSERT_WDEV_LOCK(wdev
);
333 if (!wdev
->conn
|| wdev
->conn
->state
== CFG80211_CONN_CONNECTED
)
336 if (status_code
== WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
&&
337 wdev
->conn
->auto_auth
&&
338 wdev
->conn
->params
.auth_type
!= NL80211_AUTHTYPE_NETWORK_EAP
) {
339 /* select automatically between only open, shared, leap */
340 switch (wdev
->conn
->params
.auth_type
) {
341 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
342 if (wdev
->connect_keys
)
343 wdev
->conn
->params
.auth_type
=
344 NL80211_AUTHTYPE_SHARED_KEY
;
346 wdev
->conn
->params
.auth_type
=
347 NL80211_AUTHTYPE_NETWORK_EAP
;
349 case NL80211_AUTHTYPE_SHARED_KEY
:
350 wdev
->conn
->params
.auth_type
=
351 NL80211_AUTHTYPE_NETWORK_EAP
;
355 wdev
->conn
->params
.auth_type
=
356 NL80211_AUTHTYPE_OPEN_SYSTEM
;
359 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATE_NEXT
;
360 schedule_work(&rdev
->conn_work
);
361 } else if (status_code
!= WLAN_STATUS_SUCCESS
) {
362 __cfg80211_connect_result(wdev
->netdev
, mgmt
->bssid
,
364 status_code
, false, NULL
,
365 NL80211_TIMEOUT_UNSPECIFIED
);
366 } else if (wdev
->conn
->state
== CFG80211_CONN_AUTHENTICATING
) {
367 wdev
->conn
->state
= CFG80211_CONN_ASSOCIATE_NEXT
;
368 schedule_work(&rdev
->conn_work
);
372 bool cfg80211_sme_rx_assoc_resp(struct wireless_dev
*wdev
, u16 status
)
374 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
379 if (status
== WLAN_STATUS_SUCCESS
) {
380 wdev
->conn
->state
= CFG80211_CONN_CONNECTED
;
384 if (wdev
->conn
->prev_bssid_valid
) {
386 * Some stupid APs don't accept reassoc, so we
387 * need to fall back to trying regular assoc;
388 * return true so no event is sent to userspace.
390 wdev
->conn
->prev_bssid_valid
= false;
391 wdev
->conn
->state
= CFG80211_CONN_ASSOCIATE_NEXT
;
392 schedule_work(&rdev
->conn_work
);
396 wdev
->conn
->state
= CFG80211_CONN_ASSOC_FAILED
;
397 schedule_work(&rdev
->conn_work
);
401 void cfg80211_sme_deauth(struct wireless_dev
*wdev
)
403 cfg80211_sme_free(wdev
);
406 void cfg80211_sme_auth_timeout(struct wireless_dev
*wdev
)
408 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
413 wdev
->conn
->state
= CFG80211_CONN_AUTH_FAILED_TIMEOUT
;
414 schedule_work(&rdev
->conn_work
);
417 void cfg80211_sme_disassoc(struct wireless_dev
*wdev
)
419 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
424 wdev
->conn
->state
= CFG80211_CONN_DEAUTH
;
425 schedule_work(&rdev
->conn_work
);
428 void cfg80211_sme_assoc_timeout(struct wireless_dev
*wdev
)
430 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
435 wdev
->conn
->state
= CFG80211_CONN_ASSOC_FAILED_TIMEOUT
;
436 schedule_work(&rdev
->conn_work
);
439 void cfg80211_sme_abandon_assoc(struct wireless_dev
*wdev
)
441 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
446 wdev
->conn
->state
= CFG80211_CONN_ABANDON
;
447 schedule_work(&rdev
->conn_work
);
450 static int cfg80211_sme_get_conn_ies(struct wireless_dev
*wdev
,
451 const u8
*ies
, size_t ies_len
,
452 const u8
**out_ies
, size_t *out_ies_len
)
454 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
458 if (!rdev
->wiphy
.extended_capabilities_len
||
459 (ies
&& cfg80211_find_ie(WLAN_EID_EXT_CAPABILITY
, ies
, ies_len
))) {
460 *out_ies
= kmemdup(ies
, ies_len
, GFP_KERNEL
);
463 *out_ies_len
= ies_len
;
467 buf
= kmalloc(ies_len
+ rdev
->wiphy
.extended_capabilities_len
+ 2,
473 static const u8 before_extcapa
[] = {
474 /* not listing IEs expected to be created by driver */
477 WLAN_EID_RRM_ENABLED_CAPABILITIES
,
478 WLAN_EID_MOBILITY_DOMAIN
,
479 WLAN_EID_SUPPORTED_REGULATORY_CLASSES
,
480 WLAN_EID_BSS_COEX_2040
,
483 offs
= ieee80211_ie_split(ies
, ies_len
, before_extcapa
,
484 ARRAY_SIZE(before_extcapa
), 0);
485 memcpy(buf
, ies
, offs
);
486 /* leave a whole for extended capabilities IE */
487 memcpy(buf
+ offs
+ rdev
->wiphy
.extended_capabilities_len
+ 2,
488 ies
+ offs
, ies_len
- offs
);
493 /* place extended capabilities IE (with only driver capabilities) */
494 buf
[offs
] = WLAN_EID_EXT_CAPABILITY
;
495 buf
[offs
+ 1] = rdev
->wiphy
.extended_capabilities_len
;
496 memcpy(buf
+ offs
+ 2,
497 rdev
->wiphy
.extended_capabilities
,
498 rdev
->wiphy
.extended_capabilities_len
);
501 *out_ies_len
= ies_len
+ rdev
->wiphy
.extended_capabilities_len
+ 2;
506 static int cfg80211_sme_connect(struct wireless_dev
*wdev
,
507 struct cfg80211_connect_params
*connect
,
508 const u8
*prev_bssid
)
510 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
511 struct cfg80211_bss
*bss
;
514 if (!rdev
->ops
->auth
|| !rdev
->ops
->assoc
)
517 if (wdev
->current_bss
) {
521 !ether_addr_equal(prev_bssid
, wdev
->current_bss
->pub
.bssid
))
523 cfg80211_unhold_bss(wdev
->current_bss
);
524 cfg80211_put_bss(wdev
->wiphy
, &wdev
->current_bss
->pub
);
525 wdev
->current_bss
= NULL
;
527 cfg80211_sme_free(wdev
);
530 if (WARN_ON(wdev
->conn
))
533 wdev
->conn
= kzalloc(sizeof(*wdev
->conn
), GFP_KERNEL
);
538 * Copy all parameters, and treat explicitly IEs, BSSID, SSID.
540 memcpy(&wdev
->conn
->params
, connect
, sizeof(*connect
));
541 if (connect
->bssid
) {
542 wdev
->conn
->params
.bssid
= wdev
->conn
->bssid
;
543 memcpy(wdev
->conn
->bssid
, connect
->bssid
, ETH_ALEN
);
546 if (cfg80211_sme_get_conn_ies(wdev
, connect
->ie
, connect
->ie_len
,
548 &wdev
->conn
->params
.ie_len
)) {
553 wdev
->conn
->params
.ie
= wdev
->conn
->ie
;
555 if (connect
->auth_type
== NL80211_AUTHTYPE_AUTOMATIC
) {
556 wdev
->conn
->auto_auth
= true;
557 /* start with open system ... should mostly work */
558 wdev
->conn
->params
.auth_type
=
559 NL80211_AUTHTYPE_OPEN_SYSTEM
;
561 wdev
->conn
->auto_auth
= false;
564 wdev
->conn
->params
.ssid
= wdev
->ssid
;
565 wdev
->conn
->params
.ssid_len
= wdev
->ssid_len
;
567 /* see if we have the bss already */
568 bss
= cfg80211_get_conn_bss(wdev
);
571 memcpy(wdev
->conn
->prev_bssid
, prev_bssid
, ETH_ALEN
);
572 wdev
->conn
->prev_bssid_valid
= true;
575 /* we're good if we have a matching bss struct */
577 enum nl80211_timeout_reason treason
;
579 err
= cfg80211_conn_do_work(wdev
, &treason
);
580 cfg80211_put_bss(wdev
->wiphy
, bss
);
582 /* otherwise we'll need to scan for the AP first */
583 err
= cfg80211_conn_scan(wdev
);
586 * If we can't scan right now, then we need to scan again
587 * after the current scan finished, since the parameters
588 * changed (unless we find a good AP anyway).
592 wdev
->conn
->state
= CFG80211_CONN_SCAN_AGAIN
;
597 cfg80211_sme_free(wdev
);
602 static int cfg80211_sme_disconnect(struct wireless_dev
*wdev
, u16 reason
)
604 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
610 if (!rdev
->ops
->deauth
)
613 if (wdev
->conn
->state
== CFG80211_CONN_SCANNING
||
614 wdev
->conn
->state
== CFG80211_CONN_SCAN_AGAIN
) {
619 /* wdev->conn->params.bssid must be set if > SCANNING */
620 err
= cfg80211_mlme_deauth(rdev
, wdev
->netdev
,
621 wdev
->conn
->params
.bssid
,
622 NULL
, 0, reason
, false);
624 cfg80211_sme_free(wdev
);
629 * code shared for in-device and software SME
632 static bool cfg80211_is_all_idle(void)
634 struct cfg80211_registered_device
*rdev
;
635 struct wireless_dev
*wdev
;
636 bool is_all_idle
= true;
639 * All devices must be idle as otherwise if you are actively
640 * scanning some new beacon hints could be learned and would
641 * count as new regulatory hints.
643 list_for_each_entry(rdev
, &cfg80211_rdev_list
, list
) {
644 list_for_each_entry(wdev
, &rdev
->wiphy
.wdev_list
, list
) {
646 if (wdev
->conn
|| wdev
->current_bss
)
655 static void disconnect_work(struct work_struct
*work
)
658 if (cfg80211_is_all_idle())
659 regulatory_hint_disconnect();
663 static DECLARE_WORK(cfg80211_disconnect_work
, disconnect_work
);
667 * API calls for drivers implementing connect/disconnect and
671 /* This method must consume bss one way or another */
672 void __cfg80211_connect_result(struct net_device
*dev
, const u8
*bssid
,
673 const u8
*req_ie
, size_t req_ie_len
,
674 const u8
*resp_ie
, size_t resp_ie_len
,
675 int status
, bool wextev
,
676 struct cfg80211_bss
*bss
,
677 enum nl80211_timeout_reason timeout_reason
)
679 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
680 const u8
*country_ie
;
681 #ifdef CONFIG_CFG80211_WEXT
682 union iwreq_data wrqu
;
685 ASSERT_WDEV_LOCK(wdev
);
687 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_STATION
&&
688 wdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
)) {
689 cfg80211_put_bss(wdev
->wiphy
, bss
);
693 nl80211_send_connect_result(wiphy_to_rdev(wdev
->wiphy
), dev
,
694 bssid
, req_ie
, req_ie_len
,
695 resp_ie
, resp_ie_len
,
696 status
, timeout_reason
, GFP_KERNEL
);
698 #ifdef CONFIG_CFG80211_WEXT
700 if (req_ie
&& status
== WLAN_STATUS_SUCCESS
) {
701 memset(&wrqu
, 0, sizeof(wrqu
));
702 wrqu
.data
.length
= req_ie_len
;
703 wireless_send_event(dev
, IWEVASSOCREQIE
, &wrqu
, req_ie
);
706 if (resp_ie
&& status
== WLAN_STATUS_SUCCESS
) {
707 memset(&wrqu
, 0, sizeof(wrqu
));
708 wrqu
.data
.length
= resp_ie_len
;
709 wireless_send_event(dev
, IWEVASSOCRESPIE
, &wrqu
, resp_ie
);
712 memset(&wrqu
, 0, sizeof(wrqu
));
713 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
714 if (bssid
&& status
== WLAN_STATUS_SUCCESS
) {
715 memcpy(wrqu
.ap_addr
.sa_data
, bssid
, ETH_ALEN
);
716 memcpy(wdev
->wext
.prev_bssid
, bssid
, ETH_ALEN
);
717 wdev
->wext
.prev_bssid_valid
= true;
719 wireless_send_event(dev
, SIOCGIWAP
, &wrqu
, NULL
);
723 if (!bss
&& (status
== WLAN_STATUS_SUCCESS
)) {
724 WARN_ON_ONCE(!wiphy_to_rdev(wdev
->wiphy
)->ops
->connect
);
725 bss
= cfg80211_get_bss(wdev
->wiphy
, NULL
, bssid
,
726 wdev
->ssid
, wdev
->ssid_len
,
728 IEEE80211_PRIVACY_ANY
);
730 cfg80211_hold_bss(bss_from_pub(bss
));
733 if (wdev
->current_bss
) {
734 cfg80211_unhold_bss(wdev
->current_bss
);
735 cfg80211_put_bss(wdev
->wiphy
, &wdev
->current_bss
->pub
);
736 wdev
->current_bss
= NULL
;
739 if (status
!= WLAN_STATUS_SUCCESS
) {
740 kzfree(wdev
->connect_keys
);
741 wdev
->connect_keys
= NULL
;
743 wdev
->conn_owner_nlportid
= 0;
745 cfg80211_unhold_bss(bss_from_pub(bss
));
746 cfg80211_put_bss(wdev
->wiphy
, bss
);
748 cfg80211_sme_free(wdev
);
755 wdev
->current_bss
= bss_from_pub(bss
);
757 if (!(wdev
->wiphy
->flags
& WIPHY_FLAG_HAS_STATIC_WEP
))
758 cfg80211_upload_connect_keys(wdev
);
761 country_ie
= ieee80211_bss_get_ie(bss
, WLAN_EID_COUNTRY
);
767 country_ie
= kmemdup(country_ie
, 2 + country_ie
[1], GFP_ATOMIC
);
774 * ieee80211_bss_get_ie() ensures we can access:
775 * - country_ie + 2, the start of the country ie data, and
776 * - and country_ie[1] which is the IE length
778 regulatory_hint_country_ie(wdev
->wiphy
, bss
->channel
->band
,
779 country_ie
+ 2, country_ie
[1]);
783 /* Consumes bss object one way or another */
784 void cfg80211_connect_bss(struct net_device
*dev
, const u8
*bssid
,
785 struct cfg80211_bss
*bss
, const u8
*req_ie
,
786 size_t req_ie_len
, const u8
*resp_ie
,
787 size_t resp_ie_len
, int status
, gfp_t gfp
,
788 enum nl80211_timeout_reason timeout_reason
)
790 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
791 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
792 struct cfg80211_event
*ev
;
796 /* Make sure the bss entry provided by the driver is valid. */
797 struct cfg80211_internal_bss
*ibss
= bss_from_pub(bss
);
799 if (WARN_ON(list_empty(&ibss
->list
))) {
800 cfg80211_put_bss(wdev
->wiphy
, bss
);
805 ev
= kzalloc(sizeof(*ev
) + req_ie_len
+ resp_ie_len
, gfp
);
807 cfg80211_put_bss(wdev
->wiphy
, bss
);
811 ev
->type
= EVENT_CONNECT_RESULT
;
813 memcpy(ev
->cr
.bssid
, bssid
, ETH_ALEN
);
815 ev
->cr
.req_ie
= ((u8
*)ev
) + sizeof(*ev
);
816 ev
->cr
.req_ie_len
= req_ie_len
;
817 memcpy((void *)ev
->cr
.req_ie
, req_ie
, req_ie_len
);
820 ev
->cr
.resp_ie
= ((u8
*)ev
) + sizeof(*ev
) + req_ie_len
;
821 ev
->cr
.resp_ie_len
= resp_ie_len
;
822 memcpy((void *)ev
->cr
.resp_ie
, resp_ie
, resp_ie_len
);
825 cfg80211_hold_bss(bss_from_pub(bss
));
827 ev
->cr
.status
= status
;
828 ev
->cr
.timeout_reason
= timeout_reason
;
830 spin_lock_irqsave(&wdev
->event_lock
, flags
);
831 list_add_tail(&ev
->list
, &wdev
->event_list
);
832 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
833 queue_work(cfg80211_wq
, &rdev
->event_work
);
835 EXPORT_SYMBOL(cfg80211_connect_bss
);
837 /* Consumes bss object one way or another */
838 void __cfg80211_roamed(struct wireless_dev
*wdev
,
839 struct cfg80211_bss
*bss
,
840 const u8
*req_ie
, size_t req_ie_len
,
841 const u8
*resp_ie
, size_t resp_ie_len
)
843 #ifdef CONFIG_CFG80211_WEXT
844 union iwreq_data wrqu
;
846 ASSERT_WDEV_LOCK(wdev
);
848 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_STATION
&&
849 wdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
))
852 if (WARN_ON(!wdev
->current_bss
))
855 cfg80211_unhold_bss(wdev
->current_bss
);
856 cfg80211_put_bss(wdev
->wiphy
, &wdev
->current_bss
->pub
);
857 wdev
->current_bss
= NULL
;
859 cfg80211_hold_bss(bss_from_pub(bss
));
860 wdev
->current_bss
= bss_from_pub(bss
);
862 nl80211_send_roamed(wiphy_to_rdev(wdev
->wiphy
),
863 wdev
->netdev
, bss
->bssid
,
864 req_ie
, req_ie_len
, resp_ie
, resp_ie_len
,
867 #ifdef CONFIG_CFG80211_WEXT
869 memset(&wrqu
, 0, sizeof(wrqu
));
870 wrqu
.data
.length
= req_ie_len
;
871 wireless_send_event(wdev
->netdev
, IWEVASSOCREQIE
,
876 memset(&wrqu
, 0, sizeof(wrqu
));
877 wrqu
.data
.length
= resp_ie_len
;
878 wireless_send_event(wdev
->netdev
, IWEVASSOCRESPIE
,
882 memset(&wrqu
, 0, sizeof(wrqu
));
883 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
884 memcpy(wrqu
.ap_addr
.sa_data
, bss
->bssid
, ETH_ALEN
);
885 memcpy(wdev
->wext
.prev_bssid
, bss
->bssid
, ETH_ALEN
);
886 wdev
->wext
.prev_bssid_valid
= true;
887 wireless_send_event(wdev
->netdev
, SIOCGIWAP
, &wrqu
, NULL
);
892 cfg80211_put_bss(wdev
->wiphy
, bss
);
895 void cfg80211_roamed(struct net_device
*dev
,
896 struct ieee80211_channel
*channel
,
898 const u8
*req_ie
, size_t req_ie_len
,
899 const u8
*resp_ie
, size_t resp_ie_len
, gfp_t gfp
)
901 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
902 struct cfg80211_bss
*bss
;
904 bss
= cfg80211_get_bss(wdev
->wiphy
, channel
, bssid
, wdev
->ssid
,
906 wdev
->conn_bss_type
, IEEE80211_PRIVACY_ANY
);
910 cfg80211_roamed_bss(dev
, bss
, req_ie
, req_ie_len
, resp_ie
,
913 EXPORT_SYMBOL(cfg80211_roamed
);
915 /* Consumes bss object one way or another */
916 void cfg80211_roamed_bss(struct net_device
*dev
,
917 struct cfg80211_bss
*bss
, const u8
*req_ie
,
918 size_t req_ie_len
, const u8
*resp_ie
,
919 size_t resp_ie_len
, gfp_t gfp
)
921 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
922 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
923 struct cfg80211_event
*ev
;
929 ev
= kzalloc(sizeof(*ev
) + req_ie_len
+ resp_ie_len
, gfp
);
931 cfg80211_put_bss(wdev
->wiphy
, bss
);
935 ev
->type
= EVENT_ROAMED
;
936 ev
->rm
.req_ie
= ((u8
*)ev
) + sizeof(*ev
);
937 ev
->rm
.req_ie_len
= req_ie_len
;
938 memcpy((void *)ev
->rm
.req_ie
, req_ie
, req_ie_len
);
939 ev
->rm
.resp_ie
= ((u8
*)ev
) + sizeof(*ev
) + req_ie_len
;
940 ev
->rm
.resp_ie_len
= resp_ie_len
;
941 memcpy((void *)ev
->rm
.resp_ie
, resp_ie
, resp_ie_len
);
944 spin_lock_irqsave(&wdev
->event_lock
, flags
);
945 list_add_tail(&ev
->list
, &wdev
->event_list
);
946 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
947 queue_work(cfg80211_wq
, &rdev
->event_work
);
949 EXPORT_SYMBOL(cfg80211_roamed_bss
);
951 void __cfg80211_disconnected(struct net_device
*dev
, const u8
*ie
,
952 size_t ie_len
, u16 reason
, bool from_ap
)
954 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
955 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
957 #ifdef CONFIG_CFG80211_WEXT
958 union iwreq_data wrqu
;
961 ASSERT_WDEV_LOCK(wdev
);
963 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_STATION
&&
964 wdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
))
967 if (wdev
->current_bss
) {
968 cfg80211_unhold_bss(wdev
->current_bss
);
969 cfg80211_put_bss(wdev
->wiphy
, &wdev
->current_bss
->pub
);
972 wdev
->current_bss
= NULL
;
974 wdev
->conn_owner_nlportid
= 0;
976 nl80211_send_disconnected(rdev
, dev
, reason
, ie
, ie_len
, from_ap
);
978 /* stop critical protocol if supported */
979 if (rdev
->ops
->crit_proto_stop
&& rdev
->crit_proto_nlportid
) {
980 rdev
->crit_proto_nlportid
= 0;
981 rdev_crit_proto_stop(rdev
, wdev
);
985 * Delete all the keys ... pairwise keys can't really
986 * exist any more anyway, but default keys might.
988 if (rdev
->ops
->del_key
)
989 for (i
= 0; i
< 6; i
++)
990 rdev_del_key(rdev
, dev
, i
, false, NULL
);
992 rdev_set_qos_map(rdev
, dev
, NULL
);
994 #ifdef CONFIG_CFG80211_WEXT
995 memset(&wrqu
, 0, sizeof(wrqu
));
996 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
997 wireless_send_event(dev
, SIOCGIWAP
, &wrqu
, NULL
);
998 wdev
->wext
.connect
.ssid_len
= 0;
1001 schedule_work(&cfg80211_disconnect_work
);
1004 void cfg80211_disconnected(struct net_device
*dev
, u16 reason
,
1005 const u8
*ie
, size_t ie_len
,
1006 bool locally_generated
, gfp_t gfp
)
1008 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
1009 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
1010 struct cfg80211_event
*ev
;
1011 unsigned long flags
;
1013 ev
= kzalloc(sizeof(*ev
) + ie_len
, gfp
);
1017 ev
->type
= EVENT_DISCONNECTED
;
1018 ev
->dc
.ie
= ((u8
*)ev
) + sizeof(*ev
);
1019 ev
->dc
.ie_len
= ie_len
;
1020 memcpy((void *)ev
->dc
.ie
, ie
, ie_len
);
1021 ev
->dc
.reason
= reason
;
1022 ev
->dc
.locally_generated
= locally_generated
;
1024 spin_lock_irqsave(&wdev
->event_lock
, flags
);
1025 list_add_tail(&ev
->list
, &wdev
->event_list
);
1026 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
1027 queue_work(cfg80211_wq
, &rdev
->event_work
);
1029 EXPORT_SYMBOL(cfg80211_disconnected
);
1032 * API calls for nl80211/wext compatibility code
1034 int cfg80211_connect(struct cfg80211_registered_device
*rdev
,
1035 struct net_device
*dev
,
1036 struct cfg80211_connect_params
*connect
,
1037 struct cfg80211_cached_keys
*connkeys
,
1038 const u8
*prev_bssid
)
1040 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
1043 ASSERT_WDEV_LOCK(wdev
);
1045 if (WARN_ON(wdev
->connect_keys
)) {
1046 kzfree(wdev
->connect_keys
);
1047 wdev
->connect_keys
= NULL
;
1050 cfg80211_oper_and_ht_capa(&connect
->ht_capa_mask
,
1051 rdev
->wiphy
.ht_capa_mod_mask
);
1053 if (connkeys
&& connkeys
->def
>= 0) {
1057 idx
= connkeys
->def
;
1058 cipher
= connkeys
->params
[idx
].cipher
;
1059 /* If given a WEP key we may need it for shared key auth */
1060 if (cipher
== WLAN_CIPHER_SUITE_WEP40
||
1061 cipher
== WLAN_CIPHER_SUITE_WEP104
) {
1062 connect
->key_idx
= idx
;
1063 connect
->key
= connkeys
->params
[idx
].key
;
1064 connect
->key_len
= connkeys
->params
[idx
].key_len
;
1067 * If ciphers are not set (e.g. when going through
1068 * iwconfig), we have to set them appropriately here.
1070 if (connect
->crypto
.cipher_group
== 0)
1071 connect
->crypto
.cipher_group
= cipher
;
1073 if (connect
->crypto
.n_ciphers_pairwise
== 0) {
1074 connect
->crypto
.n_ciphers_pairwise
= 1;
1075 connect
->crypto
.ciphers_pairwise
[0] = cipher
;
1079 connect
->crypto
.wep_keys
= connkeys
->params
;
1080 connect
->crypto
.wep_tx_key
= connkeys
->def
;
1082 if (WARN_ON(connkeys
))
1086 wdev
->connect_keys
= connkeys
;
1087 memcpy(wdev
->ssid
, connect
->ssid
, connect
->ssid_len
);
1088 wdev
->ssid_len
= connect
->ssid_len
;
1090 wdev
->conn_bss_type
= connect
->pbss
? IEEE80211_BSS_TYPE_PBSS
:
1091 IEEE80211_BSS_TYPE_ESS
;
1093 if (!rdev
->ops
->connect
)
1094 err
= cfg80211_sme_connect(wdev
, connect
, prev_bssid
);
1096 err
= rdev_connect(rdev
, dev
, connect
);
1099 wdev
->connect_keys
= NULL
;
1107 int cfg80211_disconnect(struct cfg80211_registered_device
*rdev
,
1108 struct net_device
*dev
, u16 reason
, bool wextev
)
1110 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
1113 ASSERT_WDEV_LOCK(wdev
);
1115 kzfree(wdev
->connect_keys
);
1116 wdev
->connect_keys
= NULL
;
1118 wdev
->conn_owner_nlportid
= 0;
1121 err
= cfg80211_sme_disconnect(wdev
, reason
);
1122 else if (!rdev
->ops
->disconnect
)
1123 cfg80211_mlme_down(rdev
, dev
);
1124 else if (wdev
->ssid_len
)
1125 err
= rdev_disconnect(rdev
, dev
, reason
);
1131 * Used to clean up after the connection / connection attempt owner socket
1134 void cfg80211_autodisconnect_wk(struct work_struct
*work
)
1136 struct wireless_dev
*wdev
=
1137 container_of(work
, struct wireless_dev
, disconnect_wk
);
1138 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
1142 if (wdev
->conn_owner_nlportid
) {
1144 * Use disconnect_bssid if still connecting and ops->disconnect
1145 * not implemented. Otherwise we can use cfg80211_disconnect.
1147 if (rdev
->ops
->disconnect
|| wdev
->current_bss
)
1148 cfg80211_disconnect(rdev
, wdev
->netdev
,
1149 WLAN_REASON_DEAUTH_LEAVING
, true);
1151 cfg80211_mlme_deauth(rdev
, wdev
->netdev
,
1152 wdev
->disconnect_bssid
, NULL
, 0,
1153 WLAN_REASON_DEAUTH_LEAVING
, false);