// SPDX-License-Identifier: GPL-2.0
/*
 * SME code for cfg80211
 * both driver SME event handling and the SME implementation
 * (for nl80211's connect() and wext)
 *
 * Copyright 2009	Johannes Berg <johannes@sipsolutions.net>
 * Copyright (C) 2009, 2020, 2022 Intel Corporation. All rights reserved.
 * Copyright 2017	Intel Deutschland GmbH
 */

#include <linux/etherdevice.h>
#include <linux/if_arp.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/wireless.h>
#include <linux/export.h>
#include <net/iw_handler.h>
#include <net/cfg80211.h>
#include <net/rtnetlink.h>
#include "nl80211.h"
#include "reg.h"
#include "rdev-ops.h"

/*
 * Software SME in cfg80211, using auth/assoc/deauth calls to the
 * driver. This is for implementing nl80211's connect/disconnect
 * and wireless extensions (if configured.)
 */

struct cfg80211_conn {
	struct cfg80211_connect_params params;
	/* these are sub-states of the _CONNECTING sme_state */
	enum {
		CFG80211_CONN_SCANNING,
		CFG80211_CONN_SCAN_AGAIN,
		CFG80211_CONN_AUTHENTICATE_NEXT,
		CFG80211_CONN_AUTHENTICATING,
		CFG80211_CONN_AUTH_FAILED_TIMEOUT,
		CFG80211_CONN_ASSOCIATE_NEXT,
		CFG80211_CONN_ASSOCIATING,
		CFG80211_CONN_ASSOC_FAILED,
		CFG80211_CONN_ASSOC_FAILED_TIMEOUT,
		CFG80211_CONN_DEAUTH,
		CFG80211_CONN_ABANDON,
		CFG80211_CONN_CONNECTED,
	} state;
	u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN];
	const u8 *ie;
	size_t ie_len;
	bool auto_auth, prev_bssid_valid;
};

static void cfg80211_sme_free(struct wireless_dev *wdev)
{
	if (!wdev->conn)
		return;

	kfree(wdev->conn->ie);
	kfree(wdev->conn);
	wdev->conn = NULL;
}

static int cfg80211_conn_scan(struct wireless_dev *wdev)
{
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
	struct cfg80211_scan_request *request;
	int n_channels, err;

	ASSERT_WDEV_LOCK(wdev);

	if (rdev->scan_req || rdev->scan_msg)
		return -EBUSY;

	if (wdev->conn->params.channel)
		n_channels = 1;
	else
		n_channels = ieee80211_get_num_supported_channels(wdev->wiphy);

	request = kzalloc(sizeof(*request) + sizeof(request->ssids[0]) +
			  sizeof(request->channels[0]) * n_channels,
			  GFP_KERNEL);
	if (!request)
		return -ENOMEM;

	if (wdev->conn->params.channel) {
		enum nl80211_band band = wdev->conn->params.channel->band;
		struct ieee80211_supported_band *sband =
			wdev->wiphy->bands[band];

		if (!sband) {
			kfree(request);
			return -EINVAL;
		}
		request->channels[0] = wdev->conn->params.channel;
		request->rates[band] = (1 << sband->n_bitrates) - 1;
	} else {
		int i = 0, j;
		enum nl80211_band band;
		struct ieee80211_supported_band *bands;
		struct ieee80211_channel *channel;

		for (band = 0; band < NUM_NL80211_BANDS; band++) {
			bands = wdev->wiphy->bands[band];
			if (!bands)
				continue;
			for (j = 0; j < bands->n_channels; j++) {
				channel = &bands->channels[j];
				if (channel->flags & IEEE80211_CHAN_DISABLED)
					continue;
				request->channels[i++] = channel;
			}
			request->rates[band] = (1 << bands->n_bitrates) - 1;
		}
		n_channels = i;
	}
	request->n_channels = n_channels;
	request->ssids = (void *)&request->channels[n_channels];
	request->n_ssids = 1;

	memcpy(request->ssids[0].ssid, wdev->conn->params.ssid,
		wdev->conn->params.ssid_len);
	request->ssids[0].ssid_len = wdev->conn->params.ssid_len;

	eth_broadcast_addr(request->bssid);

	request->wdev = wdev;
	request->wiphy = &rdev->wiphy;
	request->scan_start = jiffies;

	rdev->scan_req = request;

	err = rdev_scan(rdev, request);
	if (!err) {
		wdev->conn->state = CFG80211_CONN_SCANNING;
		nl80211_send_scan_start(rdev, wdev);
		dev_hold(wdev->netdev);
	} else {
		rdev->scan_req = NULL;
		kfree(request);
	}
	return err;
}

static int cfg80211_conn_do_work(struct wireless_dev *wdev,
				 enum nl80211_timeout_reason *treason)
{
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
	struct cfg80211_connect_params *params;
	struct cfg80211_auth_request auth_req = {};
	struct cfg80211_assoc_request req = {};
	int err;

	ASSERT_WDEV_LOCK(wdev);

	if (!wdev->conn)
		return 0;

	params = &wdev->conn->params;

	switch (wdev->conn->state) {
	case CFG80211_CONN_SCANNING:
		/* didn't find it during scan ... */
		return -ENOENT;
	case CFG80211_CONN_SCAN_AGAIN:
		return cfg80211_conn_scan(wdev);
	case CFG80211_CONN_AUTHENTICATE_NEXT:
		if (WARN_ON(!rdev->ops->auth))
			return -EOPNOTSUPP;
		wdev->conn->state = CFG80211_CONN_AUTHENTICATING;
		auth_req.key = params->key;
		auth_req.key_len = params->key_len;
		auth_req.key_idx = params->key_idx;
		auth_req.auth_type = params->auth_type;
		auth_req.bss = cfg80211_get_bss(&rdev->wiphy, params->channel,
						params->bssid,
						params->ssid, params->ssid_len,
						IEEE80211_BSS_TYPE_ESS,
						IEEE80211_PRIVACY_ANY);
		auth_req.link_id = -1;
		err = cfg80211_mlme_auth(rdev, wdev->netdev, &auth_req);
		cfg80211_put_bss(&rdev->wiphy, auth_req.bss);
		return err;
	case CFG80211_CONN_AUTH_FAILED_TIMEOUT:
		*treason = NL80211_TIMEOUT_AUTH;
		return -ENOTCONN;
	case CFG80211_CONN_ASSOCIATE_NEXT:
		if (WARN_ON(!rdev->ops->assoc))
			return -EOPNOTSUPP;
		wdev->conn->state = CFG80211_CONN_ASSOCIATING;
		if (wdev->conn->prev_bssid_valid)
			req.prev_bssid = wdev->conn->prev_bssid;
		req.ie = params->ie;
		req.ie_len = params->ie_len;
		req.use_mfp = params->mfp != NL80211_MFP_NO;
		req.crypto = params->crypto;
		req.flags = params->flags;
		req.ht_capa = params->ht_capa;
		req.ht_capa_mask = params->ht_capa_mask;
		req.vht_capa = params->vht_capa;
		req.vht_capa_mask = params->vht_capa_mask;
		req.link_id = -1;

		req.bss = cfg80211_get_bss(&rdev->wiphy, params->channel,
					   params->bssid,
					   params->ssid, params->ssid_len,
					   IEEE80211_BSS_TYPE_ESS,
					   IEEE80211_PRIVACY_ANY);
		if (!req.bss) {
			err = -ENOENT;
		} else {
			err = cfg80211_mlme_assoc(rdev, wdev->netdev, &req);
			cfg80211_put_bss(&rdev->wiphy, req.bss);
		}

		if (err)
			cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
					     NULL, 0,
					     WLAN_REASON_DEAUTH_LEAVING,
					     false);
		return err;
	case CFG80211_CONN_ASSOC_FAILED_TIMEOUT:
		*treason = NL80211_TIMEOUT_ASSOC;
		fallthrough;
	case CFG80211_CONN_ASSOC_FAILED:
		cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
				     NULL, 0,
				     WLAN_REASON_DEAUTH_LEAVING, false);
		return -ENOTCONN;
	case CFG80211_CONN_DEAUTH:
		cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
				     NULL, 0,
				     WLAN_REASON_DEAUTH_LEAVING, false);
		fallthrough;
	case CFG80211_CONN_ABANDON:
		/* free directly, disconnected event already sent */
		cfg80211_sme_free(wdev);
		return 0;
	default:
		return 0;
	}
}

