/*
 * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
 *
 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
 *
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all
 * copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/**
 * DOC: wlan_hdd_ext_scan.c
 *
 * WLAN Host Device Driver EXT SCAN feature implementation
 *
 */

#ifdef FEATURE_WLAN_EXTSCAN

#include "wlan_hdd_ext_scan.h"
#include "wlan_hdd_regulatory.h"
#include "cds_utils.h"
#include "cds_sched.h"
#include <qca_vendor.h>

/* amount of time to wait for a synchronous request/response operation */
#define WLAN_WAIT_TIME_EXTSCAN  1000

/**
 * struct hdd_ext_scan_context - hdd ext scan context
 * @request_id: userspace-assigned ID associated with the request
 * @response_event: Ext scan wait event
 * @response_status: Status returned by FW in response to a request
 * @ignore_cached_results: Flag to ignore cached results or not
 * @context_lock: Spinlock to serialize all context accesses
 * @capability_response: Ext scan capability response data from target
 * @buckets_scanned: bitmask of buckets scanned in extscan cycle
 */
struct hdd_ext_scan_context {
	uint32_t request_id;
	int response_status;
	bool ignore_cached_results;
	struct completion response_event;
	spinlock_t context_lock;
	struct ext_scan_capabilities_response capability_response;
	uint32_t buckets_scanned;
};
static struct hdd_ext_scan_context ext_scan_context;

static const struct nla_policy wlan_hdd_extscan_config_policy
[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] = {
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] = {
				.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] = {
				.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS] = {
				.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = {.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] = {
				.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = {.type = NLA_U8},
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = {.type = NLA_U8},

	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = {.type = NLA_U8},
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = {.type = NLA_U8},
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = {.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] = {
				.type = NLA_U8},
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] = {
				.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] = {
				.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] = {
				.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] = {
				.type = NLA_U8},
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] = {
				.type = NLA_U8 },
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] = {
				.type = NLA_U8},
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] = {
				.type = NLA_U8},

	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] = {
				.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = {
				.type = NLA_UNSPEC,
				.len = QDF_MAC_ADDR_SIZE},
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] = {
				.type = NLA_S32},
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] = {
				.type = NLA_S32},
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] = {
				.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] = {
				.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] = {
				.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE] = {
				.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] = {
				.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = {
				.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] = {
				.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BASE] = {
				.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] = {
				.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] = {
				.type = NLA_BINARY,
				.len = IEEE80211_MAX_SSID_LEN + 1 },
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] = {
				.type = NLA_U32 },
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] = {
				.type = NLA_U32 },
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] = {
				.type = NLA_U8 },
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] = {
				.type = NLA_S32 },
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] = {
				.type = NLA_S32 },
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] = {
				.type = NLA_U32 },
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] = {
				.type = NLA_U32},
};

static const struct nla_policy
wlan_hdd_pno_config_policy[QCA_WLAN_VENDOR_ATTR_PNO_MAX + 1] = {
	[QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_LIST_PARAM_NUM] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ID] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_NUM_NETWORKS] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_SSID] = {
		.type = NLA_BINARY,
		.len = IEEE80211_MAX_SSID_LEN + 1
	},
	[QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_FLAGS] = {
		.type = NLA_U8
	},
	[QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_AUTH_BIT] = {
		.type = NLA_U8
	},
	[QCA_WLAN_VENDOR_ATTR_EPNO_MIN5GHZ_RSSI] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_EPNO_MIN24GHZ_RSSI] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_EPNO_INITIAL_SCORE_MAX] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_EPNO_CURRENT_CONNECTION_BONUS] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_EPNO_SAME_NETWORK_BONUS] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_EPNO_SECURE_BONUS] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_EPNO_BAND5GHZ_BONUS] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_PNO_CONFIG_REQUEST_ID] = {
		.type = NLA_U32
	},
};

static const struct nla_policy
wlan_hdd_extscan_results_policy[QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_MAX + 1] = {
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD] = {
				.type = NLA_U16},
	[QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY] = {
				.type = NLA_U16},
};

/**
 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
 * @ctx: Pointer to hdd context
 * @data: Pointer to ext scan capabilities response from fw
 *
 * Return: None
 */
static void
wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx,
	struct ext_scan_capabilities_response *data)
{
	struct hdd_ext_scan_context *context;
	struct hdd_context *hdd_ctx  = ctx;

	ENTER();

	if (wlan_hdd_validate_context(hdd_ctx))
		return;
	if (!data) {
		hdd_err("data is null");
		return;
	}

	context = &ext_scan_context;

	spin_lock(&context->context_lock);
	/* validate response received from target*/
	if (context->request_id != data->requestId) {
		spin_unlock(&context->context_lock);
		hdd_err("Target response id did not match. request_id: %d response_id: %d",
			context->request_id, data->requestId);
		return;
	}

	context->capability_response = *data;
	complete(&context->response_event);
	spin_unlock(&context->context_lock);
}

/*
 * define short names for the global vendor params
 * used by hdd_extscan_nl_fill_bss()
 */
#define PARAM_TIME_STAMP \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP
#define PARAM_SSID \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID
#define PARAM_BSSID \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID
#define PARAM_CHANNEL \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL
#define PARAM_RSSI \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI
#define PARAM_RTT \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT
#define PARAM_RTT_SD \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD
#define PARAM_BEACON_PERIOD \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD
#define PARAM_CAPABILITY \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY
#define PARAM_IE_LENGTH \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH
#define PARAM_IE_DATA \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA

/** hdd_extscan_nl_fill_bss() - extscan nl fill bss
 * @skb: socket buffer
 * @ap: bss information
 * @idx: nesting index
 *
 * Return: 0 on success; error number otherwise
 */
static int hdd_extscan_nl_fill_bss(struct sk_buff *skb, tSirWifiScanResult *ap,
					int idx)
{
	struct nlattr *nla_ap;

	nla_ap = nla_nest_start(skb, idx);
	if (!nla_ap)
		return -EINVAL;

	if (hdd_wlan_nla_put_u64(skb, PARAM_TIME_STAMP, ap->ts) ||
	    nla_put(skb, PARAM_SSID, sizeof(ap->ssid), ap->ssid) ||
	    nla_put(skb, PARAM_BSSID, sizeof(ap->bssid), ap->bssid.bytes) ||
	    nla_put_u32(skb, PARAM_CHANNEL, ap->channel) ||
	    nla_put_s32(skb, PARAM_RSSI, ap->rssi) ||
	    nla_put_u32(skb, PARAM_RTT, ap->rtt) ||
	    nla_put_u32(skb, PARAM_RTT_SD, ap->rtt_sd) ||
	    nla_put_u16(skb, PARAM_BEACON_PERIOD, ap->beaconPeriod) ||
	    nla_put_u16(skb, PARAM_CAPABILITY, ap->capability) ||
	    nla_put_u16(skb, PARAM_IE_LENGTH, ap->ieLength)) {
		hdd_err("put fail");
		return -EINVAL;
	}

	if (ap->ieLength)
		if (nla_put(skb, PARAM_IE_DATA, ap->ieLength, ap->ieData)) {
			hdd_err("put fail");
			return -EINVAL;
		}

	nla_nest_end(skb, nla_ap);

	return 0;
}
/*
 * done with short names for the global vendor params
 * used by hdd_extscan_nl_fill_bss()
 */
#undef PARAM_TIME_STAMP
#undef PARAM_SSID
#undef PARAM_BSSID
#undef PARAM_CHANNEL
#undef PARAM_RSSI
#undef PARAM_RTT
#undef PARAM_RTT_SD
#undef PARAM_BEACON_PERIOD
#undef PARAM_CAPABILITY
#undef PARAM_IE_LENGTH
#undef PARAM_IE_DATA

/** wlan_hdd_cfg80211_extscan_cached_results_ind() - get cached results
 * @ctx: hdd global context
 * @data: cached results
 *
 * This function reads the cached results %data, populated the NL
 * attributes and sends the NL event to the upper layer.
 *
 * Return: none
 */
static void
wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
				struct extscan_cached_scan_results *data)
{
	struct hdd_context *hdd_ctx = ctx;
	struct sk_buff *skb = NULL;
	struct hdd_ext_scan_context *context;
	struct extscan_cached_scan_result *result;
	tSirWifiScanResult *ap;
	uint32_t i, j, nl_buf_len;
	bool ignore_cached_results = false;

	/* ENTER() intentionally not used in a frequently invoked API */

	if (wlan_hdd_validate_context(hdd_ctx))
		return;
	if (!data) {
		hdd_err("data is null");
		return;
	}

	context = &ext_scan_context;
	spin_lock(&context->context_lock);
	ignore_cached_results = context->ignore_cached_results;
	spin_unlock(&context->context_lock);

	if (ignore_cached_results) {
		hdd_err("Ignore the cached results received after timeout");
		return;
	}

#define EXTSCAN_CACHED_NEST_HDRLEN NLA_HDRLEN
#define EXTSCAN_CACHED_NL_FIXED_TLV \
		((sizeof(data->request_id) + NLA_HDRLEN) + \
		(sizeof(data->num_scan_ids) + NLA_HDRLEN) + \
		(sizeof(data->more_data) + NLA_HDRLEN))
#define EXTSCAN_CACHED_NL_SCAN_ID_TLV \
		((sizeof(result->scan_id) + NLA_HDRLEN) + \
		(sizeof(result->flags) + NLA_HDRLEN) + \
		(sizeof(result->num_results) + NLA_HDRLEN))+ \
		(sizeof(result->buckets_scanned) + NLA_HDRLEN)
#define EXTSCAN_CACHED_NL_SCAN_RESULTS_TLV \
		((sizeof(ap->ts) + NLA_HDRLEN) + \
		(sizeof(ap->ssid) + NLA_HDRLEN) + \
		(sizeof(ap->bssid) + NLA_HDRLEN) + \
		(sizeof(ap->channel) + NLA_HDRLEN) + \
		(sizeof(ap->rssi) + NLA_HDRLEN) + \
		(sizeof(ap->rtt) + NLA_HDRLEN) + \
		(sizeof(ap->rtt_sd) + NLA_HDRLEN) + \
		(sizeof(ap->beaconPeriod) + NLA_HDRLEN) + \
		(sizeof(ap->capability) + NLA_HDRLEN) + \
		(sizeof(ap->ieLength) + NLA_HDRLEN))
#define EXTSCAN_CACHED_NL_SCAN_RESULTS_IE_DATA_TLV \
		(ap->ieLength + NLA_HDRLEN)

	nl_buf_len = NLMSG_HDRLEN;
	nl_buf_len += EXTSCAN_CACHED_NL_FIXED_TLV;
	if (data->num_scan_ids) {
		nl_buf_len += sizeof(result->scan_id) + NLA_HDRLEN;
		nl_buf_len += EXTSCAN_CACHED_NEST_HDRLEN;
		result = &data->result[0];
		for (i = 0; i < data->num_scan_ids; i++) {
			nl_buf_len += EXTSCAN_CACHED_NEST_HDRLEN;
			nl_buf_len += EXTSCAN_CACHED_NL_SCAN_ID_TLV;
			nl_buf_len += EXTSCAN_CACHED_NEST_HDRLEN;

			ap = &result->ap[0];
			for (j = 0; j < result->num_results; j++) {
				nl_buf_len += EXTSCAN_CACHED_NEST_HDRLEN;
				nl_buf_len +=
					EXTSCAN_CACHED_NL_SCAN_RESULTS_TLV;
				if (ap->ieLength)
					nl_buf_len +=
					EXTSCAN_CACHED_NL_SCAN_RESULTS_IE_DATA_TLV;
				ap++;
			}
			result++;
		}
	}

	skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);

	if (!skb) {
		hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
		goto fail;
	}
	hdd_debug("Req Id %u Num_scan_ids %u More Data %u",
		data->request_id, data->num_scan_ids, data->more_data);

	result = &data->result[0];
	for (i = 0; i < data->num_scan_ids; i++) {
		hdd_debug("[i=%d] scan_id %u flags %u num_results %u buckets scanned %u",
			i, result->scan_id, result->flags, result->num_results,
			result->buckets_scanned);

		ap = &result->ap[0];
		for (j = 0; j < result->num_results; j++) {
			/*
			 * Firmware returns timestamp from ext scan start till
			 * BSSID was cached (in micro seconds). Add this with
			 * time gap between system boot up to ext scan start
			 * to derive the time since boot when the
			 * BSSID was cached.
			 */
			ap->ts += hdd_ctx->ext_scan_start_since_boot;
			hdd_debug("Timestamp %llu "
				"Ssid: %s "
				"Bssid (" MAC_ADDRESS_STR ") "
				"Channel %u "
				"Rssi %d "
				"RTT %u "
				"RTT_SD %u "
				"Beacon Period %u "
				"Capability 0x%x "
				"Ie length %d",
				ap->ts,
				ap->ssid,
				MAC_ADDR_ARRAY(ap->bssid.bytes),
				ap->channel,
				ap->rssi,
				ap->rtt,
				ap->rtt_sd,
				ap->beaconPeriod,
				ap->capability,
				ap->ieLength);
			ap++;
		}
		result++;
	}

	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
		data->request_id) ||
	    nla_put_u32(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
		data->num_scan_ids) ||
	    nla_put_u8(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
		data->more_data)) {
		hdd_err("put fail");
		goto fail;
	}

	if (data->num_scan_ids) {
		struct nlattr *nla_results;

		result = &data->result[0];

		if (nla_put_u32(skb,
			QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
			result->scan_id)) {
			hdd_err("put fail");
			goto fail;
		}
		nla_results = nla_nest_start(skb,
			      QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
		if (!nla_results)
			goto fail;

		for (i = 0; i < data->num_scan_ids; i++) {
			struct nlattr *nla_result;
			struct nlattr *nla_aps;

			nla_result = nla_nest_start(skb, i);
			if (!nla_result)
				goto fail;

			if (nla_put_u32(skb,
				QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
				result->scan_id) ||
			    nla_put_u32(skb,
				QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
				result->flags) ||
			    nla_put_u32(skb,
				QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_BUCKETS_SCANNED,
				result->buckets_scanned) ||
			    nla_put_u32(skb,
				QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
				result->num_results)) {
				hdd_err("put fail");
				goto fail;
			}

			nla_aps = nla_nest_start(skb,
				     QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
			if (!nla_aps)
				goto fail;

			ap = &result->ap[0];
			for (j = 0; j < result->num_results; j++) {
				if (hdd_extscan_nl_fill_bss(skb, ap, j))
					goto fail;

				ap++;
			}
			nla_nest_end(skb, nla_aps);
			nla_nest_end(skb, nla_result);
			result++;
		}
		nla_nest_end(skb, nla_results);
	}

	cfg80211_vendor_cmd_reply(skb);

	if (!data->more_data) {
		spin_lock(&context->context_lock);
		context->response_status = 0;
		complete(&context->response_event);
		spin_unlock(&context->context_lock);
	}
	return;

fail:
	if (skb)
		kfree_skb(skb);

	spin_lock(&context->context_lock);
	context->response_status = -EINVAL;
	spin_unlock(&context->context_lock);
}

/**
 * wlan_hdd_cfg80211_extscan_hotlist_match_ind() - hot list match ind
 * @ctx: Pointer to hdd context
 * @pData: Pointer to ext scan result event
 *
 * This callback execute in atomic context and must not invoke any
 * blocking calls.
 *
 * Return: none
 */
static void
wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
					    struct extscan_hotlist_match *data)
{
	struct hdd_context *hdd_ctx = ctx;
	struct sk_buff *skb = NULL;
	uint32_t i, index;
	int flags = cds_get_gfp_flags();

	ENTER();

	if (wlan_hdd_validate_context(hdd_ctx))
		return;
	if (!data) {
		hdd_err("data is null");
		return;
	}

	if (data->ap_found)
		index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
	else
		index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;

	skb = cfg80211_vendor_event_alloc(
		  hdd_ctx->wiphy,
		  NULL,
		  EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
		  index, flags);

	if (!skb) {
		hdd_err("cfg80211_vendor_event_alloc failed");
		return;
	}
	hdd_debug("Req Id: %u Num_APs: %u MoreData: %u ap_found: %u",
			data->requestId, data->numOfAps, data->moreData,
			data->ap_found);

