xref: /openbmc/linux/net/wireless/sme.c (revision 1fa6ac37)
1 /*
2  * SME code for cfg80211's connect emulation.
3  *
4  * Copyright 2009	Johannes Berg <johannes@sipsolutions.net>
5  * Copyright (C) 2009   Intel Corporation. All rights reserved.
6  */
7 
8 #include <linux/etherdevice.h>
9 #include <linux/if_arp.h>
10 #include <linux/slab.h>
11 #include <linux/workqueue.h>
12 #include <linux/wireless.h>
13 #include <net/iw_handler.h>
14 #include <net/cfg80211.h>
15 #include <net/rtnetlink.h>
16 #include "nl80211.h"
17 #include "reg.h"
18 
19 struct cfg80211_conn {
20 	struct cfg80211_connect_params params;
21 	/* these are sub-states of the _CONNECTING sme_state */
22 	enum {
23 		CFG80211_CONN_IDLE,
24 		CFG80211_CONN_SCANNING,
25 		CFG80211_CONN_SCAN_AGAIN,
26 		CFG80211_CONN_AUTHENTICATE_NEXT,
27 		CFG80211_CONN_AUTHENTICATING,
28 		CFG80211_CONN_ASSOCIATE_NEXT,
29 		CFG80211_CONN_ASSOCIATING,
30 		CFG80211_CONN_DEAUTH_ASSOC_FAIL,
31 	} state;
32 	u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN];
33 	u8 *ie;
34 	size_t ie_len;
35 	bool auto_auth, prev_bssid_valid;
36 };
37 
38 bool cfg80211_is_all_idle(void)
39 {
40 	struct cfg80211_registered_device *rdev;
41 	struct wireless_dev *wdev;
42 	bool is_all_idle = true;
43 
44 	mutex_lock(&cfg80211_mutex);
45 
46 	/*
47 	 * All devices must be idle as otherwise if you are actively
48 	 * scanning some new beacon hints could be learned and would
49 	 * count as new regulatory hints.
50 	 */
51 	list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
52 		cfg80211_lock_rdev(rdev);
53 		list_for_each_entry(wdev, &rdev->netdev_list, list) {
54 			wdev_lock(wdev);
55 			if (wdev->sme_state != CFG80211_SME_IDLE)
56 				is_all_idle = false;
57 			wdev_unlock(wdev);
58 		}
59 		cfg80211_unlock_rdev(rdev);
60 	}
61 
62 	mutex_unlock(&cfg80211_mutex);
63 
64 	return is_all_idle;
65 }
66 
67 static void disconnect_work(struct work_struct *work)
68 {
69 	if (!cfg80211_is_all_idle())
70 		return;
71 
72 	regulatory_hint_disconnect();
73 }
74 
75 static DECLARE_WORK(cfg80211_disconnect_work, disconnect_work);
76 
77 static int cfg80211_conn_scan(struct wireless_dev *wdev)
78 {
79 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
80 	struct cfg80211_scan_request *request;
81 	int n_channels, err;
82 
83 	ASSERT_RTNL();
84 	ASSERT_RDEV_LOCK(rdev);
85 	ASSERT_WDEV_LOCK(wdev);
86 
87 	if (rdev->scan_req)
88 		return -EBUSY;
89 
90 	if (wdev->conn->params.channel) {
91 		n_channels = 1;
92 	} else {
93 		enum ieee80211_band band;
94 		n_channels = 0;
95 
96 		for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
97 			if (!wdev->wiphy->bands[band])
98 				continue;
99 			n_channels += wdev->wiphy->bands[band]->n_channels;
100 		}
101 	}
102 	request = kzalloc(sizeof(*request) + sizeof(request->ssids[0]) +
103 			  sizeof(request->channels[0]) * n_channels,
104 			  GFP_KERNEL);
105 	if (!request)
106 		return -ENOMEM;
107 
108 	if (wdev->conn->params.channel)
109 		request->channels[0] = wdev->conn->params.channel;
110 	else {
111 		int i = 0, j;
112 		enum ieee80211_band band;
113 
114 		for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
115 			if (!wdev->wiphy->bands[band])
116 				continue;
117 			for (j = 0; j < wdev->wiphy->bands[band]->n_channels;
118 			     i++, j++)
119 				request->channels[i] =
120 					&wdev->wiphy->bands[band]->channels[j];
121 		}
122 	}
123 	request->n_channels = n_channels;
124 	request->ssids = (void *)&request->channels[n_channels];
125 	request->n_ssids = 1;
126 
127 	memcpy(request->ssids[0].ssid, wdev->conn->params.ssid,
128 		wdev->conn->params.ssid_len);
129 	request->ssids[0].ssid_len = wdev->conn->params.ssid_len;
130 
131 	request->dev = wdev->netdev;
132 	request->wiphy = &rdev->wiphy;
133 
134 	rdev->scan_req = request;
135 
136 	err = rdev->ops->scan(wdev->wiphy, wdev->netdev, request);
137 	if (!err) {
138 		wdev->conn->state = CFG80211_CONN_SCANNING;
139 		nl80211_send_scan_start(rdev, wdev->netdev);
140 		dev_hold(wdev->netdev);
141 	} else {
142 		rdev->scan_req = NULL;
143 		kfree(request);
144 	}
145 	return err;
146 }
147 
148 static int cfg80211_conn_do_work(struct wireless_dev *wdev)
149 {
150 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
151 	struct cfg80211_connect_params *params;
152 	const u8 *prev_bssid = NULL;
153 	int err;
154 
155 	ASSERT_WDEV_LOCK(wdev);
156 
157 	if (!wdev->conn)
158 		return 0;
159 
160 	params = &wdev->conn->params;
161 
162 	switch (wdev->conn->state) {
163 	case CFG80211_CONN_SCAN_AGAIN:
164 		return cfg80211_conn_scan(wdev);
165 	case CFG80211_CONN_AUTHENTICATE_NEXT:
166 		BUG_ON(!rdev->ops->auth);
167 		wdev->conn->state = CFG80211_CONN_AUTHENTICATING;
168 		return __cfg80211_mlme_auth(rdev, wdev->netdev,
169 					    params->channel, params->auth_type,
170 					    params->bssid,
171 					    params->ssid, params->ssid_len,
172 					    NULL, 0,
173 					    params->key, params->key_len,
174 					    params->key_idx, false);
175 	case CFG80211_CONN_ASSOCIATE_NEXT:
176 		BUG_ON(!rdev->ops->assoc);
177 		wdev->conn->state = CFG80211_CONN_ASSOCIATING;
178 		if (wdev->conn->prev_bssid_valid)
179 			prev_bssid = wdev->conn->prev_bssid;
180 		err = __cfg80211_mlme_assoc(rdev, wdev->netdev,
181 					    params->channel, params->bssid,
182 					    prev_bssid,
183 					    params->ssid, params->ssid_len,
184 					    params->ie, params->ie_len,
185 					    false, &params->crypto);
186 		if (err)
187 			__cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
188 					       NULL, 0,
189 					       WLAN_REASON_DEAUTH_LEAVING,
190 					       false);
191 		return err;
192 	case CFG80211_CONN_DEAUTH_ASSOC_FAIL:
193 		__cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
194 				       NULL, 0,
195 				       WLAN_REASON_DEAUTH_LEAVING, false);
196 		/* return an error so that we call __cfg80211_connect_result() */
197 		return -EINVAL;
198 	default:
199 		return 0;
200 	}
201 }
202 
203 void cfg80211_conn_work(struct work_struct *work)
204 {
205 	struct cfg80211_registered_device *rdev =
206 		container_of(work, struct cfg80211_registered_device, conn_work);
207 	struct wireless_dev *wdev;
208 	u8 bssid_buf[ETH_ALEN], *bssid = NULL;
209 
210 	rtnl_lock();
211 	cfg80211_lock_rdev(rdev);
212 	mutex_lock(&rdev->devlist_mtx);
213 
214 	list_for_each_entry(wdev, &rdev->netdev_list, list) {
215 		wdev_lock(wdev);
216 		if (!netif_running(wdev->netdev)) {
217 			wdev_unlock(wdev);
218 			continue;
219 		}
220 		if (wdev->sme_state != CFG80211_SME_CONNECTING) {
221 			wdev_unlock(wdev);
222 			continue;
223 		}
224 		if (wdev->conn->params.bssid) {
225 			memcpy(bssid_buf, wdev->conn->params.bssid, ETH_ALEN);
226 			bssid = bssid_buf;
227 		}
228 		if (cfg80211_conn_do_work(wdev))
229 			__cfg80211_connect_result(
230 					wdev->netdev, bssid,
231 					NULL, 0, NULL, 0,
232 					WLAN_STATUS_UNSPECIFIED_FAILURE,
233 					false, NULL);
234 		wdev_unlock(wdev);
235 	}
236 
237 	mutex_unlock(&rdev->devlist_mtx);
238 	cfg80211_unlock_rdev(rdev);
239 	rtnl_unlock();
240 }
241 
242 static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev)
243 {
244 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
245 	struct cfg80211_bss *bss;
246 	u16 capa = WLAN_CAPABILITY_ESS;
247 
248 	ASSERT_WDEV_LOCK(wdev);
249 
250 	if (wdev->conn->params.privacy)
251 		capa |= WLAN_CAPABILITY_PRIVACY;
252 
253 	bss = cfg80211_get_bss(wdev->wiphy, NULL, wdev->conn->params.bssid,
254 			       wdev->conn->params.ssid,
255 			       wdev->conn->params.ssid_len,
256 			       WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_PRIVACY,
257 			       capa);
258 	if (!bss)
259 		return NULL;
260 
261 	memcpy(wdev->conn->bssid, bss->bssid, ETH_ALEN);
262 	wdev->conn->params.bssid = wdev->conn->bssid;
263 	wdev->conn->params.channel = bss->channel;
264 	wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
265 	schedule_work(&rdev->conn_work);
266 
267 	return bss;
268 }
269 
270 static void __cfg80211_sme_scan_done(struct net_device *dev)
271 {
272 	struct wireless_dev *wdev = dev->ieee80211_ptr;
273 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
274 	struct cfg80211_bss *bss;
275 
276 	ASSERT_WDEV_LOCK(wdev);
277 
278 	if (wdev->sme_state != CFG80211_SME_CONNECTING)
279 		return;
280 
281 	if (!wdev->conn)
282 		return;
283 
284 	if (wdev->conn->state != CFG80211_CONN_SCANNING &&
285 	    wdev->conn->state != CFG80211_CONN_SCAN_AGAIN)
286 		return;
287 
288 	bss = cfg80211_get_conn_bss(wdev);
289 	if (bss) {
290 		cfg80211_put_bss(bss);
291 	} else {
292 		/* not found */
293 		if (wdev->conn->state == CFG80211_CONN_SCAN_AGAIN)
294 			schedule_work(&rdev->conn_work);
295 		else
296 			__cfg80211_connect_result(
297 					wdev->netdev,
298 					wdev->conn->params.bssid,
299 					NULL, 0, NULL, 0,
300 					WLAN_STATUS_UNSPECIFIED_FAILURE,
301 					false, NULL);
302 	}
303 }
304 
305 void cfg80211_sme_scan_done(struct net_device *dev)
306 {
307 	struct wireless_dev *wdev = dev->ieee80211_ptr;
308 
309 	mutex_lock(&wiphy_to_dev(wdev->wiphy)->devlist_mtx);
310 	wdev_lock(wdev);
311 	__cfg80211_sme_scan_done(dev);
312 	wdev_unlock(wdev);
313 	mutex_unlock(&wiphy_to_dev(wdev->wiphy)->devlist_mtx);
314 }
315 
316 void cfg80211_sme_rx_auth(struct net_device *dev,
317 			  const u8 *buf, size_t len)
318 {
319 	struct wireless_dev *wdev = dev->ieee80211_ptr;
320 	struct wiphy *wiphy = wdev->wiphy;
321 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
322 	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
323 	u16 status_code = le16_to_cpu(mgmt->u.auth.status_code);
324 
325 	ASSERT_WDEV_LOCK(wdev);
326 
327 	/* should only RX auth frames when connecting */
328 	if (wdev->sme_state != CFG80211_SME_CONNECTING)
329 		return;
330 
331 	if (WARN_ON(!wdev->conn))
332 		return;
333 
334 	if (status_code == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG &&
335 	    wdev->conn->auto_auth &&
336 	    wdev->conn->params.auth_type != NL80211_AUTHTYPE_NETWORK_EAP) {
337 		/* select automatically between only open, shared, leap */
338 		switch (wdev->conn->params.auth_type) {
339 		case NL80211_AUTHTYPE_OPEN_SYSTEM:
340 			if (wdev->connect_keys)
341 				wdev->conn->params.auth_type =
342 					NL80211_AUTHTYPE_SHARED_KEY;
343 			else
344 				wdev->conn->params.auth_type =
345 					NL80211_AUTHTYPE_NETWORK_EAP;
346 			break;
347 		case NL80211_AUTHTYPE_SHARED_KEY:
348 			wdev->conn->params.auth_type =
349 				NL80211_AUTHTYPE_NETWORK_EAP;
350 			break;
351 		default:
352 			/* huh? */
353 			wdev->conn->params.auth_type =
354 				NL80211_AUTHTYPE_OPEN_SYSTEM;
355 			break;
356 		}
357 		wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
358 		schedule_work(&rdev->conn_work);
359 	} else if (status_code != WLAN_STATUS_SUCCESS) {
360 		__cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0,
361 					  status_code, false, NULL);
362 	} else if (wdev->sme_state == CFG80211_SME_CONNECTING &&
363 		 wdev->conn->state == CFG80211_CONN_AUTHENTICATING) {
364 		wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT;
365 		schedule_work(&rdev->conn_work);
366 	}
367 }
368 
369 bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev)
370 {
371 	struct wiphy *wiphy = wdev->wiphy;
372 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
373 
374 	if (WARN_ON(!wdev->conn))
375 		return false;
376 
377 	if (!wdev->conn->prev_bssid_valid)
378 		return false;
379 
380 	/*
381 	 * Some stupid APs don't accept reassoc, so we
382 	 * need to fall back to trying regular assoc.
383 	 */
384 	wdev->conn->prev_bssid_valid = false;
385 	wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT;
386 	schedule_work(&rdev->conn_work);
387 
388 	return true;
389 }
390 
391 void cfg80211_sme_failed_assoc(struct wireless_dev *wdev)
392 {
393 	struct wiphy *wiphy = wdev->wiphy;
394 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
395 
396 	wdev->conn->state = CFG80211_CONN_DEAUTH_ASSOC_FAIL;
397 	schedule_work(&rdev->conn_work);
398 }
399 
400 void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
401 			       const u8 *req_ie, size_t req_ie_len,
402 			       const u8 *resp_ie, size_t resp_ie_len,
403 			       u16 status, bool wextev,
404 			       struct cfg80211_bss *bss)
405 {
406 	struct wireless_dev *wdev = dev->ieee80211_ptr;
407 	u8 *country_ie;
408 #ifdef CONFIG_CFG80211_WEXT
409 	union iwreq_data wrqu;
410 #endif
411 
412 	ASSERT_WDEV_LOCK(wdev);
413 
414 	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
415 		return;
416 
417 	if (wdev->sme_state != CFG80211_SME_CONNECTING)
418 		return;
419 
420 	nl80211_send_connect_result(wiphy_to_dev(wdev->wiphy), dev,
421 				    bssid, req_ie, req_ie_len,
422 				    resp_ie, resp_ie_len,
423 				    status, GFP_KERNEL);
424 
425 #ifdef CONFIG_CFG80211_WEXT
426 	if (wextev) {
427 		if (req_ie && status == WLAN_STATUS_SUCCESS) {
428 			memset(&wrqu, 0, sizeof(wrqu));
429 			wrqu.data.length = req_ie_len;
430 			wireless_send_event(dev, IWEVASSOCREQIE, &wrqu, req_ie);
431 		}
432 
433 		if (resp_ie && status == WLAN_STATUS_SUCCESS) {
434 			memset(&wrqu, 0, sizeof(wrqu));
435 			wrqu.data.length = resp_ie_len;
436 			wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, resp_ie);
437 		}
438 
439 		memset(&wrqu, 0, sizeof(wrqu));
440 		wrqu.ap_addr.sa_family = ARPHRD_ETHER;
441 		if (bssid && status == WLAN_STATUS_SUCCESS) {
442 			memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
443 			memcpy(wdev->wext.prev_bssid, bssid, ETH_ALEN);
444 			wdev->wext.prev_bssid_valid = true;
445 		}
446 		wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
447 	}
448 #endif
449 
450 	if (wdev->current_bss) {
451 		cfg80211_unhold_bss(wdev->current_bss);
452 		cfg80211_put_bss(&wdev->current_bss->pub);
453 		wdev->current_bss = NULL;
454 	}
455 
456 	if (wdev->conn)
457 		wdev->conn->state = CFG80211_CONN_IDLE;
458 
459 	if (status != WLAN_STATUS_SUCCESS) {
460 		wdev->sme_state = CFG80211_SME_IDLE;
461 		if (wdev->conn)
462 			kfree(wdev->conn->ie);
463 		kfree(wdev->conn);
464 		wdev->conn = NULL;
465 		kfree(wdev->connect_keys);
466 		wdev->connect_keys = NULL;
467 		wdev->ssid_len = 0;
468 		return;
469 	}
470 
471 	if (!bss)
472 		bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
473 				       wdev->ssid, wdev->ssid_len,
474 				       WLAN_CAPABILITY_ESS,
475 				       WLAN_CAPABILITY_ESS);
476 
477 	if (WARN_ON(!bss))
478 		return;
479 
480 	cfg80211_hold_bss(bss_from_pub(bss));
481 	wdev->current_bss = bss_from_pub(bss);
482 
483 	wdev->sme_state = CFG80211_SME_CONNECTED;
484 	cfg80211_upload_connect_keys(wdev);
485 
486 	country_ie = (u8 *) ieee80211_bss_get_ie(bss, WLAN_EID_COUNTRY);
487 
488 	if (!country_ie)
489 		return;
490 
491 	/*
492 	 * ieee80211_bss_get_ie() ensures we can access:
493 	 * - country_ie + 2, the start of the country ie data, and
494 	 * - and country_ie[1] which is the IE length
495 	 */
496 	regulatory_hint_11d(wdev->wiphy,
497 			    bss->channel->band,
498 			    country_ie + 2,
499 			    country_ie[1]);
500 }
501 
502 void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
503 			     const u8 *req_ie, size_t req_ie_len,
504 			     const u8 *resp_ie, size_t resp_ie_len,
505 			     u16 status, gfp_t gfp)
506 {
507 	struct wireless_dev *wdev = dev->ieee80211_ptr;
508 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
509 	struct cfg80211_event *ev;
510 	unsigned long flags;
511 
512 	CFG80211_DEV_WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTING);
513 
514 	ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len, gfp);
515 	if (!ev)
516 		return;
517 
518 	ev->type = EVENT_CONNECT_RESULT;
519 	if (bssid)
520 		memcpy(ev->cr.bssid, bssid, ETH_ALEN);
521 	if (req_ie_len) {
522 		ev->cr.req_ie = ((u8 *)ev) + sizeof(*ev);
523 		ev->cr.req_ie_len = req_ie_len;
524 		memcpy((void *)ev->cr.req_ie, req_ie, req_ie_len);
525 	}
526 	if (resp_ie_len) {
527 		ev->cr.resp_ie = ((u8 *)ev) + sizeof(*ev) + req_ie_len;
528 		ev->cr.resp_ie_len = resp_ie_len;
529 		memcpy((void *)ev->cr.resp_ie, resp_ie, resp_ie_len);
530 	}
531 	ev->cr.status = status;
532 
533 	spin_lock_irqsave(&wdev->event_lock, flags);
534 	list_add_tail(&ev->list, &wdev->event_list);
535 	spin_unlock_irqrestore(&wdev->event_lock, flags);
536 	queue_work(cfg80211_wq, &rdev->event_work);
537 }
538 EXPORT_SYMBOL(cfg80211_connect_result);
539 
540 void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid,
541 		       const u8 *req_ie, size_t req_ie_len,
542 		       const u8 *resp_ie, size_t resp_ie_len)
543 {
544 	struct cfg80211_bss *bss;
545 #ifdef CONFIG_CFG80211_WEXT
546 	union iwreq_data wrqu;
547 #endif
548 
549 	ASSERT_WDEV_LOCK(wdev);
550 
551 	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
552 		return;
553 
554 	if (wdev->sme_state != CFG80211_SME_CONNECTED)
555 		return;
556 
557 	/* internal error -- how did we get to CONNECTED w/o BSS? */
558 	if (WARN_ON(!wdev->current_bss)) {
559 		return;
560 	}
561 
562 	cfg80211_unhold_bss(wdev->current_bss);
563 	cfg80211_put_bss(&wdev->current_bss->pub);
564 	wdev->current_bss = NULL;
565 
566 	bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
567 			       wdev->ssid, wdev->ssid_len,
568 			       WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
569 
570 	if (WARN_ON(!bss))
571 		return;
572 
573 	cfg80211_hold_bss(bss_from_pub(bss));
574 	wdev->current_bss = bss_from_pub(bss);
575 
576 	nl80211_send_roamed(wiphy_to_dev(wdev->wiphy), wdev->netdev, bssid,
577 			    req_ie, req_ie_len, resp_ie, resp_ie_len,
578 			    GFP_KERNEL);
579 
580 #ifdef CONFIG_CFG80211_WEXT
581 	if (req_ie) {
582 		memset(&wrqu, 0, sizeof(wrqu));
583 		wrqu.data.length = req_ie_len;
584 		wireless_send_event(wdev->netdev, IWEVASSOCREQIE,
585 				    &wrqu, req_ie);
586 	}
587 
588 	if (resp_ie) {
589 		memset(&wrqu, 0, sizeof(wrqu));
590 		wrqu.data.length = resp_ie_len;
591 		wireless_send_event(wdev->netdev, IWEVASSOCRESPIE,
592 				    &wrqu, resp_ie);
593 	}
594 
595 	memset(&wrqu, 0, sizeof(wrqu));
596 	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
597 	memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
598 	memcpy(wdev->wext.prev_bssid, bssid, ETH_ALEN);
599 	wdev->wext.prev_bssid_valid = true;
600 	wireless_send_event(wdev->netdev, SIOCGIWAP, &wrqu, NULL);
601 #endif
602 }
603 
604 void cfg80211_roamed(struct net_device *dev, const u8 *bssid,
605 		     const u8 *req_ie, size_t req_ie_len,
606 		     const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp)
607 {
608 	struct wireless_dev *wdev = dev->ieee80211_ptr;
609 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
610 	struct cfg80211_event *ev;
611 	unsigned long flags;
612 
613 	CFG80211_DEV_WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTED);
614 
615 	ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len, gfp);
616 	if (!ev)
617 		return;
618 
619 	ev->type = EVENT_ROAMED;
620 	memcpy(ev->rm.bssid, bssid, ETH_ALEN);
621 	ev->rm.req_ie = ((u8 *)ev) + sizeof(*ev);
622 	ev->rm.req_ie_len = req_ie_len;
623 	memcpy((void *)ev->rm.req_ie, req_ie, req_ie_len);
624 	ev->rm.resp_ie = ((u8 *)ev) + sizeof(*ev) + req_ie_len;
625 	ev->rm.resp_ie_len = resp_ie_len;
626 	memcpy((void *)ev->rm.resp_ie, resp_ie, resp_ie_len);
627 
628 	spin_lock_irqsave(&wdev->event_lock, flags);
629 	list_add_tail(&ev->list, &wdev->event_list);
630 	spin_unlock_irqrestore(&wdev->event_lock, flags);
631 	queue_work(cfg80211_wq, &rdev->event_work);
632 }
633 EXPORT_SYMBOL(cfg80211_roamed);
634 
635 void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
636 			     size_t ie_len, u16 reason, bool from_ap)
637 {
638 	struct wireless_dev *wdev = dev->ieee80211_ptr;
639 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
640 	int i;
641 #ifdef CONFIG_CFG80211_WEXT
642 	union iwreq_data wrqu;
643 #endif
644 
645 	ASSERT_WDEV_LOCK(wdev);
646 
647 	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
648 		return;
649 
650 	if (wdev->sme_state != CFG80211_SME_CONNECTED)
651 		return;
652 
653 	if (wdev->current_bss) {
654 		cfg80211_unhold_bss(wdev->current_bss);
655 		cfg80211_put_bss(&wdev->current_bss->pub);
656 	}
657 
658 	wdev->current_bss = NULL;
659 	wdev->sme_state = CFG80211_SME_IDLE;
660 	wdev->ssid_len = 0;
661 
662 	if (wdev->conn) {
663 		const u8 *bssid;
664 		int ret;
665 
666 		kfree(wdev->conn->ie);
667 		wdev->conn->ie = NULL;
668 		kfree(wdev->conn);
669 		wdev->conn = NULL;
670 
671 		/*
672 		 * If this disconnect was due to a disassoc, we
673 		 * we might still have an auth BSS around. For
674 		 * the userspace SME that's currently expected,
675 		 * but for the kernel SME (nl80211 CONNECT or
676 		 * wireless extensions) we want to clear up all
677 		 * state.
678 		 */
679 		for (i = 0; i < MAX_AUTH_BSSES; i++) {
680 			if (!wdev->auth_bsses[i])
681 				continue;
682 			bssid = wdev->auth_bsses[i]->pub.bssid;
683 			ret = __cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0,
684 						WLAN_REASON_DEAUTH_LEAVING,
685 						false);
686 			WARN(ret, "deauth failed: %d\n", ret);
687 		}
688 	}
689 
690 	nl80211_send_disconnected(rdev, dev, reason, ie, ie_len, from_ap);
691 
692 	/*
693 	 * Delete all the keys ... pairwise keys can't really
694 	 * exist any more anyway, but default keys might.
695 	 */
696 	if (rdev->ops->del_key)
697 		for (i = 0; i < 6; i++)
698 			rdev->ops->del_key(wdev->wiphy, dev, i, NULL);
699 
700 #ifdef CONFIG_CFG80211_WEXT
701 	memset(&wrqu, 0, sizeof(wrqu));
702 	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
703 	wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
704 	wdev->wext.connect.ssid_len = 0;
705 #endif
706 
707 	schedule_work(&cfg80211_disconnect_work);
708 }
709 
710 void cfg80211_disconnected(struct net_device *dev, u16 reason,
711 			   u8 *ie, size_t ie_len, gfp_t gfp)
712 {
713 	struct wireless_dev *wdev = dev->ieee80211_ptr;
714 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
715 	struct cfg80211_event *ev;
716 	unsigned long flags;
717 
718 	CFG80211_DEV_WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTED);
719 
720 	ev = kzalloc(sizeof(*ev) + ie_len, gfp);
721 	if (!ev)
722 		return;
723 
724 	ev->type = EVENT_DISCONNECTED;
725 	ev->dc.ie = ((u8 *)ev) + sizeof(*ev);
726 	ev->dc.ie_len = ie_len;
727 	memcpy((void *)ev->dc.ie, ie, ie_len);
728 	ev->dc.reason = reason;
729 
730 	spin_lock_irqsave(&wdev->event_lock, flags);
731 	list_add_tail(&ev->list, &wdev->event_list);
732 	spin_unlock_irqrestore(&wdev->event_lock, flags);
733 	queue_work(cfg80211_wq, &rdev->event_work);
734 }
735 EXPORT_SYMBOL(cfg80211_disconnected);
736 
737 int __cfg80211_connect(struct cfg80211_registered_device *rdev,
738 		       struct net_device *dev,
739 		       struct cfg80211_connect_params *connect,
740 		       struct cfg80211_cached_keys *connkeys,
741 		       const u8 *prev_bssid)
742 {
743 	struct wireless_dev *wdev = dev->ieee80211_ptr;
744 	struct cfg80211_bss *bss = NULL;
745 	int err;
746 
747 	ASSERT_WDEV_LOCK(wdev);
748 
749 	if (wdev->sme_state != CFG80211_SME_IDLE)
750 		return -EALREADY;
751 
752 	if (WARN_ON(wdev->connect_keys)) {
753 		kfree(wdev->connect_keys);
754 		wdev->connect_keys = NULL;
755 	}
756 
757 	if (connkeys && connkeys->def >= 0) {
758 		int idx;
759 		u32 cipher;
760 
761 		idx = connkeys->def;
762 		cipher = connkeys->params[idx].cipher;
763 		/* If given a WEP key we may need it for shared key auth */
764 		if (cipher == WLAN_CIPHER_SUITE_WEP40 ||
765 		    cipher == WLAN_CIPHER_SUITE_WEP104) {
766 			connect->key_idx = idx;
767 			connect->key = connkeys->params[idx].key;
768 			connect->key_len = connkeys->params[idx].key_len;
769 
770 			/*
771 			 * If ciphers are not set (e.g. when going through
772 			 * iwconfig), we have to set them appropriately here.
773 			 */
774 			if (connect->crypto.cipher_group == 0)
775 				connect->crypto.cipher_group = cipher;
776 
777 			if (connect->crypto.n_ciphers_pairwise == 0) {
778 				connect->crypto.n_ciphers_pairwise = 1;
779 				connect->crypto.ciphers_pairwise[0] = cipher;
780 			}
781 		}
782 	}
783 
784 	if (!rdev->ops->connect) {
785 		if (!rdev->ops->auth || !rdev->ops->assoc)
786 			return -EOPNOTSUPP;
787 
788 		if (WARN_ON(wdev->conn))
789 			return -EINPROGRESS;
790 
791 		wdev->conn = kzalloc(sizeof(*wdev->conn), GFP_KERNEL);
792 		if (!wdev->conn)
793 			return -ENOMEM;
794 
795 		/*
796 		 * Copy all parameters, and treat explicitly IEs, BSSID, SSID.
797 		 */
798 		memcpy(&wdev->conn->params, connect, sizeof(*connect));
799 		if (connect->bssid) {
800 			wdev->conn->params.bssid = wdev->conn->bssid;
801 			memcpy(wdev->conn->bssid, connect->bssid, ETH_ALEN);
802 		}
803 
804 		if (connect->ie) {
805 			wdev->conn->ie = kmemdup(connect->ie, connect->ie_len,
806 						GFP_KERNEL);
807 			wdev->conn->params.ie = wdev->conn->ie;
808 			if (!wdev->conn->ie) {
809 				kfree(wdev->conn);
810 				wdev->conn = NULL;
811 				return -ENOMEM;
812 			}
813 		}
814 
815 		if (connect->auth_type == NL80211_AUTHTYPE_AUTOMATIC) {
816 			wdev->conn->auto_auth = true;
817 			/* start with open system ... should mostly work */
818 			wdev->conn->params.auth_type =
819 				NL80211_AUTHTYPE_OPEN_SYSTEM;
820 		} else {
821 			wdev->conn->auto_auth = false;
822 		}
823 
824 		memcpy(wdev->ssid, connect->ssid, connect->ssid_len);
825 		wdev->ssid_len = connect->ssid_len;
826 		wdev->conn->params.ssid = wdev->ssid;
827 		wdev->conn->params.ssid_len = connect->ssid_len;
828 
829 		/* see if we have the bss already */
830 		bss = cfg80211_get_conn_bss(wdev);
831 
832 		wdev->sme_state = CFG80211_SME_CONNECTING;
833 		wdev->connect_keys = connkeys;
834 
835 		if (prev_bssid) {
836 			memcpy(wdev->conn->prev_bssid, prev_bssid, ETH_ALEN);
837 			wdev->conn->prev_bssid_valid = true;
838 		}
839 
840 		/* we're good if we have a matching bss struct */
841 		if (bss) {
842 			wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
843 			err = cfg80211_conn_do_work(wdev);
844 			cfg80211_put_bss(bss);
845 		} else {
846 			/* otherwise we'll need to scan for the AP first */
847 			err = cfg80211_conn_scan(wdev);
848 			/*
849 			 * If we can't scan right now, then we need to scan again
850 			 * after the current scan finished, since the parameters
851 			 * changed (unless we find a good AP anyway).
852 			 */
853 			if (err == -EBUSY) {
854 				err = 0;
855 				wdev->conn->state = CFG80211_CONN_SCAN_AGAIN;
856 			}
857 		}
858 		if (err) {
859 			kfree(wdev->conn->ie);
860 			kfree(wdev->conn);
861 			wdev->conn = NULL;
862 			wdev->sme_state = CFG80211_SME_IDLE;
863 			wdev->connect_keys = NULL;
864 			wdev->ssid_len = 0;
865 		}
866 
867 		return err;
868 	} else {
869 		wdev->sme_state = CFG80211_SME_CONNECTING;
870 		wdev->connect_keys = connkeys;
871 		err = rdev->ops->connect(&rdev->wiphy, dev, connect);
872 		if (err) {
873 			wdev->connect_keys = NULL;
874 			wdev->sme_state = CFG80211_SME_IDLE;
875 			return err;
876 		}
877 
878 		memcpy(wdev->ssid, connect->ssid, connect->ssid_len);
879 		wdev->ssid_len = connect->ssid_len;
880 
881 		return 0;
882 	}
883 }
884 
885 int cfg80211_connect(struct cfg80211_registered_device *rdev,
886 		     struct net_device *dev,
887 		     struct cfg80211_connect_params *connect,
888 		     struct cfg80211_cached_keys *connkeys)
889 {
890 	int err;
891 
892 	mutex_lock(&rdev->devlist_mtx);
893 	wdev_lock(dev->ieee80211_ptr);
894 	err = __cfg80211_connect(rdev, dev, connect, connkeys, NULL);
895 	wdev_unlock(dev->ieee80211_ptr);
896 	mutex_unlock(&rdev->devlist_mtx);
897 
898 	return err;
899 }
900 
901 int __cfg80211_disconnect(struct cfg80211_registered_device *rdev,
902 			  struct net_device *dev, u16 reason, bool wextev)
903 {
904 	struct wireless_dev *wdev = dev->ieee80211_ptr;
905 	int err;
906 
907 	ASSERT_WDEV_LOCK(wdev);
908 
909 	if (wdev->sme_state == CFG80211_SME_IDLE)
910 		return -EINVAL;
911 
912 	kfree(wdev->connect_keys);
913 	wdev->connect_keys = NULL;
914 
915 	if (!rdev->ops->disconnect) {
916 		if (!rdev->ops->deauth)
917 			return -EOPNOTSUPP;
918 
919 		/* was it connected by userspace SME? */
920 		if (!wdev->conn) {
921 			cfg80211_mlme_down(rdev, dev);
922 			return 0;
923 		}
924 
925 		if (wdev->sme_state == CFG80211_SME_CONNECTING &&
926 		    (wdev->conn->state == CFG80211_CONN_SCANNING ||
927 		     wdev->conn->state == CFG80211_CONN_SCAN_AGAIN)) {
928 			wdev->sme_state = CFG80211_SME_IDLE;
929 			kfree(wdev->conn->ie);
930 			kfree(wdev->conn);
931 			wdev->conn = NULL;
932 			wdev->ssid_len = 0;
933 			return 0;
934 		}
935 
936 		/* wdev->conn->params.bssid must be set if > SCANNING */
937 		err = __cfg80211_mlme_deauth(rdev, dev,
938 					     wdev->conn->params.bssid,
939 					     NULL, 0, reason, false);
940 		if (err)
941 			return err;
942 	} else {
943 		err = rdev->ops->disconnect(&rdev->wiphy, dev, reason);
944 		if (err)
945 			return err;
946 	}
947 
948 	if (wdev->sme_state == CFG80211_SME_CONNECTED)
949 		__cfg80211_disconnected(dev, NULL, 0, 0, false);
950 	else if (wdev->sme_state == CFG80211_SME_CONNECTING)
951 		__cfg80211_connect_result(dev, NULL, NULL, 0, NULL, 0,
952 					  WLAN_STATUS_UNSPECIFIED_FAILURE,
953 					  wextev, NULL);
954 
955 	return 0;
956 }
957 
958 int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
959 			struct net_device *dev,
960 			u16 reason, bool wextev)
961 {
962 	int err;
963 
964 	wdev_lock(dev->ieee80211_ptr);
965 	err = __cfg80211_disconnect(rdev, dev, reason, wextev);
966 	wdev_unlock(dev->ieee80211_ptr);
967 
968 	return err;
969 }
970 
971 void cfg80211_sme_disassoc(struct net_device *dev, int idx)
972 {
973 	struct wireless_dev *wdev = dev->ieee80211_ptr;
974 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
975 	u8 bssid[ETH_ALEN];
976 
977 	ASSERT_WDEV_LOCK(wdev);
978 
979 	if (!wdev->conn)
980 		return;
981 
982 	if (wdev->conn->state == CFG80211_CONN_IDLE)
983 		return;
984 
985 	/*
986 	 * Ok, so the association was made by this SME -- we don't
987 	 * want it any more so deauthenticate too.
988 	 */
989 
990 	if (!wdev->auth_bsses[idx])
991 		return;
992 
993 	memcpy(bssid, wdev->auth_bsses[idx]->pub.bssid, ETH_ALEN);
994 	if (__cfg80211_mlme_deauth(rdev, dev, bssid,
995 				   NULL, 0, WLAN_REASON_DEAUTH_LEAVING,
996 				   false)) {
997 		/* whatever -- assume gone anyway */
998 		cfg80211_unhold_bss(wdev->auth_bsses[idx]);
999 		cfg80211_put_bss(&wdev->auth_bsses[idx]->pub);
1000 		wdev->auth_bsses[idx] = NULL;
1001 	}
1002 }
1003