void cfg80211_conn_work(struct work_struct *work)
{
	struct cfg80211_registered_device *rdev =
		container_of(work, struct cfg80211_registered_device, conn_work);
	struct wireless_dev *wdev;
	u8 bssid_buf[ETH_ALEN], *bssid = NULL;
	enum nl80211_timeout_reason treason;

	wiphy_lock(&rdev->wiphy);

	list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
		if (!wdev->netdev)
			continue;

		wdev_lock(wdev);
		if (!netif_running(wdev->netdev)) {
			wdev_unlock(wdev);
			continue;
		}
		if (!wdev->conn ||
		    wdev->conn->state == CFG80211_CONN_CONNECTED) {
			wdev_unlock(wdev);
			continue;
		}
		if (wdev->conn->params.bssid) {
			memcpy(bssid_buf, wdev->conn->params.bssid, ETH_ALEN);
			bssid = bssid_buf;
		}
		treason = NL80211_TIMEOUT_UNSPECIFIED;
		if (cfg80211_conn_do_work(wdev, &treason)) {
			struct cfg80211_connect_resp_params cr;

			memset(&cr, 0, sizeof(cr));
			cr.status = -1;
			cr.links[0].bssid = bssid;
			cr.timeout_reason = treason;
			__cfg80211_connect_result(wdev->netdev, &cr, false);
		}
		wdev_unlock(wdev);
	}

	wiphy_unlock(&rdev->wiphy);
}

static void cfg80211_step_auth_next(struct cfg80211_conn *conn,
				    struct cfg80211_bss *bss)
{
	memcpy(conn->bssid, bss->bssid, ETH_ALEN);
	conn->params.bssid = conn->bssid;
	conn->params.channel = bss->channel;
	conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
}

/* Returned bss is reference counted and must be cleaned up appropriately. */
static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev)
{
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
	struct cfg80211_bss *bss;

	ASSERT_WDEV_LOCK(wdev);

	bss = cfg80211_get_bss(wdev->wiphy, wdev->conn->params.channel,
			       wdev->conn->params.bssid,
			       wdev->conn->params.ssid,
			       wdev->conn->params.ssid_len,
			       wdev->conn_bss_type,
			       IEEE80211_PRIVACY(wdev->conn->params.privacy));
	if (!bss)
		return NULL;

	cfg80211_step_auth_next(wdev->conn, bss);
	schedule_work(&rdev->conn_work);

	return bss;
}

static void __cfg80211_sme_scan_done(struct net_device *dev)
{
	struct wireless_dev *wdev = dev->ieee80211_ptr;
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
	struct cfg80211_bss *bss;

	ASSERT_WDEV_LOCK(wdev);

	if (!wdev->conn)
		return;

	if (wdev->conn->state != CFG80211_CONN_SCANNING &&
	    wdev->conn->state != CFG80211_CONN_SCAN_AGAIN)
		return;

	bss = cfg80211_get_conn_bss(wdev);
	if (bss)
		cfg80211_put_bss(&rdev->wiphy, bss);
	else
		schedule_work(&rdev->conn_work);
}

void cfg80211_sme_scan_done(struct net_device *dev)
{
	struct wireless_dev *wdev = dev->ieee80211_ptr;

	wdev_lock(wdev);
	__cfg80211_sme_scan_done(dev);
	wdev_unlock(wdev);
}

void cfg80211_sme_rx_auth(struct wireless_dev *wdev, const u8 *buf, size_t len)
{
	struct wiphy *wiphy = wdev->wiphy;
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
	u16 status_code = le16_to_cpu(mgmt->u.auth.status_code);

	ASSERT_WDEV_LOCK(wdev);

	if (!wdev->conn || wdev->conn->state == CFG80211_CONN_CONNECTED)
		return;

	if (status_code == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG &&
	    wdev->conn->auto_auth &&
	    wdev->conn->params.auth_type != NL80211_AUTHTYPE_NETWORK_EAP) {
		/* select automatically between only open, shared, leap */
		switch (wdev->conn->params.auth_type) {
		case NL80211_AUTHTYPE_OPEN_SYSTEM:
			if (wdev->connect_keys)
				wdev->conn->params.auth_type =
					NL80211_AUTHTYPE_SHARED_KEY;
			else
				wdev->conn->params.auth_type =
					NL80211_AUTHTYPE_NETWORK_EAP;
			break;
		case NL80211_AUTHTYPE_SHARED_KEY:
			wdev->conn->params.auth_type =
				NL80211_AUTHTYPE_NETWORK_EAP;
			break;
		default:
			/* huh? */
			wdev->conn->params.auth_type =
				NL80211_AUTHTYPE_OPEN_SYSTEM;
			break;
		}
		wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
		schedule_work(&rdev->conn_work);
	} else if (status_code != WLAN_STATUS_SUCCESS) {
		struct cfg80211_connect_resp_params cr;

		memset(&cr, 0, sizeof(cr));
		cr.status = status_code;
		cr.links[0].bssid = mgmt->bssid;
		cr.timeout_reason = NL80211_TIMEOUT_UNSPECIFIED;
		__cfg80211_connect_result(wdev->netdev, &cr, false);
	} else if (wdev->conn->state == CFG80211_CONN_AUTHENTICATING) {
		wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT;
		schedule_work(&rdev->conn_work);
	}
}