	for (i = 0; i < data->numOfAps; i++) {
		data->ap[i].ts = qdf_get_monotonic_boottime();

		hdd_debug("[i=%d] Timestamp %llu "
		       "Ssid: %s "
		       "Bssid (" MAC_ADDRESS_STR ") "
		       "Channel %u "
		       "Rssi %d "
		       "RTT %u "
		       "RTT_SD %u",
		       i,
		       data->ap[i].ts,
		       data->ap[i].ssid,
		       MAC_ADDR_ARRAY(data->ap[i].bssid.bytes),
		       data->ap[i].channel,
		       data->ap[i].rssi,
		       data->ap[i].rtt, data->ap[i].rtt_sd);
	}

	if (nla_put_u32(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
		data->requestId) ||
	    nla_put_u32(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
		data->numOfAps)) {
		hdd_err("put fail");
		goto fail;
	}

	if (data->numOfAps) {
		struct nlattr *aps;

		aps = nla_nest_start(skb,
			       QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
		if (!aps)
			goto fail;

		for (i = 0; i < data->numOfAps; i++) {
			struct nlattr *ap;

			ap = nla_nest_start(skb, i);
			if (!ap)
				goto fail;

			if (hdd_wlan_nla_put_u64(skb,
				QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
				data->ap[i].ts) ||
			    nla_put(skb,
				QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
				sizeof(data->ap[i].ssid),
				data->ap[i].ssid) ||
			    nla_put(skb,
				QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
				sizeof(data->ap[i].bssid),
				data->ap[i].bssid.bytes) ||
			    nla_put_u32(skb,
				QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
				data->ap[i].channel) ||
			    nla_put_s32(skb,
				QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
				data->ap[i].rssi) ||
			    nla_put_u32(skb,
				QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
				data->ap[i].rtt) ||
			    nla_put_u32(skb,
				QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
				data->ap[i].rtt_sd))
				goto fail;

			nla_nest_end(skb, ap);
		}
		nla_nest_end(skb, aps);

		if (nla_put_u8(skb,
		       QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
		       data->moreData))
			goto fail;
	}

	cfg80211_vendor_event(skb, flags);
	EXIT();
	return;

fail:
	kfree_skb(skb);
}

/**
 * wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind() -
 *	significant wifi change results indication
 * @ctx: Pointer to hdd context
 * @pData: Pointer to signif wifi change event
 *
 * This callback execute in atomic context and must not invoke any
 * blocking calls.
 *
 * Return: none
 */
static void
wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(
			void *ctx,
			tpSirWifiSignificantChangeEvent pData)
{
	struct hdd_context *hdd_ctx = (struct hdd_context *) ctx;
	struct sk_buff *skb = NULL;
	tSirWifiSignificantChange *ap_info;
	int32_t *rssi;
	uint32_t i, j;
	int flags = cds_get_gfp_flags();

	ENTER();

	if (wlan_hdd_validate_context(hdd_ctx))
		return;
	if (!pData) {
		hdd_err("pData is null");
		return;
	}

	skb = cfg80211_vendor_event_alloc(
		hdd_ctx->wiphy,
		NULL,
		EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
		QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
		flags);

	if (!skb) {
		hdd_err("cfg80211_vendor_event_alloc failed");
		return;
	}
	hdd_debug("Req Id %u Num results %u More Data %u",
		pData->requestId, pData->numResults, pData->moreData);

	ap_info = &pData->ap[0];
	for (i = 0; i < pData->numResults; i++) {
		hdd_debug("[i=%d] "
		       "Bssid (" MAC_ADDRESS_STR ") "
		       "Channel %u "
		       "numOfRssi %d",
		       i,
		       MAC_ADDR_ARRAY(ap_info->bssid.bytes),
		       ap_info->channel, ap_info->numOfRssi);
		rssi = &(ap_info)->rssi[0];
		for (j = 0; j < ap_info->numOfRssi; j++)
			hdd_debug("Rssi %d", *rssi++);

		ap_info += ap_info->numOfRssi * sizeof(*rssi);
	}

	if (nla_put_u32(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
		pData->requestId) ||
	    nla_put_u32(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
		pData->numResults)) {
		hdd_err("put fail");
		goto fail;
	}

	if (pData->numResults) {
		struct nlattr *aps;

		aps = nla_nest_start(skb,
			       QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
		if (!aps)
			goto fail;

		ap_info = &pData->ap[0];
		for (i = 0; i < pData->numResults; i++) {
			struct nlattr *ap;

			ap = nla_nest_start(skb, i);
			if (!ap)
				goto fail;

			if (nla_put(skb,
				QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
				QDF_MAC_ADDR_SIZE, ap_info->bssid.bytes) ||
			    nla_put_u32(skb,
				QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
				ap_info->channel) ||
			    nla_put_u32(skb,
				QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
				ap_info->numOfRssi) ||
			    nla_put(skb,
				QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
				sizeof(s32) * ap_info->numOfRssi,
				&(ap_info)->rssi[0]))
				goto fail;

			nla_nest_end(skb, ap);

			ap_info += ap_info->numOfRssi * sizeof(*rssi);
		}
		nla_nest_end(skb, aps);

		if (nla_put_u8(skb,
		     QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
		     pData->moreData))
			goto fail;
	}

	cfg80211_vendor_event(skb, flags);
	return;

fail:
	kfree_skb(skb);
	return;

}

/**
 * wlan_hdd_cfg80211_extscan_full_scan_result_event() - full scan result event
 * @ctx: Pointer to hdd context
 * @pData: Pointer to full scan result event
 *
 * This callback execute in atomic context and must not invoke any
 * blocking calls.
 *
 * Return: none
 */
static void
wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
						 tpSirWifiFullScanResultEvent
						 pData)
{
	struct hdd_context *hdd_ctx = (struct hdd_context *) ctx;
	struct sk_buff *skb = NULL;
	struct timespec ts;
	struct hdd_ext_scan_context *context;

	int flags = cds_get_gfp_flags();

	/* ENTER() intentionally not used in a frequently invoked API */

	if (wlan_hdd_validate_context(hdd_ctx))
		return;
	if (!pData) {
		hdd_err("pData is null");
		return;
	}

	if ((sizeof(*pData) + pData->ap.ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
		hdd_err("Frame exceeded NL size limitation, drop it!!");
		return;
	}
	skb = cfg80211_vendor_event_alloc(
		  hdd_ctx->wiphy,
		  NULL,
		  EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
		  QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
		  flags);

	if (!skb) {
		hdd_err("cfg80211_vendor_event_alloc failed");
		return;
	}

	pData->ap.channel = cds_chan_to_freq(pData->ap.channel);

	/*
	 * Android does not want the time stamp from the frame.
	 * Instead it wants a monotonic increasing value since boot
	 */
	get_monotonic_boottime(&ts);
	pData->ap.ts = ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);

	hdd_debug("Req Id %u More Data %u", pData->requestId,
	       pData->moreData);
	hdd_debug("AP Info: Timestamp %llu Ssid: %s "
	       "Bssid (" MAC_ADDRESS_STR ") "
	       "Channel %u "
	       "Rssi %d "
	       "RTT %u "
	       "RTT_SD %u "
	       "Bcn Period %d "
	       "Capability 0x%X "
	       "IE Length %d",
	       pData->ap.ts,
	       pData->ap.ssid,
	       MAC_ADDR_ARRAY(pData->ap.bssid.bytes),
	       pData->ap.channel,
	       pData->ap.rssi,
	       pData->ap.rtt,
	       pData->ap.rtt_sd,
	       pData->ap.beaconPeriod,
	       pData->ap.capability, pData->ap.ieLength);

	if (nla_put_u32(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
		pData->requestId) ||
	    hdd_wlan_nla_put_u64(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
		pData->ap.ts) ||
	    nla_put(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
		sizeof(pData->ap.ssid),
		pData->ap.ssid) ||
	    nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
		sizeof(pData->ap.bssid),
		pData->ap.bssid.bytes) ||
	    nla_put_u32(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
		pData->ap.channel) ||
	    nla_put_s32(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
		pData->ap.rssi) ||
	    nla_put_u32(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
		pData->ap.rtt) ||
	    nla_put_u32(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
		pData->ap.rtt_sd) ||
	    nla_put_u16(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
		pData->ap.beaconPeriod) ||
	    nla_put_u16(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
		pData->ap.capability) ||
	    nla_put_u32(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
		pData->ap.ieLength) ||
	    nla_put_u8(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
		pData->moreData)) {
		hdd_err("nla put fail");
		goto nla_put_failure;
	}

	if (pData->ap.ieLength) {
		if (nla_put(skb,
		    QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
		    pData->ap.ieLength, pData->ap.ieData))
			goto nla_put_failure;
	}

	context = &ext_scan_context;
	spin_lock(&context->context_lock);
	if (nla_put_u32(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_BUCKETS_SCANNED,
		context->buckets_scanned)) {
		spin_unlock(&context->context_lock);
		hdd_debug("Failed to include buckets_scanned");
		goto nla_put_failure;
	}
	spin_unlock(&context->context_lock);

	cfg80211_vendor_event(skb, flags);
	return;

nla_put_failure:
	kfree_skb(skb);
}

/**
 * wlan_hdd_cfg80211_extscan_scan_res_available_event() - scan result event
 * @ctx: Pointer to hdd context
 * @pData: Pointer to scan results available indication param
 *
 * This callback execute in atomic context and must not invoke any
 * blocking calls.
 *
 * Return: none
 */
static void
wlan_hdd_cfg80211_extscan_scan_res_available_event(
			void *ctx,
			tpSirExtScanResultsAvailableIndParams pData)
{
	struct hdd_context *hdd_ctx = (struct hdd_context *) ctx;
	struct sk_buff *skb = NULL;
	int flags = cds_get_gfp_flags();

	ENTER();

	if (wlan_hdd_validate_context(hdd_ctx))
		return;
	if (!pData) {
		hdd_err("pData is null");
		return;
	}

	skb = cfg80211_vendor_event_alloc(
		 hdd_ctx->wiphy,
		 NULL,
		 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
		 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
		 flags);

	if (!skb) {
		hdd_err("cfg80211_vendor_event_alloc failed");
		return;
	}

	hdd_debug("Req Id %u Num results %u",
	       pData->requestId, pData->numResultsAvailable);
	if (nla_put_u32(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
		pData->requestId) ||
	    nla_put_u32(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
		pData->numResultsAvailable)) {
		hdd_err("nla put fail");
		goto nla_put_failure;
	}

	cfg80211_vendor_event(skb, flags);
	EXIT();
	return;

nla_put_failure:
	kfree_skb(skb);
}

/**
 * wlan_hdd_cfg80211_extscan_scan_progress_event() - scan progress event
 * @ctx: Pointer to hdd context
 * @pData: Pointer to scan event indication param
 *
 * This callback execute in atomic context and must not invoke any
 * blocking calls.
 *
 * Return: none
 */
static void
wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx,
					      tpSirExtScanOnScanEventIndParams
					      pData)
{
	struct hdd_context *hdd_ctx = (struct hdd_context *) ctx;
	struct sk_buff *skb = NULL;
	int flags = cds_get_gfp_flags();
	struct hdd_ext_scan_context *context;

	/* ENTER() intentionally not used in a frequently invoked API */

	if (wlan_hdd_validate_context(hdd_ctx))
		return;
	if (!pData) {
		hdd_err("pData is null");
		return;
	}

	skb = cfg80211_vendor_event_alloc(
			hdd_ctx->wiphy,
			NULL,
			EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
			QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
			flags);

	if (!skb) {
		hdd_err("cfg80211_vendor_event_alloc failed");
		return;
	}

	hdd_debug("Request Id: %u Scan event type: %u Scan event status: %u buckets scanned: %u",
		pData->requestId, pData->scanEventType, pData->status,
		pData->buckets_scanned);

	context = &ext_scan_context;
	spin_lock(&context->context_lock);
	if (pData->scanEventType == WIFI_EXTSCAN_CYCLE_COMPLETED_EVENT) {
		context->buckets_scanned = 0;
		pData->scanEventType = WIFI_EXTSCAN_RESULTS_AVAILABLE;
		spin_unlock(&context->context_lock);
	} else if (pData->scanEventType == WIFI_EXTSCAN_CYCLE_STARTED_EVENT) {
		context->buckets_scanned = pData->buckets_scanned;
		/* No need to report to user space */
		spin_unlock(&context->context_lock);
		goto nla_put_failure;
	} else {
		spin_unlock(&context->context_lock);
	}

	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
			pData->requestId) ||
	    nla_put_u8(skb,
		       QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
		       pData->scanEventType)) {
		hdd_err("nla put fail");
		goto nla_put_failure;
	}

	cfg80211_vendor_event(skb, flags);
	return;

nla_put_failure:
	kfree_skb(skb);
}

/**
 * wlan_hdd_cfg80211_extscan_epno_match_found() - pno match found
 * @hddctx: HDD context
 * @data: matched network data
 *
 * This function reads the matched network data and fills NL vendor attributes
 * and send it to upper layer.
 * This callback execute in atomic context and must not invoke any
 * blocking calls.
 *
 * Return: 0 on success, error number otherwise
 */
static void
wlan_hdd_cfg80211_extscan_epno_match_found(void *ctx,
					struct pno_match_found *data)
{
	struct hdd_context *hdd_ctx  = (struct hdd_context *)ctx;
	struct sk_buff *skb     = NULL;
	uint32_t len, i;
	int flags = cds_get_gfp_flags();

	ENTER();

	if (wlan_hdd_validate_context(hdd_ctx))
		return;
	if (!data) {
		hdd_err("data is null");
		return;
	}

	/*
	 * If the number of match found APs including IE data exceeds NL 4K size
	 * limitation, drop that beacon/probe rsp frame.
	 */
	len = sizeof(*data) +
			(data->num_results + sizeof(tSirWifiScanResult));
	for (i = 0; i < data->num_results; i++)
		len += data->ap[i].ieLength;

	if (len >= EXTSCAN_EVENT_BUF_SIZE) {
		hdd_err("Frame exceeded NL size limitation, drop it!");
		return;
	}

	skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
		  NULL,
		  EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
		QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_PNO_NETWORK_FOUND_INDEX,
		  flags);

	if (!skb) {
		hdd_err("cfg80211_vendor_event_alloc failed");
		return;
	}

	hdd_debug("Req Id %u More Data %u num_results %d",
		data->request_id, data->more_data, data->num_results);
	for (i = 0; i < data->num_results; i++) {
		data->ap[i].channel = cds_chan_to_freq(data->ap[i].channel);
		hdd_debug("AP Info: Timestamp %llu) Ssid: %s "
					"Bssid (" MAC_ADDRESS_STR ") "
					"Channel %u "
					"Rssi %d "
					"RTT %u "
					"RTT_SD %u "
					"Bcn Period %d "
					"Capability 0x%X "
					"IE Length %d",
					data->ap[i].ts,
					data->ap[i].ssid,
					MAC_ADDR_ARRAY(data->ap[i].bssid.bytes),
					data->ap[i].channel,
					data->ap[i].rssi,
					data->ap[i].rtt,
					data->ap[i].rtt_sd,
					data->ap[i].beaconPeriod,
					data->ap[i].capability,
					data->ap[i].ieLength);
	}

	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
		data->request_id) ||
	    nla_put_u32(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
		data->num_results) ||
	    nla_put_u8(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
		data->more_data)) {
		hdd_err("nla put fail");
		goto fail;
	}

	if (data->num_results) {
		struct nlattr *nla_aps;

		nla_aps = nla_nest_start(skb,
			QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
		if (!nla_aps)
			goto fail;

		for (i = 0; i < data->num_results; i++) {
			if (hdd_extscan_nl_fill_bss(skb, &data->ap[i], i))
				goto fail;
		}
		nla_nest_end(skb, nla_aps);
	}

	cfg80211_vendor_event(skb, flags);
	return;

fail:
	kfree_skb(skb);
}

/**
 * wlan_hdd_cfg80211_passpoint_match_found() - passpoint match found
 * @hddctx: HDD context
 * @data: matched network data
 *
 * This function reads the match network %data and fill in the skb with
 * NL attributes and send up the NL event
 * This callback execute in atomic context and must not invoke any
 * blocking calls.
 *
 * Return: none
 */
static void
wlan_hdd_cfg80211_passpoint_match_found(void *ctx,
					struct wifi_passpoint_match *data)
{
	struct hdd_context *hdd_ctx  = ctx;
	struct sk_buff *skb     = NULL;
	uint32_t len, i, num_matches = 1, more_data = 0;
	struct nlattr *nla_aps, *nla_bss;
	int flags = cds_get_gfp_flags();

