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.
8 * Copyright 2017 Intel Deutschland GmbH
11 #include <linux/etherdevice.h>
12 #include <linux/if_arp.h>
13 #include <linux/slab.h>
14 #include <linux/workqueue.h>
15 #include <linux/wireless.h>
16 #include <linux/export.h>
17 #include <net/iw_handler.h>
18 #include <net/cfg80211.h>
19 #include <net/rtnetlink.h>
25 * Software SME in cfg80211, using auth/assoc/deauth calls to the
26 * driver. This is is for implementing nl80211's connect/disconnect
27 * and wireless extensions (if configured.)
30 struct cfg80211_conn
{
31 struct cfg80211_connect_params params
;
32 /* these are sub-states of the _CONNECTING sme_state */
34 CFG80211_CONN_SCANNING
,
35 CFG80211_CONN_SCAN_AGAIN
,
36 CFG80211_CONN_AUTHENTICATE_NEXT
,
37 CFG80211_CONN_AUTHENTICATING
,
38 CFG80211_CONN_AUTH_FAILED_TIMEOUT
,
39 CFG80211_CONN_ASSOCIATE_NEXT
,
40 CFG80211_CONN_ASSOCIATING
,
41 CFG80211_CONN_ASSOC_FAILED
,
42 CFG80211_CONN_ASSOC_FAILED_TIMEOUT
,
44 CFG80211_CONN_ABANDON
,
45 CFG80211_CONN_CONNECTED
,
47 u8 bssid
[ETH_ALEN
], prev_bssid
[ETH_ALEN
];
50 bool auto_auth
, prev_bssid_valid
;
53 static void cfg80211_sme_free(struct wireless_dev
*wdev
)
58 kfree(wdev
->conn
->ie
);
63 static int cfg80211_conn_scan(struct wireless_dev
*wdev
)
65 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
66 struct cfg80211_scan_request
*request
;
70 ASSERT_WDEV_LOCK(wdev
);
72 if (rdev
->scan_req
|| rdev
->scan_msg
)
75 if (wdev
->conn
->params
.channel
)
78 n_channels
= ieee80211_get_num_supported_channels(wdev
->wiphy
);
80 request
= kzalloc(sizeof(*request
) + sizeof(request
->ssids
[0]) +
81 sizeof(request
->channels
[0]) * n_channels
,
86 if (wdev
->conn
->params
.channel
) {
87 enum nl80211_band band
= wdev
->conn
->params
.channel
->band
;
88 struct ieee80211_supported_band
*sband
=
89 wdev
->wiphy
->bands
[band
];
95 request
->channels
[0] = wdev
->conn
->params
.channel
;
96 request
->rates
[band
] = (1 << sband
->n_bitrates
) - 1;
99 enum nl80211_band band
;
100 struct ieee80211_supported_band
*bands
;
101 struct ieee80211_channel
*channel
;
103 for (band
= 0; band
< NUM_NL80211_BANDS
; band
++) {
104 bands
= wdev
->wiphy
->bands
[band
];
107 for (j
= 0; j
< bands
->n_channels
; j
++) {
108 channel
= &bands
->channels
[j
];
109 if (channel
->flags
& IEEE80211_CHAN_DISABLED
)
111 request
->channels
[i
++] = channel
;
113 request
->rates
[band
] = (1 << bands
->n_bitrates
) - 1;
117 request
->n_channels
= n_channels
;
118 request
->ssids
= (void *)&request
->channels
[n_channels
];
119 request
->n_ssids
= 1;
121 memcpy(request
->ssids
[0].ssid
, wdev
->conn
->params
.ssid
,
122 wdev
->conn
->params
.ssid_len
);
123 request
->ssids
[0].ssid_len
= wdev
->conn
->params
.ssid_len
;
125 eth_broadcast_addr(request
->bssid
);
127 request
->wdev
= wdev
;
128 request
->wiphy
= &rdev
->wiphy
;
129 request
->scan_start
= jiffies
;
131 rdev
->scan_req
= request
;
133 err
= rdev_scan(rdev
, request
);
135 wdev
->conn
->state
= CFG80211_CONN_SCANNING
;
136 nl80211_send_scan_start(rdev
, wdev
);
137 dev_hold(wdev
->netdev
);
139 rdev
->scan_req
= NULL
;
145 static int cfg80211_conn_do_work(struct wireless_dev
*wdev
,
146 enum nl80211_timeout_reason
*treason
)
148 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
149 struct cfg80211_connect_params
*params
;
150 struct cfg80211_assoc_request req
= {};
153 ASSERT_WDEV_LOCK(wdev
);
158 params
= &wdev
->conn
->params
;
160 switch (wdev
->conn
->state
) {
161 case CFG80211_CONN_SCANNING
:
162 /* didn't find it during scan ... */
164 case CFG80211_CONN_SCAN_AGAIN
:
165 return cfg80211_conn_scan(wdev
);
166 case CFG80211_CONN_AUTHENTICATE_NEXT
:
167 if (WARN_ON(!rdev
->ops
->auth
))
169 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATING
;
170 return cfg80211_mlme_auth(rdev
, wdev
->netdev
,
171 params
->channel
, params
->auth_type
,
173 params
->ssid
, params
->ssid_len
,
175 params
->key
, params
->key_len
,
176 params
->key_idx
, NULL
, 0);
177 case CFG80211_CONN_AUTH_FAILED_TIMEOUT
:
178 *treason
= NL80211_TIMEOUT_AUTH
;
180 case CFG80211_CONN_ASSOCIATE_NEXT
:
181 if (WARN_ON(!rdev
->ops
->assoc
))
183 wdev
->conn
->state
= CFG80211_CONN_ASSOCIATING
;
184 if (wdev
->conn
->prev_bssid_valid
)
185 req
.prev_bssid
= wdev
->conn
->prev_bssid
;
187 req
.ie_len
= params
->ie_len
;
188 req
.use_mfp
= params
->mfp
!= NL80211_MFP_NO
;
189 req
.crypto
= params
->crypto
;
190 req
.flags
= params
->flags
;
191 req
.ht_capa
= params
->ht_capa
;
192 req
.ht_capa_mask
= params
->ht_capa_mask
;
193 req
.vht_capa
= params
->vht_capa
;
194 req
.vht_capa_mask
= params
->vht_capa_mask
;
196 err
= cfg80211_mlme_assoc(rdev
, wdev
->netdev
, params
->channel
,
197 params
->bssid
, params
->ssid
,
198 params
->ssid_len
, &req
);
200 cfg80211_mlme_deauth(rdev
, wdev
->netdev
, params
->bssid
,
202 WLAN_REASON_DEAUTH_LEAVING
,
205 case CFG80211_CONN_ASSOC_FAILED_TIMEOUT
:
206 *treason
= NL80211_TIMEOUT_ASSOC
;
208 case CFG80211_CONN_ASSOC_FAILED
:
209 cfg80211_mlme_deauth(rdev
, wdev
->netdev
, params
->bssid
,
211 WLAN_REASON_DEAUTH_LEAVING
, false);
213 case CFG80211_CONN_DEAUTH
:
214 cfg80211_mlme_deauth(rdev
, wdev
->netdev
, params
->bssid
,
216 WLAN_REASON_DEAUTH_LEAVING
, false);
218 case CFG80211_CONN_ABANDON
:
219 /* free directly, disconnected event already sent */
220 cfg80211_sme_free(wdev
);
227 void cfg80211_conn_work(struct work_struct
*work
)
229 struct cfg80211_registered_device
*rdev
=
230 container_of(work
, struct cfg80211_registered_device
, conn_work
);
231 struct wireless_dev
*wdev
;
232 u8 bssid_buf
[ETH_ALEN
], *bssid
= NULL
;
233 enum nl80211_timeout_reason treason
;
237 list_for_each_entry(wdev
, &rdev
->wiphy
.wdev_list
, list
) {
242 if (!netif_running(wdev
->netdev
)) {
247 wdev
->conn
->state
== CFG80211_CONN_CONNECTED
) {
251 if (wdev
->conn
->params
.bssid
) {
252 memcpy(bssid_buf
, wdev
->conn
->params
.bssid
, ETH_ALEN
);
255 treason
= NL80211_TIMEOUT_UNSPECIFIED
;
256 if (cfg80211_conn_do_work(wdev
, &treason
)) {
257 struct cfg80211_connect_resp_params cr
;
259 memset(&cr
, 0, sizeof(cr
));
262 cr
.timeout_reason
= treason
;
263 __cfg80211_connect_result(wdev
->netdev
, &cr
, false);
271 /* Returned bss is reference counted and must be cleaned up appropriately. */
272 static struct cfg80211_bss
*cfg80211_get_conn_bss(struct wireless_dev
*wdev
)
274 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
275 struct cfg80211_bss
*bss
;
277 ASSERT_WDEV_LOCK(wdev
);
279 bss
= cfg80211_get_bss(wdev
->wiphy
, wdev
->conn
->params
.channel
,
280 wdev
->conn
->params
.bssid
,
281 wdev
->conn
->params
.ssid
,
282 wdev
->conn
->params
.ssid_len
,
284 IEEE80211_PRIVACY(wdev
->conn
->params
.privacy
));
288 memcpy(wdev
->conn
->bssid
, bss
->bssid
, ETH_ALEN
);
289 wdev
->conn
->params
.bssid
= wdev
->conn
->bssid
;
290 wdev
->conn
->params
.channel
= bss
->channel
;
291 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATE_NEXT
;
292 schedule_work(&rdev
->conn_work
);
297 static void __cfg80211_sme_scan_done(struct net_device
*dev
)
299 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
300 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
301 struct cfg80211_bss
*bss
;
303 ASSERT_WDEV_LOCK(wdev
);
308 if (wdev
->conn
->state
!= CFG80211_CONN_SCANNING
&&
309 wdev
->conn
->state
!= CFG80211_CONN_SCAN_AGAIN
)
312 bss
= cfg80211_get_conn_bss(wdev
);
314 cfg80211_put_bss(&rdev
->wiphy
, bss
);
316 schedule_work(&rdev
->conn_work
);
319 void cfg80211_sme_scan_done(struct net_device
*dev
)
321 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
324 __cfg80211_sme_scan_done(dev
);
328 void cfg80211_sme_rx_auth(struct wireless_dev
*wdev
, const u8
*buf
, size_t len
)
330 struct wiphy
*wiphy
= wdev
->wiphy
;
331 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wiphy
);
332 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*)buf
;
333 u16 status_code
= le16_to_cpu(mgmt
->u
.auth
.status_code
);
335 ASSERT_WDEV_LOCK(wdev
);
337 if (!wdev
->conn
|| wdev
->conn
->state
== CFG80211_CONN_CONNECTED
)
340 if (status_code
== WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
&&
341 wdev
->conn
->auto_auth
&&
342 wdev
->conn
->params
.auth_type
!= NL80211_AUTHTYPE_NETWORK_EAP
) {
343 /* select automatically between only open, shared, leap */
344 switch (wdev
->conn
->params
.auth_type
) {
345 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
346 if (wdev
->connect_keys
)
347 wdev
->conn
->params
.auth_type
=
348 NL80211_AUTHTYPE_SHARED_KEY
;
350 wdev
->conn
->params
.auth_type
=
351 NL80211_AUTHTYPE_NETWORK_EAP
;
353 case NL80211_AUTHTYPE_SHARED_KEY
:
354 wdev
->conn
->params
.auth_type
=
355 NL80211_AUTHTYPE_NETWORK_EAP
;
359 wdev
->conn
->params
.auth_type
=
360 NL80211_AUTHTYPE_OPEN_SYSTEM
;
363 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATE_NEXT
;
364 schedule_work(&rdev
->conn_work
);
365 } else if (status_code
!= WLAN_STATUS_SUCCESS
) {
366 struct cfg80211_connect_resp_params cr
;
368 memset(&cr
, 0, sizeof(cr
));
369 cr
.status
= status_code
;
370 cr
.bssid
= mgmt
->bssid
;
371 cr
.timeout_reason
= NL80211_TIMEOUT_UNSPECIFIED
;
372 __cfg80211_connect_result(wdev
->netdev
, &cr
, false);
373 } else if (wdev
->conn
->state
== CFG80211_CONN_AUTHENTICATING
) {
374 wdev
->conn
->state
= CFG80211_CONN_ASSOCIATE_NEXT
;
375 schedule_work(&rdev
->conn_work
);
379 bool cfg80211_sme_rx_assoc_resp(struct wireless_dev
*wdev
, u16 status
)
381 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
386 if (status
== WLAN_STATUS_SUCCESS
) {
387 wdev
->conn
->state
= CFG80211_CONN_CONNECTED
;
391 if (wdev
->conn
->prev_bssid_valid
) {
393 * Some stupid APs don't accept reassoc, so we
394 * need to fall back to trying regular assoc;
395 * return true so no event is sent to userspace.
397 wdev
->conn
->prev_bssid_valid
= false;
398 wdev
->conn
->state
= CFG80211_CONN_ASSOCIATE_NEXT
;
399 schedule_work(&rdev
->conn_work
);
403 wdev
->conn
->state
= CFG80211_CONN_ASSOC_FAILED
;
404 schedule_work(&rdev
->conn_work
);
408 void cfg80211_sme_deauth(struct wireless_dev
*wdev
)
410 cfg80211_sme_free(wdev
);
413 void cfg80211_sme_auth_timeout(struct wireless_dev
*wdev
)
415 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
420 wdev
->conn
->state
= CFG80211_CONN_AUTH_FAILED_TIMEOUT
;
421 schedule_work(&rdev
->conn_work
);
424 void cfg80211_sme_disassoc(struct wireless_dev
*wdev
)
426 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
431 wdev
->conn
->state
= CFG80211_CONN_DEAUTH
;
432 schedule_work(&rdev
->conn_work
);
435 void cfg80211_sme_assoc_timeout(struct wireless_dev
*wdev
)
437 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
442 wdev
->conn
->state
= CFG80211_CONN_ASSOC_FAILED_TIMEOUT
;
443 schedule_work(&rdev
->conn_work
);
446 void cfg80211_sme_abandon_assoc(struct wireless_dev
*wdev
)
448 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
453 wdev
->conn
->state
= CFG80211_CONN_ABANDON
;
454 schedule_work(&rdev
->conn_work
);
457 static int cfg80211_sme_get_conn_ies(struct wireless_dev
*wdev
,
458 const u8
*ies
, size_t ies_len
,
459 const u8
**out_ies
, size_t *out_ies_len
)
461 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
465 if (!rdev
->wiphy
.extended_capabilities_len
||
466 (ies
&& cfg80211_find_ie(WLAN_EID_EXT_CAPABILITY
, ies
, ies_len
))) {
467 *out_ies
= kmemdup(ies
, ies_len
, GFP_KERNEL
);
470 *out_ies_len
= ies_len
;
474 buf
= kmalloc(ies_len
+ rdev
->wiphy
.extended_capabilities_len
+ 2,
480 static const u8 before_extcapa
[] = {
481 /* not listing IEs expected to be created by driver */
484 WLAN_EID_RRM_ENABLED_CAPABILITIES
,
485 WLAN_EID_MOBILITY_DOMAIN
,
486 WLAN_EID_SUPPORTED_REGULATORY_CLASSES
,
487 WLAN_EID_BSS_COEX_2040
,
490 offs
= ieee80211_ie_split(ies
, ies_len
, before_extcapa
,
491 ARRAY_SIZE(before_extcapa
), 0);
492 memcpy(buf
, ies
, offs
);
493 /* leave a whole for extended capabilities IE */
494 memcpy(buf
+ offs
+ rdev
->wiphy
.extended_capabilities_len
+ 2,
495 ies
+ offs
, ies_len
- offs
);
500 /* place extended capabilities IE (with only driver capabilities) */
501 buf
[offs
] = WLAN_EID_EXT_CAPABILITY
;
502 buf
[offs
+ 1] = rdev
->wiphy
.extended_capabilities_len
;
503 memcpy(buf
+ offs
+ 2,
504 rdev
->wiphy
.extended_capabilities
,
505 rdev
->wiphy
.extended_capabilities_len
);
508 *out_ies_len
= ies_len
+ rdev
->wiphy
.extended_capabilities_len
+ 2;
513 static int cfg80211_sme_connect(struct wireless_dev
*wdev
,
514 struct cfg80211_connect_params
*connect
,
515 const u8
*prev_bssid
)
517 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
518 struct cfg80211_bss
*bss
;
521 if (!rdev
->ops
->auth
|| !rdev
->ops
->assoc
)
524 if (wdev
->current_bss
) {
528 !ether_addr_equal(prev_bssid
, wdev
->current_bss
->pub
.bssid
))
530 cfg80211_unhold_bss(wdev
->current_bss
);
531 cfg80211_put_bss(wdev
->wiphy
, &wdev
->current_bss
->pub
);
532 wdev
->current_bss
= NULL
;
534 cfg80211_sme_free(wdev
);
537 if (WARN_ON(wdev
->conn
))
540 wdev
->conn
= kzalloc(sizeof(*wdev
->conn
), GFP_KERNEL
);
545 * Copy all parameters, and treat explicitly IEs, BSSID, SSID.
547 memcpy(&wdev
->conn
->params
, connect
, sizeof(*connect
));
548 if (connect
->bssid
) {
549 wdev
->conn
->params
.bssid
= wdev
->conn
->bssid
;
550 memcpy(wdev
->conn
->bssid
, connect
->bssid
, ETH_ALEN
);
553 if (cfg80211_sme_get_conn_ies(wdev
, connect
->ie
, connect
->ie_len
,
555 &wdev
->conn
->params
.ie_len
)) {
560 wdev
->conn
->params
.ie
= wdev
->conn
->ie
;
562 if (connect
->auth_type
== NL80211_AUTHTYPE_AUTOMATIC
) {
563 wdev
->conn
->auto_auth
= true;
564 /* start with open system ... should mostly work */
565 wdev
->conn
->params
.auth_type
=
566 NL80211_AUTHTYPE_OPEN_SYSTEM
;
568 wdev
->conn
->auto_auth
= false;
571 wdev
->conn
->params
.ssid
= wdev
->ssid
;
572 wdev
->conn
->params
.ssid_len
= wdev
->ssid_len
;
574 /* see if we have the bss already */
575 bss
= cfg80211_get_conn_bss(wdev
);
578 memcpy(wdev
->conn
->prev_bssid
, prev_bssid
, ETH_ALEN
);
579 wdev
->conn
->prev_bssid_valid
= true;
582 /* we're good if we have a matching bss struct */
584 enum nl80211_timeout_reason treason
;
586 err
= cfg80211_conn_do_work(wdev
, &treason
);
587 cfg80211_put_bss(wdev
->wiphy
, bss
);
589 /* otherwise we'll need to scan for the AP first */
590 err
= cfg80211_conn_scan(wdev
);
593 * If we can't scan right now, then we need to scan again
594 * after the current scan finished, since the parameters
595 * changed (unless we find a good AP anyway).
599 wdev
->conn
->state
= CFG80211_CONN_SCAN_AGAIN
;
604 cfg80211_sme_free(wdev
);
609 static int cfg80211_sme_disconnect(struct wireless_dev
*wdev
, u16 reason
)
611 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
617 if (!rdev
->ops
->deauth
)
620 if (wdev
->conn
->state
== CFG80211_CONN_SCANNING
||
621 wdev
->conn
->state
== CFG80211_CONN_SCAN_AGAIN
) {
626 /* wdev->conn->params.bssid must be set if > SCANNING */
627 err
= cfg80211_mlme_deauth(rdev
, wdev
->netdev
,
628 wdev
->conn
->params
.bssid
,
629 NULL
, 0, reason
, false);
631 cfg80211_sme_free(wdev
);
636 * code shared for in-device and software SME
639 static bool cfg80211_is_all_idle(void)
641 struct cfg80211_registered_device
*rdev
;
642 struct wireless_dev
*wdev
;
643 bool is_all_idle
= true;
646 * All devices must be idle as otherwise if you are actively
647 * scanning some new beacon hints could be learned and would
648 * count as new regulatory hints.
650 list_for_each_entry(rdev
, &cfg80211_rdev_list
, list
) {
651 list_for_each_entry(wdev
, &rdev
->wiphy
.wdev_list
, list
) {
653 if (wdev
->conn
|| wdev
->current_bss
)
662 static void disconnect_work(struct work_struct
*work
)
665 if (cfg80211_is_all_idle())
666 regulatory_hint_disconnect();
670 static DECLARE_WORK(cfg80211_disconnect_work
, disconnect_work
);
674 * API calls for drivers implementing connect/disconnect and
678 /* This method must consume bss one way or another */
679 void __cfg80211_connect_result(struct net_device
*dev
,
680 struct cfg80211_connect_resp_params
*cr
,
683 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
684 const u8
*country_ie
;
685 #ifdef CONFIG_CFG80211_WEXT
686 union iwreq_data wrqu
;
689 ASSERT_WDEV_LOCK(wdev
);
691 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_STATION
&&
692 wdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
)) {
693 cfg80211_put_bss(wdev
->wiphy
, cr
->bss
);
697 nl80211_send_connect_result(wiphy_to_rdev(wdev
->wiphy
), dev
, cr
,
700 #ifdef CONFIG_CFG80211_WEXT
702 if (cr
->req_ie
&& cr
->status
== WLAN_STATUS_SUCCESS
) {
703 memset(&wrqu
, 0, sizeof(wrqu
));
704 wrqu
.data
.length
= cr
->req_ie_len
;
705 wireless_send_event(dev
, IWEVASSOCREQIE
, &wrqu
,
709 if (cr
->resp_ie
&& cr
->status
== WLAN_STATUS_SUCCESS
) {
710 memset(&wrqu
, 0, sizeof(wrqu
));
711 wrqu
.data
.length
= cr
->resp_ie_len
;
712 wireless_send_event(dev
, IWEVASSOCRESPIE
, &wrqu
,
716 memset(&wrqu
, 0, sizeof(wrqu
));
717 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
718 if (cr
->bssid
&& cr
->status
== WLAN_STATUS_SUCCESS
) {
719 memcpy(wrqu
.ap_addr
.sa_data
, cr
->bssid
, ETH_ALEN
);
720 memcpy(wdev
->wext
.prev_bssid
, cr
->bssid
, ETH_ALEN
);
721 wdev
->wext
.prev_bssid_valid
= true;
723 wireless_send_event(dev
, SIOCGIWAP
, &wrqu
, NULL
);
727 if (!cr
->bss
&& (cr
->status
== WLAN_STATUS_SUCCESS
)) {
728 WARN_ON_ONCE(!wiphy_to_rdev(wdev
->wiphy
)->ops
->connect
);
729 cr
->bss
= cfg80211_get_bss(wdev
->wiphy
, NULL
, cr
->bssid
,
730 wdev
->ssid
, wdev
->ssid_len
,
732 IEEE80211_PRIVACY_ANY
);
734 cfg80211_hold_bss(bss_from_pub(cr
->bss
));
737 if (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
;
743 if (cr
->status
!= WLAN_STATUS_SUCCESS
) {
744 kzfree(wdev
->connect_keys
);
745 wdev
->connect_keys
= NULL
;
747 wdev
->conn_owner_nlportid
= 0;
749 cfg80211_unhold_bss(bss_from_pub(cr
->bss
));
750 cfg80211_put_bss(wdev
->wiphy
, cr
->bss
);
752 cfg80211_sme_free(wdev
);
756 if (WARN_ON(!cr
->bss
))
759 wdev
->current_bss
= bss_from_pub(cr
->bss
);
761 if (!(wdev
->wiphy
->flags
& WIPHY_FLAG_HAS_STATIC_WEP
))
762 cfg80211_upload_connect_keys(wdev
);
765 country_ie
= ieee80211_bss_get_ie(cr
->bss
, WLAN_EID_COUNTRY
);
771 country_ie
= kmemdup(country_ie
, 2 + country_ie
[1], GFP_ATOMIC
);
778 * ieee80211_bss_get_ie() ensures we can access:
779 * - country_ie + 2, the start of the country ie data, and
780 * - and country_ie[1] which is the IE length
782 regulatory_hint_country_ie(wdev
->wiphy
, cr
->bss
->channel
->band
,
783 country_ie
+ 2, country_ie
[1]);
787 /* Consumes bss object one way or another */
788 void cfg80211_connect_done(struct net_device
*dev
,
789 struct cfg80211_connect_resp_params
*params
,
792 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
793 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
794 struct cfg80211_event
*ev
;
799 /* Make sure the bss entry provided by the driver is valid. */
800 struct cfg80211_internal_bss
*ibss
= bss_from_pub(params
->bss
);
802 if (WARN_ON(list_empty(&ibss
->list
))) {
803 cfg80211_put_bss(wdev
->wiphy
, params
->bss
);
808 ev
= kzalloc(sizeof(*ev
) + (params
->bssid
? ETH_ALEN
: 0) +
809 params
->req_ie_len
+ params
->resp_ie_len
+
810 params
->fils_kek_len
+ params
->pmk_len
+
811 (params
->pmkid
? WLAN_PMKID_LEN
: 0), gfp
);
813 cfg80211_put_bss(wdev
->wiphy
, params
->bss
);
817 ev
->type
= EVENT_CONNECT_RESULT
;
818 next
= ((u8
*)ev
) + sizeof(*ev
);
821 memcpy((void *)ev
->cr
.bssid
, params
->bssid
, ETH_ALEN
);
824 if (params
->req_ie_len
) {
825 ev
->cr
.req_ie
= next
;
826 ev
->cr
.req_ie_len
= params
->req_ie_len
;
827 memcpy((void *)ev
->cr
.req_ie
, params
->req_ie
,
829 next
+= params
->req_ie_len
;
831 if (params
->resp_ie_len
) {
832 ev
->cr
.resp_ie
= next
;
833 ev
->cr
.resp_ie_len
= params
->resp_ie_len
;
834 memcpy((void *)ev
->cr
.resp_ie
, params
->resp_ie
,
835 params
->resp_ie_len
);
836 next
+= params
->resp_ie_len
;
838 if (params
->fils_kek_len
) {
839 ev
->cr
.fils_kek
= next
;
840 ev
->cr
.fils_kek_len
= params
->fils_kek_len
;
841 memcpy((void *)ev
->cr
.fils_kek
, params
->fils_kek
,
842 params
->fils_kek_len
);
843 next
+= params
->fils_kek_len
;
845 if (params
->pmk_len
) {
847 ev
->cr
.pmk_len
= params
->pmk_len
;
848 memcpy((void *)ev
->cr
.pmk
, params
->pmk
, params
->pmk_len
);
849 next
+= params
->pmk_len
;
853 memcpy((void *)ev
->cr
.pmkid
, params
->pmkid
, WLAN_PMKID_LEN
);
854 next
+= WLAN_PMKID_LEN
;
856 ev
->cr
.update_erp_next_seq_num
= params
->update_erp_next_seq_num
;
857 if (params
->update_erp_next_seq_num
)
858 ev
->cr
.fils_erp_next_seq_num
= params
->fils_erp_next_seq_num
;
860 cfg80211_hold_bss(bss_from_pub(params
->bss
));
861 ev
->cr
.bss
= params
->bss
;
862 ev
->cr
.status
= params
->status
;
863 ev
->cr
.timeout_reason
= params
->timeout_reason
;
865 spin_lock_irqsave(&wdev
->event_lock
, flags
);
866 list_add_tail(&ev
->list
, &wdev
->event_list
);
867 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
868 queue_work(cfg80211_wq
, &rdev
->event_work
);
870 EXPORT_SYMBOL(cfg80211_connect_done
);
872 /* Consumes bss object one way or another */
873 void __cfg80211_roamed(struct wireless_dev
*wdev
,
874 struct cfg80211_roam_info
*info
)
876 #ifdef CONFIG_CFG80211_WEXT
877 union iwreq_data wrqu
;
879 ASSERT_WDEV_LOCK(wdev
);
881 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_STATION
&&
882 wdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
))
885 if (WARN_ON(!wdev
->current_bss
))
888 cfg80211_unhold_bss(wdev
->current_bss
);
889 cfg80211_put_bss(wdev
->wiphy
, &wdev
->current_bss
->pub
);
890 wdev
->current_bss
= NULL
;
892 if (WARN_ON(!info
->bss
))
895 cfg80211_hold_bss(bss_from_pub(info
->bss
));
896 wdev
->current_bss
= bss_from_pub(info
->bss
);
898 nl80211_send_roamed(wiphy_to_rdev(wdev
->wiphy
),
899 wdev
->netdev
, info
, GFP_KERNEL
);
901 #ifdef CONFIG_CFG80211_WEXT
903 memset(&wrqu
, 0, sizeof(wrqu
));
904 wrqu
.data
.length
= info
->req_ie_len
;
905 wireless_send_event(wdev
->netdev
, IWEVASSOCREQIE
,
906 &wrqu
, info
->req_ie
);
910 memset(&wrqu
, 0, sizeof(wrqu
));
911 wrqu
.data
.length
= info
->resp_ie_len
;
912 wireless_send_event(wdev
->netdev
, IWEVASSOCRESPIE
,
913 &wrqu
, info
->resp_ie
);
916 memset(&wrqu
, 0, sizeof(wrqu
));
917 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
918 memcpy(wrqu
.ap_addr
.sa_data
, info
->bss
->bssid
, ETH_ALEN
);
919 memcpy(wdev
->wext
.prev_bssid
, info
->bss
->bssid
, ETH_ALEN
);
920 wdev
->wext
.prev_bssid_valid
= true;
921 wireless_send_event(wdev
->netdev
, SIOCGIWAP
, &wrqu
, NULL
);
926 cfg80211_put_bss(wdev
->wiphy
, info
->bss
);
929 /* Consumes info->bss object one way or another */
930 void cfg80211_roamed(struct net_device
*dev
, struct cfg80211_roam_info
*info
,
933 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
934 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
935 struct cfg80211_event
*ev
;
939 info
->bss
= cfg80211_get_bss(wdev
->wiphy
, info
->channel
,
940 info
->bssid
, wdev
->ssid
,
943 IEEE80211_PRIVACY_ANY
);
946 if (WARN_ON(!info
->bss
))
949 ev
= kzalloc(sizeof(*ev
) + info
->req_ie_len
+ info
->resp_ie_len
, gfp
);
951 cfg80211_put_bss(wdev
->wiphy
, info
->bss
);
955 ev
->type
= EVENT_ROAMED
;
956 ev
->rm
.req_ie
= ((u8
*)ev
) + sizeof(*ev
);
957 ev
->rm
.req_ie_len
= info
->req_ie_len
;
958 memcpy((void *)ev
->rm
.req_ie
, info
->req_ie
, info
->req_ie_len
);
959 ev
->rm
.resp_ie
= ((u8
*)ev
) + sizeof(*ev
) + info
->req_ie_len
;
960 ev
->rm
.resp_ie_len
= info
->resp_ie_len
;
961 memcpy((void *)ev
->rm
.resp_ie
, info
->resp_ie
, info
->resp_ie_len
);
962 ev
->rm
.bss
= info
->bss
;
963 ev
->rm
.authorized
= info
->authorized
;
965 spin_lock_irqsave(&wdev
->event_lock
, flags
);
966 list_add_tail(&ev
->list
, &wdev
->event_list
);
967 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
968 queue_work(cfg80211_wq
, &rdev
->event_work
);
970 EXPORT_SYMBOL(cfg80211_roamed
);
972 void __cfg80211_disconnected(struct net_device
*dev
, const u8
*ie
,
973 size_t ie_len
, u16 reason
, bool from_ap
)
975 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
976 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
978 #ifdef CONFIG_CFG80211_WEXT
979 union iwreq_data wrqu
;
982 ASSERT_WDEV_LOCK(wdev
);
984 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_STATION
&&
985 wdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
))
988 if (wdev
->current_bss
) {
989 cfg80211_unhold_bss(wdev
->current_bss
);
990 cfg80211_put_bss(wdev
->wiphy
, &wdev
->current_bss
->pub
);
993 wdev
->current_bss
= NULL
;
995 wdev
->conn_owner_nlportid
= 0;
997 nl80211_send_disconnected(rdev
, dev
, reason
, ie
, ie_len
, from_ap
);
999 /* stop critical protocol if supported */
1000 if (rdev
->ops
->crit_proto_stop
&& rdev
->crit_proto_nlportid
) {
1001 rdev
->crit_proto_nlportid
= 0;
1002 rdev_crit_proto_stop(rdev
, wdev
);
1006 * Delete all the keys ... pairwise keys can't really
1007 * exist any more anyway, but default keys might.
1009 if (rdev
->ops
->del_key
)
1010 for (i
= 0; i
< 6; i
++)
1011 rdev_del_key(rdev
, dev
, i
, false, NULL
);
1013 rdev_set_qos_map(rdev
, dev
, NULL
);
1015 #ifdef CONFIG_CFG80211_WEXT
1016 memset(&wrqu
, 0, sizeof(wrqu
));
1017 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
1018 wireless_send_event(dev
, SIOCGIWAP
, &wrqu
, NULL
);
1019 wdev
->wext
.connect
.ssid_len
= 0;
1022 schedule_work(&cfg80211_disconnect_work
);
1025 void cfg80211_disconnected(struct net_device
*dev
, u16 reason
,
1026 const u8
*ie
, size_t ie_len
,
1027 bool locally_generated
, gfp_t gfp
)
1029 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
1030 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
1031 struct cfg80211_event
*ev
;
1032 unsigned long flags
;
1034 ev
= kzalloc(sizeof(*ev
) + ie_len
, gfp
);
1038 ev
->type
= EVENT_DISCONNECTED
;
1039 ev
->dc
.ie
= ((u8
*)ev
) + sizeof(*ev
);
1040 ev
->dc
.ie_len
= ie_len
;
1041 memcpy((void *)ev
->dc
.ie
, ie
, ie_len
);
1042 ev
->dc
.reason
= reason
;
1043 ev
->dc
.locally_generated
= locally_generated
;
1045 spin_lock_irqsave(&wdev
->event_lock
, flags
);
1046 list_add_tail(&ev
->list
, &wdev
->event_list
);
1047 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
1048 queue_work(cfg80211_wq
, &rdev
->event_work
);
1050 EXPORT_SYMBOL(cfg80211_disconnected
);
1053 * API calls for nl80211/wext compatibility code
1055 int cfg80211_connect(struct cfg80211_registered_device
*rdev
,
1056 struct net_device
*dev
,
1057 struct cfg80211_connect_params
*connect
,
1058 struct cfg80211_cached_keys
*connkeys
,
1059 const u8
*prev_bssid
)
1061 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
1064 ASSERT_WDEV_LOCK(wdev
);
1066 if (WARN_ON(wdev
->connect_keys
)) {
1067 kzfree(wdev
->connect_keys
);
1068 wdev
->connect_keys
= NULL
;
1071 cfg80211_oper_and_ht_capa(&connect
->ht_capa_mask
,
1072 rdev
->wiphy
.ht_capa_mod_mask
);
1074 if (connkeys
&& connkeys
->def
>= 0) {
1078 idx
= connkeys
->def
;
1079 cipher
= connkeys
->params
[idx
].cipher
;
1080 /* If given a WEP key we may need it for shared key auth */
1081 if (cipher
== WLAN_CIPHER_SUITE_WEP40
||
1082 cipher
== WLAN_CIPHER_SUITE_WEP104
) {
1083 connect
->key_idx
= idx
;
1084 connect
->key
= connkeys
->params
[idx
].key
;
1085 connect
->key_len
= connkeys
->params
[idx
].key_len
;
1088 * If ciphers are not set (e.g. when going through
1089 * iwconfig), we have to set them appropriately here.
1091 if (connect
->crypto
.cipher_group
== 0)
1092 connect
->crypto
.cipher_group
= cipher
;
1094 if (connect
->crypto
.n_ciphers_pairwise
== 0) {
1095 connect
->crypto
.n_ciphers_pairwise
= 1;
1096 connect
->crypto
.ciphers_pairwise
[0] = cipher
;
1100 connect
->crypto
.wep_keys
= connkeys
->params
;
1101 connect
->crypto
.wep_tx_key
= connkeys
->def
;
1103 if (WARN_ON(connkeys
))
1107 wdev
->connect_keys
= connkeys
;
1108 memcpy(wdev
->ssid
, connect
->ssid
, connect
->ssid_len
);
1109 wdev
->ssid_len
= connect
->ssid_len
;
1111 wdev
->conn_bss_type
= connect
->pbss
? IEEE80211_BSS_TYPE_PBSS
:
1112 IEEE80211_BSS_TYPE_ESS
;
1114 if (!rdev
->ops
->connect
)
1115 err
= cfg80211_sme_connect(wdev
, connect
, prev_bssid
);
1117 err
= rdev_connect(rdev
, dev
, connect
);
1120 wdev
->connect_keys
= NULL
;
1128 int cfg80211_disconnect(struct cfg80211_registered_device
*rdev
,
1129 struct net_device
*dev
, u16 reason
, bool wextev
)
1131 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
1134 ASSERT_WDEV_LOCK(wdev
);
1136 kzfree(wdev
->connect_keys
);
1137 wdev
->connect_keys
= NULL
;
1139 wdev
->conn_owner_nlportid
= 0;
1142 err
= cfg80211_sme_disconnect(wdev
, reason
);
1143 else if (!rdev
->ops
->disconnect
)
1144 cfg80211_mlme_down(rdev
, dev
);
1145 else if (wdev
->ssid_len
)
1146 err
= rdev_disconnect(rdev
, dev
, reason
);
1152 * Used to clean up after the connection / connection attempt owner socket
1155 void cfg80211_autodisconnect_wk(struct work_struct
*work
)
1157 struct wireless_dev
*wdev
=
1158 container_of(work
, struct wireless_dev
, disconnect_wk
);
1159 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
1163 if (wdev
->conn_owner_nlportid
) {
1165 * Use disconnect_bssid if still connecting and ops->disconnect
1166 * not implemented. Otherwise we can use cfg80211_disconnect.
1168 if (rdev
->ops
->disconnect
|| wdev
->current_bss
)
1169 cfg80211_disconnect(rdev
, wdev
->netdev
,
1170 WLAN_REASON_DEAUTH_LEAVING
, true);
1172 cfg80211_mlme_deauth(rdev
, wdev
->netdev
,
1173 wdev
->disconnect_bssid
, NULL
, 0,
1174 WLAN_REASON_DEAUTH_LEAVING
, false);