bool cfg80211_sme_rx_assoc_resp(struct wireless_dev *wdev, u16 status)
{
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);

	if (!wdev->conn)
		return false;

	if (status == WLAN_STATUS_SUCCESS) {
		wdev->conn->state = CFG80211_CONN_CONNECTED;
		return false;
	}

	if (wdev->conn->prev_bssid_valid) {
		/*
		 * Some stupid APs don't accept reassoc, so we
		 * need to fall back to trying regular assoc;
		 * return true so no event is sent to userspace.
		 */
		wdev->conn->prev_bssid_valid = false;
		wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT;
		schedule_work(&rdev->conn_work);
		return true;
	}

	wdev->conn->state = CFG80211_CONN_ASSOC_FAILED;
	schedule_work(&rdev->conn_work);
	return false;
}

void cfg80211_sme_deauth(struct wireless_dev *wdev)
{
	cfg80211_sme_free(wdev);
}

void cfg80211_sme_auth_timeout(struct wireless_dev *wdev)
{
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);

	if (!wdev->conn)
		return;

	wdev->conn->state = CFG80211_CONN_AUTH_FAILED_TIMEOUT;
	schedule_work(&rdev->conn_work);
}

void cfg80211_sme_disassoc(struct wireless_dev *wdev)
{
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);

	if (!wdev->conn)
		return;

	wdev->conn->state = CFG80211_CONN_DEAUTH;
	schedule_work(&rdev->conn_work);
}

void cfg80211_sme_assoc_timeout(struct wireless_dev *wdev)
{
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);

	if (!wdev->conn)
		return;

	wdev->conn->state = CFG80211_CONN_ASSOC_FAILED_TIMEOUT;
	schedule_work(&rdev->conn_work);
}

void cfg80211_sme_abandon_assoc(struct wireless_dev *wdev)
{
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);

	if (!wdev->conn)
		return;

	wdev->conn->state = CFG80211_CONN_ABANDON;
	schedule_work(&rdev->conn_work);
}

static void cfg80211_wdev_release_bsses(struct wireless_dev *wdev)
{
	unsigned int link;

	for_each_valid_link(wdev, link) {
		if (!wdev->links[link].client.current_bss)
			continue;
		cfg80211_unhold_bss(wdev->links[link].client.current_bss);
		cfg80211_put_bss(wdev->wiphy,
				 &wdev->links[link].client.current_bss->pub);
		wdev->links[link].client.current_bss = NULL;
	}
}

static int cfg80211_sme_get_conn_ies(struct wireless_dev *wdev,
				     const u8 *ies, size_t ies_len,
				     const u8 **out_ies, size_t *out_ies_len)
{
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
	u8 *buf;
	size_t offs;

	if (!rdev->wiphy.extended_capabilities_len ||
	    (ies && cfg80211_find_ie(WLAN_EID_EXT_CAPABILITY, ies, ies_len))) {
		*out_ies = kmemdup(ies, ies_len, GFP_KERNEL);
		if (!*out_ies)
			return -ENOMEM;
		*out_ies_len = ies_len;
		return 0;
	}

	buf = kmalloc(ies_len + rdev->wiphy.extended_capabilities_len + 2,
		      GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	if (ies_len) {
		static const u8 before_extcapa[] = {
			/* not listing IEs expected to be created by driver */
			WLAN_EID_RSN,
			WLAN_EID_QOS_CAPA,
			WLAN_EID_RRM_ENABLED_CAPABILITIES,
			WLAN_EID_MOBILITY_DOMAIN,
			WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
			WLAN_EID_BSS_COEX_2040,
		};

		offs = ieee80211_ie_split(ies, ies_len, before_extcapa,
					  ARRAY_SIZE(before_extcapa), 0);
		memcpy(buf, ies, offs);
		/* leave a whole for extended capabilities IE */
		memcpy(buf + offs + rdev->wiphy.extended_capabilities_len + 2,
		       ies + offs, ies_len - offs);
	} else {
		offs = 0;
	}

	/* place extended capabilities IE (with only driver capabilities) */
	buf[offs] = WLAN_EID_EXT_CAPABILITY;
	buf[offs + 1] = rdev->wiphy.extended_capabilities_len;
	memcpy(buf + offs + 2,
	       rdev->wiphy.extended_capabilities,
	       rdev->wiphy.extended_capabilities_len);

	*out_ies = buf;
	*out_ies_len = ies_len + rdev->wiphy.extended_capabilities_len + 2;

	return 0;
}

static int cfg80211_sme_connect(struct wireless_dev *wdev,
				struct cfg80211_connect_params *connect,
				const u8 *prev_bssid)
{
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
	struct cfg80211_bss *bss;
	int err;

	if (!rdev->ops->auth || !rdev->ops->assoc)
		return -EOPNOTSUPP;

	cfg80211_wdev_release_bsses(wdev);

	if (wdev->connected) {
		cfg80211_sme_free(wdev);
		wdev->connected = false;
	}

	if (wdev->conn)
		return -EINPROGRESS;

	wdev->conn = kzalloc(sizeof(*wdev->conn), GFP_KERNEL);
	if (!wdev->conn)
		return -ENOMEM;

	/*
	 * Copy all parameters, and treat explicitly IEs, BSSID, SSID.
	 */
	memcpy(&wdev->conn->params, connect, sizeof(*connect));
	if (connect->bssid) {
		wdev->conn->params.bssid = wdev->conn->bssid;
		memcpy(wdev->conn->bssid, connect->bssid, ETH_ALEN);
	}

	if (cfg80211_sme_get_conn_ies(wdev, connect->ie, connect->ie_len,
				      &wdev->conn->ie,
				      &wdev->conn->params.ie_len)) {
		kfree(wdev->conn);
		wdev->conn = NULL;
		return -ENOMEM;
	}
	wdev->conn->params.ie = wdev->conn->ie;

	if (connect->auth_type == NL80211_AUTHTYPE_AUTOMATIC) {
		wdev->conn->auto_auth = true;
		/* start with open system ... should mostly work */
		wdev->conn->params.auth_type =
			NL80211_AUTHTYPE_OPEN_SYSTEM;
	} else {
		wdev->conn->auto_auth = false;
	}

	wdev->conn->params.ssid = wdev->u.client.ssid;
	wdev->conn->params.ssid_len = wdev->u.client.ssid_len;

	/* see if we have the bss already */
	bss = cfg80211_get_bss(wdev->wiphy, wdev->conn->params.channel,
			       wdev->conn->params.bssid,
			       wdev->conn->params.ssid,
			       wdev->conn->params.ssid_len,
			       wdev->conn_bss_type,
			       IEEE80211_PRIVACY(wdev->conn->params.privacy));

	if (prev_bssid) {
		memcpy(wdev->conn->prev_bssid, prev_bssid, ETH_ALEN);
		wdev->conn->prev_bssid_valid = true;
	}

	/* we're good if we have a matching bss struct */
	if (bss) {
		enum nl80211_timeout_reason treason;

		cfg80211_step_auth_next(wdev->conn, bss);
		err = cfg80211_conn_do_work(wdev, &treason);
		cfg80211_put_bss(wdev->wiphy, bss);
	} else {
		/* otherwise we'll need to scan for the AP first */
		err = cfg80211_conn_scan(wdev);

		/*
		 * If we can't scan right now, then we need to scan again
		 * after the current scan finished, since the parameters
		 * changed (unless we find a good AP anyway).
		 */
		if (err == -EBUSY) {
			err = 0;
			wdev->conn->state = CFG80211_CONN_SCAN_AGAIN;
		}
	}

	if (err)
		cfg80211_sme_free(wdev);

	return err;
}

static int cfg80211_sme_disconnect(struct wireless_dev *wdev, u16 reason)
{
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
	int err;

	if (!wdev->conn)
		return 0;

	if (!rdev->ops->deauth)
		return -EOPNOTSUPP;

	if (wdev->conn->state == CFG80211_CONN_SCANNING ||
	    wdev->conn->state == CFG80211_CONN_SCAN_AGAIN) {
		err = 0;
		goto out;
	}

	/* wdev->conn->params.bssid must be set if > SCANNING */
	err = cfg80211_mlme_deauth(rdev, wdev->netdev,
				   wdev->conn->params.bssid,
				   NULL, 0, reason, false);
 out:
	cfg80211_sme_free(wdev);
	return err;
}

/*
 * code shared for in-device and software SME
 */

static bool cfg80211_is_all_idle(void)
{
	struct cfg80211_registered_device *rdev;
	struct wireless_dev *wdev;
	bool is_all_idle = true;

	/*
	 * All devices must be idle as otherwise if you are actively
	 * scanning some new beacon hints could be learned and would
	 * count as new regulatory hints.
	 * Also if there is any other active beaconing interface we
	 * need not issue a disconnect hint and reset any info such
	 * as chan dfs state, etc.
	 */
	list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
		list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
			wdev_lock(wdev);
			if (wdev->conn || wdev->connected ||
			    cfg80211_beaconing_iface_active(wdev))
				is_all_idle = false;
			wdev_unlock(wdev);
		}
	}

	return is_all_idle;
}