	ENTER();

	if (wlan_hdd_validate_context(hdd_ctx))
		return;
	if (!data) {
		hdd_err("data is null");
		return;
	}

	len = sizeof(*data) + data->ap.ieLength + data->anqp_len;
	if (len >= EXTSCAN_EVENT_BUF_SIZE) {
		hdd_err("Result exceeded NL size limitation, drop it");
		return;
	}

	skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
		  NULL,
		  EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
		  QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_PNO_PASSPOINT_NETWORK_FOUND_INDEX,
		  flags);

	if (!skb) {
		hdd_err("cfg80211_vendor_event_alloc failed");
		return;
	}

	hdd_debug("Req Id %u Id %u ANQP length %u num_matches %u",
		data->request_id, data->id, data->anqp_len, num_matches);
	for (i = 0; i < num_matches; i++) {
		hdd_debug("AP Info: Timestamp %llu Ssid: %s "
					"Bssid (" MAC_ADDRESS_STR ") "
					"Channel %u "
					"Rssi %d "
					"RTT %u "
					"RTT_SD %u "
					"Bcn Period %d "
					"Capability 0x%X "
					"IE Length %d",
					data->ap.ts,
					data->ap.ssid,
					MAC_ADDR_ARRAY(data->ap.bssid.bytes),
					data->ap.channel,
					data->ap.rssi,
					data->ap.rtt,
					data->ap.rtt_sd,
					data->ap.beaconPeriod,
					data->ap.capability,
					data->ap.ieLength);
	}

	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
		data->request_id) ||
	    nla_put_u32(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_PNO_RESULTS_PASSPOINT_NETWORK_FOUND_NUM_MATCHES,
		num_matches) ||
	    nla_put_u8(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
		more_data)) {
		hdd_err("nla put fail");
		goto fail;
	}

	nla_aps = nla_nest_start(skb,
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_PNO_RESULTS_PASSPOINT_MATCH_RESULT_LIST);
	if (!nla_aps)
		goto fail;

	for (i = 0; i < num_matches; i++) {
		struct nlattr *nla_ap;

		nla_ap = nla_nest_start(skb, i);
		if (!nla_ap)
			goto fail;

		if (nla_put_u32(skb,
			QCA_WLAN_VENDOR_ATTR_EXTSCAN_PNO_RESULTS_PASSPOINT_MATCH_ID,
			data->id) ||
		    nla_put_u32(skb,
			QCA_WLAN_VENDOR_ATTR_EXTSCAN_PNO_RESULTS_PASSPOINT_MATCH_ANQP_LEN,
			data->anqp_len)) {
			goto fail;
		}

		if (data->anqp_len)
			if (nla_put(skb,
				QCA_WLAN_VENDOR_ATTR_EXTSCAN_PNO_RESULTS_PASSPOINT_MATCH_ANQP,
				data->anqp_len, data->anqp))
				goto fail;

		nla_bss = nla_nest_start(skb,
				QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
		if (!nla_bss)
			goto fail;

		if (hdd_extscan_nl_fill_bss(skb, &data->ap, 0))
			goto fail;

		nla_nest_end(skb, nla_bss);
		nla_nest_end(skb, nla_ap);
	}
	nla_nest_end(skb, nla_aps);

	cfg80211_vendor_event(skb, flags);
	return;

fail:
	kfree_skb(skb);
}

/**
 * wlan_hdd_cfg80211_extscan_generic_rsp() -
 *	Handle a generic ExtScan Response message
 * @ctx: HDD context registered with SME
 * @response: The ExtScan response from firmware
 *
 * This function will handle a generic ExtScan response message from
 * firmware and will communicate the result to the userspace thread
 * that is waiting for the response.
 *
 * Return: none
 */
static void
wlan_hdd_cfg80211_extscan_generic_rsp
	(void *ctx,
	 struct sir_extscan_generic_response *response)
{
	struct hdd_context *hdd_ctx = ctx;
	struct hdd_ext_scan_context *context;

	ENTER();

	if (wlan_hdd_validate_context(hdd_ctx) || !response) {
		hdd_err("HDD context is not valid or response(%pK) is null",
		       response);
		return;
	}

	hdd_debug("request %u status %u",
	       response->request_id, response->status);

	context = &ext_scan_context;
	spin_lock(&context->context_lock);
	if (context->request_id == response->request_id) {
		context->response_status = response->status ? -EINVAL : 0;
		complete(&context->response_event);
	}
	spin_unlock(&context->context_lock);
}

/**
 * wlan_hdd_cfg80211_extscan_callback() - ext scan callback
 * @ctx: Pointer to hdd context
 * @evType: Event type
 * @pMag: Pointer to message
 *
 * Return: none
 */
void wlan_hdd_cfg80211_extscan_callback(void *ctx, const uint16_t evType,
					void *pMsg)
{
	struct hdd_context *hdd_ctx = (struct hdd_context *) ctx;

	/* ENTER() intentionally not used in a frequently invoked API */

	if (wlan_hdd_validate_context(hdd_ctx))
		return;

	hdd_debug("Rcvd Event %d", evType);

	switch (evType) {
	case eSIR_EXTSCAN_CACHED_RESULTS_RSP:
		/* There is no need to send this response to upper layer
		 * Just log the message
		 */
		hdd_debug("Rcvd eSIR_EXTSCAN_CACHED_RESULTS_RSP");
		break;

	case eSIR_EXTSCAN_GET_CAPABILITIES_IND:
		wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx,
			(struct ext_scan_capabilities_response *) pMsg);
		break;

	case eSIR_EXTSCAN_HOTLIST_MATCH_IND:
		wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
		break;

	case eSIR_EXTSCAN_SIGNIFICANT_WIFI_CHANGE_RESULTS_IND:
		wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx,
					(tpSirWifiSignificantChangeEvent) pMsg);
		break;

	case eSIR_EXTSCAN_CACHED_RESULTS_IND:
		wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
		break;

	case eSIR_EXTSCAN_SCAN_RES_AVAILABLE_IND:
		wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx,
			   (tpSirExtScanResultsAvailableIndParams) pMsg);
		break;

	case eSIR_EXTSCAN_FULL_SCAN_RESULT_IND:
		wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx,
					 (tpSirWifiFullScanResultEvent) pMsg);
		break;

	case eSIR_EPNO_NETWORK_FOUND_IND:
		wlan_hdd_cfg80211_extscan_epno_match_found(ctx,
					(struct pno_match_found *)pMsg);
		break;

	case eSIR_EXTSCAN_SCAN_PROGRESS_EVENT_IND:
		wlan_hdd_cfg80211_extscan_scan_progress_event(ctx,
			      (tpSirExtScanOnScanEventIndParams) pMsg);
		break;

	case eSIR_PASSPOINT_NETWORK_FOUND_IND:
		wlan_hdd_cfg80211_passpoint_match_found(ctx,
					(struct wifi_passpoint_match *) pMsg);
		break;

	case eSIR_EXTSCAN_START_RSP:
	case eSIR_EXTSCAN_STOP_RSP:
	case eSIR_EXTSCAN_SET_BSSID_HOTLIST_RSP:
	case eSIR_EXTSCAN_RESET_BSSID_HOTLIST_RSP:
	case eSIR_EXTSCAN_SET_SIGNIFICANT_WIFI_CHANGE_RSP:
	case eSIR_EXTSCAN_RESET_SIGNIFICANT_WIFI_CHANGE_RSP:
	case eSIR_EXTSCAN_SET_SSID_HOTLIST_RSP:
	case eSIR_EXTSCAN_RESET_SSID_HOTLIST_RSP:
		wlan_hdd_cfg80211_extscan_generic_rsp(ctx, pMsg);
		break;

	default:
		hdd_err("Unknown event type: %u", evType);
		break;
	}
}

/*
 * define short names for the global vendor params
 * used by wlan_hdd_send_ext_scan_capability()
 */
#define PARAM_REQUEST_ID \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
#define PARAM_STATUS \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
#define MAX_SCAN_CACHE_SIZE \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
#define MAX_SCAN_BUCKETS \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
#define MAX_AP_CACHE_PER_SCAN \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
#define MAX_RSSI_SAMPLE_SIZE \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
#define MAX_SCAN_RPT_THRHOLD \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
#define MAX_HOTLIST_BSSIDS \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
#define MAX_BSSID_HISTORY_ENTRIES \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
#define MAX_HOTLIST_SSIDS \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
#define MAX_NUM_EPNO_NETS \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_NUM_EPNO_NETS
#define MAX_NUM_EPNO_NETS_BY_SSID \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_NUM_EPNO_NETS_BY_SSID
#define MAX_NUM_WHITELISTED_SSID \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_NUM_WHITELISTED_SSID
#define MAX_NUM_BLACKLISTED_BSSID \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_MAX_NUM_BLACKLISTED_BSSID
/**
 * wlan_hdd_send_ext_scan_capability - send ext scan capability to user space
 * @hdd_ctx: Pointer to hdd context
 *
 * Return: 0 for success, non-zero for failure
 */
static int wlan_hdd_send_ext_scan_capability(struct hdd_context *hdd_ctx)
{
	int ret;
	struct sk_buff *skb;
	struct ext_scan_capabilities_response *data;
	uint32_t nl_buf_len;

	ret = wlan_hdd_validate_context(hdd_ctx);
	if (0 != ret)
		return ret;

	data = &(ext_scan_context.capability_response);

	nl_buf_len = NLMSG_HDRLEN;
	nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
	(sizeof(data->status) + NLA_HDRLEN) +
	(sizeof(data->max_scan_cache_size) + NLA_HDRLEN) +
	(sizeof(data->max_scan_buckets) + NLA_HDRLEN) +
	(sizeof(data->max_ap_cache_per_scan) + NLA_HDRLEN) +
	(sizeof(data->max_rssi_sample_size) + NLA_HDRLEN) +
	(sizeof(data->max_scan_reporting_threshold) + NLA_HDRLEN) +
	(sizeof(data->max_hotlist_bssids) + NLA_HDRLEN) +
	(sizeof(data->max_significant_wifi_change_aps) + NLA_HDRLEN) +
	(sizeof(data->max_bssid_history_entries) + NLA_HDRLEN) +
	(sizeof(data->max_hotlist_ssids) + NLA_HDRLEN) +
	(sizeof(data->max_number_epno_networks) + NLA_HDRLEN) +
	(sizeof(data->max_number_epno_networks_by_ssid) + NLA_HDRLEN) +
	(sizeof(data->max_number_of_white_listed_ssid) + NLA_HDRLEN) +
	(sizeof(data->max_number_of_black_listed_bssid) + NLA_HDRLEN);

	skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);

	if (!skb) {
		hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
		return -ENOMEM;
	}


	hdd_debug("Req Id %u", data->requestId);
	hdd_debug("Status %u", data->status);
	hdd_debug("Scan cache size %u",
	       data->max_scan_cache_size);
	hdd_debug("Scan buckets %u", data->max_scan_buckets);
	hdd_debug("Max AP per scan %u",
	       data->max_ap_cache_per_scan);
	hdd_debug("max_rssi_sample_size %u",
	       data->max_rssi_sample_size);
	hdd_debug("max_scan_reporting_threshold %u",
	       data->max_scan_reporting_threshold);
	hdd_debug("max_hotlist_bssids %u",
	       data->max_hotlist_bssids);
	hdd_debug("max_significant_wifi_change_aps %u",
	       data->max_significant_wifi_change_aps);
	hdd_debug("max_bssid_history_entries %u",
	       data->max_bssid_history_entries);
	hdd_debug("max_hotlist_ssids %u", data->max_hotlist_ssids);
	hdd_debug("max_number_epno_networks %u",
					data->max_number_epno_networks);
	hdd_debug("max_number_epno_networks_by_ssid %u",
					data->max_number_epno_networks_by_ssid);
	hdd_debug("max_number_of_white_listed_ssid %u",
					data->max_number_of_white_listed_ssid);
	hdd_debug("max_number_of_black_listed_bssid (%u)",
					data->max_number_of_black_listed_bssid);

	if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
	    nla_put_u32(skb, PARAM_STATUS, data->status) ||
	    nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->max_scan_cache_size) ||
	    nla_put_u32(skb, MAX_SCAN_BUCKETS, data->max_scan_buckets) ||
	    nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
			data->max_ap_cache_per_scan) ||
	    nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
			data->max_rssi_sample_size) ||
	    nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
			data->max_scan_reporting_threshold) ||
	    nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->max_hotlist_bssids) ||
	    nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS,
			data->max_significant_wifi_change_aps) ||
	    nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
			data->max_bssid_history_entries) ||
	    nla_put_u32(skb, MAX_HOTLIST_SSIDS,	data->max_hotlist_ssids) ||
	    nla_put_u32(skb, MAX_NUM_EPNO_NETS,
			data->max_number_epno_networks) ||
	    nla_put_u32(skb, MAX_NUM_EPNO_NETS_BY_SSID,
			data->max_number_epno_networks_by_ssid) ||
	    nla_put_u32(skb, MAX_NUM_WHITELISTED_SSID,
			data->max_number_of_white_listed_ssid) ||
	    nla_put_u32(skb, MAX_NUM_BLACKLISTED_BSSID,
			data->max_number_of_black_listed_bssid)) {
		hdd_err("nla put fail");
		goto nla_put_failure;
	}

	cfg80211_vendor_cmd_reply(skb);
	return 0;

nla_put_failure:
	kfree_skb(skb);
	return -EINVAL;
}
/*
 * done with short names for the global vendor params
 * used by wlan_hdd_send_ext_scan_capability()
 */
#undef PARAM_REQUEST_ID
#undef PARAM_STATUS
#undef MAX_SCAN_CACHE_SIZE
#undef MAX_SCAN_BUCKETS
#undef MAX_AP_CACHE_PER_SCAN
#undef MAX_RSSI_SAMPLE_SIZE
#undef MAX_SCAN_RPT_THRHOLD
#undef MAX_HOTLIST_BSSIDS
#undef MAX_SIGNIFICANT_WIFI_CHANGE_APS
#undef MAX_BSSID_HISTORY_ENTRIES
#undef MAX_HOTLIST_SSIDS
#undef MAX_NUM_EPNO_NETS
#undef MAX_NUM_EPNO_NETS_BY_SSID
#undef MAX_NUM_WHITELISTED_SSID
#undef MAX_NUM_BLACKLISTED_BSSID

/**
 * __wlan_hdd_cfg80211_extscan_get_capabilities() - get ext scan capabilities
 * @wiphy: Pointer to wireless phy
 * @wdev: Pointer to wireless device
 * @data: Pointer to data
 * @data_len: Data length
 *
 * Return: none
 */
static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
					       struct wireless_dev *wdev,
					       const void *data, int data_len)
{
	int ret;
	unsigned long rc;
	struct hdd_ext_scan_context *context;
	tpSirGetExtScanCapabilitiesReqParams pReqMsg = NULL;
	struct net_device *dev = wdev->netdev;
	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX +
			  1];
	QDF_STATUS status;

	ENTER_DEV(dev);

	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
		hdd_err("Command not allowed in FTM mode");
		return -EPERM;
	}

	ret = wlan_hdd_validate_context(hdd_ctx);
	if (0 != ret)
		return -EINVAL;

	if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
		hdd_err("Driver Modules are closed");
		return -EINVAL;
	}

	if (!hdd_ctx->config->extscan_enabled) {
		hdd_err("extscan not supported");
		return -ENOTSUPP;
	}
	if (wlan_cfg80211_nla_parse(tb,
			   QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
			   data, data_len, wlan_hdd_extscan_config_policy)) {
		hdd_err("Invalid ATTR");
		return -EINVAL;
	}

	pReqMsg = qdf_mem_malloc(sizeof(*pReqMsg));
	if (!pReqMsg) {
		hdd_err("qdf_mem_malloc failed");
		return -ENOMEM;
	}

	/* Parse and fetch request Id */
	if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
		hdd_err("attr request id failed");
		goto fail;
	}

	pReqMsg->requestId =
		nla_get_u32(tb
		 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
	pReqMsg->sessionId = adapter->session_id;
	hdd_debug("Req Id %d Session Id %d",
		pReqMsg->requestId, pReqMsg->sessionId);

	context = &ext_scan_context;
	spin_lock(&context->context_lock);
	context->request_id = pReqMsg->requestId;
	INIT_COMPLETION(context->response_event);
	spin_unlock(&context->context_lock);

	status = sme_ext_scan_get_capabilities(hdd_ctx->hHal, pReqMsg);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		hdd_err("sme_ext_scan_get_capabilities failed(err=%d)",
			status);
		goto fail;
	}

	rc = wait_for_completion_timeout(&context->response_event,
		msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
	if (!rc) {
		hdd_err("Target response timed out");
		return -ETIMEDOUT;
	}

	ret = wlan_hdd_send_ext_scan_capability(hdd_ctx);
	if (ret)
		hdd_err("Failed to send ext scan capability to user space");
	EXIT();
	return ret;
fail:
	qdf_mem_free(pReqMsg);
	return -EINVAL;
}

