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_ABANDON
,
43 CFG80211_CONN_CONNECTED
,
45 u8 bssid
[ETH_ALEN
], prev_bssid
[ETH_ALEN
];
48 bool auto_auth
, prev_bssid_valid
;
51 static void cfg80211_sme_free(struct wireless_dev
*wdev
)
56 kfree(wdev
->conn
->ie
);
61 static int cfg80211_conn_scan(struct wireless_dev
*wdev
)
63 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
64 struct cfg80211_scan_request
*request
;
68 ASSERT_WDEV_LOCK(wdev
);
70 if (rdev
->scan_req
|| rdev
->scan_msg
)
73 if (wdev
->conn
->params
.channel
)
76 n_channels
= ieee80211_get_num_supported_channels(wdev
->wiphy
);
78 request
= kzalloc(sizeof(*request
) + sizeof(request
->ssids
[0]) +
79 sizeof(request
->channels
[0]) * n_channels
,
84 if (wdev
->conn
->params
.channel
) {
85 enum nl80211_band band
= wdev
->conn
->params
.channel
->band
;
86 struct ieee80211_supported_band
*sband
=
87 wdev
->wiphy
->bands
[band
];
93 request
->channels
[0] = wdev
->conn
->params
.channel
;
94 request
->rates
[band
] = (1 << sband
->n_bitrates
) - 1;
97 enum nl80211_band band
;
98 struct ieee80211_supported_band
*bands
;
99 struct ieee80211_channel
*channel
;
101 for (band
= 0; band
< NUM_NL80211_BANDS
; band
++) {
102 bands
= wdev
->wiphy
->bands
[band
];
105 for (j
= 0; j
< bands
->n_channels
; j
++) {
106 channel
= &bands
->channels
[j
];
107 if (channel
->flags
& IEEE80211_CHAN_DISABLED
)
109 request
->channels
[i
++] = channel
;
111 request
->rates
[band
] = (1 << bands
->n_bitrates
) - 1;
115 request
->n_channels
= n_channels
;
116 request
->ssids
= (void *)&request
->channels
[n_channels
];
117 request
->n_ssids
= 1;
119 memcpy(request
->ssids
[0].ssid
, wdev
->conn
->params
.ssid
,
120 wdev
->conn
->params
.ssid_len
);
121 request
->ssids
[0].ssid_len
= wdev
->conn
->params
.ssid_len
;
123 request
->wdev
= wdev
;
124 request
->wiphy
= &rdev
->wiphy
;
125 request
->scan_start
= jiffies
;
127 rdev
->scan_req
= request
;
129 err
= rdev_scan(rdev
, request
);
131 wdev
->conn
->state
= CFG80211_CONN_SCANNING
;
132 nl80211_send_scan_start(rdev
, wdev
);
133 dev_hold(wdev
->netdev
);
135 rdev
->scan_req
= NULL
;
141 static int cfg80211_conn_do_work(struct wireless_dev
*wdev
)
143 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
144 struct cfg80211_connect_params
*params
;
145 struct cfg80211_assoc_request req
= {};
148 ASSERT_WDEV_LOCK(wdev
);
153 params
= &wdev
->conn
->params
;
155 switch (wdev
->conn
->state
) {
156 case CFG80211_CONN_SCANNING
:
157 /* didn't find it during scan ... */
159 case CFG80211_CONN_SCAN_AGAIN
:
160 return cfg80211_conn_scan(wdev
);
161 case CFG80211_CONN_AUTHENTICATE_NEXT
:
162 if (WARN_ON(!rdev
->ops
->auth
))
164 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATING
;
165 return cfg80211_mlme_auth(rdev
, wdev
->netdev
,
166 params
->channel
, params
->auth_type
,
168 params
->ssid
, params
->ssid_len
,
170 params
->key
, params
->key_len
,
171 params
->key_idx
, NULL
, 0);
172 case CFG80211_CONN_AUTH_FAILED
:
174 case CFG80211_CONN_ASSOCIATE_NEXT
:
175 if (WARN_ON(!rdev
->ops
->assoc
))
177 wdev
->conn
->state
= CFG80211_CONN_ASSOCIATING
;
178 if (wdev
->conn
->prev_bssid_valid
)
179 req
.prev_bssid
= wdev
->conn
->prev_bssid
;
181 req
.ie_len
= params
->ie_len
;
182 req
.use_mfp
= params
->mfp
!= NL80211_MFP_NO
;
183 req
.crypto
= params
->crypto
;
184 req
.flags
= params
->flags
;
185 req
.ht_capa
= params
->ht_capa
;
186 req
.ht_capa_mask
= params
->ht_capa_mask
;
187 req
.vht_capa
= params
->vht_capa
;
188 req
.vht_capa_mask
= params
->vht_capa_mask
;
190 err
= cfg80211_mlme_assoc(rdev
, wdev
->netdev
, params
->channel
,
191 params
->bssid
, params
->ssid
,
192 params
->ssid_len
, &req
);
194 cfg80211_mlme_deauth(rdev
, wdev
->netdev
, params
->bssid
,
196 WLAN_REASON_DEAUTH_LEAVING
,
199 case CFG80211_CONN_ASSOC_FAILED
:
200 cfg80211_mlme_deauth(rdev
, wdev
->netdev
, params
->bssid
,
202 WLAN_REASON_DEAUTH_LEAVING
, false);
204 case CFG80211_CONN_DEAUTH
:
205 cfg80211_mlme_deauth(rdev
, wdev
->netdev
, params
->bssid
,
207 WLAN_REASON_DEAUTH_LEAVING
, false);
209 case CFG80211_CONN_ABANDON
:
210 /* free directly, disconnected event already sent */
211 cfg80211_sme_free(wdev
);
218 void cfg80211_conn_work(struct work_struct
*work
)
220 struct cfg80211_registered_device
*rdev
=
221 container_of(work
, struct cfg80211_registered_device
, conn_work
);
222 struct wireless_dev
*wdev
;
223 u8 bssid_buf
[ETH_ALEN
], *bssid
= NULL
;
227 list_for_each_entry(wdev
, &rdev
->wdev_list
, list
) {
232 if (!netif_running(wdev
->netdev
)) {
237 wdev
->conn
->state
== CFG80211_CONN_CONNECTED
) {
241 if (wdev
->conn
->params
.bssid
) {
242 memcpy(bssid_buf
, wdev
->conn
->params
.bssid
, ETH_ALEN
);
245 if (cfg80211_conn_do_work(wdev
)) {
246 __cfg80211_connect_result(
249 WLAN_STATUS_UNSPECIFIED_FAILURE
,
258 /* Returned bss is reference counted and must be cleaned up appropriately. */
259 static struct cfg80211_bss
*cfg80211_get_conn_bss(struct wireless_dev
*wdev
)
261 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
262 struct cfg80211_bss
*bss
;
264 ASSERT_WDEV_LOCK(wdev
);
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 IEEE80211_BSS_TYPE_ESS
,
271 IEEE80211_PRIVACY(wdev
->conn
->params
.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_rdev(wdev
->wiphy
);
288 struct cfg80211_bss
*bss
;
290 ASSERT_WDEV_LOCK(wdev
);
295 if (wdev
->conn
->state
!= CFG80211_CONN_SCANNING
&&
296 wdev
->conn
->state
!= CFG80211_CONN_SCAN_AGAIN
)
299 bss
= cfg80211_get_conn_bss(wdev
);
301 cfg80211_put_bss(&rdev
->wiphy
, bss
);
303 schedule_work(&rdev
->conn_work
);
306 void cfg80211_sme_scan_done(struct net_device
*dev
)
308 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
311 __cfg80211_sme_scan_done(dev
);
315 void cfg80211_sme_rx_auth(struct wireless_dev
*wdev
, const u8
*buf
, size_t len
)
317 struct wiphy
*wiphy
= wdev
->wiphy
;
318 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wiphy
);
319 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*)buf
;
320 u16 status_code
= le16_to_cpu(mgmt
->u
.auth
.status_code
);
322 ASSERT_WDEV_LOCK(wdev
);
324 if (!wdev
->conn
|| wdev
->conn
->state
== CFG80211_CONN_CONNECTED
)
327 if (status_code
== WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
&&
328 wdev
->conn
->auto_auth
&&
329 wdev
->conn
->params
.auth_type
!= NL80211_AUTHTYPE_NETWORK_EAP
) {
330 /* select automatically between only open, shared, leap */
331 switch (wdev
->conn
->params
.auth_type
) {
332 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
333 if (wdev
->connect_keys
)
334 wdev
->conn
->params
.auth_type
=
335 NL80211_AUTHTYPE_SHARED_KEY
;
337 wdev
->conn
->params
.auth_type
=
338 NL80211_AUTHTYPE_NETWORK_EAP
;
340 case NL80211_AUTHTYPE_SHARED_KEY
:
341 wdev
->conn
->params
.auth_type
=
342 NL80211_AUTHTYPE_NETWORK_EAP
;
346 wdev
->conn
->params
.auth_type
=
347 NL80211_AUTHTYPE_OPEN_SYSTEM
;
350 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATE_NEXT
;
351 schedule_work(&rdev
->conn_work
);
352 } else if (status_code
!= WLAN_STATUS_SUCCESS
) {
353 __cfg80211_connect_result(wdev
->netdev
, mgmt
->bssid
,
355 status_code
, false, NULL
);
356 } else if (wdev
->conn
->state
== CFG80211_CONN_AUTHENTICATING
) {
357 wdev
->conn
->state
= CFG80211_CONN_ASSOCIATE_NEXT
;
358 schedule_work(&rdev
->conn_work
);
362 bool cfg80211_sme_rx_assoc_resp(struct wireless_dev
*wdev
, u16 status
)
364 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
369 if (status
== WLAN_STATUS_SUCCESS
) {
370 wdev
->conn
->state
= CFG80211_CONN_CONNECTED
;
374 if (wdev
->conn
->prev_bssid_valid
) {
376 * Some stupid APs don't accept reassoc, so we
377 * need to fall back to trying regular assoc;
378 * return true so no event is sent to userspace.
380 wdev
->conn
->prev_bssid_valid
= false;
381 wdev
->conn
->state
= CFG80211_CONN_ASSOCIATE_NEXT
;
382 schedule_work(&rdev
->conn_work
);
386 wdev
->conn
->state
= CFG80211_CONN_ASSOC_FAILED
;
387 schedule_work(&rdev
->conn_work
);
391 void cfg80211_sme_deauth(struct wireless_dev
*wdev
)
393 cfg80211_sme_free(wdev
);
396 void cfg80211_sme_auth_timeout(struct wireless_dev
*wdev
)
398 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
403 wdev
->conn
->state
= CFG80211_CONN_AUTH_FAILED
;
404 schedule_work(&rdev
->conn_work
);
407 void cfg80211_sme_disassoc(struct wireless_dev
*wdev
)
409 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
414 wdev
->conn
->state
= CFG80211_CONN_DEAUTH
;
415 schedule_work(&rdev
->conn_work
);
418 void cfg80211_sme_assoc_timeout(struct wireless_dev
*wdev
)
420 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
425 wdev
->conn
->state
= CFG80211_CONN_ASSOC_FAILED
;
426 schedule_work(&rdev
->conn_work
);
429 void cfg80211_sme_abandon_assoc(struct wireless_dev
*wdev
)
431 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
436 wdev
->conn
->state
= CFG80211_CONN_ABANDON
;
437 schedule_work(&rdev
->conn_work
);
440 static int cfg80211_sme_get_conn_ies(struct wireless_dev
*wdev
,
441 const u8
*ies
, size_t ies_len
,
442 const u8
**out_ies
, size_t *out_ies_len
)
444 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
448 if (!rdev
->wiphy
.extended_capabilities_len
||
449 (ies
&& cfg80211_find_ie(WLAN_EID_EXT_CAPABILITY
, ies
, ies_len
))) {
450 *out_ies
= kmemdup(ies
, ies_len
, GFP_KERNEL
);
453 *out_ies_len
= ies_len
;
457 buf
= kmalloc(ies_len
+ rdev
->wiphy
.extended_capabilities_len
+ 2,
463 static const u8 before_extcapa
[] = {
464 /* not listing IEs expected to be created by driver */
467 WLAN_EID_RRM_ENABLED_CAPABILITIES
,
468 WLAN_EID_MOBILITY_DOMAIN
,
469 WLAN_EID_SUPPORTED_REGULATORY_CLASSES
,
470 WLAN_EID_BSS_COEX_2040
,
473 offs
= ieee80211_ie_split(ies
, ies_len
, before_extcapa
,
474 ARRAY_SIZE(before_extcapa
), 0);
475 memcpy(buf
, ies
, offs
);
476 /* leave a whole for extended capabilities IE */
477 memcpy(buf
+ offs
+ rdev
->wiphy
.extended_capabilities_len
+ 2,
478 ies
+ offs
, ies_len
- offs
);
483 /* place extended capabilities IE (with only driver capabilities) */
484 buf
[offs
] = WLAN_EID_EXT_CAPABILITY
;
485 buf
[offs
+ 1] = rdev
->wiphy
.extended_capabilities_len
;
486 memcpy(buf
+ offs
+ 2,
487 rdev
->wiphy
.extended_capabilities
,
488 rdev
->wiphy
.extended_capabilities_len
);
491 *out_ies_len
= ies_len
+ rdev
->wiphy
.extended_capabilities_len
+ 2;
496 static int cfg80211_sme_connect(struct wireless_dev
*wdev
,
497 struct cfg80211_connect_params
*connect
,
498 const u8
*prev_bssid
)
500 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
501 struct cfg80211_bss
*bss
;
504 if (!rdev
->ops
->auth
|| !rdev
->ops
->assoc
)
507 if (wdev
->current_bss
)
510 if (WARN_ON(wdev
->conn
))
513 wdev
->conn
= kzalloc(sizeof(*wdev
->conn
), GFP_KERNEL
);
518 * Copy all parameters, and treat explicitly IEs, BSSID, SSID.
520 memcpy(&wdev
->conn
->params
, connect
, sizeof(*connect
));
521 if (connect
->bssid
) {
522 wdev
->conn
->params
.bssid
= wdev
->conn
->bssid
;
523 memcpy(wdev
->conn
->bssid
, connect
->bssid
, ETH_ALEN
);
526 if (cfg80211_sme_get_conn_ies(wdev
, connect
->ie
, connect
->ie_len
,
528 &wdev
->conn
->params
.ie_len
)) {
533 wdev
->conn
->params
.ie
= wdev
->conn
->ie
;
535 if (connect
->auth_type
== NL80211_AUTHTYPE_AUTOMATIC
) {
536 wdev
->conn
->auto_auth
= true;
537 /* start with open system ... should mostly work */
538 wdev
->conn
->params
.auth_type
=
539 NL80211_AUTHTYPE_OPEN_SYSTEM
;
541 wdev
->conn
->auto_auth
= false;
544 wdev
->conn
->params
.ssid
= wdev
->ssid
;
545 wdev
->conn
->params
.ssid_len
= wdev
->ssid_len
;
547 /* see if we have the bss already */
548 bss
= cfg80211_get_conn_bss(wdev
);
551 memcpy(wdev
->conn
->prev_bssid
, prev_bssid
, ETH_ALEN
);
552 wdev
->conn
->prev_bssid_valid
= true;
555 /* we're good if we have a matching bss struct */
557 err
= cfg80211_conn_do_work(wdev
);
558 cfg80211_put_bss(wdev
->wiphy
, bss
);
560 /* otherwise we'll need to scan for the AP first */
561 err
= cfg80211_conn_scan(wdev
);
564 * If we can't scan right now, then we need to scan again
565 * after the current scan finished, since the parameters
566 * changed (unless we find a good AP anyway).
570 wdev
->conn
->state
= CFG80211_CONN_SCAN_AGAIN
;
575 cfg80211_sme_free(wdev
);
580 static int cfg80211_sme_disconnect(struct wireless_dev
*wdev
, u16 reason
)
582 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
588 if (!rdev
->ops
->deauth
)
591 if (wdev
->conn
->state
== CFG80211_CONN_SCANNING
||
592 wdev
->conn
->state
== CFG80211_CONN_SCAN_AGAIN
) {
597 /* wdev->conn->params.bssid must be set if > SCANNING */
598 err
= cfg80211_mlme_deauth(rdev
, wdev
->netdev
,
599 wdev
->conn
->params
.bssid
,
600 NULL
, 0, reason
, false);
602 cfg80211_sme_free(wdev
);
607 * code shared for in-device and software SME
610 static bool cfg80211_is_all_idle(void)
612 struct cfg80211_registered_device
*rdev
;
613 struct wireless_dev
*wdev
;
614 bool is_all_idle
= true;
617 * All devices must be idle as otherwise if you are actively
618 * scanning some new beacon hints could be learned and would
619 * count as new regulatory hints.
621 list_for_each_entry(rdev
, &cfg80211_rdev_list
, list
) {
622 list_for_each_entry(wdev
, &rdev
->wdev_list
, list
) {
624 if (wdev
->conn
|| wdev
->current_bss
)
633 static void disconnect_work(struct work_struct
*work
)
636 if (cfg80211_is_all_idle())
637 regulatory_hint_disconnect();
641 static DECLARE_WORK(cfg80211_disconnect_work
, disconnect_work
);
645 * API calls for drivers implementing connect/disconnect and
649 /* This method must consume bss one way or another */
650 void __cfg80211_connect_result(struct net_device
*dev
, const u8
*bssid
,
651 const u8
*req_ie
, size_t req_ie_len
,
652 const u8
*resp_ie
, size_t resp_ie_len
,
653 u16 status
, bool wextev
,
654 struct cfg80211_bss
*bss
)
656 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
657 const u8
*country_ie
;
658 #ifdef CONFIG_CFG80211_WEXT
659 union iwreq_data wrqu
;
662 ASSERT_WDEV_LOCK(wdev
);
664 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_STATION
&&
665 wdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
)) {
666 cfg80211_put_bss(wdev
->wiphy
, bss
);
670 nl80211_send_connect_result(wiphy_to_rdev(wdev
->wiphy
), dev
,
671 bssid
, req_ie
, req_ie_len
,
672 resp_ie
, resp_ie_len
,
675 #ifdef CONFIG_CFG80211_WEXT
677 if (req_ie
&& status
== WLAN_STATUS_SUCCESS
) {
678 memset(&wrqu
, 0, sizeof(wrqu
));
679 wrqu
.data
.length
= req_ie_len
;
680 wireless_send_event(dev
, IWEVASSOCREQIE
, &wrqu
, req_ie
);
683 if (resp_ie
&& status
== WLAN_STATUS_SUCCESS
) {
684 memset(&wrqu
, 0, sizeof(wrqu
));
685 wrqu
.data
.length
= resp_ie_len
;
686 wireless_send_event(dev
, IWEVASSOCRESPIE
, &wrqu
, resp_ie
);
689 memset(&wrqu
, 0, sizeof(wrqu
));
690 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
691 if (bssid
&& status
== WLAN_STATUS_SUCCESS
) {
692 memcpy(wrqu
.ap_addr
.sa_data
, bssid
, ETH_ALEN
);
693 memcpy(wdev
->wext
.prev_bssid
, bssid
, ETH_ALEN
);
694 wdev
->wext
.prev_bssid_valid
= true;
696 wireless_send_event(dev
, SIOCGIWAP
, &wrqu
, NULL
);
700 if (!bss
&& (status
== WLAN_STATUS_SUCCESS
)) {
701 WARN_ON_ONCE(!wiphy_to_rdev(wdev
->wiphy
)->ops
->connect
);
702 bss
= cfg80211_get_bss(wdev
->wiphy
, NULL
, bssid
,
703 wdev
->ssid
, wdev
->ssid_len
,
704 IEEE80211_BSS_TYPE_ESS
,
705 IEEE80211_PRIVACY_ANY
);
707 cfg80211_hold_bss(bss_from_pub(bss
));
710 if (wdev
->current_bss
) {
711 cfg80211_unhold_bss(wdev
->current_bss
);
712 cfg80211_put_bss(wdev
->wiphy
, &wdev
->current_bss
->pub
);
713 wdev
->current_bss
= NULL
;
716 if (status
!= WLAN_STATUS_SUCCESS
) {
717 kzfree(wdev
->connect_keys
);
718 wdev
->connect_keys
= NULL
;
721 cfg80211_unhold_bss(bss_from_pub(bss
));
722 cfg80211_put_bss(wdev
->wiphy
, bss
);
724 cfg80211_sme_free(wdev
);
731 wdev
->current_bss
= bss_from_pub(bss
);
733 cfg80211_upload_connect_keys(wdev
);
736 country_ie
= ieee80211_bss_get_ie(bss
, WLAN_EID_COUNTRY
);
742 country_ie
= kmemdup(country_ie
, 2 + country_ie
[1], GFP_ATOMIC
);
749 * ieee80211_bss_get_ie() ensures we can access:
750 * - country_ie + 2, the start of the country ie data, and
751 * - and country_ie[1] which is the IE length
753 regulatory_hint_country_ie(wdev
->wiphy
, bss
->channel
->band
,
754 country_ie
+ 2, country_ie
[1]);
758 void cfg80211_connect_result(struct net_device
*dev
, const u8
*bssid
,
759 const u8
*req_ie
, size_t req_ie_len
,
760 const u8
*resp_ie
, size_t resp_ie_len
,
761 u16 status
, gfp_t gfp
)
763 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
764 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
765 struct cfg80211_event
*ev
;
768 ev
= kzalloc(sizeof(*ev
) + req_ie_len
+ resp_ie_len
, gfp
);
772 ev
->type
= EVENT_CONNECT_RESULT
;
774 memcpy(ev
->cr
.bssid
, bssid
, ETH_ALEN
);
776 ev
->cr
.req_ie
= ((u8
*)ev
) + sizeof(*ev
);
777 ev
->cr
.req_ie_len
= req_ie_len
;
778 memcpy((void *)ev
->cr
.req_ie
, req_ie
, req_ie_len
);
781 ev
->cr
.resp_ie
= ((u8
*)ev
) + sizeof(*ev
) + req_ie_len
;
782 ev
->cr
.resp_ie_len
= resp_ie_len
;
783 memcpy((void *)ev
->cr
.resp_ie
, resp_ie
, resp_ie_len
);
785 ev
->cr
.status
= status
;
787 spin_lock_irqsave(&wdev
->event_lock
, flags
);
788 list_add_tail(&ev
->list
, &wdev
->event_list
);
789 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
790 queue_work(cfg80211_wq
, &rdev
->event_work
);
792 EXPORT_SYMBOL(cfg80211_connect_result
);
794 /* Consumes bss object one way or another */
795 void __cfg80211_roamed(struct wireless_dev
*wdev
,
796 struct cfg80211_bss
*bss
,
797 const u8
*req_ie
, size_t req_ie_len
,
798 const u8
*resp_ie
, size_t resp_ie_len
)
800 #ifdef CONFIG_CFG80211_WEXT
801 union iwreq_data wrqu
;
803 ASSERT_WDEV_LOCK(wdev
);
805 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_STATION
&&
806 wdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
))
809 if (WARN_ON(!wdev
->current_bss
))
812 cfg80211_unhold_bss(wdev
->current_bss
);
813 cfg80211_put_bss(wdev
->wiphy
, &wdev
->current_bss
->pub
);
814 wdev
->current_bss
= NULL
;
816 cfg80211_hold_bss(bss_from_pub(bss
));
817 wdev
->current_bss
= bss_from_pub(bss
);
819 nl80211_send_roamed(wiphy_to_rdev(wdev
->wiphy
),
820 wdev
->netdev
, bss
->bssid
,
821 req_ie
, req_ie_len
, resp_ie
, resp_ie_len
,
824 #ifdef CONFIG_CFG80211_WEXT
826 memset(&wrqu
, 0, sizeof(wrqu
));
827 wrqu
.data
.length
= req_ie_len
;
828 wireless_send_event(wdev
->netdev
, IWEVASSOCREQIE
,
833 memset(&wrqu
, 0, sizeof(wrqu
));
834 wrqu
.data
.length
= resp_ie_len
;
835 wireless_send_event(wdev
->netdev
, IWEVASSOCRESPIE
,
839 memset(&wrqu
, 0, sizeof(wrqu
));
840 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
841 memcpy(wrqu
.ap_addr
.sa_data
, bss
->bssid
, ETH_ALEN
);
842 memcpy(wdev
->wext
.prev_bssid
, bss
->bssid
, ETH_ALEN
);
843 wdev
->wext
.prev_bssid_valid
= true;
844 wireless_send_event(wdev
->netdev
, SIOCGIWAP
, &wrqu
, NULL
);
849 cfg80211_put_bss(wdev
->wiphy
, bss
);
852 void cfg80211_roamed(struct net_device
*dev
,
853 struct ieee80211_channel
*channel
,
855 const u8
*req_ie
, size_t req_ie_len
,
856 const u8
*resp_ie
, size_t resp_ie_len
, gfp_t gfp
)
858 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
859 struct cfg80211_bss
*bss
;
861 bss
= cfg80211_get_bss(wdev
->wiphy
, channel
, bssid
, wdev
->ssid
,
863 IEEE80211_BSS_TYPE_ESS
, IEEE80211_PRIVACY_ANY
);
867 cfg80211_roamed_bss(dev
, bss
, req_ie
, req_ie_len
, resp_ie
,
870 EXPORT_SYMBOL(cfg80211_roamed
);
872 /* Consumes bss object one way or another */
873 void cfg80211_roamed_bss(struct net_device
*dev
,
874 struct cfg80211_bss
*bss
, const u8
*req_ie
,
875 size_t req_ie_len
, const u8
*resp_ie
,
876 size_t resp_ie_len
, gfp_t gfp
)
878 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
879 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
880 struct cfg80211_event
*ev
;
886 ev
= kzalloc(sizeof(*ev
) + req_ie_len
+ resp_ie_len
, gfp
);
888 cfg80211_put_bss(wdev
->wiphy
, bss
);
892 ev
->type
= EVENT_ROAMED
;
893 ev
->rm
.req_ie
= ((u8
*)ev
) + sizeof(*ev
);
894 ev
->rm
.req_ie_len
= req_ie_len
;
895 memcpy((void *)ev
->rm
.req_ie
, req_ie
, req_ie_len
);
896 ev
->rm
.resp_ie
= ((u8
*)ev
) + sizeof(*ev
) + req_ie_len
;
897 ev
->rm
.resp_ie_len
= resp_ie_len
;
898 memcpy((void *)ev
->rm
.resp_ie
, resp_ie
, resp_ie_len
);
901 spin_lock_irqsave(&wdev
->event_lock
, flags
);
902 list_add_tail(&ev
->list
, &wdev
->event_list
);
903 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
904 queue_work(cfg80211_wq
, &rdev
->event_work
);
906 EXPORT_SYMBOL(cfg80211_roamed_bss
);
908 void __cfg80211_disconnected(struct net_device
*dev
, const u8
*ie
,
909 size_t ie_len
, u16 reason
, bool from_ap
)
911 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
912 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
914 #ifdef CONFIG_CFG80211_WEXT
915 union iwreq_data wrqu
;
918 ASSERT_WDEV_LOCK(wdev
);
920 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_STATION
&&
921 wdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
))
924 if (wdev
->current_bss
) {
925 cfg80211_unhold_bss(wdev
->current_bss
);
926 cfg80211_put_bss(wdev
->wiphy
, &wdev
->current_bss
->pub
);
929 wdev
->current_bss
= NULL
;
932 nl80211_send_disconnected(rdev
, dev
, reason
, ie
, ie_len
, from_ap
);
935 * Delete all the keys ... pairwise keys can't really
936 * exist any more anyway, but default keys might.
938 if (rdev
->ops
->del_key
)
939 for (i
= 0; i
< 6; i
++)
940 rdev_del_key(rdev
, dev
, i
, false, NULL
);
942 rdev_set_qos_map(rdev
, dev
, NULL
);
944 #ifdef CONFIG_CFG80211_WEXT
945 memset(&wrqu
, 0, sizeof(wrqu
));
946 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
947 wireless_send_event(dev
, SIOCGIWAP
, &wrqu
, NULL
);
948 wdev
->wext
.connect
.ssid_len
= 0;
951 schedule_work(&cfg80211_disconnect_work
);
954 void cfg80211_disconnected(struct net_device
*dev
, u16 reason
,
955 const u8
*ie
, size_t ie_len
,
956 bool locally_generated
, gfp_t gfp
)
958 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
959 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
960 struct cfg80211_event
*ev
;
963 ev
= kzalloc(sizeof(*ev
) + ie_len
, gfp
);
967 ev
->type
= EVENT_DISCONNECTED
;
968 ev
->dc
.ie
= ((u8
*)ev
) + sizeof(*ev
);
969 ev
->dc
.ie_len
= ie_len
;
970 memcpy((void *)ev
->dc
.ie
, ie
, ie_len
);
971 ev
->dc
.reason
= reason
;
972 ev
->dc
.locally_generated
= locally_generated
;
974 spin_lock_irqsave(&wdev
->event_lock
, flags
);
975 list_add_tail(&ev
->list
, &wdev
->event_list
);
976 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
977 queue_work(cfg80211_wq
, &rdev
->event_work
);
979 EXPORT_SYMBOL(cfg80211_disconnected
);
982 * API calls for nl80211/wext compatibility code
984 int cfg80211_connect(struct cfg80211_registered_device
*rdev
,
985 struct net_device
*dev
,
986 struct cfg80211_connect_params
*connect
,
987 struct cfg80211_cached_keys
*connkeys
,
988 const u8
*prev_bssid
)
990 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
993 ASSERT_WDEV_LOCK(wdev
);
995 if (WARN_ON(wdev
->connect_keys
)) {
996 kzfree(wdev
->connect_keys
);
997 wdev
->connect_keys
= NULL
;
1000 cfg80211_oper_and_ht_capa(&connect
->ht_capa_mask
,
1001 rdev
->wiphy
.ht_capa_mod_mask
);
1003 if (connkeys
&& connkeys
->def
>= 0) {
1007 idx
= connkeys
->def
;
1008 cipher
= connkeys
->params
[idx
].cipher
;
1009 /* If given a WEP key we may need it for shared key auth */
1010 if (cipher
== WLAN_CIPHER_SUITE_WEP40
||
1011 cipher
== WLAN_CIPHER_SUITE_WEP104
) {
1012 connect
->key_idx
= idx
;
1013 connect
->key
= connkeys
->params
[idx
].key
;
1014 connect
->key_len
= connkeys
->params
[idx
].key_len
;
1017 * If ciphers are not set (e.g. when going through
1018 * iwconfig), we have to set them appropriately here.
1020 if (connect
->crypto
.cipher_group
== 0)
1021 connect
->crypto
.cipher_group
= cipher
;
1023 if (connect
->crypto
.n_ciphers_pairwise
== 0) {
1024 connect
->crypto
.n_ciphers_pairwise
= 1;
1025 connect
->crypto
.ciphers_pairwise
[0] = cipher
;
1030 wdev
->connect_keys
= connkeys
;
1031 memcpy(wdev
->ssid
, connect
->ssid
, connect
->ssid_len
);
1032 wdev
->ssid_len
= connect
->ssid_len
;
1034 if (!rdev
->ops
->connect
)
1035 err
= cfg80211_sme_connect(wdev
, connect
, prev_bssid
);
1037 err
= rdev_connect(rdev
, dev
, connect
);
1040 wdev
->connect_keys
= NULL
;
1048 int cfg80211_disconnect(struct cfg80211_registered_device
*rdev
,
1049 struct net_device
*dev
, u16 reason
, bool wextev
)
1051 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
1054 ASSERT_WDEV_LOCK(wdev
);
1056 kzfree(wdev
->connect_keys
);
1057 wdev
->connect_keys
= NULL
;
1060 err
= cfg80211_sme_disconnect(wdev
, reason
);
1061 else if (!rdev
->ops
->disconnect
)
1062 cfg80211_mlme_down(rdev
, dev
);
1063 else if (wdev
->current_bss
)
1064 err
= rdev_disconnect(rdev
, dev
, reason
);