static void disconnect_work(struct work_struct *work)
{
	rtnl_lock();
	if (cfg80211_is_all_idle())
		regulatory_hint_disconnect();
	rtnl_unlock();
}

DECLARE_WORK(cfg80211_disconnect_work, disconnect_work);

static void
cfg80211_connect_result_release_bsses(struct wireless_dev *wdev,
				      struct cfg80211_connect_resp_params *cr)
{
	unsigned int link;

	for_each_valid_link(cr, link) {
		if (!cr->links[link].bss)
			continue;
		cfg80211_unhold_bss(bss_from_pub(cr->links[link].bss));
		cfg80211_put_bss(wdev->wiphy, cr->links[link].bss);
	}
}

/*
 * API calls for drivers implementing connect/disconnect and
 * SME event handling
 */

/* This method must consume bss one way or another */
void __cfg80211_connect_result(struct net_device *dev,
			       struct cfg80211_connect_resp_params *cr,
			       bool wextev)
{
	struct wireless_dev *wdev = dev->ieee80211_ptr;
	const struct element *country_elem = NULL;
	const struct element *ssid;
	const u8 *country_data;
	u8 country_datalen;
#ifdef CONFIG_CFG80211_WEXT
	union iwreq_data wrqu;
#endif
	unsigned int link;
	const u8 *connected_addr;
	bool bss_not_found = false;

	ASSERT_WDEV_LOCK(wdev);

	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION &&
		    wdev->iftype != NL80211_IFTYPE_P2P_CLIENT))
		goto out;

	if (cr->valid_links) {
		if (WARN_ON(!cr->ap_mld_addr))
			goto out;

		for_each_valid_link(cr, link) {
			if (WARN_ON(!cr->links[link].addr))
				goto out;
		}

		if (WARN_ON(wdev->connect_keys))
			goto out;
	}

	wdev->unprot_beacon_reported = 0;
	nl80211_send_connect_result(wiphy_to_rdev(wdev->wiphy), dev, cr,
				    GFP_KERNEL);
	connected_addr = cr->valid_links ? cr->ap_mld_addr : cr->links[0].bssid;

#ifdef CONFIG_CFG80211_WEXT
	if (wextev && !cr->valid_links) {
		if (cr->req_ie && cr->status == WLAN_STATUS_SUCCESS) {
			memset(&wrqu, 0, sizeof(wrqu));
			wrqu.data.length = cr->req_ie_len;
			wireless_send_event(dev, IWEVASSOCREQIE, &wrqu,
					    cr->req_ie);
		}

		if (cr->resp_ie && cr->status == WLAN_STATUS_SUCCESS) {
			memset(&wrqu, 0, sizeof(wrqu));
			wrqu.data.length = cr->resp_ie_len;
			wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu,
					    cr->resp_ie);
		}

		memset(&wrqu, 0, sizeof(wrqu));
		wrqu.ap_addr.sa_family = ARPHRD_ETHER;
		if (connected_addr && cr->status == WLAN_STATUS_SUCCESS) {
			memcpy(wrqu.ap_addr.sa_data, connected_addr, ETH_ALEN);
			memcpy(wdev->wext.prev_bssid, connected_addr, ETH_ALEN);
			wdev->wext.prev_bssid_valid = true;
		}
		wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
	}