/**
 * wlan_hdd_cfg80211_extscan_get_capabilities() - get ext scan capabilities
 * @wiphy: Pointer to wiphy
 * @wdev: Pointer to wdev
 * @data: Pointer to data
 * @data_len: Data length
 *
 * Return: 0 for success, non-zero for failure
 */
int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
						struct wireless_dev *wdev,
						const void *data, int data_len)
{
	int ret = 0;

	cds_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data,
		data_len);
	cds_ssr_unprotect(__func__);

	return ret;
}

/*
 * define short names for the global vendor params
 * used by wlan_hdd_cfg80211_extscan_get_cached_results()
 */
#define PARAM_MAX \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
#define PARAM_REQUEST_ID \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
#define PARAM_FLUSH \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH
/**
 * __wlan_hdd_cfg80211_extscan_get_cached_results() - extscan get cached results
 * @wiphy: wiphy pointer
 * @wdev: pointer to struct wireless_dev
 * @data: pointer to incoming NL vendor data
 * @data_len: length of @data
 *
 * This function parses the incoming NL vendor command data attributes and
 * invokes the SME Api and blocks on a completion variable.
 * Each WMI event with cached scan results data chunk results in
 * function call wlan_hdd_cfg80211_extscan_cached_results_ind and each
 * data chunk is sent up the layer in cfg80211_vendor_cmd_alloc_reply_skb.
 *
 * If timeout happens before receiving all of the data, this function sets
 * a context variable @ignore_cached_results to %true, all of the next data
 * chunks are checked against this variable and dropped.
 *
 * Return: 0 on success; error number otherwise.
 */
static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
						 struct wireless_dev
						 *wdev, const void *data,
						 int data_len)
{
	tpSirExtScanGetCachedResultsReqParams pReqMsg = NULL;
	struct net_device *dev = wdev->netdev;
	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX +
			  1];
	struct hdd_ext_scan_context *context;
	QDF_STATUS status;
	int retval = 0;
	unsigned long rc;

	/* ENTER_DEV() intentionally not used in a frequently invoked API */

	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
		hdd_err("Command not allowed in FTM mode");
		return -EPERM;
	}

	retval = wlan_hdd_validate_context(hdd_ctx);
	if (0 != retval)
		return -EINVAL;

	if (!hdd_ctx->config->extscan_enabled) {
		hdd_err("extscan not supported");
		return -ENOTSUPP;
	}
	if (wlan_cfg80211_nla_parse(tb, PARAM_MAX, data, data_len,
				    wlan_hdd_extscan_config_policy)) {
		hdd_err("Invalid ATTR");
		return -EINVAL;
	}

	pReqMsg = qdf_mem_malloc(sizeof(*pReqMsg));
	if (!pReqMsg) {
		hdd_err("qdf_mem_malloc failed");
		return -ENOMEM;
	}

	/* Parse and fetch request Id */
	if (!tb[PARAM_REQUEST_ID]) {
		hdd_err("attr request id failed");
		goto fail;
	}

	pReqMsg->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
	pReqMsg->sessionId = adapter->session_id;

	/* Parse and fetch flush parameter */
	if (!tb[PARAM_FLUSH]) {
		hdd_err("attr flush failed");
		goto fail;
	}
	pReqMsg->flush = nla_get_u8(tb[PARAM_FLUSH]);
	hdd_debug("Req Id: %u Session Id: %d Flush: %d",
		pReqMsg->requestId, pReqMsg->sessionId, pReqMsg->flush);

	context = &ext_scan_context;
	spin_lock(&context->context_lock);
	context->request_id = pReqMsg->requestId;
	context->ignore_cached_results = false;
	INIT_COMPLETION(context->response_event);
	spin_unlock(&context->context_lock);

	status = sme_get_cached_results(hdd_ctx->hHal, pReqMsg);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		hdd_err("sme_get_cached_results failed(err=%d)", status);
		goto fail;
	}

	rc = wait_for_completion_timeout(&context->response_event,
			msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
	if (!rc) {
		hdd_err("Target response timed out");
		retval = -ETIMEDOUT;
		spin_lock(&context->context_lock);
		context->ignore_cached_results = true;
		spin_unlock(&context->context_lock);
	} else {
		spin_lock(&context->context_lock);
		retval = context->response_status;
		spin_unlock(&context->context_lock);
	}
	return retval;

fail:
	qdf_mem_free(pReqMsg);
	return -EINVAL;
}
/*
 * done with short names for the global vendor params
 * used by wlan_hdd_cfg80211_extscan_get_cached_results()
 */
#undef PARAM_MAX
#undef PARAM_REQUEST_ID
#undef PARAM_FLUSH

/**
 * wlan_hdd_cfg80211_extscan_get_cached_results() - extscan get cached results
 * @wiphy: wiphy pointer
 * @wdev: pointer to struct wireless_dev
 * @data: pointer to incoming NL vendor data
 * @data_len: length of @data
 *
 * This function parses the incoming NL vendor command data attributes and
 * invokes the SME Api and blocks on a completion variable.
 * Each WMI event with cached scan results data chunk results in
 * function call wlan_hdd_cfg80211_extscan_cached_results_ind and each
 * data chunk is sent up the layer in cfg80211_vendor_cmd_alloc_reply_skb.
 *
 * If timeout happens before receiving all of the data, this function sets
 * a context variable @ignore_cached_results to %true, all of the next data
 * chunks are checked against this variable and dropped.
 *
 * Return: 0 on success; error number otherwise.
 */
int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
					struct wireless_dev *wdev,
					const void *data, int data_len)
{
	int ret = 0;

	cds_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data,
								data_len);
	cds_ssr_unprotect(__func__);

	return ret;
}

/**
 * __wlan_hdd_cfg80211_extscan_set_bssid_hotlist() - set bssid hot list
 * @wiphy: Pointer to wireless phy
 * @wdev: Pointer to wireless device
 * @data: Pointer to data
 * @data_len: Data length
 *
 * Return: none
 */
static int
__wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
						struct wireless_dev
						*wdev, const void *data,
						int data_len)
{
	tpSirExtScanSetBssidHotListReqParams pReqMsg = NULL;
	struct net_device *dev = wdev->netdev;
	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX +
			  1];
	struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
			   + 1];
	struct nlattr *apTh;
	struct hdd_ext_scan_context *context;
	uint32_t request_id;
	QDF_STATUS status;
	uint8_t i;
	int rem, retval;
	unsigned long rc;

	ENTER_DEV(dev);

	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
		hdd_err("Command not allowed in FTM mode");
		return -EPERM;
	}

	retval = wlan_hdd_validate_context(hdd_ctx);
	if (0 != retval)
		return -EINVAL;

	if (!hdd_ctx->config->extscan_enabled) {
		hdd_err("extscan not supported");
		return -ENOTSUPP;
	}
	if (wlan_cfg80211_nla_parse(tb,
			   QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
			   data, data_len, wlan_hdd_extscan_config_policy)) {
		hdd_err("Invalid ATTR");
		return -EINVAL;
	}

	pReqMsg = qdf_mem_malloc(sizeof(*pReqMsg));
	if (!pReqMsg) {
		hdd_err("qdf_mem_malloc failed");
		return -ENOMEM;
	}

	/* Parse and fetch request Id */
	if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
		hdd_err("attr request id failed");
		goto fail;
	}

	pReqMsg->requestId =
		nla_get_u32(tb
		 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
	hdd_debug("Req Id %d", pReqMsg->requestId);

	/* Parse and fetch number of APs */
	if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
		hdd_err("attr number of AP failed");
		goto fail;
	}
	pReqMsg->numAp =
		nla_get_u32(tb
		    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
	if (pReqMsg->numAp > WLAN_EXTSCAN_MAX_HOTLIST_APS) {
		hdd_err("Number of AP: %u exceeds max: %u",
			pReqMsg->numAp, WLAN_EXTSCAN_MAX_HOTLIST_APS);
		goto fail;
	}
	pReqMsg->sessionId = adapter->session_id;
	hdd_debug("Number of AP %d Session Id %d",
		pReqMsg->numAp, pReqMsg->sessionId);

	/* Parse and fetch lost ap sample size */
	if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
		hdd_err("attr lost ap sample size failed");
		goto fail;
	}

	pReqMsg->lost_ap_sample_size = nla_get_u32(
		tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
	hdd_debug("Lost ap sample size %d",
			pReqMsg->lost_ap_sample_size);

	if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM]) {
		hdd_err("attr ap threshold failed");
		goto fail;
	}
	i = 0;
	nla_for_each_nested(apTh,
			    tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM],
			    rem) {
		if (i == pReqMsg->numAp) {
			hdd_warn("Ignoring excess AP");
			break;
		}

		if (wlan_cfg80211_nla_parse(tb2,
			   QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
			   nla_data(apTh), nla_len(apTh),
			   wlan_hdd_extscan_config_policy)) {
			hdd_err("nla_parse failed");
			goto fail;
		}

		/* Parse and fetch MAC address */
		if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
			hdd_err("attr mac address failed");
			goto fail;
		}
		nla_memcpy(pReqMsg->ap[i].bssid.bytes,
			tb2
			[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID],
			   QDF_MAC_ADDR_SIZE);
		hdd_debug(MAC_ADDRESS_STR,
		       MAC_ADDR_ARRAY(pReqMsg->ap[i].bssid.bytes));

		/* Parse and fetch low RSSI */
		if (!tb2
		    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
			hdd_err("attr low RSSI failed");
			goto fail;
		}
		pReqMsg->ap[i].low =
			nla_get_s32(tb2
			    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
		hdd_debug("RSSI low %d", pReqMsg->ap[i].low);

		/* Parse and fetch high RSSI */
		if (!tb2
		    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
			hdd_err("attr high RSSI failed");
			goto fail;
		}
		pReqMsg->ap[i].high =
			nla_get_s32(tb2
			    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
		hdd_debug("RSSI High %d", pReqMsg->ap[i].high);

		i++;
	}

	if (i < pReqMsg->numAp) {
		hdd_warn("Number of AP %u less than expected %u",
			 i, pReqMsg->numAp);
		pReqMsg->numAp = i;
	}

	context = &ext_scan_context;
	spin_lock(&context->context_lock);
	INIT_COMPLETION(context->response_event);
	context->request_id = request_id = pReqMsg->requestId;
	spin_unlock(&context->context_lock);

	status = sme_set_bss_hotlist(hdd_ctx->hHal, pReqMsg);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		hdd_err("sme_set_bss_hotlist failed(err=%d)", status);
		goto fail;
	}

	/* request was sent -- wait for the response */
	rc = wait_for_completion_timeout
		(&context->response_event,
		 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));

	if (!rc) {
		hdd_err("sme_set_bss_hotlist timed out");
		retval = -ETIMEDOUT;
	} else {
		spin_lock(&context->context_lock);
		if (context->request_id == request_id)
			retval = context->response_status;
		else
			retval = -EINVAL;
		spin_unlock(&context->context_lock);
	}
	EXIT();
	return retval;

fail:
	qdf_mem_free(pReqMsg);
	return -EINVAL;
}

/**
 * wlan_hdd_cfg80211_extscan_set_bssid_hotlist() - set ext scan bssid hotlist
 * @wiphy: Pointer to wiphy
 * @wdev: Pointer to wdev
 * @data: Pointer to data
 * @data_len: Data length
 *
 * Return: 0 for success, non-zero for failure
 */
int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
					struct wireless_dev *wdev,
					const void *data, int data_len)
{
	int ret = 0;

	cds_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
					data_len);
	cds_ssr_unprotect(__func__);

	return ret;
}


/**
 * __wlan_hdd_cfg80211_extscan_set_significant_change() - set significant change
 * @wiphy: Pointer to wireless phy
 * @wdev: Pointer to wireless device
 * @data: Pointer to data
 * @data_len: Data length
 *
 * Return: none
 */
static int
__wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
						     struct wireless_dev
						     *wdev, const void *data,
						     int data_len)
{
	tpSirExtScanSetSigChangeReqParams pReqMsg = NULL;
	struct net_device *dev = wdev->netdev;
	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX +
			  1];
	struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
			   + 1];
	struct nlattr *apTh;
	struct hdd_ext_scan_context *context;
	uint32_t request_id;
	QDF_STATUS status;
	uint8_t i;
	int rem, retval;
	unsigned long rc;

	ENTER_DEV(dev);

	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
		hdd_err("Command not allowed in FTM mode");
		return -EPERM;
	}

	retval = wlan_hdd_validate_context(hdd_ctx);
	if (0 != retval)
		return -EINVAL;

	if (wlan_cfg80211_nla_parse(tb,
			   QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
			   data, data_len, wlan_hdd_extscan_config_policy)) {
		hdd_err("Invalid ATTR");
		return -EINVAL;
	}

	pReqMsg = qdf_mem_malloc(sizeof(*pReqMsg));
	if (!pReqMsg) {
		hdd_err("qdf_mem_malloc failed");
		return -ENOMEM;
	}

	/* Parse and fetch request Id */
	if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
		hdd_err("attr request id failed");
		goto fail;
	}

	pReqMsg->requestId =
		nla_get_u32(tb
		 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
	hdd_debug("Req Id %d", pReqMsg->requestId);

	/* Parse and fetch RSSI sample size */
	if (!tb
	    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]) {
		hdd_err("attr RSSI sample size failed");
		goto fail;
	}
	pReqMsg->rssiSampleSize =
		nla_get_u32(tb
		    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
	hdd_debug("RSSI sample size %u", pReqMsg->rssiSampleSize);

	/* Parse and fetch lost AP sample size */
	if (!tb
	    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]) {
		hdd_err("attr lost AP sample size failed");
		goto fail;
	}
	pReqMsg->lostApSampleSize =
		nla_get_u32(tb
		    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
	hdd_debug("Lost AP sample size %u", pReqMsg->lostApSampleSize);

	/* Parse and fetch AP min breacing */
	if (!tb
	    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
		hdd_err("attr AP min breaching");
		goto fail;
	}
	pReqMsg->minBreaching =
		nla_get_u32(tb
		    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
	hdd_debug("AP min breaching %u", pReqMsg->minBreaching);

	/* Parse and fetch number of APs */
	if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
		hdd_err("attr number of AP failed");
		goto fail;
	}
	pReqMsg->numAp =
		nla_get_u32(tb
		    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
	if (pReqMsg->numAp > WLAN_EXTSCAN_MAX_SIGNIFICANT_CHANGE_APS) {
		hdd_err("Number of AP %u exceeds max %u",
			pReqMsg->numAp,
			WLAN_EXTSCAN_MAX_SIGNIFICANT_CHANGE_APS);
		goto fail;
	}

	pReqMsg->sessionId = adapter->session_id;
	hdd_debug("Number of AP %d Session Id %d",
		pReqMsg->numAp, pReqMsg->sessionId);

	if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM]) {
		hdd_err("attr ap threshold failed");
		goto fail;
	}
	i = 0;
	nla_for_each_nested(apTh,
			    tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM],
			    rem) {

		if (i == pReqMsg->numAp) {
			hdd_warn("Ignoring excess AP");
			break;
		}

		if (wlan_cfg80211_nla_parse(tb2,
			   QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
			   nla_data(apTh), nla_len(apTh),
			   wlan_hdd_extscan_config_policy)) {
			hdd_err("nla_parse failed");
			goto fail;
		}

		/* Parse and fetch MAC address */
		if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
			hdd_err("attr mac address failed");
			goto fail;
		}
		nla_memcpy(pReqMsg->ap[i].bssid.bytes,
			   tb2
			   [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID],
			   QDF_MAC_ADDR_SIZE);
		hdd_debug(MAC_ADDRESS_STR,
		       MAC_ADDR_ARRAY(pReqMsg->ap[i].bssid.bytes));

		/* Parse and fetch low RSSI */
		if (!tb2
		    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
			hdd_err("attr low RSSI failed");
			goto fail;
		}
		pReqMsg->ap[i].low =
			nla_get_s32(tb2
			    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
		hdd_debug("RSSI low %d", pReqMsg->ap[i].low);

		/* Parse and fetch high RSSI */
		if (!tb2
		    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
			hdd_err("attr high RSSI failed");
			goto fail;
		}
		pReqMsg->ap[i].high =
			nla_get_s32(tb2
			    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
		hdd_debug("RSSI High %d", pReqMsg->ap[i].high);

		i++;
	}
	if (i < pReqMsg->numAp) {
		hdd_warn("Number of AP %u less than expected %u",
			 i, pReqMsg->numAp);
		pReqMsg->numAp = i;
	}

	context = &ext_scan_context;
	spin_lock(&context->context_lock);
	INIT_COMPLETION(context->response_event);
	context->request_id = request_id = pReqMsg->requestId;
	spin_unlock(&context->context_lock);

	status = sme_set_significant_change(hdd_ctx->hHal, pReqMsg);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		hdd_err("sme_set_significant_change failed(err=%d)", status);
		qdf_mem_free(pReqMsg);
		return -EINVAL;
	}

	/* request was sent -- wait for the response */
	rc = wait_for_completion_timeout(&context->response_event,
				 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));

	if (!rc) {
		hdd_err("sme_set_significant_change timed out");
		retval = -ETIMEDOUT;
	} else {
		spin_lock(&context->context_lock);
		if (context->request_id == request_id)
			retval = context->response_status;
		else
			retval = -EINVAL;
		spin_unlock(&context->context_lock);
	}
	EXIT();
	return retval;

fail:
	qdf_mem_free(pReqMsg);
	return -EINVAL;
}

/**
 * wlan_hdd_cfg80211_extscan_set_significant_change() - set significant change
 * @wiphy: Pointer to wireless phy
 * @wdev: Pointer to wireless device
 * @data: Pointer to data
 * @data_len: Data length
 *
 * Return: 0 on success, negative errno on failure
 */
int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
				struct wireless_dev *wdev,
				const void *data, int data_len)
{
	int ret = 0;

	cds_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_extscan_set_significant_change(wiphy, wdev,
					data, data_len);
	cds_ssr_unprotect(__func__);

	return ret;
}

/**
 * hdd_remove_dsrc_channels () - remove dsrc chanels
 * @hdd_ctx: hdd context
 * @wiphy: Pointer to wireless phy
 * @chan_list: channel list
 * @num_channels: number of channels
 *
 * Return: none
 */
static void hdd_remove_dsrc_channels(struct hdd_context *hdd_ctx,
				     struct wiphy *wiphy, uint32_t *chan_list,
				     uint8_t *num_channels)
{
	uint8_t num_chan_temp = 0;
	int i;

	for (i = 0; i < *num_channels; i++) {
		if (!WLAN_REG_IS_11P_CH(wlan_reg_freq_to_chan(hdd_ctx->hdd_pdev,
							      chan_list[i]))) {
			chan_list[num_chan_temp] = chan_list[i];
			num_chan_temp++;
		}
	}
	*num_channels = num_chan_temp;
}

/**
 * hdd_remove_passive_channels () - remove passive channels
 * @wiphy: Pointer to wireless phy
 * @chan_list: channel list
 * @num_channels: number of channels
 *
 * Return: none
 */
static void hdd_remove_passive_channels(struct wiphy *wiphy,
					uint32_t *chan_list,
					uint8_t *num_channels)
{
	uint8_t num_chan_temp = 0;
	int i, j, k;

	for (i = 0; i < *num_channels; i++)
		for (j = 0; j < HDD_NUM_NL80211_BANDS; j++) {
			if (wiphy->bands[j] == NULL)
				continue;
			for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
				if ((chan_list[i] ==
				     wiphy->bands[j]->channels[k].center_freq)
				    && (!(wiphy->bands[j]->channels[k].flags &
				       IEEE80211_CHAN_PASSIVE_SCAN))
				) {
					chan_list[num_chan_temp] = chan_list[i];
					num_chan_temp++;
				}
			}
		}

	*num_channels = num_chan_temp;
}

/**
 * __wlan_hdd_cfg80211_extscan_get_valid_channels () - get valid channels
 * @wiphy: Pointer to wireless phy
 * @wdev: Pointer to wireless device
 * @data: Pointer to data
 * @data_len: Data length
 *
 * Return: none
 */
static int
__wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
						 struct wireless_dev
						 *wdev, const void *data,
						 int data_len)
{
	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
	struct net_device *dev = wdev->netdev;
	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
	uint8_t num_channels  = 0, i, buf[256] = {0};
	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX +
			  1];
	uint32_t requestId, maxChannels;
	tWifiBand wifiBand;
	QDF_STATUS status;
	struct sk_buff *reply_skb;
	int ret, len = 0;

	/* ENTER_DEV() intentionally not used in a frequently invoked API */

	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
		hdd_err("Command not allowed in FTM mode");
		return -EPERM;
	}

	ret = wlan_hdd_validate_context(hdd_ctx);
	if (0 != ret)
		return -EINVAL;

	if (!hdd_ctx->config->extscan_enabled) {
		hdd_err("extscan not supported");
		return -ENOTSUPP;
	}
	if (wlan_cfg80211_nla_parse(tb,
			   QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
			   data, data_len, wlan_hdd_extscan_config_policy)) {
		hdd_err("Invalid ATTR");
		return -EINVAL;
	}

	/* Parse and fetch request Id */
	if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
		hdd_err("attr request id failed");
		return -EINVAL;
	}
	requestId =
		nla_get_u32(tb
		 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);

	/* Parse and fetch wifi band */
	if (!tb
	    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]) {
		hdd_err("attr wifi band failed");
		return -EINVAL;
	}
	wifiBand =
		nla_get_u32(tb
		    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);

	if (!tb
	    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]) {
		hdd_err("attr max channels failed");
		return -EINVAL;
	}
	maxChannels =
		nla_get_u32(tb
		    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);

	if (maxChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN) {
		hdd_err("Max channels %d exceeded Valid channel list len %d",
			maxChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
		return -EINVAL;
	}

	hdd_debug("Req Id: %u Wifi band: %d Max channels: %d", requestId,
		    wifiBand, maxChannels);
	status = sme_get_valid_channels_by_band((tHalHandle) (hdd_ctx->hHal),
						wifiBand, chan_list,
						&num_channels);
	if (QDF_STATUS_SUCCESS != status) {
		hdd_err("sme_get_valid_channels_by_band failed (err=%d)",
		       status);
		return -EINVAL;
	}

	num_channels = QDF_MIN(num_channels, maxChannels);

	hdd_remove_dsrc_channels(hdd_ctx, wiphy, chan_list, &num_channels);
	if ((QDF_SAP_MODE == adapter->device_mode) ||
	    !strncmp(hdd_get_fwpath(), "ap", 2))
		hdd_remove_passive_channels(wiphy, chan_list,
					    &num_channels);

	hdd_debug("Number of channels: %d", num_channels);
	for (i = 0; i < num_channels; i++)
		len += scnprintf(buf + len, sizeof(buf) - len,
				 "%u ", chan_list[i]);

	hdd_debug("Channels: %s", buf);

	reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
							sizeof(u32) *
							num_channels +
							NLMSG_HDRLEN);

	if (reply_skb) {
		if (nla_put_u32(reply_skb,
			QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
			num_channels) ||
		    nla_put(reply_skb,
			QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
			sizeof(u32) * num_channels, chan_list)) {
			hdd_err("nla put fail");
			kfree_skb(reply_skb);
			return -EINVAL;
		}
		ret = cfg80211_vendor_cmd_reply(reply_skb);
		return ret;
	}

	hdd_err("valid channels: buffer alloc fail");
	return -EINVAL;
}

/**
 * wlan_hdd_cfg80211_extscan_get_valid_channels() - get ext scan valid channels
 * @wiphy: Pointer to wireless phy
 * @wdev: Pointer to wireless device
 * @data: Pointer to data
 * @data_len: Data length
 *
 * Return: 0 on success, negative errno on failure
 */
int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
					struct wireless_dev *wdev,
					const void *data, int data_len)
{
	int ret = 0;

	cds_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
			data_len);
	cds_ssr_unprotect(__func__);

	return ret;
}

/**
 * hdd_extscan_update_dwell_time_limits() - update dwell times
 * @req_msg: Pointer to request message
 * @bkt_idx: Index of current bucket being processed
 * @active_min: minimum active dwell time
 * @active_max: maximum active dwell time
 * @passive_min: minimum passive dwell time
 * @passive_max: maximum passive dwell time
 *
 * Return: none
 */
static void hdd_extscan_update_dwell_time_limits(
			tpSirWifiScanCmdReqParams req_msg, uint32_t bkt_idx,
			uint32_t active_min, uint32_t active_max,
			uint32_t passive_min, uint32_t passive_max)
{
	/* update per-bucket dwell times */
	if (req_msg->buckets[bkt_idx].min_dwell_time_active >
			active_min) {
		req_msg->buckets[bkt_idx].min_dwell_time_active =
			active_min;
	}
	if (req_msg->buckets[bkt_idx].max_dwell_time_active <
			active_max) {
		req_msg->buckets[bkt_idx].max_dwell_time_active =
			active_max;
	}
	if (req_msg->buckets[bkt_idx].min_dwell_time_passive >
			passive_min) {
		req_msg->buckets[bkt_idx].min_dwell_time_passive =
			passive_min;
	}
	if (req_msg->buckets[bkt_idx].max_dwell_time_passive <
			passive_max) {
		req_msg->buckets[bkt_idx].max_dwell_time_passive =
			passive_max;
	}
	/* update dwell-time across all buckets */
	if (req_msg->min_dwell_time_active >
			req_msg->buckets[bkt_idx].min_dwell_time_active) {
		req_msg->min_dwell_time_active =
			req_msg->buckets[bkt_idx].min_dwell_time_active;
	}
	if (req_msg->max_dwell_time_active <
			req_msg->buckets[bkt_idx].max_dwell_time_active) {
		req_msg->max_dwell_time_active =
			req_msg->buckets[bkt_idx].max_dwell_time_active;
	}
	if (req_msg->min_dwell_time_passive >
			req_msg->buckets[bkt_idx].min_dwell_time_passive) {
		req_msg->min_dwell_time_passive =
			req_msg->buckets[bkt_idx].min_dwell_time_passive;
	}
	if (req_msg->max_dwell_time_passive >
			req_msg->buckets[bkt_idx].max_dwell_time_passive) {
		req_msg->max_dwell_time_passive =
			req_msg->buckets[bkt_idx].max_dwell_time_passive;
	}
}

/**
 * hdd_extscan_channel_max_reached() - channel max reached
 * @req: extscan request structure
 * @total_channels: total number of channels
 *
 * Return: true if total channels reached max, false otherwise
 */
static bool hdd_extscan_channel_max_reached(tSirWifiScanCmdReqParams *req,
					    uint8_t total_channels)
{
	if (total_channels == WLAN_EXTSCAN_MAX_CHANNELS) {
		hdd_warn(
		   "max #of channels %d reached, take only first %d bucket(s)",
		   total_channels, req->numBuckets);
		return true;
	}
	return false;
}

/**
 * hdd_extscan_start_fill_bucket_channel_spec() - fill bucket channel spec
 * @hdd_ctx: HDD global context
 * @req_msg: Pointer to request structure
 * @tb: pointer to NL attributes
 *
 * Return: 0 on success; error number otherwise
 */
static int hdd_extscan_start_fill_bucket_channel_spec(
			struct hdd_context *hdd_ctx,
			tpSirWifiScanCmdReqParams req_msg,
			struct nlattr **tb)
{
	struct nlattr *bucket[
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
	struct nlattr *channel[
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
	struct nlattr *buckets;
	struct nlattr *channels;
	int rem1, rem2;
	QDF_STATUS status;
	uint8_t bkt_index, j, num_channels, total_channels = 0;
	uint32_t expected_buckets;
	uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};

	uint32_t min_dwell_time_active_bucket =
		hdd_ctx->config->extscan_active_max_chn_time;
	uint32_t max_dwell_time_active_bucket =
		hdd_ctx->config->extscan_active_max_chn_time;
	uint32_t min_dwell_time_passive_bucket =
		hdd_ctx->config->extscan_passive_max_chn_time;
	uint32_t max_dwell_time_passive_bucket =
		hdd_ctx->config->extscan_passive_max_chn_time;

	req_msg->min_dwell_time_active =
		req_msg->max_dwell_time_active =
			hdd_ctx->config->extscan_active_max_chn_time;

	req_msg->min_dwell_time_passive =
		req_msg->max_dwell_time_passive =
			hdd_ctx->config->extscan_passive_max_chn_time;

	expected_buckets = req_msg->numBuckets;
	req_msg->numBuckets = 0;
	bkt_index = 0;

	nla_for_each_nested(buckets,
			tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {

		if (bkt_index >= expected_buckets) {
			hdd_warn("ignoring excess buckets");
			break;
		}

		if (wlan_cfg80211_nla_parse(bucket,
			   QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
			   nla_data(buckets), nla_len(buckets),
			   wlan_hdd_extscan_config_policy)) {
			hdd_err("nla_parse failed");
			return -EINVAL;
		}

		/* Parse and fetch bucket spec */
		if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
			hdd_err("attr bucket index failed");
			return -EINVAL;
		}
		req_msg->buckets[bkt_index].bucket = nla_get_u8(
			bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);

		/* Parse and fetch wifi band */
		if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
			hdd_err("attr wifi band failed");
			return -EINVAL;
		}
		req_msg->buckets[bkt_index].band = nla_get_u8(
			bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);

		/* Parse and fetch period */
		if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
			hdd_err("attr period failed");
			return -EINVAL;
		}
		req_msg->buckets[bkt_index].period = nla_get_u32(
		bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);