#endif

	if (cr->status == WLAN_STATUS_SUCCESS) {
		if (!wiphy_to_rdev(wdev->wiphy)->ops->connect) {
			for_each_valid_link(cr, link) {
				if (WARN_ON_ONCE(!cr->links[link].bss))
					break;
			}
		}

		for_each_valid_link(cr, link) {
			/* don't do extra lookups for failures */
			if (cr->links[link].status != WLAN_STATUS_SUCCESS)
				continue;

			if (cr->links[link].bss)
				continue;

			cr->links[link].bss =
				cfg80211_get_bss(wdev->wiphy, NULL,
						 cr->links[link].bssid,
						 wdev->u.client.ssid,
						 wdev->u.client.ssid_len,
						 wdev->conn_bss_type,
						 IEEE80211_PRIVACY_ANY);
			if (!cr->links[link].bss) {
				bss_not_found = true;
				break;
			}
			cfg80211_hold_bss(bss_from_pub(cr->links[link].bss));
		}
	}

	cfg80211_wdev_release_bsses(wdev);

	if (cr->status != WLAN_STATUS_SUCCESS) {
		kfree_sensitive(wdev->connect_keys);
		wdev->connect_keys = NULL;
		wdev->u.client.ssid_len = 0;
		wdev->conn_owner_nlportid = 0;
		cfg80211_connect_result_release_bsses(wdev, cr);
		cfg80211_sme_free(wdev);
		return;
	}

	if (WARN_ON(bss_not_found)) {
		cfg80211_connect_result_release_bsses(wdev, cr);
		return;
	}

	memset(wdev->links, 0, sizeof(wdev->links));
	for_each_valid_link(cr, link) {
		if (cr->links[link].status == WLAN_STATUS_SUCCESS)
			continue;
		cr->valid_links &= ~BIT(link);
		/* don't require bss pointer for failed links */
		if (!cr->links[link].bss)
			continue;
		cfg80211_unhold_bss(bss_from_pub(cr->links[link].bss));
		cfg80211_put_bss(wdev->wiphy, cr->links[link].bss);
	}
	wdev->valid_links = cr->valid_links;
	for_each_valid_link(cr, link)
		wdev->links[link].client.current_bss =
			bss_from_pub(cr->links[link].bss);
	wdev->connected = true;
	ether_addr_copy(wdev->u.client.connected_addr, connected_addr);
	if (cr->valid_links) {
		for_each_valid_link(cr, link)
			memcpy(wdev->links[link].addr, cr->links[link].addr,
			       ETH_ALEN);
	}

	cfg80211_upload_connect_keys(wdev);

	rcu_read_lock();
	for_each_valid_link(cr, link) {
		country_elem =
			ieee80211_bss_get_elem(cr->links[link].bss,
					       WLAN_EID_COUNTRY);
		if (country_elem)
			break;
	}
	if (!country_elem) {
		rcu_read_unlock();
		return;
	}

	country_datalen = country_elem->datalen;
	country_data = kmemdup(country_elem->data, country_datalen, GFP_ATOMIC);
	rcu_read_unlock();

	if (!country_data)
		return;

	regulatory_hint_country_ie(wdev->wiphy,
				   cr->links[link].bss->channel->band,
				   country_data, country_datalen);
	kfree(country_data);

	if (!wdev->u.client.ssid_len) {
		rcu_read_lock();
		for_each_valid_link(cr, link) {
			ssid = ieee80211_bss_get_elem(cr->links[link].bss,
						      WLAN_EID_SSID);

			if (!ssid || !ssid->datalen)
				continue;

			memcpy(wdev->u.client.ssid, ssid->data, ssid->datalen);
			wdev->u.client.ssid_len = ssid->datalen;
			break;
		}
		rcu_read_unlock();
	}

	return;
out:
	for_each_valid_link(cr, link)
		cfg80211_put_bss(wdev->wiphy, cr->links[link].bss);
}

static void cfg80211_update_link_bss(struct wireless_dev *wdev,
				     struct cfg80211_bss **bss)
{
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
	struct cfg80211_internal_bss *ibss;

	if (!*bss)
		return;

	ibss = bss_from_pub(*bss);
	if (list_empty(&ibss->list)) {
		struct cfg80211_bss *found = NULL, *tmp = *bss;

		found = cfg80211_get_bss(wdev->wiphy, NULL,
					 (*bss)->bssid,
					 wdev->u.client.ssid,
					 wdev->u.client.ssid_len,
					 wdev->conn_bss_type,
					 IEEE80211_PRIVACY_ANY);
		if (found) {
			/* The same BSS is already updated so use it
			 * instead, as it has latest info.
			 */
			*bss = found;
		} else {
			/* Update with BSS provided by driver, it will
			 * be freshly added and ref cnted, we can free
			 * the old one.
			 *
			 * signal_valid can be false, as we are not
			 * expecting the BSS to be found.
			 *
			 * keep the old timestamp to avoid confusion
			 */
			cfg80211_bss_update(rdev, ibss, false,
					    ibss->ts);
		}

		cfg80211_put_bss(wdev->wiphy, tmp);
	}
}

/* Consumes bss object(s) one way or another */
void cfg80211_connect_done(struct net_device *dev,
			   struct cfg80211_connect_resp_params *params,
			   gfp_t gfp)
{
	struct wireless_dev *wdev = dev->ieee80211_ptr;
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
	struct cfg80211_event *ev;
	unsigned long flags;
	u8 *next;
	size_t link_info_size = 0;
	unsigned int link;

	for_each_valid_link(params, link) {
		cfg80211_update_link_bss(wdev, &params->links[link].bss);
		link_info_size += params->links[link].bssid ? ETH_ALEN : 0;
		link_info_size += params->links[link].addr ? ETH_ALEN : 0;
	}

	ev = kzalloc(sizeof(*ev) + (params->ap_mld_addr ? ETH_ALEN : 0) +
		     params->req_ie_len + params->resp_ie_len +
		     params->fils.kek_len + params->fils.pmk_len +
		     (params->fils.pmkid ? WLAN_PMKID_LEN : 0) + link_info_size,
		     gfp);

	if (!ev) {
		for_each_valid_link(params, link)
			cfg80211_put_bss(wdev->wiphy,
					 params->links[link].bss);
		return;
	}

	ev->type = EVENT_CONNECT_RESULT;
	next = ((u8 *)ev) + sizeof(*ev);
	if (params->ap_mld_addr) {
		ev->cr.ap_mld_addr = next;
		memcpy((void *)ev->cr.ap_mld_addr, params->ap_mld_addr,
		       ETH_ALEN);
		next += ETH_ALEN;
	}
	if (params->req_ie_len) {
		ev->cr.req_ie = next;
		ev->cr.req_ie_len = params->req_ie_len;
		memcpy((void *)ev->cr.req_ie, params->req_ie,
		       params->req_ie_len);
		next += params->req_ie_len;
	}
	if (params->resp_ie_len) {
		ev->cr.resp_ie = next;
		ev->cr.resp_ie_len = params->resp_ie_len;
		memcpy((void *)ev->cr.resp_ie, params->resp_ie,
		       params->resp_ie_len);
		next += params->resp_ie_len;
	}
	if (params->fils.kek_len) {
		ev->cr.fils.kek = next;
		ev->cr.fils.kek_len = params->fils.kek_len;
		memcpy((void *)ev->cr.fils.kek, params->fils.kek,
		       params->fils.kek_len);
		next += params->fils.kek_len;
	}
	if (params->fils.pmk_len) {
		ev->cr.fils.pmk = next;
		ev->cr.fils.pmk_len = params->fils.pmk_len;
		memcpy((void *)ev->cr.fils.pmk, params->fils.pmk,
		       params->fils.pmk_len);
		next += params->fils.pmk_len;
	}
	if (params->fils.pmkid) {
		ev->cr.fils.pmkid = next;
		memcpy((void *)ev->cr.fils.pmkid, params->fils.pmkid,
		       WLAN_PMKID_LEN);
		next += WLAN_PMKID_LEN;
	}
	ev->cr.fils.update_erp_next_seq_num = params->fils.update_erp_next_seq_num;
	if (params->fils.update_erp_next_seq_num)
		ev->cr.fils.erp_next_seq_num = params->fils.erp_next_seq_num;
	ev->cr.valid_links = params->valid_links;
	for_each_valid_link(params, link) {
		if (params->links[link].bss)
			cfg80211_hold_bss(
				bss_from_pub(params->links[link].bss));
		ev->cr.links[link].bss = params->links[link].bss;

		if (params->links[link].addr) {
			ev->cr.links[link].addr = next;
			memcpy((void *)ev->cr.links[link].addr,
			       params->links[link].addr,
			       ETH_ALEN);
			next += ETH_ALEN;
		}
		if (params->links[link].bssid) {
			ev->cr.links[link].bssid = next;
			memcpy((void *)ev->cr.links[link].bssid,
			       params->links[link].bssid,
			       ETH_ALEN);
			next += ETH_ALEN;
		}
	}
	ev->cr.status = params->status;
	ev->cr.timeout_reason = params->timeout_reason;

	spin_lock_irqsave(&wdev->event_lock, flags);
	list_add_tail(&ev->list, &wdev->event_list);
	spin_unlock_irqrestore(&wdev->event_lock, flags);
	queue_work(cfg80211_wq, &rdev->event_work);
}
EXPORT_SYMBOL(cfg80211_connect_done);