		/* Parse and fetch report events */
		if (!bucket[
			QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
			hdd_err("attr report events failed");
			return -EINVAL;
		}
		req_msg->buckets[bkt_index].reportEvents = nla_get_u8(
			bucket[
			QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);

		/* Parse and fetch max period */
		if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
			hdd_err("attr max period failed");
			return -EINVAL;
		}
		req_msg->buckets[bkt_index].max_period = nla_get_u32(
			bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);

		/* Parse and fetch base */
		if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BASE]) {
			hdd_err("attr base failed");
			return -EINVAL;
		}
		req_msg->buckets[bkt_index].exponent = nla_get_u32(
			bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BASE]);

		/* Parse and fetch step count */
		if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
			hdd_err("attr step count failed");
			return -EINVAL;
		}
		req_msg->buckets[bkt_index].step_count = nla_get_u32(
			bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
		hdd_debug("Bucket spec Index: %d Wifi band: %d period: %d report events: %d max period: %u base: %u Step count: %u",
				req_msg->buckets[bkt_index].bucket,
				req_msg->buckets[bkt_index].band,
				req_msg->buckets[bkt_index].period,
				req_msg->buckets[bkt_index].reportEvents,
				req_msg->buckets[bkt_index].max_period,
				req_msg->buckets[bkt_index].exponent,
				req_msg->buckets[bkt_index].step_count);

		/* start with known good values for bucket dwell times */
		req_msg->buckets[bkt_index].min_dwell_time_active =
		req_msg->buckets[bkt_index].max_dwell_time_active =
			hdd_ctx->config->extscan_active_max_chn_time;

		req_msg->buckets[bkt_index].min_dwell_time_passive =
		req_msg->buckets[bkt_index].max_dwell_time_passive =
			hdd_ctx->config->extscan_passive_max_chn_time;

		/* Framework shall pass the channel list if the input WiFi band
		 * is WIFI_BAND_UNSPECIFIED.
		 * If the input WiFi band is specified (any value other than
		 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
		 */
		if (req_msg->buckets[bkt_index].band != WIFI_BAND_UNSPECIFIED) {
			if (hdd_extscan_channel_max_reached(req_msg,
							    total_channels))
				return 0;

			num_channels = 0;
			hdd_debug("WiFi band is specified, driver to fill channel list");
			status = sme_get_valid_channels_by_band(hdd_ctx->hHal,
						req_msg->buckets[bkt_index].band,
						chan_list, &num_channels);
			if (!QDF_IS_STATUS_SUCCESS(status)) {
				hdd_err("sme_GetValidChannelsByBand failed (err=%d)",
				       status);
				return -EINVAL;
			}
			hdd_debug("before trimming, num_channels: %d",
				num_channels);

			req_msg->buckets[bkt_index].numChannels =
				QDF_MIN(num_channels,
					(WLAN_EXTSCAN_MAX_CHANNELS -
						total_channels));
			hdd_debug("Adj Num channels/bucket: %d total_channels: %d",
				req_msg->buckets[bkt_index].numChannels,
				total_channels);
			total_channels +=
				req_msg->buckets[bkt_index].numChannels;

			for (j = 0; j < req_msg->buckets[bkt_index].numChannels;
				j++) {
				req_msg->buckets[bkt_index].channels[j].channel =
							chan_list[j];
				req_msg->buckets[bkt_index].channels[j].
							chnlClass = 0;
				if ((wlan_reg_get_channel_state(
					hdd_ctx->hdd_pdev,
					cds_freq_to_chan(chan_list[j]))) !=
						CHANNEL_STATE_ENABLE) {
					req_msg->buckets[bkt_index].channels[j].
								passive = 1;
					req_msg->buckets[bkt_index].channels[j].
					dwellTimeMs =
						hdd_ctx->config->
						extscan_passive_max_chn_time;
					/* reconfigure per-bucket dwell time */
					if (min_dwell_time_passive_bucket >
							req_msg->buckets[bkt_index].channels[j].dwellTimeMs) {
						min_dwell_time_passive_bucket =
							req_msg->buckets[bkt_index].channels[j].dwellTimeMs;
					}
					if (max_dwell_time_passive_bucket <
							req_msg->buckets[bkt_index].channels[j].dwellTimeMs) {
						max_dwell_time_passive_bucket =
							req_msg->buckets[bkt_index].channels[j].dwellTimeMs;
					}

				} else {
					req_msg->buckets[bkt_index].channels[j].
							passive = 0;
					req_msg->buckets[bkt_index].channels[j].
					dwellTimeMs =
						hdd_ctx->config->extscan_active_max_chn_time;
					/* reconfigure per-bucket dwell times */
					if (min_dwell_time_active_bucket >
							req_msg->buckets[bkt_index].channels[j].dwellTimeMs) {
						min_dwell_time_active_bucket =
							req_msg->buckets[bkt_index].channels[j].dwellTimeMs;
					}
					if (max_dwell_time_active_bucket <
							req_msg->buckets[bkt_index].channels[j].dwellTimeMs) {
						max_dwell_time_active_bucket =
							req_msg->buckets[bkt_index].channels[j].dwellTimeMs;
					}

				}

				hdd_debug("Channel: %u Passive: %u Dwell time: %u ms Class: %u",
					req_msg->buckets[bkt_index].channels[j].channel,
					req_msg->buckets[bkt_index].channels[j].passive,
					req_msg->buckets[bkt_index].channels[j].dwellTimeMs,
					req_msg->buckets[bkt_index].channels[j].chnlClass);
			}

			hdd_extscan_update_dwell_time_limits(
					req_msg, bkt_index,
					min_dwell_time_active_bucket,
					max_dwell_time_active_bucket,
					min_dwell_time_passive_bucket,
					max_dwell_time_passive_bucket);

			hdd_debug("bkt_index:%d actv_min:%d actv_max:%d pass_min:%d pass_max:%d",
					bkt_index,
					req_msg->buckets[bkt_index].min_dwell_time_active,
					req_msg->buckets[bkt_index].max_dwell_time_active,
					req_msg->buckets[bkt_index].min_dwell_time_passive,
					req_msg->buckets[bkt_index].max_dwell_time_passive);

			bkt_index++;
			req_msg->numBuckets++;
			continue;
		}

		/* Parse and fetch number of channels */
		if (!bucket[
			QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
			hdd_err("attr num channels failed");
			return -EINVAL;
		}
		req_msg->buckets[bkt_index].numChannels =
		nla_get_u32(bucket[
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
		hdd_debug("before trimming: num channels %d",
			req_msg->buckets[bkt_index].numChannels);

		req_msg->buckets[bkt_index].numChannels =
			QDF_MIN(req_msg->buckets[bkt_index].numChannels,
				(WLAN_EXTSCAN_MAX_CHANNELS - total_channels));
		hdd_debug("Num channels/bucket: %d total_channels: %d",
			req_msg->buckets[bkt_index].numChannels,
			total_channels);
		if (hdd_extscan_channel_max_reached(req_msg, total_channels))
			return 0;

		if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
			hdd_err("attr channel spec failed");
			return -EINVAL;
		}

		j = 0;
		nla_for_each_nested(channels,
			bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
			if ((j >= req_msg->buckets[bkt_index].numChannels) ||
			    hdd_extscan_channel_max_reached(req_msg,
							    total_channels))
				break;

			if (wlan_cfg80211_nla_parse(channel,
			   QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
			   nla_data(channels), nla_len(channels),
			   wlan_hdd_extscan_config_policy)) {
				hdd_err("nla_parse failed");
				return -EINVAL;
			}

			/* Parse and fetch channel */
			if (!channel[
				QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
				hdd_err("attr channel failed");
				return -EINVAL;
			}
			req_msg->buckets[bkt_index].channels[j].channel =
				nla_get_u32(channel[
				QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
			hdd_debug("channel %u",
				req_msg->buckets[bkt_index].channels[j].channel);

			/* Parse and fetch dwell time */
			if (!channel[
				QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
				hdd_err("attr dwelltime failed");
				return -EINVAL;
			}
			req_msg->buckets[bkt_index].channels[j].dwellTimeMs =
				nla_get_u32(channel[
				QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);

			/* Override dwell time if required */
			if (req_msg->buckets[bkt_index].channels[j].dwellTimeMs <
				hdd_ctx->config->extscan_active_min_chn_time ||
				req_msg->buckets[bkt_index].channels[j].dwellTimeMs >
				hdd_ctx->config->extscan_active_max_chn_time) {
				hdd_debug("WiFi band is unspecified, dwellTime:%d",
						req_msg->buckets[bkt_index].channels[j].dwellTimeMs);

				if ((wlan_reg_get_channel_state(
					hdd_ctx->hdd_pdev,
					cds_freq_to_chan(
					req_msg->buckets[bkt_index].
					channels[j].channel)))
						!= CHANNEL_STATE_ENABLE) {
					req_msg->buckets[bkt_index].channels[j].dwellTimeMs =
						hdd_ctx->config->extscan_passive_max_chn_time;
				} else {
					req_msg->buckets[bkt_index].channels[j].dwellTimeMs =
						hdd_ctx->config->extscan_active_max_chn_time;
				}
			}

			hdd_debug("New Dwell time %u ms",
				req_msg->buckets[bkt_index].channels[j].dwellTimeMs);

			if ((wlan_reg_get_channel_state(hdd_ctx->hdd_pdev,
					cds_freq_to_chan(
					req_msg->buckets[bkt_index].
					channels[j].channel)))
					!= CHANNEL_STATE_ENABLE) {
				if (min_dwell_time_passive_bucket >
						req_msg->buckets[bkt_index].channels[j].dwellTimeMs) {
					min_dwell_time_passive_bucket =
						req_msg->buckets[bkt_index].channels[j].dwellTimeMs;
				}
				if (max_dwell_time_passive_bucket <
						req_msg->buckets[bkt_index].channels[j].dwellTimeMs) {
					max_dwell_time_passive_bucket =
						req_msg->buckets[bkt_index].channels[j].dwellTimeMs;
				}
			} else {
				if (min_dwell_time_active_bucket >
						req_msg->buckets[bkt_index].channels[j].dwellTimeMs) {
					min_dwell_time_active_bucket =
						req_msg->buckets[bkt_index].channels[j].dwellTimeMs;
				}
				if (max_dwell_time_active_bucket <
						req_msg->buckets[bkt_index].channels[j].dwellTimeMs) {
					max_dwell_time_active_bucket =
						req_msg->buckets[bkt_index].channels[j].dwellTimeMs;
				}
			}

			/* Parse and fetch channel spec passive */
			if (!channel[
				QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
				hdd_err("attr channel spec passive failed");
				return -EINVAL;
			}
			req_msg->buckets[bkt_index].channels[j].passive =
				nla_get_u8(channel[
				QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
			hdd_debug("Chnl spec passive %u",
				req_msg->buckets[bkt_index].channels[j].passive);
			/* Override scan type if required */
			if ((wlan_reg_get_channel_state(hdd_ctx->hdd_pdev,
					cds_freq_to_chan(
					req_msg->buckets[bkt_index].
					channels[j].channel)))
					!= CHANNEL_STATE_ENABLE) {
				req_msg->buckets[bkt_index].channels[j].passive = true;
			} else {
				req_msg->buckets[bkt_index].channels[j].passive = false;
			}
			j++;
			total_channels++;
		}

		hdd_extscan_update_dwell_time_limits(
					req_msg, bkt_index,
					min_dwell_time_active_bucket,
					max_dwell_time_active_bucket,
					min_dwell_time_passive_bucket,
					max_dwell_time_passive_bucket);

		hdd_debug("bktIndex:%d actv_min:%d actv_max:%d pass_min:%d pass_max:%d",
				bkt_index,
				req_msg->buckets[bkt_index].min_dwell_time_active,
				req_msg->buckets[bkt_index].max_dwell_time_active,
				req_msg->buckets[bkt_index].min_dwell_time_passive,
				req_msg->buckets[bkt_index].max_dwell_time_passive);

		bkt_index++;
		req_msg->numBuckets++;
	}

	hdd_debug("Global: actv_min:%d actv_max:%d pass_min:%d pass_max:%d",
				req_msg->min_dwell_time_active,
				req_msg->max_dwell_time_active,
				req_msg->min_dwell_time_passive,
				req_msg->max_dwell_time_passive);
	return 0;
}

/*
 * hdd_extscan_map_usr_drv_config_flags() - map userspace to driver config flags
 * @config_flags - [input] configuration flags.
 *
 * This function maps user space received configuration flags to
 * driver representation.
 *
 * Return: configuration flags
 */
static uint32_t hdd_extscan_map_usr_drv_config_flags(uint32_t config_flags)
{
	uint32_t configuration_flags = 0;

	if (config_flags & EXTSCAN_LP_EXTENDED_BATCHING)
		configuration_flags |= EXTSCAN_LP_EXTENDED_BATCHING;

	return configuration_flags;
}

/*
 * define short names for the global vendor params
 * used by __wlan_hdd_cfg80211_extscan_start()
 */
#define PARAM_MAX \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
#define PARAM_REQUEST_ID \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
#define PARAM_BASE_PERIOD \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
#define PARAM_MAX_AP_PER_SCAN \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
#define PARAM_RPT_THRHLD_PERCENT \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
#define PARAM_RPT_THRHLD_NUM_SCANS \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
#define PARAM_NUM_BUCKETS \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
#define PARAM_CONFIG_FLAGS \
	QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS

/**
 * __wlan_hdd_cfg80211_extscan_start() - ext scan start
 * @wiphy: Pointer to wireless phy
 * @wdev: Pointer to wireless device
 * @data: Pointer to data
 * @data_len: Length of @data
 *
 * Return: 0 on success; error number otherwise
 */
static int
__wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
				    struct wireless_dev *wdev,
				    const void *data,
				    int data_len)
{
	tpSirWifiScanCmdReqParams pReqMsg       = NULL;
	struct net_device *dev                  = wdev->netdev;
	struct hdd_adapter *adapter                 = WLAN_HDD_GET_PRIV_PTR(dev);
	struct hdd_context *hdd_ctx             = wiphy_priv(wiphy);
	struct nlattr *tb[PARAM_MAX + 1];
	struct hdd_ext_scan_context *context;
	uint32_t request_id, num_buckets;
	QDF_STATUS status;
	int retval;
	unsigned long rc;

	ENTER_DEV(dev);

	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
		hdd_err("Command not allowed in FTM mode");
		return -EPERM;
	}

	if (QDF_NDI_MODE == adapter->device_mode) {
		hdd_err("Command not allowed for NDI interface");
		return -EPERM;
	}

	retval = wlan_hdd_validate_context(hdd_ctx);
	if (0 != retval)
		return -EINVAL;

	if (!hdd_ctx->config->extscan_enabled) {
		hdd_err("extscan not supported");
		return -ENOTSUPP;
	}
	if (wlan_cfg80211_nla_parse(tb, PARAM_MAX, data, data_len,
				    wlan_hdd_extscan_config_policy)) {
		hdd_err("Invalid ATTR");
		return -EINVAL;
	}

	pReqMsg = qdf_mem_malloc(sizeof(*pReqMsg));
	if (!pReqMsg) {
		hdd_err("memory allocation failed");
		return -ENOMEM;
	}

	/* Parse and fetch request Id */
	if (!tb[PARAM_REQUEST_ID]) {
		hdd_err("attr request id failed");
		goto fail;
	}

	pReqMsg->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
	pReqMsg->sessionId = adapter->session_id;

	/* Parse and fetch base period */
	if (!tb[PARAM_BASE_PERIOD]) {
		hdd_err("attr base period failed");
		goto fail;
	}
	pReqMsg->basePeriod = nla_get_u32(tb[PARAM_BASE_PERIOD]);

	/* Parse and fetch max AP per scan */
	if (!tb[PARAM_MAX_AP_PER_SCAN]) {
		hdd_err("attr max_ap_per_scan failed");
		goto fail;
	}
	pReqMsg->maxAPperScan = nla_get_u32(tb[PARAM_MAX_AP_PER_SCAN]);

	/* Parse and fetch report threshold percent */
	if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
		hdd_err("attr report_threshold percent failed");
		goto fail;
	}
	pReqMsg->report_threshold_percent = nla_get_u8(tb[PARAM_RPT_THRHLD_PERCENT]);

	/* Parse and fetch report threshold num scans */
	if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
		hdd_err("attr report_threshold num scans failed");
		goto fail;
	}
	pReqMsg->report_threshold_num_scans = nla_get_u8(tb[PARAM_RPT_THRHLD_NUM_SCANS]);
	hdd_debug("Req Id: %d Session Id: %d Base Period: %d Max AP per Scan: %d Report Threshold percent: %d Report Threshold num scans: %d",
		pReqMsg->requestId, pReqMsg->sessionId,
		pReqMsg->basePeriod, pReqMsg->maxAPperScan,
		pReqMsg->report_threshold_percent,
		pReqMsg->report_threshold_num_scans);

	/* Parse and fetch number of buckets */
	if (!tb[PARAM_NUM_BUCKETS]) {
		hdd_err("attr number of buckets failed");
		goto fail;
	}
	num_buckets = nla_get_u8(tb[PARAM_NUM_BUCKETS]);
	if (num_buckets > WLAN_EXTSCAN_MAX_BUCKETS) {
		hdd_warn("Exceeded MAX number of buckets: %d",
				WLAN_EXTSCAN_MAX_BUCKETS);
		num_buckets = WLAN_EXTSCAN_MAX_BUCKETS;
	}
	hdd_debug("Input: Number of Buckets %d", num_buckets);
	pReqMsg->numBuckets = num_buckets;

	/* This is optional attribute, if not present set it to 0 */
	if (!tb[PARAM_CONFIG_FLAGS])
		pReqMsg->configuration_flags = 0;
	else
		pReqMsg->configuration_flags =
			hdd_extscan_map_usr_drv_config_flags(
				nla_get_u32(tb[PARAM_CONFIG_FLAGS]));

	pReqMsg->extscan_adaptive_dwell_mode =
		hdd_ctx->config->extscan_adaptive_dwell_mode;

	hdd_debug("Configuration flags: %u",
				pReqMsg->configuration_flags);

	if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
		hdd_err("attr bucket spec failed");
		goto fail;
	}

	if (hdd_extscan_start_fill_bucket_channel_spec(hdd_ctx, pReqMsg, tb))
		goto fail;

	context = &ext_scan_context;
	spin_lock(&context->context_lock);
	INIT_COMPLETION(context->response_event);
	context->request_id = request_id = pReqMsg->requestId;
	context->buckets_scanned = 0;
	spin_unlock(&context->context_lock);

	status = sme_ext_scan_start(hdd_ctx->hHal, pReqMsg);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		hdd_err("sme_ext_scan_start failed(err=%d)", status);
		goto fail;
	}

	hdd_ctx->ext_scan_start_since_boot = qdf_get_monotonic_boottime();
	hdd_debug("Timestamp since boot: %llu",
			hdd_ctx->ext_scan_start_since_boot);

	/* request was sent -- wait for the response */
	rc = wait_for_completion_timeout(&context->response_event,
				msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));

	if (!rc) {
		hdd_err("sme_ext_scan_start timed out");
		retval = -ETIMEDOUT;
	} else {
		spin_lock(&context->context_lock);
		if (context->request_id == request_id)
			retval = context->response_status;
		else
			retval = -EINVAL;
		spin_unlock(&context->context_lock);
	}
	EXIT();
	return retval;

fail:
	qdf_mem_free(pReqMsg);
	return -EINVAL;
}
/*
 * done with short names for the global vendor params
 * used by __wlan_hdd_cfg80211_extscan_start()
 */
#undef PARAM_MAX
#undef PARAM_REQUEST_ID
#undef PARAM_BASE_PERIOD
#undef PARAMS_MAX_AP_PER_SCAN
#undef PARAMS_RPT_THRHLD_PERCENT
#undef PARAMS_RPT_THRHLD_NUM_SCANS
#undef PARAMS_NUM_BUCKETS
#undef PARAM_CONFIG_FLAGS

/**
 * wlan_hdd_cfg80211_extscan_start() - start extscan
 * @wiphy: Pointer to wireless phy.
 * @wdev: Pointer to wireless device.
 * @data: Pointer to input data.
 * @data_len: Length of @data.
 *
 * Return: 0 on success, negative errno on failure
 */
int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
					struct wireless_dev *wdev,
					const void *data, int data_len)
{
	int ret = 0;

	cds_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, data_len);
	cds_ssr_unprotect(__func__);

	return ret;
}


/*
 * define short names for the global vendor params
 * used by __wlan_hdd_cfg80211_extscan_stop()
 */
#define PARAM_MAX \
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
#define PARAM_REQUEST_ID \
		QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID

/**
 * __wlan_hdd_cfg80211_extscan_stop() - ext scan stop
 * @wiphy: Pointer to wireless phy
 * @wdev: Pointer to wireless device
 * @data: Pointer to data
 * @data_len: Data length
 *
 * Return: none
 */
static int
__wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
				   struct wireless_dev *wdev,
				   const void *data, int data_len)
{
	tpSirExtScanStopReqParams pReqMsg = NULL;
	struct net_device *dev = wdev->netdev;
	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
	struct nlattr *tb[PARAM_MAX + 1];
	struct hdd_ext_scan_context *context;
	QDF_STATUS status;
	uint32_t request_id;
	int retval;
	unsigned long rc;

	ENTER_DEV(dev);

	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
		hdd_err("Command not allowed in FTM mode");
		return -EPERM;
	}

	retval = wlan_hdd_validate_context(hdd_ctx);
	if (0 != retval)
		return -EINVAL;

	if (!hdd_ctx->config->extscan_enabled) {
		hdd_err("extscan not supported");
		return -ENOTSUPP;
	}
	if (wlan_cfg80211_nla_parse(tb, PARAM_MAX, data, data_len,
				    wlan_hdd_extscan_config_policy)) {
		hdd_err("Invalid ATTR");
		return -EINVAL;
	}

	pReqMsg = qdf_mem_malloc(sizeof(*pReqMsg));
	if (!pReqMsg) {
		hdd_err("qdf_mem_malloc failed");
		return -ENOMEM;
	}

	/* Parse and fetch request Id */
	if (!tb[PARAM_REQUEST_ID]) {
		hdd_err("attr request id failed");
		goto fail;
	}

	pReqMsg->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
	pReqMsg->sessionId = adapter->session_id;
	hdd_debug("Req Id %d Session Id %d",
		pReqMsg->requestId, pReqMsg->sessionId);

	context = &ext_scan_context;
	spin_lock(&context->context_lock);
	INIT_COMPLETION(context->response_event);
	context->request_id = request_id = pReqMsg->requestId;
	spin_unlock(&context->context_lock);

	status = sme_ext_scan_stop(hdd_ctx->hHal, pReqMsg);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		hdd_err("sme_ext_scan_stop failed(err=%d)", status);
		goto fail;
	}

	/* request was sent -- wait for the response */
	rc = wait_for_completion_timeout(&context->response_event,
				msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));

	if (!rc) {
		hdd_err("sme_ext_scan_stop timed out");
		retval = -ETIMEDOUT;
	} else {
		spin_lock(&context->context_lock);
		if (context->request_id == request_id)
			retval = context->response_status;
		else
			retval = -EINVAL;
		spin_unlock(&context->context_lock);
	}
	EXIT();
	return retval;

fail:
	qdf_mem_free(pReqMsg);
	return -EINVAL;
}
/*
 * done with short names for the global vendor params
 * used by wlan_hdd_cfg80211_extscan_stop()
 */
#undef PARAM_MAX
#undef PARAM_REQUEST_ID


/**
 * wlan_hdd_cfg80211_extscan_stop() - stop extscan
 * @wiphy: Pointer to wireless phy.
 * @wdev: Pointer to wireless device.
 * @data: Pointer to input data.
 * @data_len: Length of @data.
 *
 * Return: 0 on success, negative errno on failure
 */
int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
				struct wireless_dev *wdev,
				const void *data, int data_len)
{
	int ret = 0;

	cds_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, data_len);
	cds_ssr_unprotect(__func__);

	return ret;
}


/**
 * __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist() - reset bssid hotlist
 * @wiphy: Pointer to wireless phy
 * @wdev: Pointer to wireless device
 * @data: Pointer to data
 * @data_len: Data length
 *
 * Return: none
 */
static int
__wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
						  struct wireless_dev
						  *wdev, const void *data,
						  int data_len)
{
	tpSirExtScanResetBssidHotlistReqParams pReqMsg = NULL;
	struct net_device *dev = wdev->netdev;
	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX +
			  1];
	struct hdd_ext_scan_context *context;
	uint32_t request_id;
	QDF_STATUS status;
	int retval;
	unsigned long rc;

	ENTER_DEV(dev);

	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
		hdd_err("Command not allowed in FTM mode");
		return -EPERM;
	}

	retval = wlan_hdd_validate_context(hdd_ctx);
	if (0 != retval)
		return -EINVAL;

	if (!hdd_ctx->config->extscan_enabled) {
		hdd_err("extscan not supported");
		return -ENOTSUPP;
	}
	if (wlan_cfg80211_nla_parse(tb,
			   QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
			   data, data_len, wlan_hdd_extscan_config_policy)) {
		hdd_err("Invalid ATTR");
		return -EINVAL;
	}

	pReqMsg = qdf_mem_malloc(sizeof(*pReqMsg));
	if (!pReqMsg) {
		hdd_err("qdf_mem_malloc failed");
		return -ENOMEM;
	}

	/* Parse and fetch request Id */
	if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
		hdd_err("attr request id failed");
		goto fail;
	}

	pReqMsg->requestId =
		nla_get_u32(tb
		 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
	pReqMsg->sessionId = adapter->session_id;
	hdd_debug("Req Id %d Session Id %d",
		pReqMsg->requestId, pReqMsg->sessionId);

	context = &ext_scan_context;
	spin_lock(&context->context_lock);
	INIT_COMPLETION(context->response_event);
	context->request_id = request_id = pReqMsg->requestId;
	spin_unlock(&context->context_lock);

	status = sme_reset_bss_hotlist(hdd_ctx->hHal, pReqMsg);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		hdd_err("sme_reset_bss_hotlist failed(err=%d)", status);
		goto fail;
	}

	/* request was sent -- wait for the response */
	rc = wait_for_completion_timeout
		(&context->response_event,
		 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
	if (!rc) {
		hdd_err("sme_reset_bss_hotlist timed out");
		retval = -ETIMEDOUT;
	} else {
		spin_lock(&context->context_lock);
		if (context->request_id == request_id)
			retval = context->response_status;
		else
			retval = -EINVAL;
		spin_unlock(&context->context_lock);
	}
	EXIT();
	return retval;

fail:
	qdf_mem_free(pReqMsg);
	return -EINVAL;
}

/**
 * wlan_hdd_cfg80211_extscan_reset_bssid_hotlist() - reset bssid hot list
 * @wiphy: Pointer to wireless phy
 * @wdev: Pointer to wireless device
 * @data: Pointer to data
 * @data_len: Data length
 *
 * Return: 0 on success, negative errno on failure
 */
int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
					struct wireless_dev *wdev,
					const void *data, int data_len)
{
	int ret = 0;

	cds_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev,
								data, data_len);
	cds_ssr_unprotect(__func__);

	return ret;
}

/**
 * __wlan_hdd_cfg80211_extscan_reset_significant_change() -
 *		reset significant change
 * @wiphy: Pointer to wireless phy
 * @wdev: Pointer to wireless device
 * @data: Pointer to data
 * @data_len: Data length
 *
 * Return: none
 */
static int
__wlan_hdd_cfg80211_extscan_reset_significant_change(struct wiphy
						       *wiphy,
						       struct
						       wireless_dev
						       *wdev, const void *data,
						       int data_len)
{
	tpSirExtScanResetSignificantChangeReqParams pReqMsg = NULL;
	struct net_device *dev = wdev->netdev;
	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX +
			  1];
	struct hdd_ext_scan_context *context;
	uint32_t request_id;
	QDF_STATUS status;
	int retval;
	unsigned long rc;

	ENTER_DEV(dev);

	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
		hdd_err("Command not allowed in FTM mode");
		return -EPERM;
	}

	retval = wlan_hdd_validate_context(hdd_ctx);
	if (0 != retval)
		return -EINVAL;

	if (!hdd_ctx->config->extscan_enabled) {
		hdd_err("extscan not supported");
		return -ENOTSUPP;
	}

	if (wlan_cfg80211_nla_parse(tb,
			   QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
			   data, data_len, wlan_hdd_extscan_config_policy)) {
		hdd_err("Invalid ATTR");
		return -EINVAL;
	}

	pReqMsg = qdf_mem_malloc(sizeof(*pReqMsg));
	if (!pReqMsg) {
		hdd_err("qdf_mem_malloc failed");
		return -ENOMEM;
	}

	/* Parse and fetch request Id */
	if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
		hdd_err("attr request id failed");
		goto fail;
	}

	pReqMsg->requestId =
		nla_get_u32(tb
		 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
	pReqMsg->sessionId = adapter->session_id;
	hdd_debug("Req Id %d Session Id %d",
		pReqMsg->requestId, pReqMsg->sessionId);

	context = &ext_scan_context;
	spin_lock(&context->context_lock);
	INIT_COMPLETION(context->response_event);
	context->request_id = request_id = pReqMsg->requestId;
	spin_unlock(&context->context_lock);

	status = sme_reset_significant_change(hdd_ctx->hHal, pReqMsg);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		hdd_err("sme_reset_significant_change failed(err=%d)",
			status);
		qdf_mem_free(pReqMsg);
		return -EINVAL;
	}

	/* request was sent -- wait for the response */
	rc = wait_for_completion_timeout(&context->response_event,
				msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));

	if (!rc) {
		hdd_err("sme_ResetSignificantChange timed out");
		retval = -ETIMEDOUT;
	} else {
		spin_lock(&context->context_lock);
		if (context->request_id == request_id)
			retval = context->response_status;
		else
			retval = -EINVAL;
		spin_unlock(&context->context_lock);
	}
	EXIT();
	return retval;

fail:
	qdf_mem_free(pReqMsg);
	return -EINVAL;
}

/**
 * wlan_hdd_cfg80211_extscan_reset_significant_change() - reset significant
 *							change
 * @wiphy: Pointer to wireless phy
 * @wdev: Pointer to wireless device
 * @data: Pointer to data
 * @data_len: Data length
 *
 * Return: 0 on success, negative errno on failure
 */
int wlan_hdd_cfg80211_extscan_reset_significant_change(struct wiphy *wiphy,
						struct wireless_dev *wdev,
						const void *data, int data_len)
{
	int ret = 0;

	cds_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_extscan_reset_significant_change(wiphy, wdev,
						data, data_len);
	cds_ssr_unprotect(__func__);

	return ret;
}


/**
 * hdd_extscan_epno_fill_network_list() - epno fill network list
 * @hddctx: HDD context
 * @req_msg: request message
 * @tb: vendor attribute table
 *
 * This function reads the network block NL vendor attributes from %tb and
 * fill in the epno request message.
 *
 * Return: 0 on success, error number otherwise
 */
static int hdd_extscan_epno_fill_network_list(
			struct hdd_context *hddctx,
			struct wifi_epno_params *req_msg,
			struct nlattr **tb)
{
	struct nlattr *network[QCA_WLAN_VENDOR_ATTR_PNO_MAX + 1];
	struct nlattr *networks;
	int rem1, ssid_len;
	uint8_t index, *ssid;
	uint32_t expected_networks;

	expected_networks = req_msg->num_networks;
	index = 0;

	if (!tb[QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORKS_LIST]) {
		hdd_err("attr networks list failed");
		return -EINVAL;
	}
	nla_for_each_nested(networks,
			    tb[QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORKS_LIST],
			    rem1) {

		if (index == expected_networks) {
			hdd_warn("ignoring excess networks");
			break;
		}

		if (wlan_cfg80211_nla_parse(network,
					    QCA_WLAN_VENDOR_ATTR_PNO_MAX,
					    nla_data(networks),
					    nla_len(networks),
					    wlan_hdd_pno_config_policy)) {
			hdd_err("nla_parse failed");
			return -EINVAL;
		}

		/* Parse and fetch ssid */
		if (!network[QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_SSID]) {
			hdd_err("attr network ssid failed");
			return -EINVAL;
		}
		ssid_len = nla_len(
			network[QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_SSID]);

		/* nla_parse will detect overflow but not underflow */
		if (0 == ssid_len) {
			hdd_err("zero ssid length");
			return -EINVAL;
		}

		/* Decrement by 1, don't count null character */
		ssid_len--;

		req_msg->networks[index].ssid.length = ssid_len;
		hdd_debug("network ssid length %d", ssid_len);
		ssid = nla_data(network[QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_SSID]);
		qdf_mem_copy(req_msg->networks[index].ssid.ssId,
				ssid, ssid_len);
		hdd_debug("Ssid (%.*s)",
			req_msg->networks[index].ssid.length,
			req_msg->networks[index].ssid.ssId);

		/* Parse and fetch epno flags */
		if (!network[QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_FLAGS]) {
			hdd_err("attr epno flags failed");
			return -EINVAL;
		}
		req_msg->networks[index].flags = nla_get_u8(
			network[QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_FLAGS]);
		hdd_debug("flags %u", req_msg->networks[index].flags);

		/* Parse and fetch auth bit */
		if (!network[QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_AUTH_BIT]) {
			hdd_err("attr auth bit failed");
			return -EINVAL;
		}
		req_msg->networks[index].auth_bit_field = nla_get_u8(
			network[QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_AUTH_BIT]);
		hdd_debug("auth bit %u",
			req_msg->networks[index].auth_bit_field);

		index++;
	}
	req_msg->num_networks = index;
	return 0;
}

/**
 * __wlan_hdd_cfg80211_set_epno_list() - epno set network list
 * @wiphy: wiphy
 * @wdev: pointer to wireless dev
 * @data: data pointer
 * @data_len: data length
 *
 * This function reads the NL vendor attributes from %tb and
 * fill in the epno request message.
 *
 * Return: 0 on success, error number otherwise
 */