/* Consumes bss object one way or another */
void __cfg80211_roamed(struct wireless_dev *wdev,
		       struct cfg80211_roam_info *info)
{
#ifdef CONFIG_CFG80211_WEXT
	union iwreq_data wrqu;
#endif
	unsigned int link;
	const u8 *connected_addr;

	ASSERT_WDEV_LOCK(wdev);

	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION &&
		    wdev->iftype != NL80211_IFTYPE_P2P_CLIENT))
		goto out;

	if (WARN_ON(!wdev->connected))
		goto out;

	if (info->valid_links) {
		if (WARN_ON(!info->ap_mld_addr))
			goto out;

		for_each_valid_link(info, link) {
			if (WARN_ON(!info->links[link].addr))
				goto out;
		}
	}

	cfg80211_wdev_release_bsses(wdev);

	for_each_valid_link(info, link) {
		if (WARN_ON(!info->links[link].bss))
			goto out;
	}

	memset(wdev->links, 0, sizeof(wdev->links));
	wdev->valid_links = info->valid_links;
	for_each_valid_link(info, link) {
		cfg80211_hold_bss(bss_from_pub(info->links[link].bss));
		wdev->links[link].client.current_bss =
			bss_from_pub(info->links[link].bss);
	}

	connected_addr = info->valid_links ?
			 info->ap_mld_addr :
			 info->links[0].bss->bssid;
	ether_addr_copy(wdev->u.client.connected_addr, connected_addr);
	if (info->valid_links) {
		for_each_valid_link(info, link)
			memcpy(wdev->links[link].addr, info->links[link].addr,
			       ETH_ALEN);
	}
	wdev->unprot_beacon_reported = 0;
	nl80211_send_roamed(wiphy_to_rdev(wdev->wiphy),
			    wdev->netdev, info, GFP_KERNEL);

#ifdef CONFIG_CFG80211_WEXT
	if (!info->valid_links) {
		if (info->req_ie) {
			memset(&wrqu, 0, sizeof(wrqu));
			wrqu.data.length = info->req_ie_len;
			wireless_send_event(wdev->netdev, IWEVASSOCREQIE,
					    &wrqu, info->req_ie);
		}

		if (info->resp_ie) {
			memset(&wrqu, 0, sizeof(wrqu));
			wrqu.data.length = info->resp_ie_len;
			wireless_send_event(wdev->netdev, IWEVASSOCRESPIE,
					    &wrqu, info->resp_ie);
		}

		memset(&wrqu, 0, sizeof(wrqu));
		wrqu.ap_addr.sa_family = ARPHRD_ETHER;
		memcpy(wrqu.ap_addr.sa_data, connected_addr, ETH_ALEN);
		memcpy(wdev->wext.prev_bssid, connected_addr, ETH_ALEN);
		wdev->wext.prev_bssid_valid = true;
		wireless_send_event(wdev->netdev, SIOCGIWAP, &wrqu, NULL);
	}
#endif

	return;
out:
	for_each_valid_link(info, link)
		cfg80211_put_bss(wdev->wiphy, info->links[link].bss);
}

/* Consumes info->links.bss object(s) one way or another */
void cfg80211_roamed(struct net_device *dev, struct cfg80211_roam_info *info,
		     gfp_t gfp)
{
	struct wireless_dev *wdev = dev->ieee80211_ptr;
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
	struct cfg80211_event *ev;
	unsigned long flags;
	u8 *next;
	unsigned int link;
	size_t link_info_size = 0;
	bool bss_not_found = false;

	for_each_valid_link(info, link) {
		link_info_size += info->links[link].addr ? ETH_ALEN : 0;
		link_info_size += info->links[link].bssid ? ETH_ALEN : 0;

		if (info->links[link].bss)
			continue;

		info->links[link].bss =
			cfg80211_get_bss(wdev->wiphy,
					 info->links[link].channel,
					 info->links[link].bssid,
					 wdev->u.client.ssid,
					 wdev->u.client.ssid_len,
					 wdev->conn_bss_type,
					 IEEE80211_PRIVACY_ANY);

		if (!info->links[link].bss) {
			bss_not_found = true;
			break;
		}
	}

	if (WARN_ON(bss_not_found))
		goto out;

	ev = kzalloc(sizeof(*ev) + info->req_ie_len + info->resp_ie_len +
		     info->fils.kek_len + info->fils.pmk_len +
		     (info->fils.pmkid ? WLAN_PMKID_LEN : 0) +
		     (info->ap_mld_addr ? ETH_ALEN : 0) + link_info_size, gfp);
	if (!ev)
		goto out;

	ev->type = EVENT_ROAMED;
	next = ((u8 *)ev) + sizeof(*ev);
	if (info->req_ie_len) {
		ev->rm.req_ie = next;
		ev->rm.req_ie_len = info->req_ie_len;
		memcpy((void *)ev->rm.req_ie, info->req_ie, info->req_ie_len);
		next += info->req_ie_len;
	}
	if (info->resp_ie_len) {
		ev->rm.resp_ie = next;
		ev->rm.resp_ie_len = info->resp_ie_len;
		memcpy((void *)ev->rm.resp_ie, info->resp_ie,
		       info->resp_ie_len);
		next += info->resp_ie_len;
	}
	if (info->fils.kek_len) {
		ev->rm.fils.kek = next;
		ev->rm.fils.kek_len = info->fils.kek_len;
		memcpy((void *)ev->rm.fils.kek, info->fils.kek,
		       info->fils.kek_len);
		next += info->fils.kek_len;
	}
	if (info->fils.pmk_len) {
		ev->rm.fils.pmk = next;
		ev->rm.fils.pmk_len = info->fils.pmk_len;
		memcpy((void *)ev->rm.fils.pmk, info->fils.pmk,
		       info->fils.pmk_len);
		next += info->fils.pmk_len;
	}
	if (info->fils.pmkid) {
		ev->rm.fils.pmkid = next;
		memcpy((void *)ev->rm.fils.pmkid, info->fils.pmkid,
		       WLAN_PMKID_LEN);
		next += WLAN_PMKID_LEN;
	}
	ev->rm.fils.update_erp_next_seq_num = info->fils.update_erp_next_seq_num;
	if (info->fils.update_erp_next_seq_num)
		ev->rm.fils.erp_next_seq_num = info->fils.erp_next_seq_num;
	if (info->ap_mld_addr) {
		ev->rm.ap_mld_addr = next;
		memcpy((void *)ev->rm.ap_mld_addr, info->ap_mld_addr,
		       ETH_ALEN);
		next += ETH_ALEN;
	}
	ev->rm.valid_links = info->valid_links;
	for_each_valid_link(info, link) {
		ev->rm.links[link].bss = info->links[link].bss;

		if (info->links[link].addr) {
			ev->rm.links[link].addr = next;
			memcpy((void *)ev->rm.links[link].addr,
			       info->links[link].addr,
			       ETH_ALEN);
			next += ETH_ALEN;
		}

		if (info->links[link].bssid) {
			ev->rm.links[link].bssid = next;
			memcpy((void *)ev->rm.links[link].bssid,
			       info->links[link].bssid,
			       ETH_ALEN);
			next += ETH_ALEN;
		}
	}

	spin_lock_irqsave(&wdev->event_lock, flags);
	list_add_tail(&ev->list, &wdev->event_list);
	spin_unlock_irqrestore(&wdev->event_lock, flags);
	queue_work(cfg80211_wq, &rdev->event_work);

	return;
out:
	for_each_valid_link(info, link)
		cfg80211_put_bss(wdev->wiphy, info->links[link].bss);

}
EXPORT_SYMBOL(cfg80211_roamed);

void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid,
					const u8 *td_bitmap, u8 td_bitmap_len)
{
	ASSERT_WDEV_LOCK(wdev);

	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION &&
		    wdev->iftype != NL80211_IFTYPE_P2P_CLIENT))
		return;

	if (WARN_ON(!wdev->connected) ||
	    WARN_ON(!ether_addr_equal(wdev->u.client.connected_addr, bssid)))
		return;

	nl80211_send_port_authorized(wiphy_to_rdev(wdev->wiphy), wdev->netdev,
				     bssid, td_bitmap, td_bitmap_len);
}

void cfg80211_port_authorized(struct net_device *dev, const u8 *bssid,
			      const u8 *td_bitmap, u8 td_bitmap_len, gfp_t gfp)
{
	struct wireless_dev *wdev = dev->ieee80211_ptr;
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
	struct cfg80211_event *ev;
	unsigned long flags;

	if (WARN_ON(!bssid))
		return;

	ev = kzalloc(sizeof(*ev) + td_bitmap_len, gfp);
	if (!ev)
		return;

	ev->type = EVENT_PORT_AUTHORIZED;
	memcpy(ev->pa.bssid, bssid, ETH_ALEN);
	ev->pa.td_bitmap = ((u8 *)ev) + sizeof(*ev);
	ev->pa.td_bitmap_len = td_bitmap_len;
	memcpy((void *)ev->pa.td_bitmap, td_bitmap, td_bitmap_len);

	/*
	 * Use the wdev event list so that if there are pending
	 * connected/roamed events, they will be reported first.
	 */
	spin_lock_irqsave(&wdev->event_lock, flags);
	list_add_tail(&ev->list, &wdev->event_list);
	spin_unlock_irqrestore(&wdev->event_lock, flags);
	queue_work(cfg80211_wq, &rdev->event_work);
}
EXPORT_SYMBOL(cfg80211_port_authorized);

void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
			     size_t ie_len, u16 reason, bool from_ap)
{
	struct wireless_dev *wdev = dev->ieee80211_ptr;
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
	int i;
#ifdef CONFIG_CFG80211_WEXT
	union iwreq_data wrqu;
#endif

	ASSERT_WDEV_LOCK(wdev);

	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION &&
		    wdev->iftype != NL80211_IFTYPE_P2P_CLIENT))
		return;

	cfg80211_wdev_release_bsses(wdev);
	wdev->connected = false;
	wdev->u.client.ssid_len = 0;
	wdev->conn_owner_nlportid = 0;
	kfree_sensitive(wdev->connect_keys);
	wdev->connect_keys = NULL;

	nl80211_send_disconnected(rdev, dev, reason, ie, ie_len, from_ap);

	/* stop critical protocol if supported */
	if (rdev->ops->crit_proto_stop && rdev->crit_proto_nlportid) {
		rdev->crit_proto_nlportid = 0;
		rdev_crit_proto_stop(rdev, wdev);
	}

	/*
	 * Delete all the keys ... pairwise keys can't really
	 * exist any more anyway, but default keys might.
	 */
	if (rdev->ops->del_key) {
		int max_key_idx = 5;

		if (wiphy_ext_feature_isset(
			    wdev->wiphy,
			    NL80211_EXT_FEATURE_BEACON_PROTECTION) ||
		    wiphy_ext_feature_isset(
			    wdev->wiphy,
			    NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT))
			max_key_idx = 7;
		for (i = 0; i <= max_key_idx; i++)
			rdev_del_key(rdev, dev, -1, i, false, NULL);
	}

	rdev_set_qos_map(rdev, dev, NULL);

#ifdef CONFIG_CFG80211_WEXT
	memset(&wrqu, 0, sizeof(wrqu));
	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
	wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
	wdev->wext.connect.ssid_len = 0;
#endif

	schedule_work(&cfg80211_disconnect_work);
}