static int __wlan_hdd_cfg80211_set_epno_list(struct wiphy *wiphy,
					     struct wireless_dev *wdev,
					     const void *data,
					     int data_len)
{
	struct wifi_epno_params *req_msg = NULL;
	struct net_device *dev           = wdev->netdev;
	struct hdd_adapter *adapter           = WLAN_HDD_GET_PRIV_PTR(dev);
	struct hdd_context *hdd_ctx      = wiphy_priv(wiphy);
	struct nlattr *tb[
		QCA_WLAN_VENDOR_ATTR_PNO_MAX + 1];
	QDF_STATUS status;
	uint32_t num_networks, len;
	int ret_val;

	ENTER_DEV(dev);

	ret_val = wlan_hdd_validate_context(hdd_ctx);
	if (ret_val)
		return ret_val;

	if (!hdd_ctx->config->extscan_enabled) {
		hdd_err("extscan not supported");
		return -ENOTSUPP;
	}

	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
		hdd_err("Command not allowed in FTM mode");
		return -EPERM;
	}

	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_PNO_MAX, data,
				    data_len, wlan_hdd_pno_config_policy)) {
		hdd_err("Invalid ATTR");
		return -EINVAL;
	}

	/* Parse and fetch number of networks */
	if (!tb[QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_NUM_NETWORKS]) {
		hdd_err("attr num networks failed");
		return -EINVAL;
	}

	/*
	 * num_networks is also used as EPNO SET/RESET request.
	 * if num_networks is zero then it is treated as RESET.
	 */
	num_networks = nla_get_u32(
		tb[QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_NUM_NETWORKS]);

	if (num_networks > MAX_EPNO_NETWORKS) {
		hdd_debug("num of nw: %d exceeded max: %d, resetting to: %d",
			num_networks, MAX_EPNO_NETWORKS, MAX_EPNO_NETWORKS);
		num_networks = MAX_EPNO_NETWORKS;
	}

	hdd_debug("num networks %u", num_networks);
	len = sizeof(*req_msg) +
			(num_networks * sizeof(struct wifi_epno_network));

	req_msg = qdf_mem_malloc(len);
	if (!req_msg) {
		hdd_err("qdf_mem_malloc failed");
		return -ENOMEM;
	}
	req_msg->num_networks = num_networks;

	/* Parse and fetch request Id */
	if (!tb[QCA_WLAN_VENDOR_ATTR_PNO_CONFIG_REQUEST_ID]) {
		hdd_err("attr request id failed");
		goto fail;
	}
	req_msg->request_id = nla_get_u32(
	    tb[QCA_WLAN_VENDOR_ATTR_PNO_CONFIG_REQUEST_ID]);
	hdd_debug("Req Id %u", req_msg->request_id);

	req_msg->session_id = adapter->session_id;
	hdd_debug("Session Id %d", req_msg->session_id);

	if (num_networks) {

		/* Parse and fetch min_5ghz_rssi */
		if (!tb[QCA_WLAN_VENDOR_ATTR_EPNO_MIN5GHZ_RSSI]) {
			hdd_err("min_5ghz_rssi id failed");
			goto fail;
		}
		req_msg->min_5ghz_rssi = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_EPNO_MIN5GHZ_RSSI]);

		/* Parse and fetch min_24ghz_rssi */
		if (!tb[QCA_WLAN_VENDOR_ATTR_EPNO_MIN24GHZ_RSSI]) {
			hdd_err("min_24ghz_rssi id failed");
			goto fail;
		}
		req_msg->min_24ghz_rssi = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_EPNO_MIN24GHZ_RSSI]);

		/* Parse and fetch initial_score_max */
		if (!tb[QCA_WLAN_VENDOR_ATTR_EPNO_INITIAL_SCORE_MAX]) {
			hdd_err("initial_score_max id failed");
			goto fail;
		}
		req_msg->initial_score_max = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_EPNO_INITIAL_SCORE_MAX]);

		/* Parse and fetch current_connection_bonus */
		if (!tb[QCA_WLAN_VENDOR_ATTR_EPNO_CURRENT_CONNECTION_BONUS]) {
			hdd_err("current_connection_bonus id failed");
			goto fail;
		}
		req_msg->current_connection_bonus = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_EPNO_CURRENT_CONNECTION_BONUS]
			);

		/* Parse and fetch same_network_bonus */
		if (!tb[QCA_WLAN_VENDOR_ATTR_EPNO_SAME_NETWORK_BONUS]) {
			hdd_err("same_network_bonus id failed");
			goto fail;
		}
		req_msg->same_network_bonus = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_EPNO_SAME_NETWORK_BONUS]);

		/* Parse and fetch secure_bonus */
		if (!tb[QCA_WLAN_VENDOR_ATTR_EPNO_SECURE_BONUS]) {
			hdd_err("secure_bonus id failed");
			goto fail;
		}
		req_msg->secure_bonus = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_EPNO_SECURE_BONUS]);

		/* Parse and fetch band_5ghz_bonus */
		if (!tb[QCA_WLAN_VENDOR_ATTR_EPNO_BAND5GHZ_BONUS]) {
			hdd_err("band_5ghz_bonus id failed");
			goto fail;
		}
		req_msg->band_5ghz_bonus = nla_get_u32(
			tb[QCA_WLAN_VENDOR_ATTR_EPNO_BAND5GHZ_BONUS]);

		hdd_debug("min_5ghz_rssi: %d min_24ghz_rssi: %d",
			req_msg->min_5ghz_rssi,
			req_msg->min_24ghz_rssi);
		hdd_debug("initial_score_max: %d current_connection_bonus:%d",
			req_msg->initial_score_max,
			req_msg->current_connection_bonus);
		hdd_debug("Bonuses same_network: %d secure: %d band_5ghz: %d",
			req_msg->same_network_bonus,
			req_msg->secure_bonus,
			req_msg->band_5ghz_bonus);

		if (hdd_extscan_epno_fill_network_list(hdd_ctx, req_msg, tb))
			goto fail;

	}

	status = sme_set_epno_list(hdd_ctx->hHal, req_msg);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		hdd_err("sme_set_epno_list failed(err=%d)", status);
		goto fail;
	}

	EXIT();
	qdf_mem_free(req_msg);
	return 0;

fail:
	qdf_mem_free(req_msg);
	return -EINVAL;
}

/**
 * wlan_hdd_cfg80211_set_epno_list() - epno set network list
 * @wiphy: wiphy
 * @wdev: pointer to wireless dev
 * @data: data pointer
 * @data_len: data length
 *
 * This function reads the NL vendor attributes from %tb and
 * fill in the epno request message.
 *
 * Return: 0 on success, error number otherwise
 */
int wlan_hdd_cfg80211_set_epno_list(struct wiphy *wiphy,
				    struct wireless_dev *wdev,
				    const void *data,
				    int data_len)
{
	int ret;

	cds_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_set_epno_list(wiphy, wdev,
						data, data_len);
	cds_ssr_unprotect(__func__);

	return ret;
}

/**
 * hdd_extscan_passpoint_fill_network_list() - passpoint fill network list
 * @hddctx: HDD context
 * @req_msg: request message
 * @tb: vendor attribute table
 *
 * This function reads the network block NL vendor attributes from %tb and
 * fill in the passpoint request message.
 *
 * Return: 0 on success, error number otherwise
 */
static int hdd_extscan_passpoint_fill_network_list(
			struct hdd_context *hddctx,
			struct wifi_passpoint_req *req_msg,
			struct nlattr **tb)
{
	struct nlattr *network[QCA_WLAN_VENDOR_ATTR_PNO_MAX + 1];
	struct nlattr *networks;
	int rem1, len;
	uint8_t index;
	uint32_t expected_networks;

	expected_networks = req_msg->num_networks;
	index = 0;

	if (!tb[QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_LIST_PARAM_NETWORK_ARRAY]) {
		hdd_err("attr network array failed");
		return -EINVAL;
	}
	nla_for_each_nested(networks,
		tb[QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_LIST_PARAM_NETWORK_ARRAY],
		rem1) {

		if (index == expected_networks) {
			hdd_warn("ignoring excess networks");
			break;
		}

		if (wlan_cfg80211_nla_parse(network,
					    QCA_WLAN_VENDOR_ATTR_PNO_MAX,
					    nla_data(networks),
					    nla_len(networks),
					    wlan_hdd_pno_config_policy)) {
			hdd_err("nla_parse failed");
			return -EINVAL;
		}

		/* Parse and fetch identifier */
		if (!network[QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ID]) {
			hdd_err("attr passpoint id failed");
			return -EINVAL;
		}
		req_msg->networks[index].id = nla_get_u32(
			network[QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ID]);
		hdd_debug("Id %u", req_msg->networks[index].id);

		/* Parse and fetch realm */
		if (!network[QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_REALM]) {
			hdd_err("attr realm failed");
			return -EINVAL;
		}
		len = nla_len(
			network[QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_REALM]);
		if (len < 0 || len > SIR_PASSPOINT_REALM_LEN) {
			hdd_err("Invalid realm size %d", len);
			return -EINVAL;
		}
		qdf_mem_copy(req_msg->networks[index].realm,
				nla_data(network[QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_REALM]),
				len);
		hdd_debug("realm len %d", len);
		hdd_debug("realm: %s", req_msg->networks[index].realm);

		/* Parse and fetch roaming consortium ids */
		if (!network[QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ROAM_CNSRTM_ID]) {
			hdd_err("attr roaming consortium ids failed");
			return -EINVAL;
		}
		nla_memcpy(&req_msg->networks[index].roaming_consortium_ids,
			network[QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ROAM_CNSRTM_ID],
			sizeof(req_msg->networks[0].roaming_consortium_ids));
		hdd_debug("roaming consortium ids");

		/* Parse and fetch plmn */
		if (!network[QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ROAM_PLMN]) {
			hdd_err("attr plmn failed");
			return -EINVAL;
		}
		nla_memcpy(&req_msg->networks[index].plmn,
			network[QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ROAM_PLMN],
			SIR_PASSPOINT_PLMN_LEN);
		hdd_debug("plmn %02x:%02x:%02x)",
			req_msg->networks[index].plmn[0],
			req_msg->networks[index].plmn[1],
			req_msg->networks[index].plmn[2]);

		index++;
	}
	req_msg->num_networks = index;
	return 0;
}

/**
 * __wlan_hdd_cfg80211_set_passpoint_list() - set passpoint network list
 * @wiphy: wiphy
 * @wdev: pointer to wireless dev
 * @data: data pointer
 * @data_len: data length
 *
 * This function reads the NL vendor attributes from %tb and
 * fill in the passpoint request message.
 *
 * Return: 0 on success, error number otherwise
 */
static int __wlan_hdd_cfg80211_set_passpoint_list(struct wiphy *wiphy,
						  struct wireless_dev *wdev,
						  const void *data,
						  int data_len)
{
	struct wifi_passpoint_req *req_msg = NULL;
	struct net_device *dev             = wdev->netdev;
	struct hdd_adapter *adapter             = WLAN_HDD_GET_PRIV_PTR(dev);
	struct hdd_context *hdd_ctx        = wiphy_priv(wiphy);
	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_PNO_MAX + 1];
	QDF_STATUS status;
	uint32_t num_networks = 0;
	int ret;

	ENTER_DEV(dev);

	ret = wlan_hdd_validate_context(hdd_ctx);
	if (ret)
		return ret;

	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
		hdd_err("Command not allowed in FTM mode");
		return -EPERM;
	}

	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_PNO_MAX, data,
				    data_len, wlan_hdd_pno_config_policy)) {
		hdd_err("Invalid ATTR");
		return -EINVAL;
	}

	/* Parse and fetch number of networks */
	if (!tb[QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_LIST_PARAM_NUM]) {
		hdd_err("attr num networks failed");
		return -EINVAL;
	}
	num_networks = nla_get_u32(
		tb[QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_LIST_PARAM_NUM]);
	if (num_networks > SIR_PASSPOINT_LIST_MAX_NETWORKS) {
		hdd_err("num networks %u exceeds max %u",
			num_networks, SIR_PASSPOINT_LIST_MAX_NETWORKS);
		return -EINVAL;
	}

	hdd_debug("num networks %u", num_networks);

	req_msg = qdf_mem_malloc(sizeof(*req_msg) +
			(num_networks * sizeof(req_msg->networks[0])));
	if (!req_msg) {
		hdd_err("qdf_mem_malloc failed");
		return -ENOMEM;
	}
	req_msg->num_networks = num_networks;

	/* Parse and fetch request Id */
	if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
		hdd_err("attr request id failed");
		goto fail;
	}
	req_msg->request_id = nla_get_u32(
	    tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);

	req_msg->session_id = adapter->session_id;
	hdd_debug("Req Id %u Session Id %d", req_msg->request_id,
			req_msg->session_id);

	if (hdd_extscan_passpoint_fill_network_list(hdd_ctx, req_msg, tb))
		goto fail;

	status = sme_set_passpoint_list(hdd_ctx->hHal, req_msg);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		hdd_err("sme_set_passpoint_list failed(err=%d)", status);
		goto fail;
	}

	EXIT();
	qdf_mem_free(req_msg);
	return 0;

fail:
	qdf_mem_free(req_msg);
	return -EINVAL;
}

/**
 * wlan_hdd_cfg80211_set_passpoint_list() - set passpoint network list
 * @wiphy: wiphy
 * @wdev: pointer to wireless dev
 * @data: data pointer
 * @data_len: data length
 *
 * This function reads the NL vendor attributes from %tb and
 * fill in the passpoint request message.
 *
 * Return: 0 on success, error number otherwise
 */
int wlan_hdd_cfg80211_set_passpoint_list(struct wiphy *wiphy,
					 struct wireless_dev *wdev,
					 const void *data,
					 int data_len)
{
	int ret;

	cds_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_set_passpoint_list(wiphy, wdev,
						     data, data_len);
	cds_ssr_unprotect(__func__);

	return ret;
}

/**
 * __wlan_hdd_cfg80211_reset_passpoint_list() - reset passpoint network list
 * @wiphy: wiphy
 * @wdev: pointer to wireless dev
 * @data: data pointer
 * @data_len: data length
 *
 * This function resets passpoint networks list
 *
 * Return: 0 on success, error number otherwise
 */
static int __wlan_hdd_cfg80211_reset_passpoint_list(struct wiphy *wiphy,
						    struct wireless_dev *wdev,
						    const void *data,
						    int data_len)
{
	struct wifi_passpoint_req *req_msg = NULL;
	struct net_device *dev             = wdev->netdev;
	struct hdd_adapter *adapter             = WLAN_HDD_GET_PRIV_PTR(dev);
	struct hdd_context *hdd_ctx        = wiphy_priv(wiphy);
	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_PNO_MAX + 1];
	QDF_STATUS status;
	int ret;

	ENTER_DEV(dev);

	ret = wlan_hdd_validate_context(hdd_ctx);
	if (ret)
		return ret;

	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
		hdd_err("Command not allowed in FTM mode");
		return -EPERM;
	}

	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_PNO_MAX, data,
				    data_len, wlan_hdd_extscan_config_policy)) {
		hdd_err("Invalid ATTR");
		return -EINVAL;
	}

	req_msg = qdf_mem_malloc(sizeof(*req_msg));
	if (!req_msg) {
		hdd_err("qdf_mem_malloc failed");
		return -ENOMEM;
	}

	/* Parse and fetch request Id */
	if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
		hdd_err("attr request id failed");
		goto fail;
	}
	req_msg->request_id = nla_get_u32(
	    tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);

	req_msg->session_id = adapter->session_id;
	hdd_debug("Req Id %u Session Id %d",
			req_msg->request_id, req_msg->session_id);

	status = sme_reset_passpoint_list(hdd_ctx->hHal, req_msg);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		hdd_err("sme_reset_passpoint_list failed(err=%d)", status);
		goto fail;
	}

	EXIT();
	qdf_mem_free(req_msg);
	return 0;

fail:
	qdf_mem_free(req_msg);
	return -EINVAL;
}

/**
 * wlan_hdd_cfg80211_reset_passpoint_list() - reset passpoint network list
 * @wiphy: wiphy
 * @wdev: pointer to wireless dev
 * @data: data pointer
 * @data_len: data length
 *
 * This function resets passpoint networks list
 *
 * Return: 0 on success, error number otherwise
 */
int wlan_hdd_cfg80211_reset_passpoint_list(struct wiphy *wiphy,
					   struct wireless_dev *wdev,
					   const void *data,
					   int data_len)
{
	int ret;

	cds_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_reset_passpoint_list(wiphy, wdev,
						       data, data_len);
	cds_ssr_unprotect(__func__);

	return ret;
}

/**
 * wlan_hdd_init_completion_extwow() - Initialize ext wow variable
 * @hdd_ctx: Global HDD context
 *
 * Return: none
 */
#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
static inline void wlan_hdd_init_completion_extwow(struct hdd_context *hdd_ctx)
{
	init_completion(&hdd_ctx->ready_to_extwow);
}
#else
static inline void wlan_hdd_init_completion_extwow(struct hdd_context *hdd_ctx)
{
}
#endif

/**
 * wlan_hdd_cfg80211_extscan_init() - Initialize the ExtScan feature
 * @hdd_ctx: Global HDD context
 *
 * Return: none
 */
void wlan_hdd_cfg80211_extscan_init(struct hdd_context *hdd_ctx)
{
	wlan_hdd_init_completion_extwow(hdd_ctx);
	init_completion(&ext_scan_context.response_event);
	spin_lock_init(&ext_scan_context.context_lock);
}

#endif /* FEATURE_WLAN_EXTSCAN */