void cfg80211_disconnected(struct net_device *dev, u16 reason,
			   const u8 *ie, size_t ie_len,
			   bool locally_generated, gfp_t gfp)
{
	struct wireless_dev *wdev = dev->ieee80211_ptr;
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
	struct cfg80211_event *ev;
	unsigned long flags;

	ev = kzalloc(sizeof(*ev) + ie_len, gfp);
	if (!ev)
		return;

	ev->type = EVENT_DISCONNECTED;
	ev->dc.ie = ((u8 *)ev) + sizeof(*ev);
	ev->dc.ie_len = ie_len;
	memcpy((void *)ev->dc.ie, ie, ie_len);
	ev->dc.reason = reason;
	ev->dc.locally_generated = locally_generated;

	spin_lock_irqsave(&wdev->event_lock, flags);
	list_add_tail(&ev->list, &wdev->event_list);
	spin_unlock_irqrestore(&wdev->event_lock, flags);
	queue_work(cfg80211_wq, &rdev->event_work);
}
EXPORT_SYMBOL(cfg80211_disconnected);

/*
 * API calls for nl80211/wext compatibility code
 */
int cfg80211_connect(struct cfg80211_registered_device *rdev,
		     struct net_device *dev,
		     struct cfg80211_connect_params *connect,
		     struct cfg80211_cached_keys *connkeys,
		     const u8 *prev_bssid)
{
	struct wireless_dev *wdev = dev->ieee80211_ptr;
	int err;

	ASSERT_WDEV_LOCK(wdev);

	/*
	 * If we have an ssid_len, we're trying to connect or are
	 * already connected, so reject a new SSID unless it's the
	 * same (which is the case for re-association.)
	 */
	if (wdev->u.client.ssid_len &&
	    (wdev->u.client.ssid_len != connect->ssid_len ||
	     memcmp(wdev->u.client.ssid, connect->ssid, wdev->u.client.ssid_len)))
		return -EALREADY;

	/*
	 * If connected, reject (re-)association unless prev_bssid
	 * matches the current BSSID.
	 */
	if (wdev->connected) {
		if (!prev_bssid)
			return -EALREADY;
		if (!ether_addr_equal(prev_bssid,
				      wdev->u.client.connected_addr))
			return -ENOTCONN;
	}

	/*
	 * Reject if we're in the process of connecting with WEP,
	 * this case isn't very interesting and trying to handle
	 * it would make the code much more complex.
	 */
	if (wdev->connect_keys)
		return -EINPROGRESS;

	cfg80211_oper_and_ht_capa(&connect->ht_capa_mask,
				  rdev->wiphy.ht_capa_mod_mask);
	cfg80211_oper_and_vht_capa(&connect->vht_capa_mask,
				   rdev->wiphy.vht_capa_mod_mask);

	if (connkeys && connkeys->def >= 0) {
		int idx;
		u32 cipher;

		idx = connkeys->def;
		cipher = connkeys->params[idx].cipher;
		/* If given a WEP key we may need it for shared key auth */
		if (cipher == WLAN_CIPHER_SUITE_WEP40 ||
		    cipher == WLAN_CIPHER_SUITE_WEP104) {
			connect->key_idx = idx;
			connect->key = connkeys->params[idx].key;
			connect->key_len = connkeys->params[idx].key_len;

			/*
			 * If ciphers are not set (e.g. when going through
			 * iwconfig), we have to set them appropriately here.
			 */
			if (connect->crypto.cipher_group == 0)
				connect->crypto.cipher_group = cipher;

			if (connect->crypto.n_ciphers_pairwise == 0) {
				connect->crypto.n_ciphers_pairwise = 1;
				connect->crypto.ciphers_pairwise[0] = cipher;
			}
		}
	} else {
		if (WARN_ON(connkeys))
			return -EINVAL;

		/* connect can point to wdev->wext.connect which
		 * can hold key data from a previous connection
		 */
		connect->key = NULL;
		connect->key_len = 0;
		connect->key_idx = 0;
	}

	wdev->connect_keys = connkeys;
	memcpy(wdev->u.client.ssid, connect->ssid, connect->ssid_len);
	wdev->u.client.ssid_len = connect->ssid_len;

	wdev->conn_bss_type = connect->pbss ? IEEE80211_BSS_TYPE_PBSS :
					      IEEE80211_BSS_TYPE_ESS;

	if (!rdev->ops->connect)
		err = cfg80211_sme_connect(wdev, connect, prev_bssid);
	else
		err = rdev_connect(rdev, dev, connect);

	if (err) {
		wdev->connect_keys = NULL;
		/*
		 * This could be reassoc getting refused, don't clear
		 * ssid_len in that case.
		 */
		if (!wdev->connected)
			wdev->u.client.ssid_len = 0;
		return err;
	}

	return 0;
}

int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
			struct net_device *dev, u16 reason, bool wextev)
{
	struct wireless_dev *wdev = dev->ieee80211_ptr;
	int err = 0;

	ASSERT_WDEV_LOCK(wdev);

	kfree_sensitive(wdev->connect_keys);
	wdev->connect_keys = NULL;

	wdev->conn_owner_nlportid = 0;

	if (wdev->conn)
		err = cfg80211_sme_disconnect(wdev, reason);
	else if (!rdev->ops->disconnect)
		cfg80211_mlme_down(rdev, dev);
	else if (wdev->u.client.ssid_len)
		err = rdev_disconnect(rdev, dev, reason);

	/*
	 * Clear ssid_len unless we actually were fully connected,
	 * in which case cfg80211_disconnected() will take care of
	 * this later.
	 */
	if (!wdev->connected)
		wdev->u.client.ssid_len = 0;

	return err;
}

/*
 * Used to clean up after the connection / connection attempt owner socket
 * disconnects
 */
void cfg80211_autodisconnect_wk(struct work_struct *work)
{
	struct wireless_dev *wdev =
		container_of(work, struct wireless_dev, disconnect_wk);
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);

	wdev_lock(wdev);

	if (wdev->conn_owner_nlportid) {
		switch (wdev->iftype) {
		case NL80211_IFTYPE_ADHOC:
			__cfg80211_leave_ibss(rdev, wdev->netdev, false);
			break;
		case NL80211_IFTYPE_AP:
		case NL80211_IFTYPE_P2P_GO:
			__cfg80211_stop_ap(rdev, wdev->netdev, -1, false);
			break;
		case NL80211_IFTYPE_MESH_POINT:
			__cfg80211_leave_mesh(rdev, wdev->netdev);
			break;
		case NL80211_IFTYPE_STATION:
		case NL80211_IFTYPE_P2P_CLIENT:
			/*
			 * Use disconnect_bssid if still connecting and
			 * ops->disconnect not implemented.  Otherwise we can
			 * use cfg80211_disconnect.
			 */
			if (rdev->ops->disconnect || wdev->connected)
				cfg80211_disconnect(rdev, wdev->netdev,
						    WLAN_REASON_DEAUTH_LEAVING,
						    true);
			else
				cfg80211_mlme_deauth(rdev, wdev->netdev,
						     wdev->disconnect_bssid,
						     NULL, 0,
						     WLAN_REASON_DEAUTH_LEAVING,
						     false);
			break;
		default:
			break;
		}
	}

	wdev_unlock(wdev);
}
