/*
 * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved.
 *
 * 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.
 */

/* Include Files */

#include "osif_sync.h"
#include <wlan_hdd_includes.h>
#include <wlan_hdd_wowl.h>
#include <wlan_hdd_stats.h>
#include "cfg_ucfg_api.h"
#include "wlan_hdd_trace.h"
#include "wlan_hdd_ioctl.h"
#include "wlan_hdd_power.h"
#include "wlan_hdd_regulatory.h"
#include "wlan_osif_request_manager.h"
#include "wlan_hdd_driver_ops.h"
#include "wlan_policy_mgr_api.h"
#include "wlan_hdd_hostapd.h"
#include "scheduler_api.h"
#include "wlan_reg_ucfg_api.h"
#include "wlan_hdd_p2p.h"
#include <linux/ctype.h>
#include "wma.h"
#include "wlan_hdd_napi.h"
#include "wlan_mlme_ucfg_api.h"
#ifdef FEATURE_WLAN_ESE
#include <sme_api.h>
#include <sir_api.h>
#endif
#include "hif.h"
#include "wlan_scan_ucfg_api.h"
#include "wlan_reg_ucfg_api.h"

#if defined(LINUX_QCMBR)
#define SIOCIOCTLTX99 (SIOCDEVPRIVATE+13)
#endif

/*
 * Size of Driver command strings from upper layer
 */
#define SIZE_OF_SETROAMMODE             11      /* size of SETROAMMODE */
#define SIZE_OF_GETROAMMODE             11      /* size of GETROAMMODE */
#define SIZE_OF_SETSUSPENDMODE          14

/*
 * Size of GETCOUNTRYREV output = (sizeof("GETCOUNTRYREV") = 14) + one (space) +
 *				  (sizeof("country_code") = 3) +
 *                                one (NULL terminating character)
 */
#define SIZE_OF_GETCOUNTRYREV_OUTPUT 20

#ifdef FEATURE_WLAN_ESE
#define TID_MIN_VALUE 0
#define TID_MAX_VALUE 15
#endif /* FEATURE_WLAN_ESE */

/*
 * Maximum buffer size used for returning the data back to user space
 */
#define WLAN_MAX_BUF_SIZE 1024
#define WLAN_PRIV_DATA_MAX_LEN    8192

/*
 * Driver miracast parameters 0-Disabled
 * 1-Source, 2-Sink
 */
#define WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL 0
#define WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL 2

/*
 * When ever we need to print IBSSPEERINFOALL for more than 16 STA
 * we will split the printing.
 */
#define NUM_OF_STA_DATA_TO_PRINT 16

#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
/**
 * struct enable_ext_wow_priv - Private data structure for ext wow
 * @ext_wow_should_suspend: Suspend status of ext wow
 */
struct enable_ext_wow_priv {
	bool ext_wow_should_suspend;
};
#endif

/*
 * Android DRIVER command structures
 */
struct android_wifi_reassoc_params {
	unsigned char bssid[18];
	int channel;
};

#define ANDROID_WIFI_ACTION_FRAME_SIZE 1040
struct android_wifi_af_params {
	unsigned char bssid[18];
	int channel;
	int dwell_time;
	int len;
	unsigned char data[ANDROID_WIFI_ACTION_FRAME_SIZE];
};

/*
 * Define HDD driver command handling entry, each contains a command
 * string and the handler.
 */
typedef int (*hdd_drv_cmd_handler_t)(struct hdd_adapter *adapter,
				     struct hdd_context *hdd_ctx,
				     uint8_t *cmd,
				     uint8_t cmd_name_len,
				     struct hdd_priv_data *priv_data);

/**
 * struct hdd_drv_cmd - Structure to store ioctl command handling info
 * @cmd: Name of the command
 * @handler: Command handler to be invoked
 * @args: Set to true if command expects input parameters
 */
struct hdd_drv_cmd {
	const char *cmd;
	hdd_drv_cmd_handler_t handler;
	bool args;
};

#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
#define WLAN_WAIT_TIME_READY_TO_EXTWOW   2000
#define WLAN_HDD_MAX_TCP_PORT            65535
#endif

/**
 * drv_cmd_validate() - Validates for space in hdd driver command
 * @command: pointer to input data (its a NULL terminated string)
 * @len: length of command name
 *
 * This function checks for space after command name and if no space
 * is found returns error.
 *
 * Return: 0 for success non-zero for failure
 */
static int drv_cmd_validate(uint8_t *command, int len)
{
	if (command[len] != ' ')
		return -EINVAL;

	return 0;
}

#ifdef FEATURE_WLAN_ESE
struct tsm_priv {
	tAniTrafStrmMetrics tsm_metrics;
};

static void hdd_get_tsm_stats_cb(tAniTrafStrmMetrics tsm_metrics,
				 void *context)
{
	struct osif_request *request;
	struct tsm_priv *priv;

	request = osif_request_get(context);
	if (!request) {
		hdd_err("Obsolete request");
		return;
	}
	priv = osif_request_priv(request);
	priv->tsm_metrics = tsm_metrics;
	osif_request_complete(request);
	osif_request_put(request);
	hdd_exit();

}

static int hdd_get_tsm_stats(struct hdd_adapter *adapter,
			     const uint8_t tid,
			     tAniTrafStrmMetrics *tsm_metrics)
{
	struct hdd_context *hdd_ctx;
	struct hdd_station_ctx *hdd_sta_ctx;
	QDF_STATUS status;
	int ret;
	void *cookie;
	struct osif_request *request;
	struct tsm_priv *priv;
	static const struct osif_request_params params = {
		.priv_size = sizeof(*priv),
		.timeout_ms = WLAN_WAIT_TIME_STATS,
	};

	if (!adapter) {
		hdd_err("adapter is NULL");
		return -EINVAL;
	}

	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);

	request = osif_request_alloc(&params);
	if (!request) {
		hdd_err("Request allocation failure");
		return -ENOMEM;
	}
	cookie = osif_request_cookie(request);

	status = sme_get_tsm_stats(hdd_ctx->mac_handle, hdd_get_tsm_stats_cb,
				   hdd_sta_ctx->conn_info.bssid,
				   cookie, tid);
	if (QDF_STATUS_SUCCESS != status) {
		hdd_err("Unable to retrieve tsm statistics");
		ret = qdf_status_to_os_return(status);
		goto cleanup;
	}

	ret = osif_request_wait_for_response(request);
	if (ret) {
		hdd_err("SME timed out while retrieving tsm statistics");
		goto cleanup;
	}

	priv = osif_request_priv(request);
	*tsm_metrics = priv->tsm_metrics;

 cleanup:
	osif_request_put(request);

	return ret;
}
#endif /*FEATURE_WLAN_ESE */

#ifdef QCA_IBSS_SUPPORT
/*
 * Ibss prop IE from command will be of size:
 * size  = sizeof(oui) + sizeof(oui_data) + 1(Element ID) + 1(EID Length)
 * OUI_DATA should be at least 3 bytes long
 */
#define WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH (3)
static uint16_t cesium_pid;

void
hdd_get_ibss_peer_info_cb(void *context,
			  tSirPeerInfoRspParams *peer_info)
{
	struct hdd_adapter *adapter = context;
	struct hdd_station_ctx *sta_ctx;
	uint8_t i;

	if ((!adapter) ||
	    (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
		hdd_err("invalid adapter or adapter has invalid magic");
		return;
	}

	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
	if (peer_info && QDF_STATUS_SUCCESS == peer_info->status) {
		/* validate number of peers */
		if (peer_info->numPeers > SIR_MAX_NUM_STA_IN_IBSS) {
			hdd_warn("Limiting num_peers %u to %u",
				peer_info->numPeers, SIR_MAX_NUM_STA_IN_IBSS);
			peer_info->numPeers = SIR_MAX_NUM_STA_IN_IBSS;
		}
		sta_ctx->ibss_peer_info.status = peer_info->status;
		sta_ctx->ibss_peer_info.numPeers = peer_info->numPeers;

		for (i = 0; i < peer_info->numPeers; i++)
			sta_ctx->ibss_peer_info.peerInfoParams[i] =
				peer_info->peerInfoParams[i];
	} else {
		hdd_debug("peerInfo %s: status %u, numPeers %u",
			peer_info ? "valid" : "null",
			peer_info ? peer_info->status : QDF_STATUS_E_FAILURE,
			peer_info ? peer_info->numPeers : 0);
		sta_ctx->ibss_peer_info.numPeers = 0;
		sta_ctx->ibss_peer_info.status = QDF_STATUS_E_FAILURE;
	}

	complete(&adapter->ibss_peer_info_comp);
}

/**
 * hdd_cfg80211_get_ibss_peer_info_all() - get ibss peers' info
 * @adapter:	Adapter context
 *
 * Request function to get IBSS peer info from lower layers
 *
 * Return: 0 for success non-zero for failure
 */
static
QDF_STATUS hdd_cfg80211_get_ibss_peer_info_all(struct hdd_adapter *adapter)
{
	QDF_STATUS status;
	unsigned long rc;
	struct qdf_mac_addr bcast = QDF_MAC_ADDR_BCAST_INIT;

	INIT_COMPLETION(adapter->ibss_peer_info_comp);

	status = sme_request_ibss_peer_info(adapter->hdd_ctx->mac_handle,
					    adapter,
					    hdd_get_ibss_peer_info_cb,
					    true, bcast.bytes);

	if (QDF_STATUS_SUCCESS == status) {
		rc = wait_for_completion_timeout
			     (&adapter->ibss_peer_info_comp,
			     msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));

		/* status will be 0 if timed out */
		if (!rc) {
			hdd_warn("Warning: IBSS_PEER_INFO_TIMEOUT");
			status = QDF_STATUS_E_FAILURE;
		}
	} else {
		hdd_warn("Warning: sme_request_ibss_peer_info Request failed");
	}

	return status;
}

/**
 * hdd_cfg80211_get_ibss_peer_info() - get ibss peer info
 * @adapter:	Adapter context
 * @sta_id:	Sta index for which the peer info is requested
 *
 * Request function to get IBSS peer info from lower layers
 *
 * Return: 0 for success non-zero for failure
 */
static QDF_STATUS
hdd_cfg80211_get_ibss_peer_info(struct hdd_adapter *adapter, uint8_t *mac_addr)
{
	unsigned long rc;
	QDF_STATUS status;

	INIT_COMPLETION(adapter->ibss_peer_info_comp);

	status = sme_request_ibss_peer_info(adapter->hdd_ctx->mac_handle,
					    adapter,
					    hdd_get_ibss_peer_info_cb,
					    false, mac_addr);

	if (QDF_STATUS_SUCCESS == status) {
		rc = wait_for_completion_timeout(
				&adapter->ibss_peer_info_comp,
				msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));

		/* status = 0 on timeout */
		if (!rc) {
			hdd_warn("Warning: IBSS_PEER_INFO_TIMEOUT");
			status = QDF_STATUS_E_FAILURE;
		}
	} else {
		hdd_warn("Warning: sme_request_ibss_peer_info Request failed");
	}

	return status;
}

/* Function header is left blank intentionally */
static QDF_STATUS
hdd_parse_get_ibss_peer_info(uint8_t *command,
			     struct qdf_mac_addr *peer_macaddr)
{
	uint8_t *in_ptr = command;
	size_t in_ptr_len = strlen(command);

	in_ptr = strnchr(command, in_ptr_len, SPACE_ASCII_VALUE);

	if (!in_ptr)
		return QDF_STATUS_E_FAILURE;
	else if (SPACE_ASCII_VALUE != *in_ptr)
		return QDF_STATUS_E_FAILURE;

	while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr))
		in_ptr++;

	if ('\0' == *in_ptr)
		return QDF_STATUS_E_FAILURE;

	in_ptr_len -= (in_ptr - command);
	if (in_ptr_len < 17)
		return QDF_STATUS_E_FAILURE;

	if (in_ptr[2] != ':' || in_ptr[5] != ':' || in_ptr[8] != ':' ||
	    in_ptr[11] != ':' || in_ptr[14] != ':')
		return QDF_STATUS_E_FAILURE;

	sscanf(in_ptr, "%2x:%2x:%2x:%2x:%2x:%2x",
	       (unsigned int *)&peer_macaddr->bytes[0],
	       (unsigned int *)&peer_macaddr->bytes[1],
	       (unsigned int *)&peer_macaddr->bytes[2],
	       (unsigned int *)&peer_macaddr->bytes[3],
	       (unsigned int *)&peer_macaddr->bytes[4],
	       (unsigned int *)&peer_macaddr->bytes[5]);

	return QDF_STATUS_SUCCESS;
}

static void hdd_tx_fail_ind_callback(uint8_t *macaddr, uint8_t seq_no)
{
	int payload_len;
	struct sk_buff *skb;
	struct nlmsghdr *nlh;
	uint8_t *data;

	payload_len = ETH_ALEN;

	if (0 == cesium_pid || !cesium_nl_srv_sock) {
		hdd_err("cesium process not registered");
		return;
	}

	skb = nlmsg_new(payload_len, GFP_ATOMIC);
	if (!skb) {
		hdd_err("nlmsg_new() failed for msg size[%d]",
			 NLMSG_SPACE(payload_len));
		return;
	}

	nlh = nlmsg_put(skb, cesium_pid, seq_no, 0, payload_len, NLM_F_REQUEST);

	if (!nlh) {
		hdd_err("nlmsg_put() failed for msg size[%d]",
			 NLMSG_SPACE(payload_len));

		kfree_skb(skb);
		return;
	}

	data = nlmsg_data(nlh);
	memcpy(data, macaddr, ETH_ALEN);

	if (nlmsg_unicast(cesium_nl_srv_sock, skb, cesium_pid) < 0) {
		hdd_err("nlmsg_unicast() failed for msg size[%d]",
			 NLMSG_SPACE(payload_len));
	}
}

/**
 * hdd_parse_user_params() - return a pointer to the next argument
 * @command: Input argument string
 * @arg: Output pointer to the next argument
 *
 * This function parses argument stream and finds the pointer
 * to the next argument
 *
 * Return: 0 if the next argument found; -EINVAL otherwise
 */
static int hdd_parse_user_params(uint8_t *command, uint8_t **arg)
{
	uint8_t *cursor;

	cursor = strnchr(command, strlen(command), SPACE_ASCII_VALUE);

	/* no argument remains ? */
	if (!cursor)
		return -EINVAL;

	/* no space after the current arg ? */
	if (SPACE_ASCII_VALUE != *cursor)
		return -EINVAL;

	cursor++;

	/* remove empty spaces */
	while (SPACE_ASCII_VALUE == *cursor)
		cursor++;

	/* no argument after the spaces ? */
	if ('\0' == *cursor)
		return -EINVAL;

	*arg = cursor;

	return 0;
}

/**
 * hdd_parse_ibsstx_fail_event_params - Parse params
 *                                             for SETIBSSTXFAILEVENT
 * @command: Input ibss tx fail event argument
 * @tx_fail_count: (Output parameter) Tx fail counter
 * @pid: (Output parameter) PID
 *
 * Return: 0 if the parsing succeeds; -EINVAL otherwise
 */
static int hdd_parse_ibsstx_fail_event_params(uint8_t *command,
					      uint8_t *tx_fail_count,
					      uint16_t *pid)
{
	uint8_t *param = NULL;
	int ret;

	ret = hdd_parse_user_params(command, &param);

	if (0 == ret && param) {
		if (1 != sscanf(param, "%hhu", tx_fail_count)) {
			ret = -EINVAL;
			goto done;
		}
	} else {
		goto done;
	}

	if (0 == *tx_fail_count) {
		*pid = 0;
		goto done;
	}

	command = param;
	command++;

	ret = hdd_parse_user_params(command, &param);

	if (0 == ret) {
		if (1 != sscanf(param, "%hu", pid)) {
			ret = -EINVAL;
			goto done;
		}
	} else {
		goto done;
	}

done:
	return ret;
}

/* Function header is left blank intentionally */
static int hdd_parse_set_ibss_oui_data_command(uint8_t *command, uint8_t *ie,
					int32_t *oui_length, int32_t limit)
{
	uint8_t len;
	uint8_t data;

	while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command)) {
		command++;
		limit--;
	}

	len = 2;

	while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
		(limit > 1)) {
		sscanf(command, "%02x", (unsigned int *)&data);
		ie[len++] = data;
		command += 2;
		limit -= 2;
	}

	*oui_length = len - 2;

	while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command)) {
		command++;
		limit--;
	}

	while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
		(limit > 1)) {
		sscanf(command, "%02x", (unsigned int *)&data);
		ie[len++] = data;
		command += 2;
		limit -= 2;
	}

	ie[0] = WLAN_ELEMID_VENDOR;
	ie[1] = len - 2;

	return len;
}

/**
 * drv_cmd_set_ibss_beacon_oui_data() - set ibss oui data command
 * @adapter: Pointer to adapter
 * @hdd_ctx: Pointer to HDD context
 * @command: Pointer to command string
 * @command_len : Command length
 * @priv_data : Pointer to priv data
 *
 * Return:
 *      int status code
 */
static int drv_cmd_set_ibss_beacon_oui_data(struct hdd_adapter *adapter,
					    struct hdd_context *hdd_ctx,
					    uint8_t *command,
					    uint8_t command_len,
					    struct hdd_priv_data *priv_data)
{
	int i = 0;
	int status;
	int ret = 0;
	uint8_t *ibss_ie;
	int32_t oui_length = 0;
	uint32_t ibss_ie_length;
	uint8_t *value = command;
	tSirModifyIE modify_ie;
	struct csr_roam_profile *roam_profile;
	mac_handle_t mac_handle;

	if (QDF_IBSS_MODE != adapter->device_mode) {
		hdd_debug("Device_mode %s(%d) not IBSS",
			  qdf_opmode_str(adapter->device_mode),
			  adapter->device_mode);
		return ret;
	}

	hdd_debug("received command %s", ((char *)value));

	/* validate argument of command */
	if (strlen(value) <= command_len) {
		hdd_err("No arguments in command length %zu",
			 strlen(value));
		ret = -EFAULT;
		goto exit;
	}

	/* moving to arguments of commands */
	value = value + command_len;
	command_len = strlen(value);

	/* oui_data can't be less than 3 bytes */
	if (command_len < (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH)) {
		hdd_err("Invalid SETIBSSBEACONOUIDATA command length %d",
			 command_len);
		ret = -EFAULT;
		goto exit;
	}

	ibss_ie = qdf_mem_malloc(command_len);
	if (!ibss_ie) {
		hdd_err("Could not allocate memory for command length %d",
			 command_len);
		ret = -ENOMEM;
		goto exit;
	}

	ibss_ie_length = hdd_parse_set_ibss_oui_data_command(value, ibss_ie,
							     &oui_length,
							     command_len);
	if (ibss_ie_length <= (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH)) {
		hdd_err("Could not parse command %s return length %d",
			 value, ibss_ie_length);
		ret = -EFAULT;
		qdf_mem_free(ibss_ie);
		goto exit;
	}

	roam_profile = hdd_roam_profile(adapter);

	qdf_copy_macaddr(&modify_ie.bssid,
		     roam_profile->BSSIDs.bssid);

	modify_ie.vdev_id = adapter->vdev_id;
	modify_ie.notify = true;
	modify_ie.ieID = WLAN_ELEMID_VENDOR;
	modify_ie.ieIDLen = ibss_ie_length;
	modify_ie.ieBufferlength = ibss_ie_length;
	modify_ie.pIEBuffer = ibss_ie;
	modify_ie.oui_length = oui_length;

	hdd_warn("ibss_ie length %d oui_length %d ibss_ie:",
		 ibss_ie_length, oui_length);
	while (i < modify_ie.ieBufferlength)
		hdd_warn("0x%x", ibss_ie[i++]);

	/* Probe Bcn modification */
	mac_handle = hdd_ctx->mac_handle;
	sme_modify_add_ie(mac_handle, &modify_ie, eUPDATE_IE_PROBE_BCN);

	/* Populating probe resp frame */
	sme_modify_add_ie(mac_handle, &modify_ie, eUPDATE_IE_PROBE_RESP);

	qdf_mem_free(ibss_ie);

	status = sme_send_cesium_enable_ind(mac_handle,
					    adapter->vdev_id);
	if (QDF_STATUS_SUCCESS != status) {
		hdd_err("Could not send cesium enable indication %d",
			  status);
		ret = -EINVAL;
		goto exit;
	}

exit:
	return ret;
}

static int drv_cmd_get_ibss_peer_info_all(struct hdd_adapter *adapter,
					  struct hdd_context *hdd_ctx,
					  uint8_t *command,
					  uint8_t command_len,
					  struct hdd_priv_data *priv_data)
{
	int ret = 0;
	int status = QDF_STATUS_SUCCESS;
	struct hdd_station_ctx *sta_ctx = NULL;
	char *extra = NULL;
	int idx = 0;
	int length = 0;
	uint8_t mac_addr[QDF_MAC_ADDR_SIZE];
	uint32_t print_break_index = 0;

	if (QDF_IBSS_MODE != adapter->device_mode) {
		hdd_warn("Unsupported in mode %s(%d)",
			 qdf_opmode_str(adapter->device_mode),
			 adapter->device_mode);
		return -EINVAL;
	}

	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
	hdd_debug("Received GETIBSSPEERINFOALL Command");

	/* Handle the command */
	status = hdd_cfg80211_get_ibss_peer_info_all(adapter);
	if (QDF_STATUS_SUCCESS == status) {
		size_t user_size = qdf_min(WLAN_MAX_BUF_SIZE,
					   priv_data->total_len);

		/*
		 * The variable extra needed to be allocated on the heap since
		 * amount of memory required to copy the data for 32 devices
		 * exceeds the size of 1024 bytes of default stack size. On
		 * 64 bit devices, the default max stack size of 2048 bytes
		 */
		extra = qdf_mem_malloc(user_size);

		if (!extra) {
			hdd_err("memory allocation failed");
			ret = -ENOMEM;
			goto exit;
		}

		/* Copy number of stations */
		length = scnprintf(extra, user_size, "%d ",
				   sta_ctx->ibss_peer_info.numPeers);
		print_break_index = length;
		for (idx = 0; idx < sta_ctx->ibss_peer_info.numPeers;
								idx++) {
			int8_t rssi;
			uint32_t tx_rate;

			qdf_mem_copy(mac_addr,
				sta_ctx->ibss_peer_info.peerInfoParams[idx].
				mac_addr, sizeof(mac_addr));

			tx_rate =
				sta_ctx->ibss_peer_info.peerInfoParams[idx].
									txRate;
			/*
			 * Only lower 3 bytes are rate info. Mask of the MSByte
			 */
			tx_rate &= 0x00FFFFFF;

			rssi = sta_ctx->ibss_peer_info.peerInfoParams[idx].
									rssi;

			length += scnprintf(extra + length,
				user_size - length,
				QDF_MAC_ADDR_STR" %d %d ",
				QDF_MAC_ADDR_ARRAY(mac_addr),
				tx_rate, rssi);
			/*
			 * cdf_trace_msg has limitation of 512 bytes for the
			 * print buffer. Hence printing the data in two chunks.
			 * The first chunk will have the data for 16 devices
			 * and the second chunk will have the rest.
			 */
			if (idx < NUM_OF_STA_DATA_TO_PRINT)
				print_break_index = length;
		}

		/*
		 * Copy the data back into buffer, if the data to copy is
		 * more than 512 bytes than we will split the data and do
		 * it in two shots
		 */
		if (copy_to_user(priv_data->buf, extra, print_break_index)) {
			hdd_err("Copy into user data buffer failed");
			ret = -EFAULT;
			goto mem_free;
		}

		/* This overwrites the last space, which we already copied */
		extra[print_break_index - 1] = '\0';
		hdd_debug("%s", extra);

		if (length > print_break_index) {
			if (copy_to_user
				    (priv_data->buf + print_break_index,
				    extra + print_break_index,
				    length - print_break_index + 1)) {
				hdd_err("Copy into user data buffer failed");
				ret = -EFAULT;
				goto mem_free;
			}
			hdd_debug("%s", &extra[print_break_index]);
		}
	} else {
		/* Command failed, log error */
		hdd_err("GETIBSSPEERINFOALL command failed with status code %d",
			  status);
		ret = -EINVAL;
		goto exit;
	}
	ret = 0;

mem_free:
	qdf_mem_free(extra);
exit:
	return ret;
}

/* Peer Info <Peer Addr> command */
static int drv_cmd_get_ibss_peer_info(struct hdd_adapter *adapter,
				      struct hdd_context *hdd_ctx,
				      uint8_t *command,
				      uint8_t command_len,
				      struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint8_t *value = command;
	QDF_STATUS status;
	struct hdd_station_ctx *sta_ctx = NULL;
	char extra[128] = { 0 };
	uint32_t length = 0;
	struct qdf_mac_addr peer_macaddr;

	if (QDF_IBSS_MODE != adapter->device_mode) {
		hdd_warn("Unsupported in mode %s(%d)",
			 qdf_opmode_str(adapter->device_mode),
			 adapter->device_mode);
		return -EINVAL;
	}

	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);

	hdd_debug("Received GETIBSSPEERINFO Command");

	/* if there are no peers, no need to continue with the command */
	if (eConnectionState_IbssConnected !=
	    sta_ctx->conn_info.conn_state) {
		hdd_err("No IBSS Peers coalesced");
		ret = -EINVAL;
		goto exit;
	}

	/* Parse the incoming command buffer */
	status = hdd_parse_get_ibss_peer_info(value, &peer_macaddr);
	if (QDF_STATUS_SUCCESS != status) {
		hdd_err("Invalid GETIBSSPEERINFO command");
		ret = -EINVAL;
		goto exit;
	}

	/* Handle the command */
	status = hdd_cfg80211_get_ibss_peer_info(adapter, peer_macaddr.bytes);
	if (QDF_STATUS_SUCCESS == status) {
		uint32_t tx_rate =
			sta_ctx->ibss_peer_info.peerInfoParams[0].txRate;
		/* Only lower 3 bytes are rate info. Mask of the MSByte */
		tx_rate &= 0x00FFFFFF;

		length = scnprintf(extra, sizeof(extra), "%d %d",
				(int)tx_rate,
				(int)sta_ctx->ibss_peer_info.
				peerInfoParams[0].rssi);
		length = QDF_MIN(priv_data->total_len, length + 1);

		/* Copy the data back into buffer */
		if (copy_to_user(priv_data->buf, &extra, length)) {
			hdd_err("copy data to user buffer failed GETIBSSPEERINFO command");
			ret = -EFAULT;
			goto exit;
		}
	} else {
		/* Command failed, log error */
		hdd_err("GETIBSSPEERINFO command failed with status code %d",
			  status);
		ret = -EINVAL;
		goto exit;
	}

	/* Success ! */
	hdd_debug("%s", extra);
	ret = 0;

exit:
	return ret;
}

static int drv_cmd_set_ibss_tx_fail_event(struct hdd_adapter *adapter,
					  struct hdd_context *hdd_ctx,
					  uint8_t *command,
					  uint8_t command_len,
					  struct hdd_priv_data *priv_data)
{
	int ret = 0;
	char *value;
	uint8_t tx_fail_count = 0;
	uint16_t pid = 0;
	mac_handle_t mac_handle;

	value = command;

	ret = hdd_parse_ibsstx_fail_event_params(value, &tx_fail_count, &pid);

	if (0 != ret) {
		hdd_err("Failed to parse SETIBSSTXFAILEVENT arguments");
		goto exit;
	}

	hdd_debug("tx_fail_cnt=%hhu, pid=%hu", tx_fail_count, pid);
	mac_handle = hdd_ctx->mac_handle;

	if (0 == tx_fail_count) {
		/* Disable TX Fail Indication */
		if (QDF_STATUS_SUCCESS ==
		    sme_tx_fail_monitor_start_stop_ind(mac_handle,
						       tx_fail_count,
						       NULL)) {
			cesium_pid = 0;
		} else {
			hdd_err("failed to disable TX Fail Event");
			ret = -EINVAL;
		}
	} else {
		if (QDF_STATUS_SUCCESS ==
		    sme_tx_fail_monitor_start_stop_ind(mac_handle,
				tx_fail_count,
				(void *)hdd_tx_fail_ind_callback)) {
			cesium_pid = pid;
			hdd_debug("Registered Cesium pid %u",
				  cesium_pid);
		} else {
			hdd_err("Failed to enable TX Fail Monitoring");
			ret = -EINVAL;
		}
	}

exit:
	return ret;
}
#else
/**
 * drv_cmd_get_ibss_peer_info() - get ibss peer info all
 * @adapter: Pointer to adapter
 * @hdd_ctx: Pointer to HDD context
 * @command: Pointer to command string
 * @command_len : Command length
 * @priv_data : Pointer to priv data
 *
 * This function is dummy
 *
 * Return: 0
 */
static inline int
drv_cmd_get_ibss_peer_info_all(struct hdd_adapter *adapter,
			       struct hdd_context *hdd_ctx,
			       uint8_t *command,
			       uint8_t command_len,
			       struct hdd_priv_data *priv_data)
{
	return 0;
}

/**
 * drv_cmd_get_ibss_peer_info() - get ibss peer info
 * @adapter: Pointer to adapter
 * @hdd_ctx: Pointer to HDD context
 * @command: Pointer to command string
 * @command_len : Command length
 * @priv_data : Pointer to priv data
 *
 * This function is dummy
 *
 * Return: 0
 */
static inline int
drv_cmd_get_ibss_peer_info(struct hdd_adapter *adapter,
			   struct hdd_context *hdd_ctx,
			   uint8_t *command,
			   uint8_t command_len,
			   struct hdd_priv_data *priv_data)
{
	return 0;
}

/**
 * drv_cmd_set_ibss_tx_fail_event() - set ibss tx fail event
 * @adapter: Pointer to adapter
 * @hdd_ctx: Pointer to HDD context
 * @command: Pointer to command string
 * @command_len : Command length
 * @priv_data : Pointer to priv data
 *
 * This function is dummy
 *
 * Return: 0
 */
static inline int
drv_cmd_set_ibss_tx_fail_event(struct hdd_adapter *adapter,
			       struct hdd_context *hdd_ctx,
			       uint8_t *command,
			       uint8_t command_len,
			       struct hdd_priv_data *priv_data)
{
	return 0;
}

/**
 * drv_cmd_set_ibss_beacon_oui_data() - set ibss oui data command
 * @adapter: Pointer to adapter
 * @hdd_ctx: Pointer to HDD context
 * @command: Pointer to command string
 * @command_len : Command length
 * @priv_data : Pointer to priv data
 *
 * This function is dummy
 *
 * Return: 0
 */
static inline int
drv_cmd_set_ibss_beacon_oui_data(struct hdd_adapter *adapter,
				 struct hdd_context *hdd_ctx,
				 uint8_t *command,
				 uint8_t command_len,
				 struct hdd_priv_data *priv_data)
{
	return 0;
}
#endif

static void hdd_get_band_helper(struct hdd_context *hdd_ctx, int *ui_band)
{
	enum band_info band = -1;

	ucfg_reg_get_band(hdd_ctx->pdev, &band);
	switch (band) {
	case BAND_ALL:
		*ui_band = WLAN_HDD_UI_BAND_AUTO;
		break;

	case BAND_2G:
		*ui_band = WLAN_HDD_UI_BAND_2_4_GHZ;
		break;

	case BAND_5G:
		*ui_band = WLAN_HDD_UI_BAND_5_GHZ;
		break;

	default:
		hdd_warn("Invalid Band %d", band);
		*ui_band = -1;
		break;
	}
}

/**
 * _hdd_parse_bssid_and_chan() - helper function to parse bssid and channel
 * @data:            input data
 * @target_ap_bssid: pointer to bssid (output parameter)
 * @channel:         pointer to channel (output parameter)
 *
 * Return: 0 if parsing is successful; -EINVAL otherwise
 */
static int _hdd_parse_bssid_and_chan(const uint8_t **data,
				     uint8_t *bssid,
				     uint8_t *channel)
{
	const uint8_t *in_ptr;
	int            v = 0;
	int            temp_int;
	uint8_t        temp_buf[32];

	/* 12 hexa decimal digits, 5 ':' and '\0' */
	uint8_t        mac_addr[18];

	if (!data || !*data)
		return -EINVAL;

	in_ptr = *data;

	in_ptr = strnchr(in_ptr, strlen(in_ptr), SPACE_ASCII_VALUE);
	/* no argument after the command */
	if (!in_ptr)
		goto error;
	/* no space after the command */
	else if (SPACE_ASCII_VALUE != *in_ptr)
		goto error;

	/* remove empty spaces */
	while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr))
		in_ptr++;

	/* no argument followed by spaces */
	if ('\0' == *in_ptr)
		goto error;

	v = sscanf(in_ptr, "%17s", mac_addr);
	if (!((1 == v) && hdd_is_valid_mac_address(mac_addr))) {
		hdd_err("Invalid MAC address or All hex inputs are not read (%d)",
			 v);
		goto error;
	}

	bssid[0] = hex_to_bin(mac_addr[0]) << 4 |
			hex_to_bin(mac_addr[1]);
	bssid[1] = hex_to_bin(mac_addr[3]) << 4 |
			hex_to_bin(mac_addr[4]);
	bssid[2] = hex_to_bin(mac_addr[6]) << 4 |
			hex_to_bin(mac_addr[7]);
	bssid[3] = hex_to_bin(mac_addr[9]) << 4 |
			hex_to_bin(mac_addr[10]);
	bssid[4] = hex_to_bin(mac_addr[12]) << 4 |
			hex_to_bin(mac_addr[13]);
	bssid[5] = hex_to_bin(mac_addr[15]) << 4 |
			hex_to_bin(mac_addr[16]);

	/* point to the next argument */
	in_ptr = strnchr(in_ptr, strlen(in_ptr), SPACE_ASCII_VALUE);
	/* no argument after the command */
	if (!in_ptr)
		goto error;

	/* remove empty spaces */
	while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr))
		in_ptr++;

	/* no argument followed by spaces */
	if ('\0' == *in_ptr)
		goto error;

	/* get the next argument ie the channel number */
	v = sscanf(in_ptr, "%31s ", temp_buf);
	if (1 != v)
		goto error;

	v = kstrtos32(temp_buf, 10, &temp_int);
	if ((v < 0) || (temp_int < 0) ||
	    (temp_int > WNI_CFG_CURRENT_CHANNEL_STAMAX))
		return -EINVAL;

	*channel = temp_int;
	*data = in_ptr;
	return 0;
error:
	*data = in_ptr;
	return -EINVAL;
}

/**
 * hdd_parse_send_action_frame_data() - HDD Parse send action frame data
 * @command: Pointer to input data
 * @bssid: Pointer to target Ap bssid
 * @channel: Pointer to the Target AP channel
 * @dwell_time: Pointer to the time to stay off-channel
 *              after transmitting action frame
 * @buf: Pointer to data
 * @buf_len: Pointer to data length
 *
 * This function parses the send action frame data passed in the format
 * SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
 *
 * Return: 0 for success non-zero for failure
 */
static int
hdd_parse_send_action_frame_v1_data(const uint8_t *command,
				    uint8_t *bssid,
				    uint8_t *channel, uint8_t *dwell_time,
				    uint8_t **buf, uint8_t *buf_len)
{
	const uint8_t *in_ptr = command;
	const uint8_t *end_ptr;
	int temp_int;
	int j = 0;
	int i = 0;
	int v = 0;
	uint8_t temp_buf[32];
	uint8_t temp_u8 = 0;

	if (_hdd_parse_bssid_and_chan(&in_ptr, bssid, channel))
		return -EINVAL;

	/* point to the next argument */
	in_ptr = strnchr(in_ptr, strlen(in_ptr), SPACE_ASCII_VALUE);
	/* no argument after the command */
	if (!in_ptr)
		return -EINVAL;
	/* removing empty spaces */
	while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr))
		in_ptr++;

	/* no argument followed by spaces */
	if ('\0' == *in_ptr)
		return -EINVAL;

	/* getting the next argument ie the dwell time */
	v = sscanf(in_ptr, "%31s ", temp_buf);
	if (1 != v)
		return -EINVAL;

	v = kstrtos32(temp_buf, 10, &temp_int);
	if (v < 0 || temp_int < 0)
		return -EINVAL;

	*dwell_time = temp_int;

	/* point to the next argument */
	in_ptr = strnchr(in_ptr, strlen(in_ptr), SPACE_ASCII_VALUE);
	/* no argument after the command */
	if (!in_ptr)
		return -EINVAL;
	/* removing empty spaces */
	while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr))
		in_ptr++;

	/* no argument followed by spaces */
	if ('\0' == *in_ptr)
		return -EINVAL;

	/* find the length of data */
	end_ptr = in_ptr;
	while (('\0' != *end_ptr))
		end_ptr++;

	*buf_len = end_ptr - in_ptr;
	if (*buf_len <= 0)
		return -EINVAL;

	/*
	 * Allocate the number of bytes based on the number of input characters
	 * whether it is even or odd.
	 * if the number of input characters are even, then we need N/2 byte.
	 * if the number of input characters are odd, then we need do (N+1)/2
	 * to compensate rounding off.
	 * For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
	 * If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes
	 */
	*buf = qdf_mem_malloc((*buf_len + 1) / 2);
	if (!*buf) {
		hdd_err("qdf_mem_malloc failed");
		return -ENOMEM;
	}

	/* the buffer received from the upper layer is character buffer,
	 * we need to prepare the buffer taking 2 characters in to a U8 hex
	 * decimal number for example 7f0000f0...form a buffer to contain 7f
	 * in 0th location, 00 in 1st and f0 in 3rd location
	 */
	for (i = 0, j = 0; j < *buf_len; j += 2) {
		if (j + 1 == *buf_len) {
			temp_u8 = hex_to_bin(in_ptr[j]);
		} else {
			temp_u8 =
				(hex_to_bin(in_ptr[j]) << 4) |
				(hex_to_bin(in_ptr[j + 1]));
		}
		(*buf)[i++] = temp_u8;
	}
	*buf_len = i;
	return 0;
}

/**
 * hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
 * @command: Pointer to input data (its a NULL terminated string)
 * @bssid: Pointer to target Ap bssid
 * @channel: Pointer to the Target AP channel
 *
 * This function parses the reasoc command data passed in the format
 * REASSOC<space><bssid><space><channel>
 *
 * Return: 0 for success non-zero for failure
 */
static int hdd_parse_reassoc_command_v1_data(const uint8_t *command,
					     uint8_t *bssid,
					     uint8_t *channel)
{
	const uint8_t *in_ptr = command;

	if (_hdd_parse_bssid_and_chan(&in_ptr, bssid, channel))
		return -EINVAL;

	return 0;
}

#ifdef WLAN_FEATURE_ROAM_OFFLOAD
QDF_STATUS hdd_wma_send_fastreassoc_cmd(struct hdd_adapter *adapter,
					const tSirMacAddr bssid,
					uint32_t ch_freq)
{
	struct hdd_station_ctx *hdd_sta_ctx =
			WLAN_HDD_GET_STATION_CTX_PTR(adapter);
	struct csr_roam_profile *roam_profile;
	tSirMacAddr connected_bssid;

	roam_profile = hdd_roam_profile(adapter);
	qdf_mem_copy(connected_bssid, hdd_sta_ctx->conn_info.bssid.bytes,
		     ETH_ALEN);
	return sme_fast_reassoc(adapter->hdd_ctx->mac_handle,
				roam_profile, bssid, ch_freq,
				adapter->vdev_id, connected_bssid);
}
#endif

int hdd_reassoc(struct hdd_adapter *adapter, const uint8_t *bssid,
		uint32_t ch_freq, const handoff_src src)
{
	struct hdd_station_ctx *sta_ctx;
	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	int ret = 0;
	QDF_STATUS status;

	if (!hdd_ctx) {
		hdd_err("Invalid hdd ctx");
		return -EINVAL;
	}

	if (QDF_STA_MODE != adapter->device_mode) {
		hdd_warn("Unsupported in mode %s(%d)",
			 qdf_opmode_str(adapter->device_mode),
			 adapter->device_mode);
		return -EINVAL;
	}

	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);

	/*
	 * pHddStaCtx->conn_info.conn_state is set to disconnected only
	 * after the disconnect done indication from SME. If the SME is
	 * in the process of disconnecting, the SME Connection state is
	 * set to disconnected and the pHddStaCtx->conn_info.conn_state
	 * will still be associated till the disconnect is done.
	 * So check both the HDD state and SME state here.
	 * If not associated, no need to proceed with reassoc
	 */
	if ((eConnectionState_Associated != sta_ctx->conn_info.conn_state) ||
	    (!sme_is_conn_state_connected(hdd_ctx->mac_handle,
	    adapter->vdev_id))) {
		hdd_warn("Not associated");
		ret = -EINVAL;
		goto exit;
	}

	/*
	 * if the target bssid is same as currently associated AP,
	 * use the current connections's channel.
	 */
	if (!memcmp(bssid, sta_ctx->conn_info.bssid.bytes,
		    QDF_MAC_ADDR_SIZE)) {
		hdd_warn("Reassoc BSSID is same as currently associated AP bssid");
		ch_freq = sta_ctx->conn_info.chan_freq;
	}

	if (QDF_STATUS_SUCCESS !=
	    wlan_hdd_validate_operation_channel(adapter, ch_freq)) {
		hdd_err("Invalid Ch freq: %d", ch_freq);
		ret = -EINVAL;
		goto exit;
	}

	/* Proceed with reassoc */
	if (roaming_offload_enabled(hdd_ctx)) {
		status = hdd_wma_send_fastreassoc_cmd(adapter, bssid, ch_freq);
		if (status != QDF_STATUS_SUCCESS) {
			hdd_err("Failed to send fast reassoc cmd");
			ret = -EINVAL;
		}
	} else {
		tCsrHandoffRequest handoff;

		handoff.ch_freq = ch_freq;
		handoff.src = src;
		qdf_mem_copy(handoff.bssid.bytes, bssid, QDF_MAC_ADDR_SIZE);
		sme_handoff_request(hdd_ctx->mac_handle, adapter->vdev_id,
				    &handoff);
	}
exit:
	return ret;
}

/**
 * hdd_parse_reassoc_v1() - parse version 1 of the REASSOC command
 * @adapter:	Adapter upon which the command was received
 * @command:	ASCII text command that was received
 *
 * This function parses the v1 REASSOC command with the format
 *
 *    REASSOC xx:xx:xx:xx:xx:xx CH
 *
 * Where "xx:xx:xx:xx:xx:xx" is the Hex-ASCII representation of the
 * BSSID and CH is the ASCII representation of the channel.  For
 * example
 *
 *    REASSOC 00:0a:0b:11:22:33 48
 *
 * Return: 0 for success non-zero for failure
 */
static int hdd_parse_reassoc_v1(struct hdd_adapter *adapter, const char *command)
{
	uint8_t channel = 0;
	tSirMacAddr bssid;
	int ret;

	ret = hdd_parse_reassoc_command_v1_data(command, bssid, &channel);
	if (ret)
		hdd_err("Failed to parse reassoc command data");
	else
		ret = hdd_reassoc(adapter, bssid,
				  wlan_chan_to_freq(channel), REASSOC);

	return ret;
}

/**
 * hdd_parse_reassoc_v2() - parse version 2 of the REASSOC command
 * @adapter:	Adapter upon which the command was received
 * @command:	Command that was received, ASCII command
 *		followed by binary data
 * @total_len:  Total length of the command received
 *
 * This function parses the v2 REASSOC command with the format
 *
 *    REASSOC <android_wifi_reassoc_params>
 *
 * Return: 0 for success non-zero for failure
 */
static int hdd_parse_reassoc_v2(struct hdd_adapter *adapter,
				const char *command,
				int total_len)
{
	struct android_wifi_reassoc_params params;
	tSirMacAddr bssid;
	int ret;

	if (total_len < sizeof(params) + 8) {
		hdd_err("Invalid command length");
		return -EINVAL;
	}

	/* The params are located after "REASSOC " */
	memcpy(&params, command + 8, sizeof(params));

	if (!mac_pton(params.bssid, (u8 *) &bssid)) {
		hdd_err("MAC address parsing failed");
		ret = -EINVAL;
	} else {
		ret = hdd_reassoc(adapter, bssid,
				  wlan_chan_to_freq(params.channel), REASSOC);
	}
	return ret;
}

/**
 * hdd_parse_reassoc() - parse the REASSOC command
 * @adapter:	Adapter upon which the command was received
 * @command:	Command that was received
 * @total_len:  Total length of the command received
 *
 * There are two different versions of the REASSOC command.  Version 1
 * of the command contains a parameter list that is ASCII characters
 * whereas version 2 contains a combination of ASCII and binary
 * payload.  Determine if a version 1 or a version 2 command is being
 * parsed by examining the parameters, and then dispatch the parser
 * that is appropriate for the command.
 *
 * Return: 0 for success non-zero for failure
 */
static int hdd_parse_reassoc(struct hdd_adapter *adapter, const char *command,
			     int total_len)
{
	int ret;

	/* both versions start with "REASSOC "
	 * v1 has a bssid and channel # as an ASCII string
	 *    REASSOC xx:xx:xx:xx:xx:xx CH
	 * v2 has a C struct
	 *    REASSOC <binary c struct>
	 *
	 * The first field in the v2 struct is also the bssid in ASCII.
	 * But in the case of a v2 message the BSSID is NUL-terminated.
	 * Hence we can peek at that offset to see if this is V1 or V2
	 * REASSOC xx:xx:xx:xx:xx:xx*
	 *           1111111111222222
	 * 01234567890123456789012345
	 */

	if (total_len < 26) {
		hdd_err("Invalid command, total_len = %d", total_len);
		return -EINVAL;
	}

	if (command[25])
		ret = hdd_parse_reassoc_v1(adapter, command);
	else
		ret = hdd_parse_reassoc_v2(adapter, command, total_len);

	return ret;
}

/**
 * hdd_sendactionframe() - send a userspace-supplied action frame
 * @adapter:	Adapter upon which the command was received
 * @bssid:	BSSID target of the action frame
 * @channel:	Channel upon which to send the frame
 * @dwell_time:	Amount of time to dwell when the frame is sent
 * @payload_len:Length of the payload
 * @payload:	Payload of the frame
 *
 * This function sends a userspace-supplied action frame
 *
 * Return: 0 for success non-zero for failure
 */
static int
hdd_sendactionframe(struct hdd_adapter *adapter, const uint8_t *bssid,
		    const uint8_t channel, const uint8_t dwell_time,
		    const int payload_len, const uint8_t *payload)
{
	struct ieee80211_channel chan;
	uint8_t conn_info_channel;
	int frame_len, ret = 0;
	uint8_t *frame;
	struct ieee80211_hdr_3addr *hdr;
	u64 cookie;
	struct hdd_station_ctx *sta_ctx;
	struct hdd_context *hdd_ctx;
	tpSirMacVendorSpecificFrameHdr vendor =
		(tpSirMacVendorSpecificFrameHdr) payload;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
	struct cfg80211_mgmt_tx_params params;
#endif

	if (QDF_STA_MODE != adapter->device_mode) {
		hdd_warn("Unsupported in mode %s(%d)",
			 qdf_opmode_str(adapter->device_mode),
			 adapter->device_mode);
		return -EINVAL;
	}

	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
	hdd_ctx = WLAN_HDD_GET_CTX(adapter);

	/* if not associated, no need to send action frame */
	if (eConnectionState_Associated != sta_ctx->conn_info.conn_state) {
		hdd_warn("Not associated");
		ret = -EINVAL;
		goto exit;
	}

	/*
	 * if the target bssid is different from currently associated AP,
	 * then no need to send action frame
	 */
	if (memcmp(bssid, sta_ctx->conn_info.bssid.bytes,
			QDF_MAC_ADDR_SIZE)) {
		hdd_warn("STA is not associated to this AP");
		ret = -EINVAL;
		goto exit;
	}

	chan.center_freq = sme_chn_to_freq(channel);
	/* Check if it is specific action frame */
	if (vendor->category ==
	    SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY) {
		static const uint8_t oui[] = { 0x00, 0x00, 0xf0 };

		if (!qdf_mem_cmp(vendor->Oui, oui, 3)) {
			conn_info_channel = wlan_reg_freq_to_chan(
						hdd_ctx->pdev,
						sta_ctx->conn_info.chan_freq);
			/*
			 * if the channel number is different from operating
			 * channel then no need to send action frame
			 */
			if (channel != 0) {
				if (channel != conn_info_channel) {
					hdd_warn("channel(%u) is different from operating channel(%u)",
						 channel,
						 conn_info_channel);
					ret = -EINVAL;
					goto exit;
				}
				/*
				 * If channel number is specified and same
				 * as home channel, ensure that action frame
				 * is sent immediately by cancelling
				 * roaming scans. Otherwise large dwell times
				 * may cause long delays in sending action
				 * frames.
				 */
				sme_abort_roam_scan(hdd_ctx->mac_handle,
						    adapter->vdev_id);
			} else {
				/*
				 * 0 is accepted as current home channel,
				 * delayed transmission of action frame is ok.
				 */
				chan.center_freq = sta_ctx->conn_info.chan_freq;
			}
		}
	}
	if (chan.center_freq == 0) {
		hdd_err("Invalid channel number: %d", channel);
		ret = -EINVAL;
		goto exit;
	}

	frame_len = payload_len + 24;
	frame = qdf_mem_malloc(frame_len);
	if (!frame) {
		hdd_err("memory allocation failed");
		ret = -ENOMEM;
		goto exit;
	}

	hdr = (struct ieee80211_hdr_3addr *)frame;
	hdr->frame_control =
		cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION);
	qdf_mem_copy(hdr->addr1, bssid, QDF_MAC_ADDR_SIZE);
	qdf_mem_copy(hdr->addr2, adapter->mac_addr.bytes,
		     QDF_MAC_ADDR_SIZE);
	qdf_mem_copy(hdr->addr3, bssid, QDF_MAC_ADDR_SIZE);
	qdf_mem_copy(hdr + 1, payload, payload_len);

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
	params.chan = &chan;
	params.offchan = 0;
	params.wait = dwell_time;
	params.buf = frame;
	params.len = frame_len;
	params.no_cck = 1;
	params.dont_wait_for_ack = 1;
	ret = wlan_hdd_mgmt_tx(NULL, &adapter->wdev, &params, &cookie);
#else
	ret = wlan_hdd_mgmt_tx(NULL,
			       &(adapter->wdev),
			       &chan, 0,

			       dwell_time, frame, frame_len, 1, 1, &cookie);
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */

	qdf_mem_free(frame);
exit:
	return ret;
}

/**
 * hdd_parse_sendactionframe_v1() - parse version 1 of the
 *       SENDACTIONFRAME command
 * @adapter:	Adapter upon which the command was received
 * @command:	ASCII text command that was received
 *
 * This function parses the v1 SENDACTIONFRAME command with the format
 *
 *    SENDACTIONFRAME xx:xx:xx:xx:xx:xx CH DW xxxxxx
 *
 * Where "xx:xx:xx:xx:xx:xx" is the Hex-ASCII representation of the
 * BSSID, CH is the ASCII representation of the channel, DW is the
 * ASCII representation of the dwell time, and xxxxxx is the Hex-ASCII
 * payload.  For example
 *
 *    SENDACTIONFRAME 00:0a:0b:11:22:33 48 40 aabbccddee
 *
 * Return: 0 for success non-zero for failure
 */
static int
hdd_parse_sendactionframe_v1(struct hdd_adapter *adapter, const char *command)
{
	uint8_t channel = 0;
	uint8_t dwell_time = 0;
	uint8_t payload_len = 0;
	uint8_t *payload = NULL;
	tSirMacAddr bssid;
	int ret;

	ret = hdd_parse_send_action_frame_v1_data(command, bssid, &channel,
						  &dwell_time, &payload,
						  &payload_len);
	if (ret) {
		hdd_err("Failed to parse send action frame data");
	} else {
		ret = hdd_sendactionframe(adapter, bssid, channel,
					  dwell_time, payload_len, payload);
		qdf_mem_free(payload);
	}

	return ret;
}

/**
 * hdd_parse_sendactionframe_v2() - parse version 2 of the
 *       SENDACTIONFRAME command
 * @adapter:	Adapter upon which the command was received
 * @command:	Command that was received, ASCII command
 *		followed by binary data
 *
 * This function parses the v2 SENDACTIONFRAME command with the format
 *
 *    SENDACTIONFRAME <android_wifi_af_params>
 *
 * Return: 0 for success non-zero for failure
 */
static int
hdd_parse_sendactionframe_v2(struct hdd_adapter *adapter,
			     const char *command, int total_len)
{
	struct android_wifi_af_params *params;
	tSirMacAddr bssid;
	int ret;
	int len_wo_payload = 0;

	/* The params are located after "SENDACTIONFRAME " */
	total_len -= 16;
	len_wo_payload = sizeof(*params) - ANDROID_WIFI_ACTION_FRAME_SIZE;
	if (total_len <= len_wo_payload) {
		hdd_err("Invalid command len");
		return -EINVAL;
	}

	params = (struct android_wifi_af_params *)(command + 16);

	if (params->len <= 0 || params->len > ANDROID_WIFI_ACTION_FRAME_SIZE ||
		(params->len > (total_len - len_wo_payload))) {
		hdd_err("Invalid payload length: %d", params->len);
		return -EINVAL;
	}

	if (!mac_pton(params->bssid, (u8 *)&bssid)) {
		hdd_err("MAC address parsing failed");
		return -EINVAL;
	}

	if (params->channel < 0 ||
	    params->channel > WNI_CFG_CURRENT_CHANNEL_STAMAX) {
		hdd_err("Invalid channel: %d", params->channel);
		return -EINVAL;
	}

	if (params->dwell_time < 0) {
		hdd_err("Invalid dwell_time: %d", params->dwell_time);
		return -EINVAL;
	}

	ret = hdd_sendactionframe(adapter, bssid, params->channel,
				params->dwell_time, params->len, params->data);

	return ret;
}

/**
 * hdd_parse_sendactionframe() - parse the SENDACTIONFRAME command
 * @adapter:	Adapter upon which the command was received
 * @command:	Command that was received
 *
 * There are two different versions of the SENDACTIONFRAME command.
 * Version 1 of the command contains a parameter list that is ASCII
 * characters whereas version 2 contains a combination of ASCII and
 * binary payload.  Determine if a version 1 or a version 2 command is
 * being parsed by examining the parameters, and then dispatch the
 * parser that is appropriate for the version of the command.
 *
 * Return: 0 for success non-zero for failure
 */
static int
hdd_parse_sendactionframe(struct hdd_adapter *adapter, const char *command,
			  int total_len)
{
	int ret;

	/*
	 * both versions start with "SENDACTIONFRAME "
	 * v1 has a bssid and other parameters as an ASCII string
	 *    SENDACTIONFRAME xx:xx:xx:xx:xx:xx CH DWELL LEN FRAME
	 * v2 has a C struct
	 *    SENDACTIONFRAME <binary c struct>
	 *
	 * The first field in the v2 struct is also the bssid in ASCII.
	 * But in the case of a v2 message the BSSID is NUL-terminated.
	 * Hence we can peek at that offset to see if this is V1 or V2
	 * SENDACTIONFRAME xx:xx:xx:xx:xx:xx*
	 *           111111111122222222223333
	 * 0123456789012345678901234567890123
	 * For both the commands, a valid command must have atleast
	 * first 34 length of data.
	 */
	if (total_len < 34) {
		hdd_err("Invalid command (total_len=%d)", total_len);
		return -EINVAL;
	}

	if (command[33])
		ret = hdd_parse_sendactionframe_v1(adapter, command);
	else
		ret = hdd_parse_sendactionframe_v2(adapter, command, total_len);

	return ret;
}

/**
 * hdd_parse_channellist() - HDD Parse channel list
 * @hdd_ctx: hdd context
 * @command: Pointer to input channel list
 * @channel_freq_list: Pointer to local output array to record
 *                channel list
 * @num_channels: Pointer to number of roam scan channels
 *
 * This function parses the channel list passed in the format
 * SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>
 * Channel 2<space>Channel N
 * if the Number of channels (N) does not match with the actual number
 * of channels passed then take the minimum of N and count of
 * (Ch1, Ch2, ...Ch M). For example, if SETROAMSCANCHANNELS 3 36 40 44 48,
 * only 36, 40 and 44 shall be taken. If SETROAMSCANCHANNELS 5 36 40 44 48,
 * ignore 5 and take 36, 40, 44 and 48. This function does not take care of
 * removing duplicate channels from the list
 *
 * Return: 0 for success non-zero for failure
 */
static int
hdd_parse_channellist(struct hdd_context *hdd_ctx,
		      const uint8_t *command,
		      uint32_t *channel_freq_list,
		      uint8_t *num_channels)
{
	const uint8_t *in_ptr = command;
	int temp_int;
	int j = 0;
	int v = 0;
	char buf[32];

	in_ptr = strnchr(command, strlen(command), SPACE_ASCII_VALUE);
	/* no argument after the command */
	if (!in_ptr)
		return -EINVAL;
	else if (SPACE_ASCII_VALUE != *in_ptr) /* no space after the command */
		return -EINVAL;

	/* remove empty spaces */
	while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr))
		in_ptr++;

	/* no argument followed by spaces */
	if ('\0' == *in_ptr)
		return -EINVAL;

	/* get the first argument ie the number of channels */
	v = sscanf(in_ptr, "%31s ", buf);
	if (1 != v)
		return -EINVAL;

	v = kstrtos32(buf, 10, &temp_int);
	if ((v < 0) ||
	    (temp_int <= 0) || (temp_int > CFG_VALID_CHANNEL_LIST_LEN))
		return -EINVAL;

	*num_channels = temp_int;

	hdd_debug("Number of channels are: %d", *num_channels);

	for (j = 0; j < (*num_channels); j++) {
		/*
		 * in_ptr pointing to the beginning of first space after number
		 * of channels
		 */
		in_ptr = strpbrk(in_ptr, " ");
		/* no channel list after the number of channels argument */
		if (!in_ptr) {
			if (0 != j) {
				*num_channels = j;
				return 0;
			} else {
				return -EINVAL;
			}
		}

		/* remove empty space */
		while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr))
			in_ptr++;

		/*
		 * no channel list after the number of channels
		 * argument and spaces
		 */
		if ('\0' == *in_ptr) {
			if (0 != j) {
				*num_channels = j;
				return 0;
			} else {
				return -EINVAL;
			}
		}

		v = sscanf(in_ptr, "%31s ", buf);
		if (1 != v)
			return -EINVAL;

		v = kstrtos32(buf, 10, &temp_int);
		if ((v < 0) ||
		    (temp_int <= 0) ||
		    (temp_int > WNI_CFG_CURRENT_CHANNEL_STAMAX)) {
			return -EINVAL;
		}
		channel_freq_list[j] =
			wlan_reg_chan_to_freq(hdd_ctx->pdev, temp_int);

		hdd_debug("Channel %d added to preferred channel list",
			  channel_freq_list[j]);
	}

	return 0;
}

/**
 * hdd_parse_set_roam_scan_channels_v1() - parse version 1 of the
 * SETROAMSCANCHANNELS command
 * @adapter:	Adapter upon which the command was received
 * @command:	ASCII text command that was received
 *
 * This function parses the v1 SETROAMSCANCHANNELS command with the format
 *
 *    SETROAMSCANCHANNELS N C1 C2 ... Cn
 *
 * Where "N" is the ASCII representation of the number of channels and
 * C1 thru Cn is the ASCII representation of the channels.  For example
 *
 *    SETROAMSCANCHANNELS 4 36 40 44 48
 *
 * Return: 0 for success non-zero for failure
 */
static int
hdd_parse_set_roam_scan_channels_v1(struct hdd_adapter *adapter,
				    const char *command)
{
	uint32_t channel_freq_list[CFG_VALID_CHANNEL_LIST_LEN] = { 0 };
	uint8_t num_chan = 0;
	QDF_STATUS status;
	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	int ret;
	mac_handle_t mac_handle;

	if (!hdd_ctx) {
		hdd_err("invalid hdd ctx");
		ret = -EINVAL;
		goto exit;
	}

	ret = hdd_parse_channellist(hdd_ctx, command, channel_freq_list,
				    &num_chan);
	if (ret) {
		hdd_err("Failed to parse channel list information");
		goto exit;
	}

	qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
		   TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
		   adapter->vdev_id, num_chan);

	if (num_chan > CFG_VALID_CHANNEL_LIST_LEN) {
		hdd_err("number of channels (%d) supported exceeded max (%d)",
			 num_chan, CFG_VALID_CHANNEL_LIST_LEN);
		ret = -EINVAL;
		goto exit;
	}

	mac_handle = hdd_ctx->mac_handle;
	if (!sme_validate_channel_list(mac_handle,
				       channel_freq_list, num_chan)) {
		hdd_err("List contains invalid channel(s)");
		ret = -EINVAL;
		goto exit;
	}

	status = sme_change_roam_scan_channel_list(mac_handle,
						   adapter->vdev_id,
						   channel_freq_list,
						   num_chan);
	if (QDF_STATUS_SUCCESS != status) {
		hdd_err("Failed to update channel list information");
		ret = -EINVAL;
		goto exit;
	}
exit:
	return ret;
}

/**
 * hdd_parse_set_roam_scan_channels_v2() - parse version 2 of the
 * SETROAMSCANCHANNELS command
 * @adapter:	Adapter upon which the command was received
 * @command:	Command that was received, ASCII command
 *		followed by binary data
 *
 * This function parses the v2 SETROAMSCANCHANNELS command with the format
 *
 *    SETROAMSCANCHANNELS [N][C1][C2][Cn]
 *
 * The command begins with SETROAMSCANCHANNELS followed by a space, but
 * what follows the space is an array of u08 parameters.  For example
 *
 *    SETROAMSCANCHANNELS [0x04 0x24 0x28 0x2c 0x30]
 *
 * Return: 0 for success non-zero for failure
 */
static int
hdd_parse_set_roam_scan_channels_v2(struct hdd_adapter *adapter,
				    const char *command)
{
	const uint8_t *value;
	uint32_t channel_freq_list[CFG_VALID_CHANNEL_LIST_LEN] = { 0 };
	uint8_t channel;
	uint8_t num_chan;
	int i;
	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	QDF_STATUS status;
	int ret = 0;
	mac_handle_t mac_handle;

	/* array of values begins after "SETROAMSCANCHANNELS " */
	value = command + 20;

	num_chan = *value++;
	if (num_chan > CFG_VALID_CHANNEL_LIST_LEN) {
		hdd_err("number of channels (%d) supported exceeded max (%d)",
			  num_chan, CFG_VALID_CHANNEL_LIST_LEN);
		ret = -EINVAL;
		goto exit;
	}

	qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
		   TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
		   adapter->vdev_id, num_chan);


	for (i = 0; i < num_chan; i++) {
		channel = *value++;
		if (!channel) {
			hdd_err("Channels end at index %d, expected %d",
				i, num_chan);
			ret = -EINVAL;
			goto exit;
		}

		if (channel > WNI_CFG_CURRENT_CHANNEL_STAMAX) {
			hdd_err("index %d invalid channel %d",
				  i, channel);
			ret = -EINVAL;
			goto exit;
		}
		channel_freq_list[i] = wlan_reg_chan_to_freq(hdd_ctx->pdev,
							     channel);
	}

	mac_handle = hdd_ctx->mac_handle;
	if (!sme_validate_channel_list(mac_handle, channel_freq_list,
				       num_chan)) {
		hdd_err("List contains invalid channel(s)");
		ret = -EINVAL;
		goto exit;
	}

	status = sme_change_roam_scan_channel_list(mac_handle,
						   adapter->vdev_id,
						   channel_freq_list, num_chan);
	if (QDF_STATUS_SUCCESS != status) {
		hdd_err("Failed to update channel list information");
		ret = -EINVAL;
		goto exit;
	}
exit:
	return ret;
}

/**
 * hdd_parse_set_roam_scan_channels() - parse the
 * SETROAMSCANCHANNELS command
 * @adapter:	Adapter upon which the command was received
 * @command:	Command that was received
 *
 * There are two different versions of the SETROAMSCANCHANNELS command.
 * Version 1 of the command contains a parameter list that is ASCII
 * characters whereas version 2 contains a binary payload.  Determine
 * if a version 1 or a version 2 command is being parsed by examining
 * the parameters, and then dispatch the parser that is appropriate for
 * the command.
 *
 * Return: 0 for success non-zero for failure
 */
static int
hdd_parse_set_roam_scan_channels(struct hdd_adapter *adapter, const char *command)
{
	const char *cursor;
	char ch;
	bool v1;
	int ret;

	/* start after "SETROAMSCANCHANNELS " */
	cursor = command + 20;

	/* assume we have a version 1 command until proven otherwise */
	v1 = true;

	/* v1 params will only contain ASCII digits and space */
	while ((ch = *cursor++) && v1) {
		if (!(isdigit(ch) || isspace(ch)))
			v1 = false;
	}

	if (v1)
		ret = hdd_parse_set_roam_scan_channels_v1(adapter, command);
	else
		ret = hdd_parse_set_roam_scan_channels_v2(adapter, command);

	return ret;
}

#ifdef FEATURE_WLAN_ESE
/**
 * hdd_parse_plm_cmd() - HDD Parse Plm command
 * @command: Pointer to input data
 * @req: Pointer to output struct plm_req
 *
 * This function parses the plm command passed in the format
 * CCXPLMREQ<space><enable><space><dialog_token><space>
 * <meas_token><space><num_of_bursts><space><burst_int><space>
 * <measu duration><space><burst_len><space><desired_tx_pwr>
 * <space><multcast_addr><space><number_of_channels>
 * <space><channel_numbers>
 *
 * Return: 0 for success non-zero for failure
 */
static QDF_STATUS hdd_parse_plm_cmd(uint8_t *command,
				    struct plm_req_params *req)
{
	uint8_t *in_ptr = NULL;
	int count, content = 0, ret = 0;
	char buf[32];

	/* move to argument list */
	in_ptr = strnchr(command, strlen(command), SPACE_ASCII_VALUE);
	if (!in_ptr)
		return QDF_STATUS_E_FAILURE;

	/* no space after the command */
	if (SPACE_ASCII_VALUE != *in_ptr)
		return QDF_STATUS_E_FAILURE;

	/* remove empty spaces */
	while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr))
		in_ptr++;

	/* START/STOP PLM req */
	ret = sscanf(in_ptr, "%31s ", buf);
	if (1 != ret)
		return QDF_STATUS_E_FAILURE;

	ret = kstrtos32(buf, 10, &content);
	if (ret < 0)
		return QDF_STATUS_E_FAILURE;

	req->enable = content;
	in_ptr = strpbrk(in_ptr, " ");

	if (!in_ptr)
		return QDF_STATUS_E_FAILURE;

	/* remove empty spaces */
	while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr))
		in_ptr++;

	/* Dialog token of radio meas req containing meas reqIE */
	ret = sscanf(in_ptr, "%31s ", buf);
	if (1 != ret)
		return QDF_STATUS_E_FAILURE;

	ret = kstrtos32(buf, 10, &content);
	if (ret < 0)
		return QDF_STATUS_E_FAILURE;

	req->diag_token = content;
	hdd_debug("diag token %d", req->diag_token);
	in_ptr = strpbrk(in_ptr, " ");

	if (!in_ptr)
		return QDF_STATUS_E_FAILURE;

	/* remove empty spaces */
	while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr))
		in_ptr++;

	/* measurement token of meas req IE */
	ret = sscanf(in_ptr, "%31s ", buf);
	if (1 != ret)
		return QDF_STATUS_E_FAILURE;

	ret = kstrtos32(buf, 10, &content);
	if (ret < 0)
		return QDF_STATUS_E_FAILURE;

	req->meas_token = content;
	hdd_debug("meas token %d", req->meas_token);

	hdd_debug("PLM req %s", req->enable ? "START" : "STOP");
	if (req->enable) {

		in_ptr = strpbrk(in_ptr, " ");

		if (!in_ptr)
			return QDF_STATUS_E_FAILURE;

		/* remove empty spaces */
		while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr))
			in_ptr++;

		/* total number of bursts after which STA stops sending */
		ret = sscanf(in_ptr, "%31s ", buf);
		if (1 != ret)
			return QDF_STATUS_E_FAILURE;

		ret = kstrtos32(buf, 10, &content);
		if (ret < 0)
			return QDF_STATUS_E_FAILURE;

		if (content < 0)
			return QDF_STATUS_E_FAILURE;

		req->num_bursts = content;
		hdd_debug("num bursts %d", req->num_bursts);
		in_ptr = strpbrk(in_ptr, " ");

		if (!in_ptr)
			return QDF_STATUS_E_FAILURE;

		/* remove empty spaces */
		while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr))
			in_ptr++;

		/* burst interval in seconds */
		ret = sscanf(in_ptr, "%31s ", buf);
		if (1 != ret)
			return QDF_STATUS_E_FAILURE;

		ret = kstrtos32(buf, 10, &content);
		if (ret < 0)
			return QDF_STATUS_E_FAILURE;

		if (content <= 0)
			return QDF_STATUS_E_FAILURE;

		req->burst_int = content;
		hdd_debug("burst int %d", req->burst_int);
		in_ptr = strpbrk(in_ptr, " ");

		if (!in_ptr)
			return QDF_STATUS_E_FAILURE;

		/* remove empty spaces */
		while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr))
			in_ptr++;

		/* Meas dur in TU's,STA goes off-ch and transmit PLM bursts */
		ret = sscanf(in_ptr, "%31s ", buf);
		if (1 != ret)
			return QDF_STATUS_E_FAILURE;

		ret = kstrtos32(buf, 10, &content);
		if (ret < 0)
			return QDF_STATUS_E_FAILURE;

		if (content <= 0)
			return QDF_STATUS_E_FAILURE;

		req->meas_duration = content;
		hdd_debug("meas duration %d", req->meas_duration);
		in_ptr = strpbrk(in_ptr, " ");

		if (!in_ptr)
			return QDF_STATUS_E_FAILURE;

		/* remove empty spaces */
		while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr))
			in_ptr++;

		/* burst length of PLM bursts */
		ret = sscanf(in_ptr, "%31s ", buf);
		if (1 != ret)
			return QDF_STATUS_E_FAILURE;

		ret = kstrtos32(buf, 10, &content);
		if (ret < 0)
			return QDF_STATUS_E_FAILURE;

		if (content <= 0)
			return QDF_STATUS_E_FAILURE;

		req->burst_len = content;
		hdd_debug("burst len %d", req->burst_len);
		in_ptr = strpbrk(in_ptr, " ");

		if (!in_ptr)
			return QDF_STATUS_E_FAILURE;

		/* remove empty spaces */
		while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr))
			in_ptr++;

		/* desired tx power for transmission of PLM bursts */
		ret = sscanf(in_ptr, "%31s ", buf);
		if (1 != ret)
			return QDF_STATUS_E_FAILURE;

		ret = kstrtos32(buf, 10, &content);
		if (ret < 0)
			return QDF_STATUS_E_FAILURE;

		if (content <= 0)
			return QDF_STATUS_E_FAILURE;

		req->desired_tx_pwr = content;
		hdd_debug("desired tx pwr %d", req->desired_tx_pwr);

		for (count = 0; count < QDF_MAC_ADDR_SIZE; count++) {
			in_ptr = strpbrk(in_ptr, " ");

			if (!in_ptr)
				return QDF_STATUS_E_FAILURE;

			/* remove empty spaces */
			while ((SPACE_ASCII_VALUE == *in_ptr)
			       && ('\0' != *in_ptr))
				in_ptr++;

			ret = sscanf(in_ptr, "%31s ", buf);
			if (1 != ret)
				return QDF_STATUS_E_FAILURE;

			ret = kstrtos32(buf, 16, &content);
			if (ret < 0)
				return QDF_STATUS_E_FAILURE;

			req->mac_addr.bytes[count] = content;
		}

		hdd_debug("MAC addr " QDF_MAC_ADDR_STR,
			  QDF_MAC_ADDR_ARRAY(req->mac_addr.bytes));

		in_ptr = strpbrk(in_ptr, " ");

		if (!in_ptr)
			return QDF_STATUS_E_FAILURE;

		/* remove empty spaces */
		while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr))
			in_ptr++;

		/* number of channels */
		ret = sscanf(in_ptr, "%31s ", buf);
		if (1 != ret)
			return QDF_STATUS_E_FAILURE;

		ret = kstrtos32(buf, 10, &content);
		if (ret < 0)
			return QDF_STATUS_E_FAILURE;

		if (content < 0)
			return QDF_STATUS_E_FAILURE;

		content = QDF_MIN(content, CFG_VALID_CHANNEL_LIST_LEN);
		req->plm_num_ch = content;
		hdd_debug("num ch: %d", req->plm_num_ch);

		/* Channel numbers */
		for (count = 0; count < req->plm_num_ch; count++) {
			in_ptr = strpbrk(in_ptr, " ");

			if (!in_ptr)
				return QDF_STATUS_E_FAILURE;

			/* remove empty spaces */
			while ((SPACE_ASCII_VALUE == *in_ptr)
			       && ('\0' != *in_ptr))
				in_ptr++;

			ret = sscanf(in_ptr, "%31s ", buf);
			if (1 != ret)
				return QDF_STATUS_E_FAILURE;

			ret = kstrtos32(buf, 10, &content);
			if (ret < 0 || content <= 0 ||
			    content > WNI_CFG_CURRENT_CHANNEL_STAMAX)
				return QDF_STATUS_E_FAILURE;

			req->plm_ch_freq_list[count] =
				cds_chan_to_freq(content);
			hdd_debug(" ch-freq- %d", req->plm_ch_freq_list[count]);
		}
	}
	/* If PLM START */
	return QDF_STATUS_SUCCESS;
}
#endif

#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
/**
 * wlan_hdd_ready_to_extwow() - Callback function for enable ext wow
 * @cookie: callback context
 * @is_success: suspend status of ext wow
 *
 * Return: none
 */
static void wlan_hdd_ready_to_extwow(void *cookie, bool is_success)
{
	struct osif_request *request = NULL;
	struct enable_ext_wow_priv *priv = NULL;

	request = osif_request_get(cookie);
	if (!request) {
		hdd_err("Obselete request");
		return;
	}
	priv = osif_request_priv(request);
	priv->ext_wow_should_suspend = is_success;

	osif_request_complete(request);
	osif_request_put(request);
}

static int hdd_enable_ext_wow(struct hdd_adapter *adapter,
			      tpSirExtWoWParams arg_params)
{
	tSirExtWoWParams params;
	QDF_STATUS status;
	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	int rc;
	struct enable_ext_wow_priv *priv = NULL;
	struct osif_request *request = NULL;
	void *cookie = NULL;
	struct osif_request_params hdd_params = {
		.priv_size = sizeof(*priv),
		.timeout_ms = WLAN_WAIT_TIME_READY_TO_EXTWOW,
	};

	qdf_mem_copy(&params, arg_params, sizeof(params));

	request = osif_request_alloc(&hdd_params);
	if (!request) {
		hdd_err("Request Allocation Failure");
		return -ENOMEM;
	}
	cookie = osif_request_cookie(request);

	status = sme_configure_ext_wow(hdd_ctx->mac_handle, &params,
				       &wlan_hdd_ready_to_extwow,
				       cookie);
	if (QDF_STATUS_SUCCESS != status) {
		hdd_err("sme_configure_ext_wow returned failure %d",
			 status);
		rc = -EPERM;
		goto exit;
	}

	rc = osif_request_wait_for_response(request);
	if (rc) {
		hdd_err("Failed to get ready to extwow");
		rc = -EPERM;
		goto exit;
	}

	priv = osif_request_priv(request);
	if (!priv->ext_wow_should_suspend) {
		hdd_err("Received ready to ExtWoW failure");
		rc = -EPERM;
		goto exit;
	}

	if (ucfg_pmo_extwow_is_goto_suspend_enabled(hdd_ctx->psoc)) {
		hdd_info("Received ready to ExtWoW. Going to suspend");

		rc = wlan_hdd_cfg80211_suspend_wlan(hdd_ctx->wiphy, NULL);
		if (rc < 0) {
			hdd_err("wlan_hdd_cfg80211_suspend_wlan failed, error = %d",
				rc);
			goto exit;
		}
		rc = wlan_hdd_bus_suspend();
		if (rc) {
			hdd_err("wlan_hdd_bus_suspend failed, status = %d",
				rc);
			wlan_hdd_cfg80211_resume_wlan(hdd_ctx->wiphy);
			goto exit;
		}
	}

exit:
	osif_request_put(request);
	return rc;
}

static int hdd_enable_ext_wow_parser(struct hdd_adapter *adapter, int vdev_id,
				     int value)
{
	tSirExtWoWParams params;
	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	int rc;
	uint8_t pin1, pin2;

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

	if (value < EXT_WOW_TYPE_APP_TYPE1 ||
	    value > EXT_WOW_TYPE_APP_TYPE1_2) {
		hdd_err("Invalid type: %d", value);
		return -EINVAL;
	}

	if (value == EXT_WOW_TYPE_APP_TYPE1 &&
	    hdd_ctx->is_extwow_app_type1_param_set)
		params.type = value;
	else if (value == EXT_WOW_TYPE_APP_TYPE2 &&
		 hdd_ctx->is_extwow_app_type2_param_set)
		params.type = value;
	else if (value == EXT_WOW_TYPE_APP_TYPE1_2 &&
		 hdd_ctx->is_extwow_app_type1_param_set &&
		 hdd_ctx->is_extwow_app_type2_param_set)
		params.type = value;
	else {
		hdd_err("Set app params before enable it value %d",
			 value);
		return -EINVAL;
	}

	params.vdev_id = vdev_id;
	pin1 = ucfg_pmo_extwow_app1_wakeup_pin_num(hdd_ctx->psoc);
	pin2 = ucfg_pmo_extwow_app2_wakeup_pin_num(hdd_ctx->psoc);
	params.wakeup_pin_num = pin1 | (pin2 << 8);

	return hdd_enable_ext_wow(adapter, &params);
}

static int hdd_set_app_type1_params(mac_handle_t mac_handle,
				    tpSirAppType1Params arg_params)
{
	tSirAppType1Params params;
	QDF_STATUS status;

	qdf_mem_copy(&params, arg_params, sizeof(params));

	status = sme_configure_app_type1_params(mac_handle, &params);
	if (QDF_STATUS_SUCCESS != status) {
		hdd_err("sme_configure_app_type1_params returned failure %d",
			 status);
		return -EPERM;
	}

	return 0;
}

static int hdd_set_app_type1_parser(struct hdd_adapter *adapter,
				    char *arg, int len)
{
	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	char id[20], password[20];
	tSirAppType1Params params;
	int rc;

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

	if (2 != sscanf(arg, "%8s %16s", id, password)) {
		hdd_err("Invalid Number of arguments");
		return -EINVAL;
	}

	memset(&params, 0, sizeof(tSirAppType1Params));
	params.vdev_id = adapter->vdev_id;
	qdf_copy_macaddr(&params.wakee_mac_addr, &adapter->mac_addr);

	params.id_length = strlen(id);
	qdf_mem_copy(params.identification_id, id, params.id_length);
	params.pass_length = strlen(password);
	qdf_mem_copy(params.password, password, params.pass_length);

	hdd_debug("%d %pM %.8s %u %.16s %u",
		  params.vdev_id, params.wakee_mac_addr.bytes,
		  params.identification_id, params.id_length,
		  params.password, params.pass_length);

	return hdd_set_app_type1_params(hdd_ctx->mac_handle, &params);
}

static int hdd_set_app_type2_params(mac_handle_t mac_handle,
				    tpSirAppType2Params arg_params)
{
	tSirAppType2Params params;
	QDF_STATUS status;

	qdf_mem_copy(&params, arg_params, sizeof(params));

	status = sme_configure_app_type2_params(mac_handle, &params);
	if (QDF_STATUS_SUCCESS != status) {
		hdd_err("sme_configure_app_type2_params returned failure %d",
			 status);
		return -EPERM;
	}

	return 0;
}

static int hdd_set_app_type2_parser(struct hdd_adapter *adapter,
				    char *arg, int len)
{
	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	char mac_addr[20], rc4_key[20];
	unsigned int gateway_mac[QDF_MAC_ADDR_SIZE];
	tSirAppType2Params params;
	int ret;

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

	memset(&params, 0, sizeof(tSirAppType2Params));

	ret = sscanf(arg, "%17s %16s %x %x %x %u %u %hu %hu %u %u %u %u %u %u",
		     mac_addr, rc4_key, (unsigned int *)&params.ip_id,
		     (unsigned int *)&params.ip_device_ip,
		     (unsigned int *)&params.ip_server_ip,
		     (unsigned int *)&params.tcp_seq,
		     (unsigned int *)&params.tcp_ack_seq,
		     (uint16_t *)&params.tcp_src_port,
		     (uint16_t *)&params.tcp_dst_port,
		     (unsigned int *)&params.keepalive_init,
		     (unsigned int *)&params.keepalive_min,
		     (unsigned int *)&params.keepalive_max,
		     (unsigned int *)&params.keepalive_inc,
		     (unsigned int *)&params.tcp_tx_timeout_val,
		     (unsigned int *)&params.tcp_rx_timeout_val);

	if (ret != 15 && ret != 7) {
		hdd_err("Invalid Number of arguments");
		return -EINVAL;
	}

	if (6 != sscanf(mac_addr, QDF_MAC_ADDR_STR,
			&gateway_mac[0], &gateway_mac[1], &gateway_mac[2],
			&gateway_mac[3], &gateway_mac[4], &gateway_mac[5])) {
		hdd_err("Invalid MacAddress Input %s", mac_addr);
		return -EINVAL;
	}

	if (params.tcp_src_port > WLAN_HDD_MAX_TCP_PORT ||
	    params.tcp_dst_port > WLAN_HDD_MAX_TCP_PORT) {
		hdd_err("Invalid TCP Port Number");
		return -EINVAL;
	}

	qdf_mem_copy(&params.gateway_mac.bytes, (uint8_t *) &gateway_mac,
			QDF_MAC_ADDR_SIZE);

	params.rc4_key_len = strlen(rc4_key);
	qdf_mem_copy(params.rc4_key, rc4_key, params.rc4_key_len);

	params.vdev_id = adapter->vdev_id;

	if (!params.tcp_src_port)
		params.tcp_src_port =
		  ucfg_pmo_extwow_app2_tcp_src_port(hdd_ctx->psoc);

	if (!params.tcp_dst_port)
		params.tcp_dst_port =
		  ucfg_pmo_extwow_app2_tcp_dst_port(hdd_ctx->psoc);

	if (!params.keepalive_init)
		params.keepalive_init =
		  ucfg_pmo_extwow_app2_init_ping_interval(hdd_ctx->psoc);

	if (!params.keepalive_min)
		params.keepalive_min =
		  ucfg_pmo_extwow_app2_min_ping_interval(hdd_ctx->psoc);

	if (!params.keepalive_max)
		params.keepalive_max =
		  ucfg_pmo_extwow_app2_max_ping_interval(hdd_ctx->psoc);

	if (!params.keepalive_inc)
		params.keepalive_inc =
		  ucfg_pmo_extwow_app2_inc_ping_interval(hdd_ctx->psoc);

	if (!params.tcp_tx_timeout_val)
		params.tcp_tx_timeout_val =
		  ucfg_pmo_extwow_app2_tcp_tx_timeout(hdd_ctx->psoc);

	if (!params.tcp_rx_timeout_val)
		params.tcp_rx_timeout_val =
		  ucfg_pmo_extwow_app2_tcp_rx_timeout(hdd_ctx->psoc);

	hdd_debug("%pM %.16s %u %u %u %u %u %u %u %u %u %u %u %u %u",
		  gateway_mac, rc4_key, params.ip_id,
		  params.ip_device_ip, params.ip_server_ip, params.tcp_seq,
		  params.tcp_ack_seq, params.tcp_src_port, params.tcp_dst_port,
		  params.keepalive_init, params.keepalive_min,
		  params.keepalive_max, params.keepalive_inc,
		  params.tcp_tx_timeout_val, params.tcp_rx_timeout_val);

	return hdd_set_app_type2_params(hdd_ctx->mac_handle, &params);
}
#endif /* WLAN_FEATURE_EXTWOW_SUPPORT */

/**
 * hdd_parse_setmaxtxpower_command() - HDD Parse MAXTXPOWER command
 * @command: Pointer to MAXTXPOWER command
 * @tx_power: Pointer to tx power
 *
 * This function parses the MAXTXPOWER command passed in the format
 * MAXTXPOWER<space>X(Tx power in dbm)
 *
 * For example input commands:
 * 1) MAXTXPOWER -8 -> This is translated into set max TX power to -8 dbm
 * 2) MAXTXPOWER -23 -> This is translated into set max TX power to -23 dbm
 *
 * Return: 0 for success non-zero for failure
 */
static int hdd_parse_setmaxtxpower_command(uint8_t *command, int *tx_power)
{
	uint8_t *in_ptr = command;
	int temp_int;
	int v = 0;
	*tx_power = 0;

	in_ptr = strnchr(command, strlen(command), SPACE_ASCII_VALUE);
	/* no argument after the command */
	if (!in_ptr)
		return -EINVAL;
	else if (SPACE_ASCII_VALUE != *in_ptr) /* no space after the command */
		return -EINVAL;

	/* remove empty spaces */
	while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr))
		in_ptr++;

	/* no argument followed by spaces */
	if ('\0' == *in_ptr)
		return 0;

	v = kstrtos32(in_ptr, 10, &temp_int);

	/* Range checking for passed parameter */
	if ((temp_int < HDD_MIN_TX_POWER) || (temp_int > HDD_MAX_TX_POWER))
		return -EINVAL;

	*tx_power = temp_int;

	hdd_debug("SETMAXTXPOWER: %d", *tx_power);

	return 0;
} /* End of hdd_parse_setmaxtxpower_command */

static int hdd_get_dwell_time(struct wlan_objmgr_psoc *psoc, uint8_t *command,
			      char *extra, uint8_t n, uint8_t *len)
{
	uint32_t val = 0;

	if (!psoc || !command || !extra || !len) {
		hdd_err("argument passed for GETDWELLTIME is incorrect");
		return -EINVAL;
	}

	if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0) {
		ucfg_scan_cfg_get_active_dwelltime(psoc, &val);
		*len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n", val);
		return 0;
	}
	if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0) {
		ucfg_scan_cfg_get_passive_dwelltime(psoc, &val);
		*len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
				 val);
		return 0;
	}
	if (strncmp(command, "GETDWELLTIME", 12) == 0) {
		ucfg_scan_cfg_get_active_dwelltime(psoc, &val);
		*len = scnprintf(extra, n, "GETDWELLTIME %u\n", val);
		return 0;
	}

	return -EINVAL;
}

static int hdd_set_dwell_time(struct wlan_objmgr_psoc *psoc, uint8_t *command)
{
	uint8_t *value = command;
	int retval = 0, temp = 0;
	uint32_t val = 0;

	if (!psoc) {
		hdd_err("psoc is null");
		return -EINVAL;
	}

	if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0) {
		if (drv_cmd_validate(command, 23))
			return -EINVAL;

		value = value + 24;
		temp = kstrtou32(value, 10, &val);
		if (temp || !cfg_in_range(CFG_ACTIVE_MAX_CHANNEL_TIME, val)) {
			hdd_err("argument passed for SETDWELLTIME ACTIVE MAX is incorrect");
			return -EFAULT;
		}
		ucfg_scan_cfg_set_active_dwelltime(psoc, val);
	} else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0) {
		if (drv_cmd_validate(command, 24))
			return -EINVAL;

		value = value + 25;
		temp = kstrtou32(value, 10, &val);
		if (temp || !cfg_in_range(CFG_PASSIVE_MAX_CHANNEL_TIME, val)) {
			hdd_err("argument passed for SETDWELLTIME PASSIVE MAX is incorrect");
			return -EFAULT;
		}
		ucfg_scan_cfg_set_passive_dwelltime(psoc, val);
	} else if (strncmp(command, "SETDWELLTIME", 12) == 0) {
		if (drv_cmd_validate(command, 12))
			return -EINVAL;

		value = value + 13;
		temp = kstrtou32(value, 10, &val);
		if (temp || !cfg_in_range(CFG_ACTIVE_MAX_CHANNEL_TIME, val)) {
			hdd_err("argument passed for SETDWELLTIME is incorrect");
			return -EFAULT;
		}
		ucfg_scan_cfg_set_active_dwelltime(psoc, val);
	} else {
		retval = -EINVAL;
	}

	return retval;
}

struct link_status_priv {
	uint8_t link_status;
};

/**
 * hdd_conc_set_dwell_time() - Set Concurrent dwell time parameters
 * @adapter: Adapter upon which the command was received
 * @command: ASCII text command that is received
 *
 * Driver commands:
 * wpa_cli DRIVER CONCSETDWELLTIME ACTIVE MAX <value>
 * wpa_cli DRIVER CONCSETDWELLTIME ACTIVE MIN <value>
 * wpa_cli DRIVER CONCSETDWELLTIME PASSIVE MAX <value>
 * wpa_cli DRIVER CONCSETDWELLTIME PASSIVE MIN <value>
 *
 * Return: 0 for success non-zero for failure
 */
static int hdd_conc_set_dwell_time(struct hdd_adapter *adapter,
				   uint8_t *command)
{
	u8 *value = command;
	int val = 0, temp = 0;
	int retval = 0;

	if (strncmp(command, "CONCSETDWELLTIME ACTIVE MAX", 27) == 0) {
		if (drv_cmd_validate(command, 27)) {
			hdd_err("Invalid driver command");
			return -EINVAL;
		}

		value = value + 28;
		temp = kstrtou32(value, 10, &val);
		if (temp ||
		    !cfg_in_range(CFG_ACTIVE_MAX_CHANNEL_TIME_CONC, val)) {
			hdd_err("CONC ACTIVE MAX value %d incorrect", val);
			return -EFAULT;
		}
		ucfg_scan_cfg_set_conc_active_dwelltime(
				(WLAN_HDD_GET_CTX(adapter))->psoc, val);
	} else if (strncmp(command, "CONCSETDWELLTIME PASSIVE MAX", 28) == 0) {
		if (drv_cmd_validate(command, 28)) {
			hdd_err("Invalid driver command");
			return -EINVAL;
		}

		value = value + 29;
		temp = kstrtou32(value, 10, &val);
		if (temp ||
		    !cfg_in_range(CFG_PASSIVE_MAX_CHANNEL_TIME_CONC, val)) {
			hdd_err("CONC PASSIVE MAX val %d incorrect", val);
			return -EFAULT;
		}
		ucfg_scan_cfg_set_conc_passive_dwelltime(
				(WLAN_HDD_GET_CTX(adapter))->psoc, val);
	} else {
		retval = -EINVAL;
	}

	return retval;
}

static void hdd_get_link_status_cb(uint8_t status, void *context)
{
	struct osif_request *request;
	struct link_status_priv *priv;

	request = osif_request_get(context);
	if (!request) {
		hdd_err("Obsolete request");
		return;
	}

	priv = osif_request_priv(request);
	priv->link_status = status;
	osif_request_complete(request);
	osif_request_put(request);
}

/**
 * wlan_hdd_get_link_status() - get link status
 * @adapter:     pointer to the adapter
 *
 * This function sends a request to query the link status and waits
 * on a timer to invoke the callback. if the callback is invoked then
 * latest link status shall be returned or otherwise cached value
 * will be returned.
 *
 * Return: On success, link status shall be returned.
 *         On error or not associated, link status 0 will be returned.
 */
static int wlan_hdd_get_link_status(struct hdd_adapter *adapter)
{
	struct hdd_station_ctx *sta_ctx;
	QDF_STATUS status;
	int ret;
	void *cookie;
	struct osif_request *request;
	struct link_status_priv *priv;
	static const struct osif_request_params params = {
		.priv_size = sizeof(*priv),
		.timeout_ms = WLAN_WAIT_TIME_LINK_STATUS,
	};

	if (cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
		hdd_warn("Recovery in Progress. State: 0x%x Ignore!!!",
			 cds_get_driver_state());
		return 0;
	}

	if ((QDF_STA_MODE != adapter->device_mode) &&
	    (QDF_P2P_CLIENT_MODE != adapter->device_mode)) {
		hdd_warn("Unsupported in mode %s(%d)",
			 qdf_opmode_str(adapter->device_mode),
			 adapter->device_mode);
		return 0;
	}

	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
	if (eConnectionState_Associated != sta_ctx->conn_info.conn_state) {
		/* If not associated, then expected link status return
		 * value is 0
		 */
		hdd_warn("Not associated!");
		return 0;
	}

	request = osif_request_alloc(&params);
	if (!request) {
		hdd_err("Request allocation failure");
		return 0;
	}
	cookie = osif_request_cookie(request);

	status = sme_get_link_status(adapter->hdd_ctx->mac_handle,
				     hdd_get_link_status_cb,
				     cookie, adapter->vdev_id);
	if (QDF_STATUS_SUCCESS != status) {
		hdd_err("Unable to retrieve link status");
		/* return a cached value */
	} else {
		/* request is sent -- wait for the response */
		ret = osif_request_wait_for_response(request);
		if (ret) {
			hdd_err("SME timed out while retrieving link status");
			/* return a cached value */
		} else {
			/* update the adapter with the fresh results */
			priv = osif_request_priv(request);
			adapter->link_status = priv->link_status;
		}
	}

	/*
	 * either we never sent a request, we sent a request and
	 * received a response or we sent a request and timed out.
	 * regardless we are done with the request.
	 */
	osif_request_put(request);

	/* either callback updated adapter stats or it has cached data */
	return adapter->link_status;
}

#ifdef FEATURE_WLAN_ESE
/**
 * hdd_parse_ese_beacon_req() - Parse ese beacon request
 * @command: Pointer to data
 * @req:	Output pointer to store parsed ie information
 *
 * This function parses the ese beacon request passed in the format
 * CCXBEACONREQ<space><Number of fields><space><Measurement token>
 * <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
 * <space>Scan Mode N<space>Meas Duration N
 *
 * If the Number of bcn req fields (N) does not match with the
 * actual number of fields passed then take N.
 * <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated
 * as one pair. For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
 * This function does not take care of removing duplicate channels from the
 * list
 *
 * Return: 0 for success non-zero for failure
 */
static int hdd_parse_ese_beacon_req(struct wlan_objmgr_pdev *pdev,
				    uint8_t *command,
				    tCsrEseBeaconReq *req)
{
	uint8_t *in_ptr = command;
	uint8_t input = 0;
	uint32_t temp_int = 0;
	int j = 0, i = 0, v = 0;
	char buf[32];

	in_ptr = strnchr(command, strlen(command), SPACE_ASCII_VALUE);
	if (!in_ptr) /* no argument after the command */
		return -EINVAL;
	else if (SPACE_ASCII_VALUE != *in_ptr) /* no space after the command */
		return -EINVAL;

	/* remove empty spaces */
	while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr))
		in_ptr++;

	/* no argument followed by spaces */
	if ('\0' == *in_ptr)
		return -EINVAL;

	/* Getting the first argument ie Number of IE fields */
	v = sscanf(in_ptr, "%31s ", buf);
	if (1 != v)
		return -EINVAL;

	v = kstrtou8(buf, 10, &input);
	if (v < 0)
		return -EINVAL;

	input = QDF_MIN(input, SIR_ESE_MAX_MEAS_IE_REQS);
	req->numBcnReqIe = input;

	hdd_debug("Number of Bcn Req Ie fields: %d", req->numBcnReqIe);

	for (j = 0; j < (req->numBcnReqIe); j++) {
		for (i = 0; i < 4; i++) {
			/*
			 * in_ptr pointing to the beginning of 1st space
			 * after number of ie fields
			 */
			in_ptr = strpbrk(in_ptr, " ");
			/* no ie data after the number of ie fields argument */
			if (!in_ptr)
				return -EINVAL;

			/* remove empty space */
			while ((SPACE_ASCII_VALUE == *in_ptr)
			       && ('\0' != *in_ptr))
				in_ptr++;

			/*
			 * no ie data after the number of ie fields
			 * argument and spaces
			 */
			if ('\0' == *in_ptr)
				return -EINVAL;

			v = sscanf(in_ptr, "%31s ", buf);
			if (1 != v)
				return -EINVAL;

			v = kstrtou32(buf, 10, &temp_int);
			if (v < 0)
				return -EINVAL;

			switch (i) {
			case 0: /* Measurement token */
				if (!temp_int) {
					hdd_err("Invalid Measurement Token: %u",
						  temp_int);
					return -EINVAL;
				}
				req->bcnReq[j].measurementToken =
					temp_int;
				break;

			case 1: /* Channel number */
				if (!temp_int ||
				    (temp_int >
				     WNI_CFG_CURRENT_CHANNEL_STAMAX)) {
					hdd_err("Invalid Channel Number: %u",
						  temp_int);
					return -EINVAL;
				}
				req->bcnReq[j].ch_freq =
				wlan_reg_chan_to_freq(pdev, temp_int);
				break;

			case 2: /* Scan mode */
				if ((temp_int < eSIR_PASSIVE_SCAN)
				    || (temp_int > eSIR_BEACON_TABLE)) {
					hdd_err("Invalid Scan Mode: %u Expected{0|1|2}",
						  temp_int);
					return -EINVAL;
				}
				req->bcnReq[j].scanMode = temp_int;
				break;

			case 3: /* Measurement duration */
				if ((!temp_int
				     && (req->bcnReq[j].scanMode !=
					 eSIR_BEACON_TABLE)) ||
				    (req->bcnReq[j].scanMode ==
						eSIR_BEACON_TABLE)) {
					hdd_err("Invalid Measurement Duration: %u",
						  temp_int);
					return -EINVAL;
				}
				req->bcnReq[j].measurementDuration =
					temp_int;
				break;
			}
		}
	}

	for (j = 0; j < req->numBcnReqIe; j++) {
		hdd_debug("Index: %d Measurement Token: %u ch_freq: %u Scan Mode: %u Measurement Duration: %u",
			  j,
			  req->bcnReq[j].measurementToken,
			  req->bcnReq[j].ch_freq,
			  req->bcnReq[j].scanMode,
			  req->bcnReq[j].measurementDuration);
	}

	return 0;
}

/**
 * hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
 * @command: Pointer to input data
 * @cckm_ie: Pointer to output cckm Ie
 * @cckm_ie_len: Pointer to output cckm ie length
 *
 * This function parses the SETCCKM IE command
 * SETCCKMIE<space><ie data>
 *
 * Return: 0 for success non-zero for failure
 */
static int hdd_parse_get_cckm_ie(uint8_t *command, uint8_t **cckm_ie,
				 uint8_t *cckm_ie_len)
{
	uint8_t *in_ptr = command;
	uint8_t *end_ptr;
	int j = 0;
	int i = 0;
	uint8_t temp_u8 = 0;

	in_ptr = strnchr(command, strlen(command), SPACE_ASCII_VALUE);
	/* no argument after the command */
	if (!in_ptr)
		return -EINVAL;
	else if (SPACE_ASCII_VALUE != *in_ptr) /* no space after the command */
		return -EINVAL;

	/* remove empty spaces */
	while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr))
		in_ptr++;
	/* no argument followed by spaces */
	if ('\0' == *in_ptr)
		return -EINVAL;

	/* find the length of data */
	end_ptr = in_ptr;
	while (('\0' != *end_ptr)) {
		end_ptr++;
		++(*cckm_ie_len);
	}
	if (*cckm_ie_len <= 0)
		return -EINVAL;
	/*
	 * Allocate the number of bytes based on the number of input characters
	 * whether it is even or odd.
	 * if the number of input characters are even, then we need N / 2 byte.
	 * if the number of input characters are odd, then we need do
	 * (N + 1) / 2 to compensate rounding off.
	 * For example, if N = 18, then (18 + 1) / 2 = 9 bytes are enough.
	 * If N = 19, then we need 10 bytes, hence (19 + 1) / 2 = 10 bytes
	 */
	*cckm_ie = qdf_mem_malloc((*cckm_ie_len + 1) / 2);
	if (!*cckm_ie) {
		hdd_err("qdf_mem_malloc failed");
		return -ENOMEM;
	}
	/*
	 * the buffer received from the upper layer is character buffer,
	 * we need to prepare the buffer taking 2 characters in to a U8 hex
	 * decimal number for example 7f0000f0...form a buffer to contain
	 * 7f in 0th location, 00 in 1st and f0 in 3rd location
	 */
	for (i = 0, j = 0; j < *cckm_ie_len; j += 2) {
		temp_u8 = (hex_to_bin(in_ptr[j]) << 4) |
			   (hex_to_bin(in_ptr[j + 1]));
		(*cckm_ie)[i++] = temp_u8;
	}
	*cckm_ie_len = i;
	return 0;
}
#endif /* FEATURE_WLAN_ESE */

int wlan_hdd_set_mc_rate(struct hdd_adapter *adapter, int target_rate)
{
	tSirRateUpdateInd rate_update = {0};
	QDF_STATUS status;
	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	bool bval = false;

	if (!hdd_ctx) {
		hdd_err("HDD context is null");
		return -EINVAL;
	}
	if ((QDF_IBSS_MODE != adapter->device_mode) &&
	    (QDF_SAP_MODE != adapter->device_mode) &&
	    (QDF_STA_MODE != adapter->device_mode)) {
		hdd_err("Received SETMCRATE cmd in invalid mode %s(%d)",
			qdf_opmode_str(adapter->device_mode),
			adapter->device_mode);
		hdd_err("SETMCRATE cmd is allowed only in STA, IBSS or SOFTAP mode");
		return -EINVAL;
	}

	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		hdd_err("unable to get vht_enable2x2");
		return -EINVAL;
	}
	rate_update.nss = (bval == 0) ? 0 : 1;

	rate_update.dev_mode = adapter->device_mode;
	rate_update.mcastDataRate24GHz = target_rate;
	rate_update.mcastDataRate24GHzTxFlag = 1;
	rate_update.mcastDataRate5GHz = target_rate;
	rate_update.bcastDataRate = -1;
	qdf_copy_macaddr(&rate_update.bssid, &adapter->mac_addr);
	hdd_debug("MC Target rate %d, mac = %pM, dev_mode %s(%d)",
		  rate_update.mcastDataRate24GHz, rate_update.bssid.bytes,
		  qdf_opmode_str(adapter->device_mode), adapter->device_mode);
	status = sme_send_rate_update_ind(hdd_ctx->mac_handle, &rate_update);
	if (QDF_STATUS_SUCCESS != status) {
		hdd_err("SETMCRATE failed");
		return -EFAULT;
	}
	return 0;
}

static int drv_cmd_p2p_dev_addr(struct hdd_adapter *adapter,
				struct hdd_context *hdd_ctx,
				uint8_t *command,
				uint8_t command_len,
				struct hdd_priv_data *priv_data)
{
	struct qdf_mac_addr *addr = &hdd_ctx->p2p_device_address;
	size_t user_size = qdf_min(sizeof(addr->bytes),
				   (size_t)priv_data->total_len);

	qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
		   TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
		   adapter->vdev_id,
		   (unsigned int)(*(addr->bytes + 2) << 24 |
				*(addr->bytes + 3) << 16 |
				*(addr->bytes + 4) << 8 |
				*(addr->bytes + 5)));


	if (copy_to_user(priv_data->buf, addr->bytes, user_size)) {
		hdd_err("failed to copy data to user buffer");
		return -EFAULT;
	}

	return 0;
}

/**
 * drv_cmd_p2p_set_noa() - Handler for P2P_SET_NOA driver command
 * @adapter: Adapter on which the command was received
 * @hdd_ctx: HDD global context
 * @command: Entire driver command received from userspace
 * @command_len: Length of @command
 * @priv_data: Pointer to ioctl private data structure
 *
 * This is a trivial command handler function which simply forwards the
 * command to the actual command processor within the P2P module.
 *
 * Return: 0 on success, non-zero on failure
 */
static int drv_cmd_p2p_set_noa(struct hdd_adapter *adapter,
			       struct hdd_context *hdd_ctx,
			       uint8_t *command,
			       uint8_t command_len,
			       struct hdd_priv_data *priv_data)
{
	return hdd_set_p2p_noa(adapter->dev, command);
}

/**
 * drv_cmd_p2p_set_ps() - Handler for P2P_SET_PS driver command
 * @adapter: Adapter on which the command was received
 * @hdd_ctx: HDD global context
 * @command: Entire driver command received from userspace
 * @command_len: Length of @command
 * @priv_data: Pointer to ioctl private data structure
 *
 * This is a trivial command handler function which simply forwards the
 * command to the actual command processor within the P2P module.
 *
 * Return: 0 on success, non-zero on failure
 */
static int drv_cmd_p2p_set_ps(struct hdd_adapter *adapter,
			      struct hdd_context *hdd_ctx,
			      uint8_t *command,
			      uint8_t command_len,
			      struct hdd_priv_data *priv_data)
{
	return hdd_set_p2p_opps(adapter->dev, command);
}

static int drv_cmd_set_band(struct hdd_adapter *adapter,
			    struct hdd_context *hdd_ctx,
			    uint8_t *command,
			    uint8_t command_len,
			    struct hdd_priv_data *priv_data)
{
	int err;
	uint8_t band;

	/*
	 * Parse the band value passed from userspace. The first 8 bytes
	 * should be "SETBAND " and the 9th byte should be a UI band value
	 */
	err = kstrtou8(command + command_len + 1, 10, &band);
	if (err) {
		hdd_err("error %d parsing userspace band parameter", err);
		return err;
	}

	return hdd_reg_set_band(adapter->dev, band);
}

static int drv_cmd_set_wmmps(struct hdd_adapter *adapter,
			     struct hdd_context *hdd_ctx,
			     uint8_t *command,
			     uint8_t command_len,
			     struct hdd_priv_data *priv_data)
{
	return hdd_wmmps_helper(adapter, command);
}

static inline int drv_cmd_country(struct hdd_adapter *adapter,
				  struct hdd_context *hdd_ctx,
				  uint8_t *command,
				  uint8_t command_len,
				  struct hdd_priv_data *priv_data)
{
	char *country_code;

	country_code = strnchr(command, strlen(command), ' ');
	/* no argument after the command */
	if (!country_code)
		return -EINVAL;

	/* no space after the command */
	if (*country_code != SPACE_ASCII_VALUE)
		return -EINVAL;

	country_code++;

	/* removing empty spaces */
	while ((*country_code == SPACE_ASCII_VALUE) &&
	       (*country_code != '\0'))
		country_code++;

	/* no or less than 2  arguments followed by spaces */
	if (*country_code == '\0' || *(country_code + 1) == '\0')
		return -EINVAL;

	return hdd_reg_set_country(hdd_ctx, country_code);
}

/**
 * drv_cmd_get_country() - Helper function to get current county code
 * @adapter: pointer to adapter on which request is received
 * @hdd_ctx: pointer to hdd context
 * @command: command name
 * @command_len: command buffer length
 * @priv_data: output pointer to hold current country code
 *
 * Return: On success 0, negative value on error.
 */
static int drv_cmd_get_country(struct hdd_adapter *adapter,
			       struct hdd_context *hdd_ctx,
			       uint8_t *command, uint8_t command_len,
			       struct hdd_priv_data *priv_data)
{
	uint8_t buf[SIZE_OF_GETCOUNTRYREV_OUTPUT] = {0};
	uint8_t cc[REG_ALPHA2_LEN + 1];
	int ret = 0, len;

	qdf_mem_copy(cc, hdd_ctx->reg.alpha2, REG_ALPHA2_LEN);
	cc[REG_ALPHA2_LEN] = '\0';

	len = scnprintf(buf, sizeof(buf), "%s %s",
			"GETCOUNTRYREV", cc);
	hdd_debug("buf = %s", buf);
	len = QDF_MIN(priv_data->total_len, len + 1);
	if (copy_to_user(priv_data->buf, buf, len)) {
		hdd_err("failed to copy data to user buffer");
		ret = -EFAULT;
	}

	return ret;
}

static int drv_cmd_set_roam_trigger(struct hdd_adapter *adapter,
				    struct hdd_context *hdd_ctx,
				    uint8_t *command,
				    uint8_t command_len,
				    struct hdd_priv_data *priv_data)
{
	int ret;
	uint8_t *value = command;
	int8_t rssi = 0;
	uint8_t lookup_threshold = cfg_default(
					CFG_LFR_NEIGHBOR_LOOKUP_RSSI_THRESHOLD);
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	/* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
	value = value + command_len + 1;

	/* Convert the value from ascii to integer */
	ret = kstrtos8(value, 10, &rssi);
	if (ret < 0) {
		/*
		 * If the input value is greater than max value of datatype,
		 * then also kstrtou8 fails
		 */
		hdd_err("kstrtou8 failed Input value may be out of range[%d - %d]",
			cfg_min(CFG_LFR_NEIGHBOR_LOOKUP_RSSI_THRESHOLD),
			cfg_max(CFG_LFR_NEIGHBOR_LOOKUP_RSSI_THRESHOLD));
		ret = -EINVAL;
		goto exit;
	}

	lookup_threshold = abs(rssi);

	if (!cfg_in_range(CFG_LFR_NEIGHBOR_LOOKUP_RSSI_THRESHOLD,
			  lookup_threshold)) {
		hdd_err("Neighbor lookup threshold value %d is out of range (Min: %d Max: %d)",
			  lookup_threshold,
			  cfg_min(CFG_LFR_NEIGHBOR_LOOKUP_RSSI_THRESHOLD),
			  cfg_max(CFG_LFR_NEIGHBOR_LOOKUP_RSSI_THRESHOLD));
		ret = -EINVAL;
		goto exit;
	}

	qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
		   TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
		   adapter->vdev_id, lookup_threshold);

	hdd_debug("Received Command to Set Roam trigger (Neighbor lookup threshold) = %d",
		  lookup_threshold);

	status = sme_set_neighbor_lookup_rssi_threshold(hdd_ctx->mac_handle,
							adapter->vdev_id,
							lookup_threshold);
	if (QDF_STATUS_SUCCESS != status) {
		hdd_err("Failed to set roam trigger, try again");
		ret = -EPERM;
		goto exit;
	}

exit:
	return ret;
}

static int drv_cmd_get_roam_trigger(struct hdd_adapter *adapter,
				    struct hdd_context *hdd_ctx,
				    uint8_t *command,
				    uint8_t command_len,
				    struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint8_t lookup_threshold;
	int rssi;
	char extra[32];
	uint8_t len = 0;
	QDF_STATUS status;

	status = sme_get_neighbor_lookup_rssi_threshold(hdd_ctx->mac_handle,
							adapter->vdev_id,
							&lookup_threshold);
	if (QDF_IS_STATUS_ERROR(status))
		return qdf_status_to_os_return(status);

	qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
		   TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
		   adapter->vdev_id, lookup_threshold);

	hdd_debug("vdev_id: %u, lookup_threshold: %u",
		  adapter->vdev_id, lookup_threshold);

	rssi = (-1) * lookup_threshold;

	len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
	len = QDF_MIN(priv_data->total_len, len + 1);
	if (copy_to_user(priv_data->buf, &extra, len)) {
		hdd_err("failed to copy data to user buffer");
		ret = -EFAULT;
	}

	return ret;
}

static int drv_cmd_set_roam_scan_period(struct hdd_adapter *adapter,
					struct hdd_context *hdd_ctx,
					uint8_t *command,
					uint8_t command_len,
					struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint8_t *value = command;
	uint8_t roam_scan_period = 0;
	uint16_t empty_scan_refresh_period =
		cfg_default(CFG_LFR_EMPTY_SCAN_REFRESH_PERIOD);

	/* input refresh period is in terms of seconds */

	/* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
	value = value + command_len + 1;

	/* Convert the value from ascii to integer */
	ret = kstrtou8(value, 10, &roam_scan_period);
	if (ret < 0) {
		/*
		 * If the input value is greater than max value of datatype,
		 * then also kstrtou8 fails
		 */
		hdd_err("kstrtou8 failed Input value may be out of range[%d - %d]",
			(cfg_min(CFG_LFR_EMPTY_SCAN_REFRESH_PERIOD) / 1000),
			(cfg_max(CFG_LFR_EMPTY_SCAN_REFRESH_PERIOD) / 1000));
		ret = -EINVAL;
		goto exit;
	}

	if (!ucfg_mlme_validate_scan_period(roam_scan_period * 1000)) {
		ret = -EINVAL;
		goto exit;
	}

	qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
		   TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
		   adapter->vdev_id, roam_scan_period);

	empty_scan_refresh_period = roam_scan_period * 1000;

	hdd_debug("Received Command to Set roam scan period (Empty Scan refresh period) = %d",
		  roam_scan_period);

	sme_update_empty_scan_refresh_period(hdd_ctx->mac_handle,
					     adapter->vdev_id,
					     empty_scan_refresh_period);

exit:
	return ret;
}

static int drv_cmd_get_roam_scan_period(struct hdd_adapter *adapter,
					struct hdd_context *hdd_ctx,
					uint8_t *command,
					uint8_t command_len,
					struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint16_t empty_scan_refresh_period;
	char extra[32];
	uint8_t len;
	QDF_STATUS status;

	status = sme_get_empty_scan_refresh_period(hdd_ctx->mac_handle,
						   adapter->vdev_id,
						   &empty_scan_refresh_period);
	if (QDF_IS_STATUS_ERROR(status))
		return qdf_status_to_os_return(status);

	hdd_debug("vdev_id: %u, empty_scan_refresh_period: %u",
		  adapter->vdev_id, empty_scan_refresh_period);

	qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
		   TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
		   adapter->vdev_id,
		   empty_scan_refresh_period);

	len = scnprintf(extra, sizeof(extra), "%s %d",
			"GETROAMSCANPERIOD",
			(empty_scan_refresh_period / 1000));
	/* Returned value is in units of seconds */
	len = QDF_MIN(priv_data->total_len, len + 1);
	if (copy_to_user(priv_data->buf, &extra, len)) {
		hdd_err("failed to copy data to user buffer");
		ret = -EFAULT;
	}

	return ret;
}

static int drv_cmd_set_roam_scan_refresh_period(struct hdd_adapter *adapter,
						struct hdd_context *hdd_ctx,
						uint8_t *command,
						uint8_t command_len,
						struct hdd_priv_data *priv_data)
{
	int ret;
	uint8_t *value = command;
	uint8_t roam_scan_refresh_period = 0;
	uint16_t neighbor_scan_refresh_period =
		cfg_default(CFG_LFR_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD);

	/* input refresh period is in terms of seconds */
	/* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
	value = value + command_len + 1;

	/* Convert the value from ascii to integer */
	ret = kstrtou8(value, 10, &roam_scan_refresh_period);
	if (ret < 0) {
		/*
		 * If the input value is greater than max value of datatype,
		 * then also kstrtou8 fails
		 */
		hdd_err("kstrtou8 failed Input value may be out of range[%d - %d]",
			(cfg_min(CFG_LFR_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD)
			 / 1000),
			(cfg_max(CFG_LFR_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD)
			 / 1000));
		ret = -EINVAL;
		goto exit;
	}

	if (!cfg_in_range(CFG_LFR_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD,
			  roam_scan_refresh_period)) {
		hdd_err("Neighbor scan results refresh period value %d is out of range (Min: %d Max: %d)",
			roam_scan_refresh_period,
			(cfg_min(CFG_LFR_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD)
			 / 1000),
			(cfg_max(CFG_LFR_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD)
			 / 1000));
		ret = -EINVAL;
		goto exit;
	}
	neighbor_scan_refresh_period = roam_scan_refresh_period * 1000;

	hdd_debug("Received Command to Set roam scan refresh period (Scan refresh period) = %d",
		  neighbor_scan_refresh_period);

	sme_set_neighbor_scan_refresh_period(hdd_ctx->mac_handle,
					     adapter->vdev_id,
					     neighbor_scan_refresh_period);

exit:
	return ret;
}

static int drv_cmd_get_roam_scan_refresh_period(struct hdd_adapter *adapter,
						struct hdd_context *hdd_ctx,
						uint8_t *command,
						uint8_t command_len,
						struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint16_t value =
		sme_get_neighbor_scan_refresh_period(hdd_ctx->mac_handle);
	char extra[32];
	uint8_t len;

	len = scnprintf(extra, sizeof(extra), "%s %d",
			"GETROAMSCANREFRESHPERIOD",
			(value / 1000));
	/* Returned value is in units of seconds */
	len = QDF_MIN(priv_data->total_len, len + 1);
	if (copy_to_user(priv_data->buf, &extra, len)) {
		hdd_err("failed to copy data to user buffer");
		ret = -EFAULT;
	}

	return ret;
}

static int drv_cmd_set_roam_mode(struct hdd_adapter *adapter,
				 struct hdd_context *hdd_ctx,
				 uint8_t *command,
				 uint8_t command_len,
				 struct hdd_priv_data *priv_data)
{
	mac_handle_t mac_handle;
	int ret;
	uint8_t *value = command;
	uint8_t roam_mode = cfg_default(CFG_LFR_FEATURE_ENABLED);

	/* Move pointer to ahead of SETROAMMODE<delimiter> */
	value = value + SIZE_OF_SETROAMMODE + 1;

	/* Convert the value from ascii to integer */
	ret = kstrtou8(value, 10, &roam_mode);
	if (ret < 0) {
		/*
		 * If the input value is greater than max value of datatype,
		 * then also kstrtou8 fails
		 */
		hdd_err("kstrtou8 failed range [%d - %d]",
			cfg_min(CFG_LFR_FEATURE_ENABLED),
			cfg_max(CFG_LFR_FEATURE_ENABLED));
		ret = -EINVAL;
		goto exit;
	}

	hdd_debug("Received Command to Set Roam Mode = %d",
		  roam_mode);
	/*
	 * Note that
	 *     SETROAMMODE 0 is to enable LFR while
	 *     SETROAMMODE 1 is to disable LFR, but
	 *     notify_is_fast_roam_ini_feature_enabled 0/1 is to
	 *     enable/disable. So, we have to invert the value
	 *     to call sme_update_is_fast_roam_ini_feature_enabled.
	 */
	if (roam_mode) {
		/* Roam enable */
		roam_mode = cfg_min(CFG_LFR_FEATURE_ENABLED);
	} else {
		/* Roam disable */
		roam_mode = cfg_max(CFG_LFR_FEATURE_ENABLED);
	}

	ucfg_mlme_set_lfr_enabled(hdd_ctx->psoc, (bool)roam_mode);
	mac_handle = hdd_ctx->mac_handle;
	if (roam_mode) {
		ucfg_mlme_set_roam_scan_offload_enabled(hdd_ctx->psoc,
							(bool)roam_mode);
		sme_update_is_fast_roam_ini_feature_enabled(mac_handle,
							    adapter->vdev_id,
							    roam_mode);
	} else {
		sme_update_is_fast_roam_ini_feature_enabled(mac_handle,
							    adapter->vdev_id,
							    roam_mode);
		ucfg_mlme_set_roam_scan_offload_enabled(hdd_ctx->psoc,
							roam_mode);
	}

exit:
	return ret;
}

static int drv_cmd_set_suspend_mode(struct hdd_adapter *adapter,
				    struct hdd_context *hdd_ctx,
				    uint8_t *command,
				    uint8_t command_len,
				    struct hdd_priv_data *priv_data)
{
	int errno;
	uint8_t *value = command;
	QDF_STATUS status;
	uint8_t idle_monitor;

	if (QDF_STA_MODE != adapter->device_mode) {
		hdd_debug("Non-STA interface");
		return 0;
	}

	/* Move pointer to ahead of SETSUSPENDMODE<delimiter> */
	value = value + SIZE_OF_SETSUSPENDMODE + 1;

	/* Convert the value from ascii to integer */
	errno = kstrtou8(value, 10, &idle_monitor);
	if (errno < 0) {
		/*
		 * If the input value is greater than max value of datatype,
		 * then also kstrtou8 fails
		 */
		hdd_err("Range validation failed");
		return -EINVAL;
	}

	hdd_debug("idle_monitor:%d", idle_monitor);
	status = ucfg_pmo_tgt_psoc_send_idle_roam_suspend_mode(hdd_ctx->psoc,
							       idle_monitor);
	if (QDF_IS_STATUS_ERROR(status)) {
		hdd_debug("Send suspend mode to fw failed");
		return -EINVAL;
	}
	return 0;
}

static int drv_cmd_get_roam_mode(struct hdd_adapter *adapter,
				 struct hdd_context *hdd_ctx,
				 uint8_t *command,
				 uint8_t command_len,
				 struct hdd_priv_data *priv_data)
{
	int ret = 0;
	bool roam_mode = sme_get_is_lfr_feature_enabled(hdd_ctx->mac_handle);
	char extra[32];
	uint8_t len;

	/*
	 * roamMode value shall be inverted because the sementics is different.
	 */
	if (roam_mode)
		roam_mode = cfg_min(CFG_LFR_FEATURE_ENABLED);
	else
		roam_mode = cfg_max(CFG_LFR_FEATURE_ENABLED);

	len = scnprintf(extra, sizeof(extra), "%s %d", command, roam_mode);
	len = QDF_MIN(priv_data->total_len, len + 1);
	if (copy_to_user(priv_data->buf, &extra, len)) {
		hdd_err("failed to copy data to user buffer");
		ret = -EFAULT;
	}

	return ret;
}

static int drv_cmd_set_roam_delta(struct hdd_adapter *adapter,
				  struct hdd_context *hdd_ctx,
				  uint8_t *command,
				  uint8_t command_len,
				  struct hdd_priv_data *priv_data)
{
	int ret;
	uint8_t *value = command;
	uint8_t roam_rssi_diff = cfg_default(CFG_LFR_ROAM_RSSI_DIFF);

	/* Move pointer to ahead of SETROAMDELTA<delimiter> */
	value = value + command_len + 1;

	/* Convert the value from ascii to integer */
	ret = kstrtou8(value, 10, &roam_rssi_diff);
	if (ret < 0) {
		/*
		 * If the input value is greater than max value of datatype,
		 * then also kstrtou8 fails
		 */
		hdd_err("kstrtou8 failed range [%d - %d]",
			cfg_min(CFG_LFR_ROAM_RSSI_DIFF),
			cfg_max(CFG_LFR_ROAM_RSSI_DIFF));
		ret = -EINVAL;
		goto exit;
	}

	if (!cfg_in_range(CFG_LFR_ROAM_RSSI_DIFF, roam_rssi_diff)) {
		hdd_err("Roam rssi diff value %d is out of range (Min: %d Max: %d)",
			roam_rssi_diff,
			cfg_min(CFG_LFR_ROAM_RSSI_DIFF),
			cfg_max(CFG_LFR_ROAM_RSSI_DIFF));
		ret = -EINVAL;
		goto exit;
	}

	hdd_debug("Received Command to Set roam rssi diff = %d",
		  roam_rssi_diff);

	sme_update_roam_rssi_diff(hdd_ctx->mac_handle,
				  adapter->vdev_id,
				  roam_rssi_diff);

exit:
	return ret;
}

static int drv_cmd_get_roam_delta(struct hdd_adapter *adapter,
				  struct hdd_context *hdd_ctx,
				  uint8_t *command,
				  uint8_t command_len,
				  struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint8_t rssi_diff;
	char extra[32];
	uint8_t len;
	QDF_STATUS status;

	status = sme_get_roam_rssi_diff(hdd_ctx->mac_handle, adapter->vdev_id,
					&rssi_diff);
	if (QDF_IS_STATUS_ERROR(status))
		return qdf_status_to_os_return(status);

	hdd_debug("vdev_id: %u, rssi_diff: %u", adapter->vdev_id, rssi_diff);

	qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
		   TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
		   adapter->vdev_id, rssi_diff);
	len = scnprintf(extra, sizeof(extra), "%s %d",
			command, rssi_diff);
	len = QDF_MIN(priv_data->total_len, len + 1);

	if (copy_to_user(priv_data->buf, &extra, len)) {
		hdd_err("failed to copy data to user buffer");
		ret = -EFAULT;
	}

	return ret;
}

static int drv_cmd_get_band(struct hdd_adapter *adapter,
			    struct hdd_context *hdd_ctx,
			    uint8_t *command,
			    uint8_t command_len,
			    struct hdd_priv_data *priv_data)
{
	int ret = 0;
	int band = -1;
	char extra[32];
	uint8_t len = 0;

	hdd_get_band_helper(hdd_ctx, &band);

	qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
		   TRACE_CODE_HDD_GETBAND_IOCTL,
		   adapter->vdev_id, band);

	len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
	len = QDF_MIN(priv_data->total_len, len + 1);

	if (copy_to_user(priv_data->buf, &extra, len)) {
		hdd_err("failed to copy data to user buffer");
		ret = -EFAULT;
	}

	return ret;
}

static int drv_cmd_set_roam_scan_channels(struct hdd_adapter *adapter,
					  struct hdd_context *hdd_ctx,
					  uint8_t *command,
					  uint8_t command_len,
					  struct hdd_priv_data *priv_data)
{
	return hdd_parse_set_roam_scan_channels(adapter, command);
}

static int drv_cmd_get_roam_scan_channels(struct hdd_adapter *adapter,
					  struct hdd_context *hdd_ctx,
					  uint8_t *command,
					  uint8_t command_len,
					  struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint32_t freq_list[CFG_VALID_CHANNEL_LIST_LEN] = { 0 };
	uint8_t num_channels = 0;
	uint8_t j = 0;
	char extra[128] = { 0 };
	int len;
	uint8_t chan;

	if (QDF_STATUS_SUCCESS !=
		sme_get_roam_scan_channel_list(hdd_ctx->mac_handle,
					       freq_list,
					       &num_channels,
					       adapter->vdev_id)) {
		hdd_err("failed to get roam scan channel list");
		ret = -EFAULT;
		goto exit;
	}

	qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
		   TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
		   adapter->vdev_id, num_channels);

	/*
	 * output channel list is of the format
	 * [Number of roam scan channels][Channel1][Channel2]...
	 * copy the number of channels in the 0th index
	 */
	len = scnprintf(extra, sizeof(extra), "%s %d", command,
			num_channels);
	for (j = 0; (j < num_channels) && len <= sizeof(extra); j++) {
		chan = wlan_reg_freq_to_chan(hdd_ctx->pdev, freq_list[j]);
		len += scnprintf(extra + len, sizeof(extra) - len,
				 " %d", chan);
	}
	len = QDF_MIN(priv_data->total_len, len + 1);
	if (copy_to_user(priv_data->buf, &extra, len)) {
		hdd_err("failed to copy data to user buffer");
		ret = -EFAULT;
		goto exit;
	}

exit:
	return ret;
}

static int drv_cmd_get_ccx_mode(struct hdd_adapter *adapter,
				struct hdd_context *hdd_ctx,
				uint8_t *command,
				uint8_t command_len,
				struct hdd_priv_data *priv_data)
{
	int ret = 0;
	mac_handle_t mac_handle = hdd_ctx->mac_handle;
	bool ese_mode = sme_get_is_ese_feature_enabled(mac_handle);
	char extra[32];
	uint8_t len = 0;
	struct pmkid_mode_bits pmkid_modes;

	hdd_get_pmkid_modes(hdd_ctx, &pmkid_modes);
	/*
	 * Check if the features PMKID/ESE/11R are supported simultaneously,
	 * then this operation is not permitted (return FAILURE)
	 */
	if (ese_mode &&
	    (pmkid_modes.fw_okc || pmkid_modes.fw_pmksa_cache) &&
	    sme_get_is_ft_feature_enabled(mac_handle)) {
		hdd_warn("PMKID/ESE/11R are supported simultaneously hence this operation is not permitted!");
		ret = -EPERM;
		goto exit;
	}

	len = scnprintf(extra, sizeof(extra), "%s %d",
			"GETCCXMODE", ese_mode);
	len = QDF_MIN(priv_data->total_len, len + 1);
	if (copy_to_user(priv_data->buf, &extra, len)) {
		hdd_err("failed to copy data to user buffer");
		ret = -EFAULT;
		goto exit;
	}

exit:
	return ret;
}

static int drv_cmd_get_okc_mode(struct hdd_adapter *adapter,
				struct hdd_context *hdd_ctx,
				uint8_t *command,
				uint8_t command_len,
				struct hdd_priv_data *priv_data)
{
	int ret = 0;
	struct pmkid_mode_bits pmkid_modes;
	char extra[32];
	uint8_t len = 0;
	mac_handle_t mac_handle = hdd_ctx->mac_handle;

	hdd_get_pmkid_modes(hdd_ctx, &pmkid_modes);
	/*
	 * Check if the features OKC/ESE/11R are supported simultaneously,
	 * then this operation is not permitted (return FAILURE)
	 */
	if (pmkid_modes.fw_okc &&
	    sme_get_is_ese_feature_enabled(mac_handle) &&
	    sme_get_is_ft_feature_enabled(mac_handle)) {
		hdd_warn("PMKID/ESE/11R are supported simultaneously hence this operation is not permitted!");
		ret = -EPERM;
		goto exit;
	}

	len = scnprintf(extra, sizeof(extra), "%s %d",
			"GETOKCMODE", pmkid_modes.fw_okc);
	len = QDF_MIN(priv_data->total_len, len + 1);

	if (copy_to_user(priv_data->buf, &extra, len)) {
		hdd_err("failed to copy data to user buffer");
		ret = -EFAULT;
		goto exit;
	}

exit:
	return ret;
}

static int drv_cmd_get_fast_roam(struct hdd_adapter *adapter,
				 struct hdd_context *hdd_ctx,
				 uint8_t *command,
				 uint8_t command_len,
				 struct hdd_priv_data *priv_data)
{
	int ret = 0;
	bool lfr_mode = sme_get_is_lfr_feature_enabled(hdd_ctx->mac_handle);
	char extra[32];
	uint8_t len = 0;

	len = scnprintf(extra, sizeof(extra), "%s %d",
			"GETFASTROAM", lfr_mode);
	len = QDF_MIN(priv_data->total_len, len + 1);

	if (copy_to_user(priv_data->buf, &extra, len)) {
		hdd_err("failed to copy data to user buffer");
		ret = -EFAULT;
	}

	return ret;
}

static int drv_cmd_get_fast_transition(struct hdd_adapter *adapter,
				       struct hdd_context *hdd_ctx,
				       uint8_t *command,
				       uint8_t command_len,
				       struct hdd_priv_data *priv_data)
{
	int ret = 0;
	bool ft = sme_get_is_ft_feature_enabled(hdd_ctx->mac_handle);
	char extra[32];
	uint8_t len = 0;

	len = scnprintf(extra, sizeof(extra), "%s %d",
					"GETFASTTRANSITION", ft);
	len = QDF_MIN(priv_data->total_len, len + 1);

	if (copy_to_user(priv_data->buf, &extra, len)) {
		hdd_err("failed to copy data to user buffer");
		ret = -EFAULT;
	}

	return ret;
}

static int drv_cmd_set_roam_scan_channel_min_time(struct hdd_adapter *adapter,
						  struct hdd_context *hdd_ctx,
						  uint8_t *command,
						  uint8_t command_len,
						  struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint8_t *value = command;
	uint8_t min_time = cfg_default(CFG_LFR_NEIGHBOR_SCAN_MIN_CHAN_TIME);

	/* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
	value = value + command_len + 1;

	/* Convert the value from ascii to integer */
	ret = kstrtou8(value, 10, &min_time);
	if (ret < 0) {
		/*
		 * If the input value is greater than max value of datatype,
		 * then also kstrtou8 fails
		 */
		hdd_err("kstrtou8 failed range [%d - %d]",
			cfg_min(CFG_LFR_NEIGHBOR_SCAN_MIN_CHAN_TIME),
			cfg_max(CFG_LFR_NEIGHBOR_SCAN_MIN_CHAN_TIME));
		ret = -EINVAL;
		goto exit;
	}

	if (!cfg_in_range(CFG_LFR_NEIGHBOR_SCAN_MIN_CHAN_TIME, min_time)) {
		hdd_err("scan min channel time value %d is out of range (Min: %d Max: %d)",
			min_time,
			cfg_min(CFG_LFR_NEIGHBOR_SCAN_MIN_CHAN_TIME),
			cfg_max(CFG_LFR_NEIGHBOR_SCAN_MIN_CHAN_TIME));
		ret = -EINVAL;
		goto exit;
	}

	qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
		   TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
		   adapter->vdev_id, min_time);

	hdd_debug("Received Command to change channel min time = %d",
		  min_time);

	sme_set_neighbor_scan_min_chan_time(hdd_ctx->mac_handle,
					    min_time,
					    adapter->vdev_id);

exit:
	return ret;
}

static int drv_cmd_send_action_frame(struct hdd_adapter *adapter,
				     struct hdd_context *hdd_ctx,
				     uint8_t *command,
				     uint8_t command_len,
				     struct hdd_priv_data *priv_data)
{
	return hdd_parse_sendactionframe(adapter, command,
					 priv_data->total_len);
}

static int drv_cmd_get_roam_scan_channel_min_time(struct hdd_adapter *adapter,
						  struct hdd_context *hdd_ctx,
						  uint8_t *command,
						  uint8_t command_len,
						  struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint16_t val = sme_get_neighbor_scan_min_chan_time(hdd_ctx->mac_handle,
							   adapter->vdev_id);
	char extra[32];
	uint8_t len = 0;

	/* value is interms of msec */
	len = scnprintf(extra, sizeof(extra), "%s %d",
			"GETROAMSCANCHANNELMINTIME", val);
	len = QDF_MIN(priv_data->total_len, len + 1);

	qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
		   TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
		   adapter->vdev_id, val);

	if (copy_to_user(priv_data->buf, &extra, len)) {
		hdd_err("failed to copy data to user buffer");
		ret = -EFAULT;
	}

	return ret;
}

static int drv_cmd_set_scan_channel_time(struct hdd_adapter *adapter,
					 struct hdd_context *hdd_ctx,
					 uint8_t *command,
					 uint8_t command_len,
					 struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint8_t *value = command;
	uint16_t max_time = cfg_default(CFG_LFR_NEIGHBOR_SCAN_MAX_CHAN_TIME);

	/* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
	value = value + command_len + 1;

	/* Convert the value from ascii to integer */
	ret = kstrtou16(value, 10, &max_time);
	if (ret < 0) {
		/*
		 * If the input value is greater than max value of datatype,
		 * then also kstrtou8 fails
		 */
		hdd_err("kstrtou16 failed range [%d - %d]",
			cfg_min(CFG_LFR_NEIGHBOR_SCAN_MAX_CHAN_TIME),
			cfg_max(CFG_LFR_NEIGHBOR_SCAN_MAX_CHAN_TIME));
		ret = -EINVAL;
		goto exit;
	}

	if (!cfg_in_range(CFG_LFR_NEIGHBOR_SCAN_MAX_CHAN_TIME, max_time)) {
		hdd_err("lfr mode value %d is out of range (Min: %d Max: %d)",
			max_time,
			cfg_min(CFG_LFR_NEIGHBOR_SCAN_MAX_CHAN_TIME),
			cfg_max(CFG_LFR_NEIGHBOR_SCAN_MAX_CHAN_TIME));
		ret = -EINVAL;
		goto exit;
	}

	hdd_debug("Received Command to change channel max time = %d",
		  max_time);

	sme_set_neighbor_scan_max_chan_time(hdd_ctx->mac_handle,
					    adapter->vdev_id,
					    max_time);

exit:
	return ret;
}

static int drv_cmd_get_scan_channel_time(struct hdd_adapter *adapter,
					 struct hdd_context *hdd_ctx,
					 uint8_t *command,
					 uint8_t command_len,
					 struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint16_t val = sme_get_neighbor_scan_max_chan_time(hdd_ctx->mac_handle,
							   adapter->vdev_id);
	char extra[32];
	uint8_t len = 0;

	/* value is interms of msec */
	len = scnprintf(extra, sizeof(extra), "%s %d",
			"GETSCANCHANNELTIME", val);
	len = QDF_MIN(priv_data->total_len, len + 1);

	if (copy_to_user(priv_data->buf, &extra, len)) {
		hdd_err("failed to copy data to user buffer");
		ret = -EFAULT;
	}

	return ret;
}

static int drv_cmd_set_scan_home_time(struct hdd_adapter *adapter,
				      struct hdd_context *hdd_ctx,
				      uint8_t *command,
				      uint8_t command_len,
				      struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint8_t *value = command;
	uint16_t val = cfg_default(CFG_LFR_NEIGHBOR_SCAN_TIMER_PERIOD);

	/* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
	value = value + command_len + 1;

	/* Convert the value from ascii to integer */
	ret = kstrtou16(value, 10, &val);
	if (ret < 0) {
		/*
		 * If the input value is greater than max value of datatype,
		 * then also kstrtou8 fails
		 */
		hdd_err("kstrtou16 failed range [%d - %d]",
			cfg_min(CFG_LFR_NEIGHBOR_SCAN_TIMER_PERIOD),
			cfg_max(CFG_LFR_NEIGHBOR_SCAN_TIMER_PERIOD));
		ret = -EINVAL;
		goto exit;
	}

	if (!cfg_in_range(CFG_LFR_NEIGHBOR_SCAN_TIMER_PERIOD, val)) {
		hdd_err("scan home time value %d is out of range (Min: %d Max: %d)",
			val,
			cfg_min(CFG_LFR_NEIGHBOR_SCAN_TIMER_PERIOD),
			cfg_max(CFG_LFR_NEIGHBOR_SCAN_TIMER_PERIOD));
		ret = -EINVAL;
		goto exit;
	}

	hdd_debug("Received Command to change scan home time = %d",
		  val);

	sme_set_neighbor_scan_period(hdd_ctx->mac_handle,
				     adapter->vdev_id, val);

exit:
	return ret;
}

static int drv_cmd_get_scan_home_time(struct hdd_adapter *adapter,
				      struct hdd_context *hdd_ctx,
				      uint8_t *command,
				      uint8_t command_len,
				      struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint16_t val = sme_get_neighbor_scan_period(hdd_ctx->mac_handle,
						    adapter->vdev_id);
	char extra[32];
	uint8_t len = 0;

	/* value is interms of msec */
	len = scnprintf(extra, sizeof(extra), "%s %d",
			"GETSCANHOMETIME", val);
	len = QDF_MIN(priv_data->total_len, len + 1);

	if (copy_to_user(priv_data->buf, &extra, len)) {
		hdd_err("failed to copy data to user buffer");
		ret = -EFAULT;
	}

	return ret;
}

static int drv_cmd_set_roam_intra_band(struct hdd_adapter *adapter,
				       struct hdd_context *hdd_ctx,
				       uint8_t *command,
				       uint8_t command_len,
				       struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint8_t *value = command;
	uint8_t val = cfg_default(CFG_LFR_ROAM_INTRA_BAND);

	/* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
	value = value + command_len + 1;

	/* Convert the value from ascii to integer */
	ret = kstrtou8(value, 10, &val);
	if (ret < 0) {
		/*
		 * If the input value is greater than max value of datatype,
		 * then also kstrtou8 fails
		 */
		hdd_err("kstrtou8 failed range [%d - %d]",
			cfg_min(CFG_LFR_ROAM_INTRA_BAND),
			cfg_max(CFG_LFR_ROAM_INTRA_BAND));
		ret = -EINVAL;
		goto exit;
	}

	hdd_debug("Received Command to change intra band = %d",
		  val);

	ucfg_mlme_set_roam_intra_band(hdd_ctx->psoc, (bool)val);
	policy_mgr_set_pcl_for_existing_combo(
					hdd_ctx->psoc,
					PM_STA_MODE);

exit:
	return ret;
}

static int drv_cmd_get_roam_intra_band(struct hdd_adapter *adapter,
				       struct hdd_context *hdd_ctx,
				       uint8_t *command,
				       uint8_t command_len,
				       struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint16_t val = sme_get_roam_intra_band(hdd_ctx->mac_handle);
	char extra[32];
	uint8_t len = 0;

	/* value is interms of msec */
	len = scnprintf(extra, sizeof(extra), "%s %d",
			"GETROAMINTRABAND", val);
	len = QDF_MIN(priv_data->total_len, len + 1);
	if (copy_to_user(priv_data->buf, &extra, len)) {
		hdd_err("failed to copy data to user buffer");
		ret = -EFAULT;
	}

	return ret;
}

static int drv_cmd_set_scan_n_probes(struct hdd_adapter *adapter,
				     struct hdd_context *hdd_ctx,
				     uint8_t *command,
				     uint8_t command_len,
				     struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint8_t *value = command;
	uint8_t nprobes = cfg_default(CFG_LFR_ROAM_SCAN_N_PROBES);

	/* Move pointer to ahead of SETSCANNPROBES<delimiter> */
	value = value + command_len + 1;

	/* Convert the value from ascii to integer */
	ret = kstrtou8(value, 10, &nprobes);
	if (ret < 0) {
		/*
		 * If the input value is greater than max value of datatype,
		 * then also kstrtou8 fails
		 */
		hdd_err("kstrtou8 failed range [%d - %d]",
			cfg_min(CFG_LFR_ROAM_SCAN_N_PROBES),
			cfg_max(CFG_LFR_ROAM_SCAN_N_PROBES));
		ret = -EINVAL;
		goto exit;
	}

	if (!cfg_in_range(CFG_LFR_ROAM_SCAN_N_PROBES, nprobes)) {
		hdd_err("NProbes value %d is out of range (Min: %d Max: %d)",
			nprobes,
			cfg_min(CFG_LFR_ROAM_SCAN_N_PROBES),
			cfg_max(CFG_LFR_ROAM_SCAN_N_PROBES));
		ret = -EINVAL;
		goto exit;
	}

	hdd_debug("Received Command to Set nProbes = %d",
		  nprobes);

	sme_update_roam_scan_n_probes(hdd_ctx->mac_handle,
				      adapter->vdev_id, nprobes);

exit:
	return ret;
}

static int drv_cmd_get_scan_n_probes(struct hdd_adapter *adapter,
				     struct hdd_context *hdd_ctx,
				     uint8_t *command,
				     uint8_t command_len,
				     struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint8_t val;
	char extra[32];
	uint8_t len = 0;
	QDF_STATUS status;

	status = sme_get_roam_scan_n_probes(hdd_ctx->mac_handle,
					    adapter->vdev_id,
					    &val);
	if (QDF_IS_STATUS_ERROR(status))
		return qdf_status_to_os_return(status);

	hdd_debug("vdev_id: %u, scan_n_probes: %u",
		  adapter->vdev_id, val);

	len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
	len = QDF_MIN(priv_data->total_len, len + 1);
	if (copy_to_user(priv_data->buf, &extra, len)) {
		hdd_err("failed to copy data to user buffer");
		ret = -EFAULT;
	}

	return ret;
}

static int drv_cmd_set_scan_home_away_time(struct hdd_adapter *adapter,
					   struct hdd_context *hdd_ctx,
					   uint8_t *command,
					   uint8_t command_len,
					   struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint8_t *value = command;
	uint16_t home_away_time = cfg_default(CFG_LFR_ROAM_SCAN_HOME_AWAY_TIME);

	/* input value is in units of msec */

	/* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
	value = value + command_len + 1;

	/* Convert the value from ascii to integer */
	ret = kstrtou16(value, 10, &home_away_time);
	if (ret < 0) {
		/*
		 * If the input value is greater than max value of datatype,
		 * then also kstrtou8 fails
		 */
		hdd_err("kstrtou8 failed range [%d - %d]",
			cfg_min(CFG_LFR_ROAM_SCAN_HOME_AWAY_TIME),
			cfg_max(CFG_LFR_ROAM_SCAN_HOME_AWAY_TIME));
		ret = -EINVAL;
		goto exit;
	}

	if (!cfg_in_range(CFG_LFR_ROAM_SCAN_HOME_AWAY_TIME, home_away_time)) {
		hdd_err("home_away_time value %d is out of range (min: %d max: %d)",
			home_away_time,
			cfg_min(CFG_LFR_ROAM_SCAN_HOME_AWAY_TIME),
			cfg_max(CFG_LFR_ROAM_SCAN_HOME_AWAY_TIME));
		ret = -EINVAL;
		goto exit;
	}

	hdd_debug("Received Command to Set scan away time = %d",
		  home_away_time);

	sme_update_roam_scan_home_away_time(hdd_ctx->mac_handle,
					    adapter->vdev_id,
					    home_away_time,
					    true);

exit:
	return ret;
}

static int drv_cmd_get_scan_home_away_time(struct hdd_adapter *adapter,
					   struct hdd_context *hdd_ctx,
					   uint8_t *command,
					   uint8_t command_len,
					   struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint16_t val;
	char extra[32];
	uint8_t len = 0;
	QDF_STATUS status;

	status = sme_get_roam_scan_home_away_time(hdd_ctx->mac_handle,
						  adapter->vdev_id,
						  &val);
	if (QDF_IS_STATUS_ERROR(status))
		return qdf_status_to_os_return(status);

	hdd_debug("vdev_id: %u, scan home away time: %u",
		  adapter->vdev_id, val);

	len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
	len = QDF_MIN(priv_data->total_len, len + 1);

	if (copy_to_user(priv_data->buf, &extra, len)) {
		hdd_err("failed to copy data to user buffer");
		ret = -EFAULT;
	}

	return ret;
}

static int drv_cmd_reassoc(struct hdd_adapter *adapter,
			   struct hdd_context *hdd_ctx,
			   uint8_t *command,
			   uint8_t command_len,
			   struct hdd_priv_data *priv_data)
{
	return hdd_parse_reassoc(adapter, command, priv_data->total_len);
}

static int drv_cmd_set_wes_mode(struct hdd_adapter *adapter,
				struct hdd_context *hdd_ctx,
				uint8_t *command,
				uint8_t command_len,
				struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint8_t *value = command;
	uint8_t wes_mode = cfg_default(CFG_LFR_ENABLE_WES_MODE);

	/* Move pointer to ahead of SETWESMODE<delimiter> */
	value = value + command_len + 1;

	/* Convert the value from ascii to integer */
	ret = kstrtou8(value, 10, &wes_mode);
	if (ret < 0) {
		/*
		 * If the input value is greater than max value of datatype,
		 * then also kstrtou8 fails
		 */
		hdd_err("kstrtou8 failed range [%d - %d]",
			cfg_min(CFG_LFR_ENABLE_WES_MODE),
			cfg_max(CFG_LFR_ENABLE_WES_MODE));
		ret = -EINVAL;
		goto exit;
	}

	hdd_debug("Received Command to Set WES Mode rssi diff = %d", wes_mode);

	sme_update_wes_mode(hdd_ctx->mac_handle, wes_mode, adapter->vdev_id);

exit:
	return ret;
}

static int drv_cmd_get_wes_mode(struct hdd_adapter *adapter,
				struct hdd_context *hdd_ctx,
				uint8_t *command,
				uint8_t command_len,
				struct hdd_priv_data *priv_data)
{
	int ret = 0;
	bool wes_mode = sme_get_wes_mode(hdd_ctx->mac_handle);
	char extra[32];
	uint8_t len = 0;

	len = scnprintf(extra, sizeof(extra), "%s %d", command, wes_mode);
	len = QDF_MIN(priv_data->total_len, len + 1);
	if (copy_to_user(priv_data->buf, &extra, len)) {
		hdd_err("failed to copy data to user buffer");
		ret = -EFAULT;
	}

	return ret;
}

static int drv_cmd_set_opportunistic_rssi_diff(struct hdd_adapter *adapter,
					       struct hdd_context *hdd_ctx,
					       uint8_t *command,
					       uint8_t command_len,
					       struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint8_t *value = command;
	uint8_t diff =
		cfg_default(CFG_LFR_OPPORTUNISTIC_SCAN_THRESHOLD_DIFF);

	/* Move pointer to ahead of SETOPPORTUNISTICRSSIDIFF<delimiter> */
	value = value + command_len + 1;

	/* Convert the value from ascii to integer */
	ret = kstrtou8(value, 10, &diff);
	if (ret < 0) {
		/*
		 * If the input value is greater than max value of datatype,
		 * then also kstrtou8 fails
		 */
		hdd_err("kstrtou8 failed");
		ret = -EINVAL;
		goto exit;
	}

	hdd_debug("Received Command to Set Opportunistic Threshold diff = %d",
		  diff);

	sme_set_roam_opportunistic_scan_threshold_diff(hdd_ctx->mac_handle,
						       adapter->vdev_id,
						       diff);

exit:
	return ret;
}

static int drv_cmd_get_opportunistic_rssi_diff(struct hdd_adapter *adapter,
					       struct hdd_context *hdd_ctx,
					       uint8_t *command,
					       uint8_t command_len,
					       struct hdd_priv_data *priv_data)
{
	int ret = 0;
	mac_handle_t mac_handle = hdd_ctx->mac_handle;
	int8_t val = sme_get_roam_opportunistic_scan_threshold_diff(mac_handle);
	char extra[32];
	uint8_t len = 0;

	len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
	len = QDF_MIN(priv_data->total_len, len + 1);
	if (copy_to_user(priv_data->buf, &extra, len)) {
		hdd_err("failed to copy data to user buffer");
		ret = -EFAULT;
	}

	return ret;
}

static int drv_cmd_set_roam_rescan_rssi_diff(struct hdd_adapter *adapter,
					     struct hdd_context *hdd_ctx,
					     uint8_t *command,
					     uint8_t command_len,
					     struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint8_t *value = command;
	uint8_t rescan_rssi_diff = cfg_default(CFG_LFR_ROAM_RESCAN_RSSI_DIFF);

	/* Move pointer to ahead of SETROAMRESCANRSSIDIFF<delimiter> */
	value = value + command_len + 1;

	/* Convert the value from ascii to integer */
	ret = kstrtou8(value, 10, &rescan_rssi_diff);
	if (ret < 0) {
		/*
		 * If the input value is greater than max value of datatype,
		 * then also kstrtou8 fails
		 */
		hdd_err("kstrtou8 failed");
		ret = -EINVAL;
		goto exit;
	}

	hdd_debug("Received Command to Set Roam Rescan RSSI Diff = %d",
		  rescan_rssi_diff);

	sme_set_roam_rescan_rssi_diff(hdd_ctx->mac_handle,
				      adapter->vdev_id,
				      rescan_rssi_diff);

exit:
	return ret;
}

static int drv_cmd_get_roam_rescan_rssi_diff(struct hdd_adapter *adapter,
					     struct hdd_context *hdd_ctx,
					     uint8_t *command,
					     uint8_t command_len,
					     struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint8_t val = sme_get_roam_rescan_rssi_diff(hdd_ctx->mac_handle);
	char extra[32];
	uint8_t len = 0;

	len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
	len = QDF_MIN(priv_data->total_len, len + 1);
	if (copy_to_user(priv_data->buf, &extra, len)) {
		hdd_err("failed to copy data to user buffer");
		ret = -EFAULT;
	}

	return ret;
}

static int drv_cmd_set_fast_roam(struct hdd_adapter *adapter,
				 struct hdd_context *hdd_ctx,
				 uint8_t *command,
				 uint8_t command_len,
				 struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint8_t *value = command;
	uint8_t lfr_mode = cfg_default(CFG_LFR_FEATURE_ENABLED);

	/* Move pointer to ahead of SETFASTROAM<delimiter> */
	value = value + command_len + 1;

	/* Convert the value from ascii to integer */
	ret = kstrtou8(value, 10, &lfr_mode);
	if (ret < 0) {
		/*
		 * If the input value is greater than max value of datatype,
		 * then also kstrtou8 fails
		 */
		hdd_err("kstrtou8 failed range [%d - %d]",
			cfg_min(CFG_LFR_FEATURE_ENABLED),
			cfg_max(CFG_LFR_FEATURE_ENABLED));
		ret = -EINVAL;
		goto exit;
	}

	hdd_debug("Received Command to change lfr mode = %d",
		  lfr_mode);

	ucfg_mlme_set_lfr_enabled(hdd_ctx->psoc, (bool)lfr_mode);
	sme_update_is_fast_roam_ini_feature_enabled(hdd_ctx->mac_handle,
						    adapter->vdev_id,
						    lfr_mode);

exit:
	return ret;
}

static int drv_cmd_set_fast_transition(struct hdd_adapter *adapter,
				       struct hdd_context *hdd_ctx,
				       uint8_t *command,
				       uint8_t command_len,
				       struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint8_t *value = command;
	uint8_t ft = cfg_default(CFG_LFR_FAST_TRANSITION_ENABLED);

	/* Move pointer to ahead of SETFASTROAM<delimiter> */
	value = value + command_len + 1;

	/* Convert the value from ascii to integer */
	ret = kstrtou8(value, 10, &ft);
	if (ret < 0) {
		/*
		 * If the input value is greater than max value of datatype,
		 * then also kstrtou8 fails
		 */
		hdd_err("kstrtou8 failed range [%d - %d]",
			cfg_min(CFG_LFR_FAST_TRANSITION_ENABLED),
			cfg_max(CFG_LFR_FAST_TRANSITION_ENABLED));
		ret = -EINVAL;
		goto exit;
	}

	hdd_debug("Received Command to change ft mode = %d", ft);

	ucfg_mlme_set_fast_transition_enabled(hdd_ctx->psoc, (bool)ft);

exit:
	return ret;
}

static int drv_cmd_fast_reassoc(struct hdd_adapter *adapter,
				struct hdd_context *hdd_ctx,
				uint8_t *command,
				uint8_t command_len,
				struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint8_t *value = command;
	uint8_t channel = 0;
	tSirMacAddr bssid;
	uint32_t roam_id = INVALID_ROAM_ID;
	tCsrRoamModifyProfileFields mod_fields;
	tCsrHandoffRequest req;
	struct hdd_station_ctx *sta_ctx;
	mac_handle_t mac_handle;

	if (QDF_STA_MODE != adapter->device_mode) {
		hdd_warn("Unsupported in mode %s(%d)",
			 qdf_opmode_str(adapter->device_mode),
			 adapter->device_mode);
		return -EINVAL;
	}

	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
	hdd_ctx = WLAN_HDD_GET_CTX(adapter);

	/* if not associated, no need to proceed with reassoc */
	if (eConnectionState_Associated != sta_ctx->conn_info.conn_state) {
		hdd_warn("Not associated!");
		ret = -EINVAL;
		goto exit;
	}

	ret = hdd_parse_reassoc_command_v1_data(value, bssid,
						&channel);
	if (ret) {
		hdd_err("Failed to parse reassoc command data");
		goto exit;
	}

	mac_handle = hdd_ctx->mac_handle;

	/*
	 * if the target bssid is same as currently associated AP,
	 * issue reassoc to same AP
	 */
	if (!qdf_mem_cmp(bssid, sta_ctx->conn_info.bssid.bytes,
			 QDF_MAC_ADDR_SIZE)) {
		hdd_warn("Reassoc BSSID is same as currently associated AP bssid");
		if (roaming_offload_enabled(hdd_ctx)) {
			channel = wlan_reg_freq_to_chan(
					hdd_ctx->pdev,
					sta_ctx->conn_info.chan_freq);
			hdd_wma_send_fastreassoc_cmd(adapter, bssid,
						     channel);
		} else {
			sme_get_modify_profile_fields(mac_handle,
				adapter->vdev_id,
				&mod_fields);
			sme_roam_reassoc(mac_handle, adapter->vdev_id,
				NULL, mod_fields, &roam_id, 1);
		}
		return 0;
	}

	/* Check channel number is a valid channel number */
	if (channel && (QDF_STATUS_SUCCESS !=
		wlan_hdd_validate_operation_channel(adapter, channel))) {
		hdd_err("Invalid Channel [%d]", channel);
		return -EINVAL;
	}

	if (roaming_offload_enabled(hdd_ctx)) {
		hdd_wma_send_fastreassoc_cmd(adapter, bssid, (int)channel);
		goto exit;
	}
	/* Proceed with reassoc */
	req.ch_freq = wlan_reg_chan_to_freq(hdd_ctx->pdev, channel);
	req.src = FASTREASSOC;
	qdf_mem_copy(req.bssid.bytes, bssid, sizeof(tSirMacAddr));
	sme_handoff_request(mac_handle, adapter->vdev_id, &req);
exit:
	return ret;
}

static int drv_cmd_set_roam_scan_control(struct hdd_adapter *adapter,
					 struct hdd_context *hdd_ctx,
					 uint8_t *command,
					 uint8_t command_len,
					 struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint8_t *value = command;
	uint8_t roam_scan_control = 0;

	/* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
	value = value + command_len + 1;

	/* Convert the value from ascii to integer */
	ret = kstrtou8(value, 10, &roam_scan_control);
	if (ret < 0) {
		/*
		 * If the input value is greater than max value of datatype,
		 * then also kstrtou8 fails
		 */
		hdd_err("kstrtou8 failed");
		ret = -EINVAL;
		goto exit;
	}

	hdd_debug("Received Command to Set roam scan control = %d",
		  roam_scan_control);

	if (0 != roam_scan_control) {
		ret = 0; /* return success but ignore param value "true" */
		goto exit;
	}

	sme_set_roam_scan_control(hdd_ctx->mac_handle,
				  adapter->vdev_id,
				  roam_scan_control);

exit:
	return ret;
}

static int drv_cmd_set_okc_mode(struct hdd_adapter *adapter,
				struct hdd_context *hdd_ctx,
				uint8_t *command,
				uint8_t command_len,
				struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint8_t *value = command;
	uint32_t okc_mode;
	struct pmkid_mode_bits pmkid_modes;
	mac_handle_t mac_handle;
	uint32_t cur_pmkid_modes;
	QDF_STATUS status;

	hdd_get_pmkid_modes(hdd_ctx, &pmkid_modes);

	/*
	 * Check if the features PMKID/ESE/11R are supported simultaneously,
	 * then this operation is not permitted (return FAILURE)
	 */
	mac_handle = hdd_ctx->mac_handle;
	if (sme_get_is_ese_feature_enabled(mac_handle) &&
	    pmkid_modes.fw_okc &&
	    sme_get_is_ft_feature_enabled(mac_handle)) {
		hdd_warn("PMKID/ESE/11R are supported simultaneously hence this operation is not permitted!");
		ret = -EPERM;
		goto exit;
	}

	/* Move pointer to ahead of SETOKCMODE<delimiter> */
	value = value + command_len + 1;

	/* get the current configured value */
	status = ucfg_mlme_get_pmkid_modes(hdd_ctx->psoc,
					   &cur_pmkid_modes);
	if (status != QDF_STATUS_SUCCESS)
		hdd_err("get pmkid modes failed");

	okc_mode = cur_pmkid_modes & CFG_PMKID_MODES_OKC;

	/* Convert the value from ascii to integer */
	ret = kstrtou32(value, 10, &okc_mode);
	if (ret < 0) {
		/*
		 * If the input value is greater than max value of datatype,
		 * then also kstrtou8 fails
		 */
		hdd_err("value out of range [0 - 1]");
		ret = -EINVAL;
		goto exit;
	}

	if ((okc_mode < 0) ||
	    (okc_mode > 1)) {
		hdd_err("Okc mode value %d is out of range (Min: 0 Max: 1)",
			  okc_mode);
		ret = -EINVAL;
		goto exit;
	}
	hdd_debug("Received Command to change okc mode = %d",
		  okc_mode);

	if (okc_mode)
		cur_pmkid_modes |= CFG_PMKID_MODES_OKC;
	else
		cur_pmkid_modes &= ~CFG_PMKID_MODES_OKC;
	status = ucfg_mlme_set_pmkid_modes(hdd_ctx->psoc,
					   cur_pmkid_modes);
	if (status != QDF_STATUS_SUCCESS) {
		ret = -EPERM;
		hdd_err("set pmkid modes failed");
	}
exit:
	return ret;
}

static int drv_cmd_get_roam_scan_control(struct hdd_adapter *adapter,
					 struct hdd_context *hdd_ctx,
					 uint8_t *command,
					 uint8_t command_len,
					 struct hdd_priv_data *priv_data)
{
	int ret = 0;
	bool roam_scan_control = sme_get_roam_scan_control(hdd_ctx->mac_handle);
	char extra[32];
	uint8_t len = 0;

	len = scnprintf(extra, sizeof(extra), "%s %d",
			command, roam_scan_control);
	len = QDF_MIN(priv_data->total_len, len + 1);
	if (copy_to_user(priv_data->buf, &extra, len)) {
		hdd_err("failed to copy data to user buffer");
		ret = -EFAULT;
	}

	return ret;
}

static int drv_cmd_bt_coex_mode(struct hdd_adapter *adapter,
				struct hdd_context *hdd_ctx,
				uint8_t *command,
				uint8_t command_len,
				struct hdd_priv_data *priv_data)
{
	int ret = 0;
	char *coex_mode;

	coex_mode = command + 11;
	if ('1' == *coex_mode) {
		hdd_debug("BTCOEXMODE %d", *coex_mode);
		hdd_ctx->bt_coex_mode_set = true;
		ret = wlan_hdd_scan_abort(adapter);
		if (ret < 0) {
			hdd_err("Failed to abort existing scan status: %d",
				ret);
		}
	} else if ('2' == *coex_mode) {
		hdd_debug("BTCOEXMODE %d", *coex_mode);
		hdd_ctx->bt_coex_mode_set = false;
	}

	return ret;
}

static int drv_cmd_scan_active(struct hdd_adapter *adapter,
			       struct hdd_context *hdd_ctx,
			       uint8_t *command,
			       uint8_t command_len,
			       struct hdd_priv_data *priv_data)
{
	hdd_ctx->ioctl_scan_mode = eSIR_ACTIVE_SCAN;
	return 0;
}

static int drv_cmd_scan_passive(struct hdd_adapter *adapter,
				struct hdd_context *hdd_ctx,
				uint8_t *command,
				uint8_t command_len,
				struct hdd_priv_data *priv_data)
{
	hdd_ctx->ioctl_scan_mode = eSIR_PASSIVE_SCAN;
	return 0;
}

static int drv_cmd_get_dwell_time(struct hdd_adapter *adapter,
				  struct hdd_context *hdd_ctx,
				  uint8_t *command,
				  uint8_t command_len,
				  struct hdd_priv_data *priv_data)
{
	int ret = 0;
	char extra[32];
	uint8_t len = 0;

	memset(extra, 0, sizeof(extra));
	ret = hdd_get_dwell_time(hdd_ctx->psoc, command, extra,
				 sizeof(extra), &len);
	len = QDF_MIN(priv_data->total_len, len + 1);
	if (ret != 0 || copy_to_user(priv_data->buf, &extra, len)) {
		hdd_err("failed to copy data to user buffer");
		ret = -EFAULT;
		goto exit;
	}
	ret = len;
exit:
	return ret;
}

static int drv_cmd_set_dwell_time(struct hdd_adapter *adapter,
				  struct hdd_context *hdd_ctx,
				  uint8_t *command,
				  uint8_t command_len,
				  struct hdd_priv_data *priv_data)
{
	return hdd_set_dwell_time(hdd_ctx->psoc, command);
}

static int drv_cmd_conc_set_dwell_time(struct hdd_adapter *adapter,
				       struct hdd_context *hdd_ctx,
				       u8 *command,
				       u8 command_len,
				       struct hdd_priv_data *priv_data)
{
	return hdd_conc_set_dwell_time(adapter, command);
}

static int drv_cmd_miracast(struct hdd_adapter *adapter,
			    struct hdd_context *hdd_ctx,
			    uint8_t *command,
			    uint8_t command_len,
			    struct hdd_priv_data *priv_data)
{
	QDF_STATUS ret_status;
	int ret = 0;
	uint8_t filter_type = 0;
	uint8_t *value;

	if (wlan_hdd_validate_context(hdd_ctx))
		return -EINVAL;

	value = command + 9;

	/* Convert the value from ascii to integer */
	ret = kstrtou8(value, 10, &filter_type);
	if (ret < 0) {
		/*
		 * If the input value is greater than max value of datatype,
		 * then also kstrtou8 fails
		 */
		hdd_err("kstrtou8 failed range");
		ret = -EINVAL;
		goto exit;
	}
	if ((filter_type < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL) ||
	    (filter_type > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL)) {
		hdd_err("Accepted Values are 0 to 2. 0-Disabled, 1-Source, 2-Sink");
		ret = -EINVAL;
		goto exit;
	}
	/* Filtertype value should be either 0-Disabled, 1-Source, 2-sink */
	hdd_ctx->miracast_value = filter_type;

	ret_status = sme_set_miracast(hdd_ctx->mac_handle, filter_type);
	if (QDF_STATUS_SUCCESS != ret_status) {
		hdd_err("Failed to set miracast");
		return -EBUSY;
	}
	ret_status = ucfg_scan_set_miracast(hdd_ctx->psoc,
					    filter_type ? true : false);
	if (QDF_IS_STATUS_ERROR(ret_status)) {
		hdd_err("Failed to set miracastn scan");
		return -EBUSY;
	}

	if (policy_mgr_is_mcc_in_24G(hdd_ctx->psoc))
		return wlan_hdd_set_mas(adapter, filter_type);

exit:
	return ret;
}

#ifdef FEATURE_WLAN_RMC
/* Function header is left blank intentionally */
static int hdd_parse_setrmcenable_command(uint8_t *command,
					  uint8_t *rmc_enable)
{
	uint8_t *in_ptr = command;
	int temp_int;
	int v = 0;
	char buf[32];
	*rmc_enable = 0;

	in_ptr = strnchr(command, strlen(command), SPACE_ASCII_VALUE);

	if (!in_ptr)
		return 0;
	else if (SPACE_ASCII_VALUE != *in_ptr)
		return 0;

	while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr))
		in_ptr++;

	if ('\0' == *in_ptr)
		return 0;

	v = sscanf(in_ptr, "%31s ", buf);
	if (1 != v)
		return -EINVAL;

	v = kstrtos32(buf, 10, &temp_int);
	if (v < 0)
		return -EINVAL;

	*rmc_enable = temp_int;

	hdd_debug("rmc_enable: %d", *rmc_enable);

	return 0;
}

/* Function header is left blank intentionally */
static int hdd_parse_setrmcactionperiod_command(uint8_t *pvalue,
						uint32_t *paction_period)
{
	uint8_t *inptr = pvalue;
	int temp_int;
	int v = 0;
	char buf[32];
	*paction_period = 0;

	inptr = strnchr(pvalue, strlen(pvalue), SPACE_ASCII_VALUE);

	if (!inptr)
		return -EINVAL;
	else if (SPACE_ASCII_VALUE != *inptr)
		return -EINVAL;

	while ((SPACE_ASCII_VALUE == *inptr) && ('\0' != *inptr))
		inptr++;

	if ('\0' == *inptr)
		return 0;

	v = sscanf(inptr, "%31s ", buf);
	if (1 != v)
		return -EINVAL;

	v = kstrtos32(buf, 10, &temp_int);
	if (v < 0)
		return -EINVAL;

	if (!cfg_in_range(CFG_RMC_ACTION_PERIOD_FREQUENCY, temp_int))
		return -EINVAL;

	*paction_period = temp_int;

	hdd_debug("action_period: %d", *paction_period);

	return 0;
}

/* Function header is left blank intentionally */
static int hdd_parse_setrmcrate_command(uint8_t *command,
					uint32_t *rate,
					enum tx_rate_info *tx_flags)
{
	uint8_t *in_ptr = command;
	int temp_int;
	int v = 0;
	char buf[32];
	*rate = 0;
	*tx_flags = 0;

	in_ptr = strnchr(command, strlen(command), SPACE_ASCII_VALUE);

	if (!in_ptr)
		return -EINVAL;
	else if (SPACE_ASCII_VALUE != *in_ptr)
		return -EINVAL;

	while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr))
		in_ptr++;

	if ('\0' == *in_ptr)
		return 0;

	v = sscanf(in_ptr, "%31s ", buf);
	if (1 != v)
		return -EINVAL;

	v = kstrtos32(buf, 10, &temp_int);
	if (v < 0)
		return -EINVAL;

	switch (temp_int) {
	default:
		hdd_warn("Unsupported rate: %d", temp_int);
		return -EINVAL;
	case 0:
	case 6:
	case 9:
	case 12:
	case 18:
	case 24:
	case 36:
	case 48:
	case 54:
		*tx_flags = TX_RATE_LEGACY;
		*rate = temp_int * 10;
		break;
	case 65:
		*tx_flags = TX_RATE_HT20;
		*rate = temp_int * 10;
		break;
	case 72:
		*tx_flags = TX_RATE_HT20 | TX_RATE_SGI;
		*rate = 722;
		break;
	}

	hdd_debug("Rate: %d", *rate);

	return 0;
}

static int drv_cmd_set_rmc_enable(struct hdd_adapter *adapter,
				  struct hdd_context *hdd_ctx,
				  uint8_t *command,
				  uint8_t command_len,
				  struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint8_t *value = command;
	uint8_t rmc_enable = 0;
	int status;
	mac_handle_t mac_handle;

	if ((QDF_IBSS_MODE != adapter->device_mode) &&
	    (QDF_SAP_MODE != adapter->device_mode)) {
		hdd_err("Received SETRMCENABLE cmd in invalid mode %s(%d)",
			qdf_opmode_str(adapter->device_mode),
			adapter->device_mode);
		hdd_err("SETRMCENABLE cmd is allowed only in IBSS/SOFTAP mode");
		ret = -EINVAL;
		goto exit;
	}

	status = hdd_parse_setrmcenable_command(value, &rmc_enable);
	if (status) {
		hdd_err("Invalid SETRMCENABLE command");
		ret = -EINVAL;
		goto exit;
	}

	hdd_debug("rmc_enable %d", rmc_enable);
	mac_handle = hdd_ctx->mac_handle;

	if (true == rmc_enable) {
		status = sme_enable_rmc(mac_handle, adapter->vdev_id);
	} else if (false == rmc_enable) {
		status = sme_disable_rmc(mac_handle, adapter->vdev_id);
	} else {
		hdd_err("Invalid SETRMCENABLE command %d", rmc_enable);
		ret = -EINVAL;
		goto exit;
	}

	if (QDF_STATUS_SUCCESS != status) {
		hdd_err("SETRMC %d failed status %d", rmc_enable, status);
		ret = -EINVAL;
		goto exit;
	}

exit:
	return ret;
}

static int drv_cmd_set_rmc_action_period(struct hdd_adapter *adapter,
					 struct hdd_context *hdd_ctx,
					 uint8_t *command,
					 uint8_t command_len,
					 struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint8_t *value = command;
	uint32_t action_period = 0;
	int status;
	mac_handle_t mac_handle;

	if ((QDF_IBSS_MODE != adapter->device_mode) &&
	    (QDF_SAP_MODE != adapter->device_mode)) {
		hdd_err("Received SETRMC cmd in invalid mode %s(%d)",
			qdf_opmode_str(adapter->device_mode),
			adapter->device_mode);
		hdd_err("SETRMC cmd is allowed only in IBSS/SOFTAP mode");
		ret = -EINVAL;
		goto exit;
	}

	status = hdd_parse_setrmcactionperiod_command(value, &action_period);
	if (status) {
		hdd_err("Invalid SETRMCACTIONPERIOD command");
		ret = -EINVAL;
		goto exit;
	}

	hdd_debug("action_period %d", action_period);
	mac_handle = hdd_ctx->mac_handle;

	if (ucfg_mlme_set_rmc_action_period_freq(hdd_ctx->psoc,
						 action_period) !=
						 QDF_STATUS_SUCCESS) {
		hdd_err("Could not set SETRMCACTIONPERIOD %d", action_period);
		ret = -EINVAL;
		goto exit;
	}

	status = sme_send_rmc_action_period(mac_handle,
					    adapter->vdev_id);
	if (QDF_STATUS_SUCCESS != status) {
		hdd_err("Could not send cesium enable indication %d",
			  status);
		ret = -EINVAL;
		goto exit;
	}

exit:
	return ret;
}

static int drv_cmd_set_rmc_tx_rate(struct hdd_adapter *adapter,
				   struct hdd_context *hdd_ctx,
				   uint8_t *command,
				   uint8_t command_len,
				   struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint8_t *value = command;
	uint32_t rate = 0;
	enum tx_rate_info tx_flags = 0;
	tSirRateUpdateInd params = {0};
	int status;
	bool bval = false;

	if ((QDF_IBSS_MODE != adapter->device_mode) &&
	    (QDF_SAP_MODE != adapter->device_mode)) {
		hdd_err("Received SETRMCTXRATE cmd in invalid mode %s(%d)",
			qdf_opmode_str(adapter->device_mode),
			adapter->device_mode);
		hdd_err("SETRMCTXRATE cmd is allowed only in IBSS/SOFTAP mode");
		ret = -EINVAL;
		goto exit;
	}

	status = hdd_parse_setrmcrate_command(value, &rate, &tx_flags);
	if (status) {
		hdd_err("Invalid SETRMCTXRATE command");
		ret = -EINVAL;
		goto exit;
	}
	hdd_debug("rate %d", rate);

	/*
	 * Fill the user specifieed RMC rate param
	 * and the derived tx flags.
	 */
	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		hdd_err("unable to get vht_enable2x2");
		ret = -EINVAL;
		goto exit;
	}
	params.nss = (bval == 0) ? 0 : 1;
	params.reliableMcastDataRate = rate;
	params.reliableMcastDataRateTxFlag = tx_flags;
	params.dev_mode = adapter->device_mode;
	params.bcastDataRate = -1;
	memcpy(params.bssid.bytes,
	       adapter->mac_addr.bytes,
	       sizeof(params.bssid));
	status = sme_send_rate_update_ind(hdd_ctx->mac_handle,
					  &params);

exit:
	return ret;
}
#endif /* FEATURE_WLAN_RMC */

#ifdef FEATURE_WLAN_ESE
static int drv_cmd_set_ccx_roam_scan_channels(struct hdd_adapter *adapter,
					      struct hdd_context *hdd_ctx,
					      uint8_t *command,
					      uint8_t command_len,
					      struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint8_t *value = command;
	uint32_t channel_freq_list[CFG_VALID_CHANNEL_LIST_LEN] = { 0 };
	uint8_t num_channels = 0;
	QDF_STATUS status;
	mac_handle_t mac_handle;

	if (!hdd_ctx) {
		hdd_err("invalid hdd ctx");
		ret = -EINVAL;
		goto exit;
	}

	ret = hdd_parse_channellist(hdd_ctx, value, channel_freq_list,
				    &num_channels);
	if (ret) {
		hdd_err("Failed to parse channel list information");
		goto exit;
	}
	if (num_channels > CFG_VALID_CHANNEL_LIST_LEN) {
		hdd_err("number of channels (%d) supported exceeded max (%d)",
			num_channels,
			CFG_VALID_CHANNEL_LIST_LEN);
		ret = -EINVAL;
		goto exit;
	}

	mac_handle = hdd_ctx->mac_handle;
	if (!sme_validate_channel_list(mac_handle, channel_freq_list,
				       num_channels)) {
		hdd_err("List contains invalid channel(s)");
		ret = -EINVAL;
		goto exit;
	}

	status = sme_set_ese_roam_scan_channel_list(mac_handle,
						    adapter->vdev_id,
						    channel_freq_list,
						    num_channels);
	if (QDF_STATUS_SUCCESS != status) {
		hdd_err("Failed to update channel list information");
		ret = -EINVAL;
		goto exit;
	}

exit:
	return ret;
}

static int drv_cmd_get_tsm_stats(struct hdd_adapter *adapter,
				 struct hdd_context *hdd_ctx,
				 uint8_t *command,
				 uint8_t command_len,
				 struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint8_t *value = command;
	char extra[128] = { 0 };
	int len = 0;
	uint8_t tid = 0;
	struct hdd_station_ctx *sta_ctx;
	tAniTrafStrmMetrics tsm_metrics = {0};

	if ((QDF_STA_MODE != adapter->device_mode) &&
	    (QDF_P2P_CLIENT_MODE != adapter->device_mode)) {
		hdd_warn("Unsupported in mode %s(%d)",
			 qdf_opmode_str(adapter->device_mode),
			 adapter->device_mode);
		return -EINVAL;
	}

	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);

	/* if not associated, return error */
	if (eConnectionState_Associated != sta_ctx->conn_info.conn_state) {
		hdd_err("Not associated!");
		ret = -EINVAL;
		goto exit;
	}

	/* Move pointer to ahead of GETTSMSTATS<delimiter> */
	value = value + command_len + 1;

	/* Convert the value from ascii to integer */
	ret = kstrtou8(value, 10, &tid);
	if (ret < 0) {
		/*
		 * If the input value is greater than max value of datatype,
		 * then also kstrtou8 fails
		 */
		hdd_err("kstrtou8 failed range [%d - %d]",
			  TID_MIN_VALUE,
			  TID_MAX_VALUE);
		ret = -EINVAL;
		goto exit;
	}
	if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE)) {
		hdd_err("tid value %d is out of range (Min: %d Max: %d)",
			  tid, TID_MIN_VALUE, TID_MAX_VALUE);
		ret = -EINVAL;
		goto exit;
	}
	hdd_debug("Received Command to get tsm stats tid = %d",
		 tid);
	ret = hdd_get_tsm_stats(adapter, tid, &tsm_metrics);
	if (ret) {
		hdd_err("failed to get tsm stats");
		goto exit;
	}
	hdd_debug(
		"UplinkPktQueueDly(%d) UplinkPktQueueDlyHist[0](%d) UplinkPktQueueDlyHist[1](%d) UplinkPktQueueDlyHist[2](%d) UplinkPktQueueDlyHist[3](%d) UplinkPktTxDly(%u) UplinkPktLoss(%d) UplinkPktCount(%d) RoamingCount(%d) RoamingDly(%d)",
		  tsm_metrics.UplinkPktQueueDly,
		  tsm_metrics.UplinkPktQueueDlyHist[0],
		  tsm_metrics.UplinkPktQueueDlyHist[1],
		  tsm_metrics.UplinkPktQueueDlyHist[2],
		  tsm_metrics.UplinkPktQueueDlyHist[3],
		  tsm_metrics.UplinkPktTxDly,
		  tsm_metrics.UplinkPktLoss,
		  tsm_metrics.UplinkPktCount,
		  tsm_metrics.RoamingCount,
		  tsm_metrics.RoamingDly);
	/*
	 * Output TSM stats is of the format
	 * GETTSMSTATS [PktQueueDly]
	 * [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
	 * eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800
	 */
	len = scnprintf(extra,
			sizeof(extra),
			"%s %d %d:%d:%d:%d %u %d %d %d %d",
			command,
			tsm_metrics.UplinkPktQueueDly,
			tsm_metrics.UplinkPktQueueDlyHist[0],
			tsm_metrics.UplinkPktQueueDlyHist[1],
			tsm_metrics.UplinkPktQueueDlyHist[2],
			tsm_metrics.UplinkPktQueueDlyHist[3],
			tsm_metrics.UplinkPktTxDly,
			tsm_metrics.UplinkPktLoss,
			tsm_metrics.UplinkPktCount,
			tsm_metrics.RoamingCount,
			tsm_metrics.RoamingDly);
	len = QDF_MIN(priv_data->total_len, len + 1);
	if (copy_to_user(priv_data->buf, &extra, len)) {
		hdd_err("failed to copy data to user buffer");
		ret = -EFAULT;
		goto exit;
	}

exit:
	return ret;
}

static int drv_cmd_set_cckm_ie(struct hdd_adapter *adapter,
			       struct hdd_context *hdd_ctx,
			       uint8_t *command,
			       uint8_t command_len,
			       struct hdd_priv_data *priv_data)
{
	int ret;
	uint8_t *value = command;
	uint8_t *cckm_ie = NULL;
	uint8_t cckm_ie_len = 0;

	ret = hdd_parse_get_cckm_ie(value, &cckm_ie, &cckm_ie_len);
	if (ret) {
		hdd_err("Failed to parse cckm ie data");
		goto exit;
	}

	if (cckm_ie_len > DOT11F_IE_RSN_MAX_LEN) {
		hdd_err("CCKM Ie input length is more than max[%d]",
			  DOT11F_IE_RSN_MAX_LEN);
		if (cckm_ie) {
			qdf_mem_free(cckm_ie);
			cckm_ie = NULL;
		}
		ret = -EINVAL;
		goto exit;
	}

	sme_set_cckm_ie(hdd_ctx->mac_handle, adapter->vdev_id,
			cckm_ie, cckm_ie_len);
	if (cckm_ie) {
		qdf_mem_free(cckm_ie);
		cckm_ie = NULL;
	}

exit:
	return ret;
}

static int drv_cmd_ccx_beacon_req(struct hdd_adapter *adapter,
				  struct hdd_context *hdd_ctx,
				  uint8_t *command,
				  uint8_t command_len,
				  struct hdd_priv_data *priv_data)
{
	int ret;
	uint8_t *value = command;
	tCsrEseBeaconReq req = {0};
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	if (QDF_STA_MODE != adapter->device_mode) {
		hdd_warn("Unsupported in mode %s(%d)",
			 qdf_opmode_str(adapter->device_mode),
			 adapter->device_mode);
		return -EINVAL;
	}

	ret = hdd_parse_ese_beacon_req(hdd_ctx->pdev, value, &req);
	if (ret) {
		hdd_err("Failed to parse ese beacon req");
		goto exit;
	}

	if (!hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
		hdd_debug("Not associated");

		if (!req.numBcnReqIe)
			return -EINVAL;

		hdd_indicate_ese_bcn_report_no_results(adapter,
			req.bcnReq[0].measurementToken,
			0x02, /* BIT(1) set for measurement done */
			0);   /* no BSS */
		goto exit;
	}

	status = sme_set_ese_beacon_request(hdd_ctx->mac_handle,
					    adapter->vdev_id,
					    &req);

	if (QDF_STATUS_E_RESOURCES == status) {
		hdd_err("sme_set_ese_beacon_request failed (%d), a request already in progress",
			  status);
		ret = -EBUSY;
		goto exit;
	} else if (QDF_STATUS_SUCCESS != status) {
		hdd_err("sme_set_ese_beacon_request failed (%d)",
			status);
		ret = -EINVAL;
		goto exit;
	}

exit:
	return ret;
}

/**
 * drv_cmd_ccx_plm_req() - Set ESE PLM request
 * @adapter: Pointer to the HDD adapter
 * @hdd_ctx: Pointer to the HDD context
 * @command: Driver command string
 * @command_len: Driver command string length
 * @priv_data: Private data coming with the driver command. Unused here
 *
 * This function handles driver command that sets the ESE PLM request
 *
 * Return: 0 on success; negative errno otherwise
 */
static int drv_cmd_ccx_plm_req(struct hdd_adapter *adapter,
			       struct hdd_context *hdd_ctx,
			       uint8_t *command,
			       uint8_t command_len,
			       struct hdd_priv_data *priv_data)
{
	QDF_STATUS status;
	struct plm_req_params *req;

	req = qdf_mem_malloc(sizeof(*req));
	if (!req)
		return -ENOMEM;

	status = hdd_parse_plm_cmd(command, req);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		req->vdev_id = adapter->vdev_id;
		status = sme_set_plm_request(hdd_ctx->mac_handle, req);
	}
	qdf_mem_free(req);

	return qdf_status_to_os_return(status);
}

/**
 * drv_cmd_set_ccx_mode() - Set ESE mode
 * @adapter:     Pointer to the HDD adapter
 * @hdd_ctx:     Pointer to the HDD context
 * @command:     Driver command string
 * @command_len: Driver command string length
 * @priv_data:   Private data coming with the driver command. Unused here
 *
 * This function handles driver command that sets ESE mode
 *
 * Return: 0 on success; negative errno otherwise
 */
static int drv_cmd_set_ccx_mode(struct hdd_adapter *adapter,
				struct hdd_context *hdd_ctx,
				uint8_t *command,
				uint8_t command_len,
				struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint8_t *value = command;
	uint8_t ese_mode = cfg_default(CFG_LFR_ESE_FEATURE_ENABLED);
	struct pmkid_mode_bits pmkid_modes;
	mac_handle_t mac_handle;

	hdd_get_pmkid_modes(hdd_ctx, &pmkid_modes);
	mac_handle = hdd_ctx->mac_handle;
	/*
	 * Check if the features OKC/ESE/11R are supported simultaneously,
	 * then this operation is not permitted (return FAILURE)
	 */
	if (sme_get_is_ese_feature_enabled(mac_handle) &&
	    pmkid_modes.fw_okc &&
	    sme_get_is_ft_feature_enabled(mac_handle)) {
		hdd_warn("OKC/ESE/11R are supported simultaneously hence this operation is not permitted!");
		ret = -EPERM;
		goto exit;
	}

	/* Move pointer to ahead of SETCCXMODE<delimiter> */
	value = value + command_len + 1;

	/* Convert the value from ascii to integer */
	ret = kstrtou8(value, 10, &ese_mode);
	if (ret < 0) {
		/*
		 * If the input value is greater than max value of datatype,
		 * then also kstrtou8 fails
		 */
		hdd_err("kstrtou8 failed range [%d - %d]",
			cfg_min(CFG_LFR_ESE_FEATURE_ENABLED),
			cfg_max(CFG_LFR_ESE_FEATURE_ENABLED));
		ret = -EINVAL;
		goto exit;
	}

	hdd_debug("Received Command to change ese mode = %d", ese_mode);

	sme_update_is_ese_feature_enabled(mac_handle,
					  adapter->vdev_id,
					  ese_mode);

exit:
	return ret;
}
#endif /* FEATURE_WLAN_ESE */

static int drv_cmd_set_mc_rate(struct hdd_adapter *adapter,
			       struct hdd_context *hdd_ctx,
			       uint8_t *command,
			       uint8_t command_len,
			       struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint8_t *value = command;
	uint32_t target_rate = 0;

	/* input value is in units of hundred kbps */

	/* Move pointer to ahead of SETMCRATE<delimiter> */
	value = value + command_len + 1;

	/* Convert the value from ascii to integer, decimal base */
	ret = kstrtouint(value, 10, &target_rate);

	ret = wlan_hdd_set_mc_rate(adapter, target_rate);
	return ret;
}

static int drv_cmd_max_tx_power(struct hdd_adapter *adapter,
				struct hdd_context *hdd_ctx,
				uint8_t *command,
				uint8_t command_len,
				struct hdd_priv_data *priv_data)
{
	int ret;
	int tx_power;
	QDF_STATUS status;
	uint8_t *value = command;
	struct qdf_mac_addr bssid = QDF_MAC_ADDR_BCAST_INIT;
	struct qdf_mac_addr selfmac = QDF_MAC_ADDR_BCAST_INIT;

	ret = hdd_parse_setmaxtxpower_command(value, &tx_power);
	if (ret) {
		hdd_err("Invalid MAXTXPOWER command");
		return ret;
	}

	hdd_for_each_adapter(hdd_ctx, adapter) {
		/* Assign correct self MAC address */
		qdf_copy_macaddr(&bssid,
				 &adapter->mac_addr);
		qdf_copy_macaddr(&selfmac,
				 &adapter->mac_addr);

		hdd_debug("Device mode %d max tx power %d selfMac: "
			  QDF_MAC_ADDR_STR " bssId: " QDF_MAC_ADDR_STR,
			  adapter->device_mode, tx_power,
			  QDF_MAC_ADDR_ARRAY(selfmac.bytes),
			  QDF_MAC_ADDR_ARRAY(bssid.bytes));

		status = sme_set_max_tx_power(hdd_ctx->mac_handle,
					      bssid, selfmac, tx_power);
		if (QDF_STATUS_SUCCESS != status) {
			hdd_err("Set max tx power failed");
			ret = -EINVAL;
			goto exit;
		}
		hdd_debug("Set max tx power success");
	}

exit:
	return ret;
}

static int drv_cmd_set_dfs_scan_mode(struct hdd_adapter *adapter,
				    struct hdd_context *hdd_ctx,
				    uint8_t *command,
				    uint8_t command_len,
				    struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint8_t *value = command;
	uint8_t dfs_scan_mode = cfg_default(CFG_LFR_ROAMING_DFS_CHANNEL);

	/* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
	value = value + command_len + 1;

	/* Convert the value from ascii to integer */
	ret = kstrtou8(value, 10, &dfs_scan_mode);
	if (ret < 0) {
		/*
		 * If the input value is greater than max value of datatype,
		 * then also kstrtou8 fails
		 */
		hdd_err("kstrtou8 failed range [%d - %d]",
			  cfg_min(CFG_LFR_ROAMING_DFS_CHANNEL),
			  cfg_max(CFG_LFR_ROAMING_DFS_CHANNEL));
		ret = -EINVAL;
		goto exit;
	}

	if (!cfg_in_range(CFG_LFR_ROAMING_DFS_CHANNEL, dfs_scan_mode)) {
		hdd_err("dfs_scan_mode value %d is out of range (Min: %d Max: %d)",
			  dfs_scan_mode,
			  cfg_min(CFG_LFR_ROAMING_DFS_CHANNEL),
			  cfg_max(CFG_LFR_ROAMING_DFS_CHANNEL));
		ret = -EINVAL;
		goto exit;
	}

	hdd_debug("Received Command to Set DFS Scan Mode = %d",
		  dfs_scan_mode);

	/* When DFS scanning is disabled, the DFS channels need to be
	 * removed from the operation of device.
	 */
	ret = wlan_hdd_enable_dfs_chan_scan(hdd_ctx,
			dfs_scan_mode != ROAMING_DFS_CHANNEL_DISABLED);
	if (ret < 0) {
		/* Some conditions prevented it from disabling DFS channels */
		hdd_err("disable/enable DFS channel request was denied");
		goto exit;
	}

	sme_update_dfs_scan_mode(hdd_ctx->mac_handle, adapter->vdev_id,
				 dfs_scan_mode);

exit:
	return ret;
}

static int drv_cmd_get_dfs_scan_mode(struct hdd_adapter *adapter,
				     struct hdd_context *hdd_ctx,
				     uint8_t *command,
				     uint8_t command_len,
				     struct hdd_priv_data *priv_data)
{
	int ret = 0;
	uint8_t dfs_scan_mode = sme_get_dfs_scan_mode(hdd_ctx->mac_handle);
	char extra[32];
	uint8_t len = 0;

	len = scnprintf(extra, sizeof(extra), "%s %d", command, dfs_scan_mode);
	len = QDF_MIN(priv_data->total_len, len + 1);
	if (copy_to_user(priv_data->buf, &extra, len)) {
		hdd_err("failed to copy data to user buffer");
		ret = -EFAULT;
	}

	return ret;
}

static int drv_cmd_get_link_status(struct hdd_adapter *adapter,
				   struct hdd_context *hdd_ctx,
				   uint8_t *command,
				   uint8_t command_len,
				   struct hdd_priv_data *priv_data)
{
	int ret = 0;
	int value = wlan_hdd_get_link_status(adapter);
	char extra[32];
	uint8_t len;

	len = scnprintf(extra, sizeof(extra), "%s %d", command, value);
	len = QDF_MIN(priv_data->total_len, len + 1);
	if (copy_to_user(priv_data->buf, &extra, len)) {
		hdd_err("failed to copy data to user buffer");
		ret = -EFAULT;
	}

	return ret;
}

#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
static int drv_cmd_enable_ext_wow(struct hdd_adapter *adapter,
				  struct hdd_context *hdd_ctx,
				  uint8_t *command,
				  uint8_t command_len,
				  struct hdd_priv_data *priv_data)
{
	uint8_t *value = command;
	int set_value;

	/* Move pointer to ahead of ENABLEEXTWOW */
	value = value + command_len;

	if (!(sscanf(value, "%d", &set_value))) {
		hdd_info("No input identified");
		return -EINVAL;
	}

	return hdd_enable_ext_wow_parser(adapter,
					 adapter->vdev_id,
					 set_value);
}

static int drv_cmd_set_app1_params(struct hdd_adapter *adapter,
				   struct hdd_context *hdd_ctx,
				   uint8_t *command,
				   uint8_t command_len,
				   struct hdd_priv_data *priv_data)
{
	int ret;
	uint8_t *value = command;

	/* Move pointer to ahead of SETAPP1PARAMS */
	value = value + command_len;

	ret = hdd_set_app_type1_parser(adapter,
				       value, strlen(value));
	if (ret >= 0)
		hdd_ctx->is_extwow_app_type1_param_set = true;

	return ret;
}

static int drv_cmd_set_app2_params(struct hdd_adapter *adapter,
				   struct hdd_context *hdd_ctx,
				   uint8_t *command,
				   uint8_t command_len,
				   struct hdd_priv_data *priv_data)
{
	int ret;
	uint8_t *value = command;

	/* Move pointer to ahead of SETAPP2PARAMS */
	value = value + command_len;

	ret = hdd_set_app_type2_parser(adapter, value, strlen(value));
	if (ret >= 0)
		hdd_ctx->is_extwow_app_type2_param_set = true;

	return ret;
}
#endif /* WLAN_FEATURE_EXTWOW_SUPPORT */

#ifdef FEATURE_WLAN_TDLS
/**
 * drv_cmd_tdls_secondary_channel_offset() - secondary tdls off channel offset
 * @adapter:     Pointer to the HDD adapter
 * @hdd_ctx:     Pointer to the HDD context
 * @command:     Driver command string
 * @command_len: Driver command string length
 * @priv_data:   Private data coming with the driver command. Unused here
 *
 * This function handles driver command that sets the secondary tdls off channel
 * offset
 *
 * Return: 0 on success; negative errno otherwise
 */
static int drv_cmd_tdls_secondary_channel_offset(struct hdd_adapter *adapter,
						 struct hdd_context *hdd_ctx,
						 uint8_t *command,
						 uint8_t command_len,
						 struct hdd_priv_data *priv_data)
{
	int ret;
	uint8_t *value = command;
	int set_value;

	/* Move pointer to point the string */
	value += command_len;

	ret = sscanf(value, "%d", &set_value);
	if (ret != 1)
		return -EINVAL;

	hdd_debug("Tdls offchannel offset:%d", set_value);

	ret = hdd_set_tdls_secoffchanneloffset(hdd_ctx, adapter, set_value);

	return ret;
}

/**
 * drv_cmd_tdls_off_channel_mode() - set tdls off channel mode
 * @adapter:     Pointer to the HDD adapter
 * @hdd_ctx:     Pointer to the HDD context
 * @command:     Driver command string
 * @command_len: Driver command string length
 * @priv_data:   Private data coming with the driver command. Unused here
 *
 * This function handles driver command that sets tdls off channel mode
 *
 * Return: 0 on success; negative errno otherwise
 */
static int drv_cmd_tdls_off_channel_mode(struct hdd_adapter *adapter,
					 struct hdd_context *hdd_ctx,
					 uint8_t *command,
					 uint8_t command_len,
					 struct hdd_priv_data *priv_data)
{
	int ret;
	uint8_t *value = command;
	int set_value;

	/* Move pointer to point the string */
	value += command_len;

	ret = sscanf(value, "%d", &set_value);
	if (ret != 1)
		return -EINVAL;

	hdd_debug("Tdls offchannel mode:%d", set_value);

	ret = hdd_set_tdls_offchannelmode(hdd_ctx, adapter, set_value);

	return ret;
}

/**
 * drv_cmd_tdls_off_channel() - set tdls off channel number
 * @adapter:     Pointer to the HDD adapter
 * @hdd_ctx:     Pointer to the HDD context
 * @command:     Driver command string
 * @command_len: Driver command string length
 * @priv_data:   Private data coming with the driver command. Unused here
 *
 * This function handles driver command that sets tdls off channel number
 *
 * Return: 0 on success; negative errno otherwise
 */
static int drv_cmd_tdls_off_channel(struct hdd_adapter *adapter,
				    struct hdd_context *hdd_ctx,
				    uint8_t *command,
				    uint8_t command_len,
				    struct hdd_priv_data *priv_data)
{
	int ret;
	uint8_t *value = command;
	int channel;
	enum channel_state reg_state;

	/* Move pointer to point the string */
	value += command_len;

	ret = sscanf(value, "%d", &channel);
	if (ret != 1)
		return -EINVAL;
	reg_state = wlan_reg_get_channel_state(hdd_ctx->pdev, channel);

	if (reg_state == CHANNEL_STATE_DFS ||
		reg_state == CHANNEL_STATE_DISABLE ||
		reg_state == CHANNEL_STATE_INVALID) {
		hdd_err("reg state of the  channel %d is %d and not supported",
			channel, reg_state);
		return -EINVAL;
	}

	hdd_debug("Tdls offchannel num: %d", channel);

	ret = hdd_set_tdls_offchannel(hdd_ctx, adapter, channel);

	return ret;
}

/**
 * drv_cmd_tdls_scan() - set tdls scan type
 * @adapter:     Pointer to the HDD adapter
 * @hdd_ctx:     Pointer to the HDD context
 * @command:     Driver command string
 * @command_len: Driver command string length
 * @priv_data:   Private data coming with the driver command. Unused here
 *
 * This function handles driver command that sets tdls scan type
 *
 * Return: 0 on success; negative errno otherwise
 */
static int drv_cmd_tdls_scan(struct hdd_adapter *adapter,
				    struct hdd_context *hdd_ctx,
				    uint8_t *command,
				    uint8_t command_len,
				    struct hdd_priv_data *priv_data)
{
	int ret;
	uint8_t *value = command;
	int set_value;

	/* Move pointer to point the string */
	value += command_len;

	ret = sscanf(value, "%d", &set_value);
	if (ret != 1)
		return -EINVAL;

	hdd_debug("Tdls scan type val: %d", set_value);

	ret = hdd_set_tdls_scan_type(hdd_ctx, set_value);

	return ret;
}
#endif

static int drv_cmd_get_rssi(struct hdd_adapter *adapter,
			    struct hdd_context *hdd_ctx,
			    uint8_t *command,
			    uint8_t command_len,
			    struct hdd_priv_data *priv_data)
{
	int ret = 0;
	int8_t rssi = 0;
	char extra[32];

	uint8_t len = 0;

	wlan_hdd_get_rssi(adapter, &rssi);

	len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
	len = QDF_MIN(priv_data->total_len, len + 1);

	if (copy_to_user(priv_data->buf, &extra, len)) {
		hdd_err("Failed to copy data to user buffer");
		ret = -EFAULT;
	}

	return ret;
}

static int drv_cmd_get_linkspeed(struct hdd_adapter *adapter,
				 struct hdd_context *hdd_ctx,
				 uint8_t *command,
				 uint8_t command_len,
				 struct hdd_priv_data *priv_data)
{
	int ret;
	uint32_t link_speed = 0;
	char extra[32];
	uint8_t len = 0;

	ret = wlan_hdd_get_link_speed(adapter, &link_speed);
	if (0 != ret)
		return ret;

	len = scnprintf(extra, sizeof(extra), "%s %d", command, link_speed);
	len = QDF_MIN(priv_data->total_len, len + 1);
	if (copy_to_user(priv_data->buf, &extra, len)) {
		hdd_err("Failed to copy data to user buffer");
		ret = -EFAULT;
	}

	return ret;
}

#ifdef WLAN_FEATURE_PACKET_FILTERING
/**
 * hdd_set_rx_filter() - set RX filter
 * @adapter: Pointer to adapter
 * @action: Filter action
 * @pattern: Address pattern
 *
 * Address pattern is most significant byte of address for example
 * 0x01 for IPV4 multicast address
 * 0x33 for IPV6 multicast address
 * 0xFF for broadcast address
 *
 * Return: 0 for success, non-zero for failure
 */
static int hdd_set_rx_filter(struct hdd_adapter *adapter, bool action,
			uint8_t pattern)
{
	int ret;
	uint8_t i, j;
	tSirRcvFltMcAddrList *filter;
	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	mac_handle_t mac_handle;

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

	mac_handle = hdd_ctx->mac_handle;
	if (!mac_handle) {
		hdd_err("MAC Handle is NULL");
		return -EINVAL;
	}

	if (!ucfg_pmo_is_mc_addr_list_enabled(hdd_ctx->psoc)) {
		hdd_warn("mc addr ini is disabled");
		return -EINVAL;
	}

	/*
	 * If action is false it means start dropping packets
	 * Set addr_filter_pattern which will be used when sending
	 * MC/BC address list to target
	 */
	if (!action)
		adapter->addr_filter_pattern = pattern;
	else
		adapter->addr_filter_pattern = 0;

	if (((adapter->device_mode == QDF_STA_MODE) ||
		(adapter->device_mode == QDF_P2P_CLIENT_MODE)) &&
		adapter->mc_addr_list.mc_cnt &&
		hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {


		filter = qdf_mem_malloc(sizeof(*filter));
		if (!filter) {
			hdd_err("Could not allocate Memory");
			return -ENOMEM;
		}
		filter->action = action;
		for (i = 0, j = 0; i < adapter->mc_addr_list.mc_cnt; i++) {
			if (!memcmp(adapter->mc_addr_list.addr[i],
				&pattern, 1)) {
				memcpy(filter->multicastAddr[j].bytes,
					adapter->mc_addr_list.addr[i],
					sizeof(adapter->mc_addr_list.addr[i]));

				hdd_debug("%s RX filter : addr ="
				    QDF_MAC_ADDR_STR,
				    action ? "setting" : "clearing",
				    QDF_MAC_ADDR_ARRAY(filter->multicastAddr[j].bytes));
				j++;
			}
			if (j == SIR_MAX_NUM_MULTICAST_ADDRESS)
				break;
		}
		filter->ulMulticastAddrCnt = j;
		/* Set rx filter */
		sme_8023_multicast_list(mac_handle, adapter->vdev_id,
					filter);
		qdf_mem_free(filter);
	} else {
		hdd_debug("mode %d mc_cnt %d",
			  adapter->device_mode, adapter->mc_addr_list.mc_cnt);
	}

	return 0;
}

/**
 * hdd_driver_rxfilter_command_handler() - RXFILTER driver command handler
 * @command: Pointer to input string driver command
 * @adapter: Pointer to adapter
 * @action: Action to enable/disable filtering
 *
 * If action == false
 * Start filtering out data packets based on type
 * RXFILTER-REMOVE 0 -> Start filtering out unicast data packets
 * RXFILTER-REMOVE 1 -> Start filtering out broadcast data packets
 * RXFILTER-REMOVE 2 -> Start filtering out IPV4 mcast data packets
 * RXFILTER-REMOVE 3 -> Start filtering out IPV6 mcast data packets
 *
 * if action == true
 * Stop filtering data packets based on type
 * RXFILTER-ADD 0 -> Stop filtering unicast data packets
 * RXFILTER-ADD 1 -> Stop filtering broadcast data packets
 * RXFILTER-ADD 2 -> Stop filtering IPV4 mcast data packets
 * RXFILTER-ADD 3 -> Stop filtering IPV6 mcast data packets
 *
 * Current implementation only supports IPV4 address filtering by
 * selectively allowing IPV4 multicast data packest based on
 * address list received in .ndo_set_rx_mode
 *
 * Return: 0 for success, non-zero for failure
 */
static int hdd_driver_rxfilter_command_handler(uint8_t *command,
						struct hdd_adapter *adapter,
						bool action)
{
	int ret = 0;
	uint8_t *value;
	uint8_t type;

	value = command;
	/* Skip space after RXFILTER-REMOVE OR RXFILTER-ADD based on action */
	if (!action)
		value = command + 16;
	else
		value = command + 13;
	ret = kstrtou8(value, 10, &type);
	if (ret < 0) {
		hdd_err("kstrtou8 failed invalid input value");
		return -EINVAL;
	}

	switch (type) {
	case 2:
		/* Set rx filter for IPV4 multicast data packets */
		ret = hdd_set_rx_filter(adapter, action, 0x01);
		break;
	default:
		hdd_warn("Unsupported RXFILTER type %d", type);
		break;
	}

	return ret;
}

/**
 * drv_cmd_rx_filter_remove() - RXFILTER REMOVE driver command handler
 * @adapter: Pointer to network adapter
 * @hdd_ctx: Pointer to hdd context
 * @command: Pointer to input command
 * @command_len: Command length
 * @priv_data: Pointer to private data in command
 */
static int drv_cmd_rx_filter_remove(struct hdd_adapter *adapter,
				struct hdd_context *hdd_ctx,
				uint8_t *command,
				uint8_t command_len,
				struct hdd_priv_data *priv_data)
{
	return hdd_driver_rxfilter_command_handler(command, adapter, false);
}

/**
 * drv_cmd_rx_filter_add() - RXFILTER ADD driver command handler
 * @adapter: Pointer to network adapter
 * @hdd_ctx: Pointer to hdd context
 * @command: Pointer to input command
 * @command_len: Command length
 * @priv_data: Pointer to private data in command
 */
static int drv_cmd_rx_filter_add(struct hdd_adapter *adapter,
				struct hdd_context *hdd_ctx,
				uint8_t *command,
				uint8_t command_len,
				struct hdd_priv_data *priv_data)
{
	return hdd_driver_rxfilter_command_handler(command, adapter, true);
}
#endif /* WLAN_FEATURE_PACKET_FILTERING */

/**
 * hdd_parse_setantennamode_command() - HDD Parse SETANTENNAMODE
 * command
 * @value: Pointer to SETANTENNAMODE command
 * @mode: Pointer to antenna mode
 * @reason: Pointer to reason for set antenna mode
 *
 * This function parses the SETANTENNAMODE command passed in the format
 * SETANTENNAMODE<space>mode
 *
 * Return: 0 for success non-zero for failure
 */
static int hdd_parse_setantennamode_command(const uint8_t *value)
{
	const uint8_t *in_ptr = value;
	int tmp, v;
	char arg1[32];

	in_ptr = strnchr(value, strlen(value), SPACE_ASCII_VALUE);

	/* no argument after the command */
	if (!in_ptr) {
		hdd_err("No argument after the command");
		return -EINVAL;
	}

	/* no space after the command */
	if (SPACE_ASCII_VALUE != *in_ptr) {
		hdd_err("No space after the command");
		return -EINVAL;
	}

	/* remove empty spaces */
	while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr))
		in_ptr++;

	/* no argument followed by spaces */
	if ('\0' == *in_ptr) {
		hdd_err("No argument followed by spaces");
		return -EINVAL;
	}

	/* get the argument i.e. antenna mode */
	v = sscanf(in_ptr, "%31s ", arg1);
	if (1 != v) {
		hdd_err("argument retrieval from cmd string failed");
		return -EINVAL;
	}

	v = kstrtos32(arg1, 10, &tmp);
	if (v < 0) {
		hdd_err("argument string to int conversion failed");
		return -EINVAL;
	}

	return tmp;
}

/**
 * hdd_is_supported_chain_mask_2x2() - Verify if supported chain
 * mask is 2x2 mode
 * @hdd_ctx: Pointer to hdd contex
 *
 * Return: true if supported chain mask 2x2 else false
 */
static bool hdd_is_supported_chain_mask_2x2(struct hdd_context *hdd_ctx)
{
	QDF_STATUS status;
	bool bval = false;

/*
	 * Revisit and the update logic to determine the number
	 * of TX/RX chains supported in the system when
	 * antenna sharing per band chain mask support is
	 * brought in
	 */
	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
	if (!QDF_IS_STATUS_SUCCESS(status))
		hdd_err("unable to get vht_enable2x2");

	return (bval == 0x01) ? true : false;
}

/**
 * hdd_is_supported_chain_mask_1x1() - Verify if the supported
 * chain mask is 1x1
 * @hdd_ctx: Pointer to hdd contex
 *
 * Return: true if supported chain mask 1x1 else false
 */
static bool hdd_is_supported_chain_mask_1x1(struct hdd_context *hdd_ctx)
{
	QDF_STATUS status;
	bool bval = false;

	/*
	 * Revisit and update the logic to determine the number
	 * of TX/RX chains supported in the system when
	 * antenna sharing per band chain mask support is
	 * brought in
	 */
	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
	if (!QDF_IS_STATUS_SUCCESS(status))
		hdd_err("unable to get vht_enable2x2");

	return (!bval) ? true : false;
}

QDF_STATUS hdd_update_smps_antenna_mode(struct hdd_context *hdd_ctx, int mode)
{
	QDF_STATUS status;
	uint8_t smps_mode;
	uint8_t smps_enable;
	mac_handle_t mac_handle;

	/* Update SME SMPS config */
	if (HDD_ANTENNA_MODE_1X1 == mode) {
		smps_enable = true;
		smps_mode = HDD_SMPS_MODE_STATIC;
	} else {
		smps_enable = false;
		smps_mode = HDD_SMPS_MODE_DISABLED;
	}

	hdd_debug("Update SME SMPS enable: %d mode: %d",
		 smps_enable, smps_mode);
	mac_handle = hdd_ctx->mac_handle;
	status = sme_update_mimo_power_save(mac_handle, smps_enable,
					    smps_mode, false);
	if (QDF_STATUS_SUCCESS != status) {
		hdd_err("Update SMPS config failed enable: %d mode: %d status: %d",
			smps_enable, smps_mode, status);
		return QDF_STATUS_E_FAILURE;
	}

	hdd_ctx->current_antenna_mode = mode;
	/*
	 * Update the user requested nss in the mac context.
	 * This will be used in tdls protocol engine to form tdls
	 * Management frames.
	 */
	sme_update_user_configured_nss(mac_handle,
				       hdd_ctx->current_antenna_mode);

	hdd_debug("Successfully switched to mode: %d x %d",
		 hdd_ctx->current_antenna_mode,
		 hdd_ctx->current_antenna_mode);

	return QDF_STATUS_SUCCESS;
}

/**
 * wlan_hdd_soc_set_antenna_mode_cb() - Callback for set antenna mode
 * @status: Status of set antenna mode
 * @context: callback context
 *
 * Callback on setting antenna mode
 *
 * Return: None
 */
static void
wlan_hdd_soc_set_antenna_mode_cb(enum set_antenna_mode_status status,
				 void *context)
{
	struct osif_request *request = NULL;

	hdd_debug("Status: %d", status);

	request = osif_request_get(context);
	if (!request) {
		hdd_err("obselete request");
		return;
	}

	/* Signal the completion of set dual mac config */
	osif_request_complete(request);
	osif_request_put(request);
}

static QDF_STATUS
hdd_populate_vdev_chains(struct wlan_mlme_nss_chains *nss_chains_cfg,
			 uint8_t tx_chains,
			 uint8_t rx_chains,
			 enum nss_chains_band_info band,
			 struct wlan_objmgr_vdev *vdev)
{
	struct wlan_mlme_nss_chains *dynamic_cfg;

	nss_chains_cfg->num_rx_chains[band] = rx_chains;
	nss_chains_cfg->num_tx_chains[band] = tx_chains;

	dynamic_cfg = ucfg_mlme_get_dynamic_vdev_config(vdev);
	if (!dynamic_cfg) {
		hdd_err("nss chain dynamic config NULL");
		return QDF_STATUS_E_FAILURE;
	}
	/*
	 * If user gives any nss value, then chains will be adjusted based on
	 * nss (in SME func sme_validate_user_nss_chain_params).
	 * If Chains are not suitable as per current NSS then, we need to
	 * return, and the below logic is added for the same.
	 */

	if ((dynamic_cfg->rx_nss[band] > rx_chains) ||
	    (dynamic_cfg->tx_nss[band] > tx_chains)) {
		hdd_err("Chains less than nss, configure correct nss first.");
		return QDF_STATUS_E_FAILURE;
	}

	return QDF_STATUS_SUCCESS;
}

static int
hdd_set_dynamic_antenna_mode(struct hdd_adapter *adapter,
			     uint8_t num_rx_chains,
			     uint8_t num_tx_chains)
{
	enum nss_chains_band_info band;
	struct wlan_mlme_nss_chains user_cfg;
	QDF_STATUS status;
	mac_handle_t mac_handle;
	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);

	mac_handle = hdd_ctx->mac_handle;
	if (!mac_handle) {
		hdd_err("NULL MAC handle");
		return -EINVAL;
	}

	if (!hdd_is_vdev_in_conn_state(adapter)) {
		hdd_debug("Vdev (id %d) not in connected/started state, cannot accept command",
			  adapter->vdev_id);
		return -EINVAL;
	}

	qdf_mem_zero(&user_cfg, sizeof(user_cfg));
	for (band = NSS_CHAINS_BAND_2GHZ; band < NSS_CHAINS_BAND_MAX; band++) {
		status = hdd_populate_vdev_chains(&user_cfg,
						  num_rx_chains,
						  num_tx_chains, band,
						  adapter->vdev);
		if (QDF_IS_STATUS_ERROR(status))
			return -EINVAL;
	}
	status = sme_nss_chains_update(mac_handle,
				       &user_cfg,
				       adapter->vdev_id);
	if (QDF_IS_STATUS_ERROR(status))
		return -EINVAL;

	return 0;
}
int hdd_set_antenna_mode(struct hdd_adapter *adapter,
				  struct hdd_context *hdd_ctx, int mode)
{
	struct sir_antenna_mode_param params;
	QDF_STATUS status;
	int ret = 0;
	struct osif_request *request = NULL;
	static const struct osif_request_params request_params = {
		.priv_size = 0,
		.timeout_ms = SME_POLICY_MGR_CMD_TIMEOUT,
	};

	switch (mode) {
	case HDD_ANTENNA_MODE_1X1:
		params.num_rx_chains = 1;
		params.num_tx_chains = 1;
		break;
	case HDD_ANTENNA_MODE_2X2:
		params.num_rx_chains = 2;
		params.num_tx_chains = 2;
		break;
	default:
		hdd_err("unsupported antenna mode");
		ret = -EINVAL;
		goto exit;
	}

	if (hdd_ctx->dynamic_nss_chains_support)
		return hdd_set_dynamic_antenna_mode(adapter,
						    params.num_rx_chains,
						    params.num_tx_chains);

	if ((HDD_ANTENNA_MODE_2X2 == mode) &&
	    (!hdd_is_supported_chain_mask_2x2(hdd_ctx))) {
		hdd_err("System does not support 2x2 mode");
		ret = -EPERM;
		goto exit;
	}

	if ((HDD_ANTENNA_MODE_1X1 == mode) &&
	    hdd_is_supported_chain_mask_1x1(hdd_ctx)) {
		hdd_err("System only supports 1x1 mode");
		goto exit;
	}

	/* Check TDLS status and update antenna mode */
	if ((QDF_STA_MODE == adapter->device_mode) &&
	    policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc)) {
		ret = wlan_hdd_tdls_antenna_switch(hdd_ctx, adapter, mode);
		if (0 != ret)
			goto exit;
	}

	request = osif_request_alloc(&request_params);
	if (!request) {
		hdd_err("Request Allocation Failure");
		ret = -ENOMEM;
		goto exit;
	}

	params.set_antenna_mode_ctx = osif_request_cookie(request);
	params.set_antenna_mode_resp = (void *)wlan_hdd_soc_set_antenna_mode_cb;
	hdd_debug("Set antenna mode rx chains: %d tx chains: %d",
		 params.num_rx_chains,
		 params.num_tx_chains);

	status = sme_soc_set_antenna_mode(hdd_ctx->mac_handle, &params);
	if (QDF_IS_STATUS_ERROR(status)) {
		hdd_err("set antenna mode failed status : %d", status);
		ret = -EFAULT;
		goto request_put;
	}

	ret = osif_request_wait_for_response(request);
	if (ret) {
		hdd_err("send set antenna mode timed out");
		goto request_put;
	}

	status = hdd_update_smps_antenna_mode(hdd_ctx, mode);
	if (QDF_STATUS_SUCCESS != status) {
		ret = -EFAULT;
		goto request_put;
	}
	ret = 0;
request_put:
	osif_request_put(request);
exit:
	hdd_debug("Set antenna status: %d current mode: %d",
		 ret, hdd_ctx->current_antenna_mode);

	return ret;
}

/**
 * drv_cmd_set_antenna_mode() - SET ANTENNA MODE driver command
 * handler
 * @adapter: Pointer to network adapter
 * @hdd_ctx: Pointer to hdd context
 * @command: Pointer to input command
 * @command_len: Command length
 * @priv_data: Pointer to private data in command
 */
static int drv_cmd_set_antenna_mode(struct hdd_adapter *adapter,
				struct hdd_context *hdd_ctx,
				uint8_t *command,
				uint8_t command_len,
				struct hdd_priv_data *priv_data)
{
	int mode;
	uint8_t *value = command;

	mode = hdd_parse_setantennamode_command(value);
	if (mode < 0) {
		hdd_err("Invalid SETANTENNA command");
		return mode;
	}

	hdd_debug("Processing antenna mode switch to: %d", mode);

	return hdd_set_antenna_mode(adapter, hdd_ctx, mode);
}

/**
 * hdd_get_dynamic_antenna_mode() -get the dynamic antenna mode for vdev
 * @antenna_mode: pointer to antenna mode of vdev
 * @dynamic_nss_chains_support: feature support for dynamic nss chains update
 * @vdev: Pointer to vdev
 *
 * This API will check for the num of chains configured for the vdev, and fill
 * that info in the antenna mode if the dynamic chains per vdev are supported.
 *
 * Return: None
 */
static void
hdd_get_dynamic_antenna_mode(uint32_t *antenna_mode,
			     bool dynamic_nss_chains_support,
			     struct wlan_objmgr_vdev *vdev)
{
	struct wlan_mlme_nss_chains *nss_chains_dynamic_cfg;

	if (!dynamic_nss_chains_support)
		return;

	nss_chains_dynamic_cfg = ucfg_mlme_get_dynamic_vdev_config(vdev);
	if (!nss_chains_dynamic_cfg) {
		hdd_err("nss chain dynamic config NULL");
		return;
	}
	/*
	 * At present, this command doesn't include band, so by default
	 * it will return the band 2ghz present rf chains.
	 */
	*antenna_mode =
		nss_chains_dynamic_cfg->num_rx_chains[NSS_CHAINS_BAND_2GHZ];
}

/**
 * drv_cmd_get_antenna_mode() - GET ANTENNA MODE driver command
 * handler
 * @adapter: Pointer to hdd adapter
 * @hdd_ctx: Pointer to hdd context
 * @command: Pointer to input command
 * @command_len: length of the command
 * @priv_data: private data coming with the driver command
 *
 * Return: 0 for success non-zero for failure
 */
static inline int drv_cmd_get_antenna_mode(struct hdd_adapter *adapter,
					   struct hdd_context *hdd_ctx,
					   uint8_t *command,
					   uint8_t command_len,
					   struct hdd_priv_data *priv_data)
{
	uint32_t antenna_mode = 0;
	char extra[32];
	uint8_t len = 0;

	antenna_mode = hdd_ctx->current_antenna_mode;
	/* Overwrite this antenna mode if dynamic vdev chains are supported */
	hdd_get_dynamic_antenna_mode(&antenna_mode,
				     hdd_ctx->dynamic_nss_chains_support,
				     adapter->vdev);
	len = scnprintf(extra, sizeof(extra), "%s %d", command,
			antenna_mode);
	len = QDF_MIN(priv_data->total_len, len + 1);
	if (copy_to_user(priv_data->buf, &extra, len)) {
		hdd_err("Failed to copy data to user buffer");
		return -EFAULT;
	}

	hdd_debug("Get antenna mode: %d", antenna_mode);

	return 0;
}

/*
 * dummy (no-op) hdd driver command handler
 */
static int drv_cmd_dummy(struct hdd_adapter *adapter,
			 struct hdd_context *hdd_ctx,
			 uint8_t *command,
			 uint8_t command_len,
			 struct hdd_priv_data *priv_data)
{
	hdd_debug("%s: Ignoring driver command \"%s\"",
		 adapter->dev->name, command);
	return 0;
}

/*
 * handler for any unsupported wlan hdd driver command
 */
static int drv_cmd_invalid(struct hdd_adapter *adapter,
			   struct hdd_context *hdd_ctx,
			   uint8_t *command,
			   uint8_t command_len,
			   struct hdd_priv_data *priv_data)
{
	qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
		   TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
		   adapter->vdev_id, 0);

	hdd_warn("%s: Unsupported driver command \"%s\"",
		 adapter->dev->name, command);

	return -ENOTSUPP;
}

/**
 * drv_cmd_set_fcc_channel() - Handle fcc constraint request
 * @adapter: HDD adapter
 * @hdd_ctx: HDD context
 * @command: command ptr, SET_FCC_CHANNEL 0/-1 is the command
 * @command_len: command len
 * @priv_data: private data
 *
 * Return: status
 */
static int drv_cmd_set_fcc_channel(struct hdd_adapter *adapter,
				   struct hdd_context *hdd_ctx,
				   uint8_t *command,
				   uint8_t command_len,
				   struct hdd_priv_data *priv_data)
{
	QDF_STATUS status;
	int8_t input_value;
	bool fcc_constraint;
	int err;

	/*
	 * This command would be called by user-space when it detects WLAN
	 * ON after airplane mode is set. When APM is set, WLAN turns off.
	 * But it can be turned back on. Otherwise; when APM is turned back
	 * off, WLAN would turn back on. So at that point the command is
	 * expected to come down. 0 means reduce power as per fcc constraint
	 * and -1 means remove constraint.
	 */

	err = kstrtos8(command + command_len + 1, 10, &input_value);
	if (err) {
		hdd_err("error %d parsing userspace fcc parameter", err);
		return err;
	}

	fcc_constraint = input_value ? false : true;
	hdd_debug("input_value = %d && fcc_constraint = %u",
		  input_value, fcc_constraint);

	status = ucfg_reg_set_fcc_constraint(hdd_ctx->pdev, fcc_constraint);

	if (QDF_IS_STATUS_ERROR(status))
		hdd_err("Failed to %s tx power for channels 12/13",
			fcc_constraint ? "restore" : "reduce");

	return qdf_status_to_os_return(status);
}

/**
 * hdd_parse_set_channel_switch_command() - Parse and validate CHANNEL_SWITCH
 * command
 * @value: Pointer to the command
 * @chan_number: Pointer to the channel number
 * @chan_bw: Pointer to the channel bandwidth
 *
 * Parses and provides the channel number and channel width from the input
 * command which is expected to be of the format: CHANNEL_SWITCH <CH> <BW>
 * <CH> is channel number to move (where 1 = channel 1, 149 = channel 149, ...)
 * <BW> is bandwidth to move (where 20 = BW 20, 40 = BW 40, 80 = BW 80)
 *
 * Return: 0 for success, non-zero for failure
 */
static int hdd_parse_set_channel_switch_command(uint8_t *value,
					 uint32_t *chan_number,
					 uint32_t *chan_bw)
{
	const uint8_t *in_ptr = value;
	int ret;

	in_ptr = strnchr(value, strlen(value), SPACE_ASCII_VALUE);

	/* no argument after the command */
	if (!in_ptr) {
		hdd_err("No argument after the command");
		return -EINVAL;
	}

	/* no space after the command */
	if (SPACE_ASCII_VALUE != *in_ptr) {
		hdd_err("No space after the command ");
		return -EINVAL;
	}

	/* remove empty spaces and move the next argument */
	while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr))
		in_ptr++;

	/* no argument followed by spaces */
	if ('\0' == *in_ptr) {
		hdd_err("No argument followed by spaces");
		return -EINVAL;
	}

	/* get the two arguments: channel number and bandwidth */
	ret = sscanf(in_ptr, "%u %u", chan_number, chan_bw);
	if (ret != 2) {
		hdd_err("Arguments retrieval from cmd string failed");
		return -EINVAL;
	}

	return 0;
}

/**
 * drv_cmd_set_channel_switch() - Switch SAP/P2P-GO operating channel
 * @adapter: HDD adapter
 * @hdd_ctx: HDD context
 * @command: Pointer to the input command CHANNEL_SWITCH
 * @command_len: Command len
 * @priv_data: Private data
 *
 * Handles private IOCTL CHANNEL_SWITCH command to switch the operating channel
 * of SAP/P2P-GO
 *
 * Return: 0 for success, non-zero for failure
 */
static int drv_cmd_set_channel_switch(struct hdd_adapter *adapter,
				   struct hdd_context *hdd_ctx,
				   uint8_t *command,
				   uint8_t command_len,
				   struct hdd_priv_data *priv_data)
{
	struct net_device *dev = adapter->dev;
	int status;
	uint32_t chan_number = 0, chan_bw = 0;
	uint8_t *value = command;
	enum phy_ch_width width;

	if ((adapter->device_mode != QDF_P2P_GO_MODE) &&
		(adapter->device_mode != QDF_SAP_MODE)) {
		hdd_err("IOCTL CHANNEL_SWITCH not supported for mode %d",
			adapter->device_mode);
		return -EINVAL;
	}

	status = hdd_parse_set_channel_switch_command(value,
							&chan_number, &chan_bw);
	if (status) {
		hdd_err("Invalid CHANNEL_SWITCH command");
		return status;
	}

	if ((chan_bw != 20) && (chan_bw != 40) && (chan_bw != 80)) {
		hdd_err("BW %d is not allowed for CHANNEL_SWITCH", chan_bw);
		return -EINVAL;
	}

	if (chan_bw == 80)
		width = CH_WIDTH_80MHZ;
	else if (chan_bw == 40)
		width = CH_WIDTH_40MHZ;
	else
		width = CH_WIDTH_20MHZ;

	hdd_debug("CH:%d BW:%d", chan_number, chan_bw);

	wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc, adapter->vdev_id,
				    CSA_REASON_USER_INITIATED);
	status = hdd_softap_set_channel_change(dev,
					       wlan_reg_legacy_chan_to_freq(hdd_ctx->pdev, chan_number),
					       width, true);
	if (status) {
		hdd_err("Set channel change fail");
		return status;
	}

	return 0;
}

#ifdef DISABLE_CHANNEL_LIST
void wlan_hdd_free_cache_channels(struct hdd_context *hdd_ctx)
{
	hdd_enter();

	if (!hdd_ctx->original_channels)
		return;

	qdf_mutex_acquire(&hdd_ctx->cache_channel_lock);
	hdd_ctx->original_channels->num_channels = 0;
	if (hdd_ctx->original_channels->channel_info) {
		qdf_mem_free(hdd_ctx->original_channels->channel_info);
		hdd_ctx->original_channels->channel_info = NULL;
	}
	qdf_mem_free(hdd_ctx->original_channels);
	hdd_ctx->original_channels = NULL;
	qdf_mutex_release(&hdd_ctx->cache_channel_lock);

	hdd_exit();
}

/**
 * hdd_alloc_chan_cache() - Allocate the memory to cache the channel
 * info for the channels received in command SET_DISABLE_CHANNEL_LIST
 * @hdd_ctx: Pointer to HDD context
 * @num_chan: Number of channels for which memory needs to
 * be allocated
 *
 * Return: 0 on success and error code on failure
 */
static int hdd_alloc_chan_cache(struct hdd_context *hdd_ctx, int num_chan)
{
	hdd_ctx->original_channels =
			qdf_mem_malloc(sizeof(struct hdd_cache_channels));
	if (!hdd_ctx->original_channels) {
		hdd_err("QDF_MALLOC_ERR");
		return -ENOMEM;
	}
	hdd_ctx->original_channels->num_channels = num_chan;
	hdd_ctx->original_channels->channel_info =
					qdf_mem_malloc(num_chan *
					sizeof(struct hdd_cache_channel_info));
	if (!hdd_ctx->original_channels->channel_info) {
		hdd_err("QDF_MALLOC_ERR");
		hdd_ctx->original_channels->num_channels = 0;
		qdf_mem_free(hdd_ctx->original_channels);
		hdd_ctx->original_channels = NULL;
		return -ENOMEM;
	}
	return 0;
}

/**
 * check_disable_channels() - Check for disable channel
 * @hdd_ctx: Pointer to hdd context
 * @operating_channel: Current operating channel of adapter
 *
 * This function checks original_channels array for a specific channel
 *
 * Return: 0 if channel not found, 1 if channel found
 */
static bool check_disable_channels(struct hdd_context *hdd_ctx,
				   uint8_t operating_channel)
{
	uint32_t num_channels;
	uint8_t i;

	if (!hdd_ctx || !hdd_ctx->original_channels ||
	    !hdd_ctx->original_channels->channel_info)
		return false;

	num_channels = hdd_ctx->original_channels->num_channels;
	for (i = 0; i < num_channels; i++)
		if (hdd_ctx->original_channels->channel_info[i].channel_num ==
				operating_channel)
			return true;
	return false;
}

/**
 * disconnect_sta_and_stop_sap() - Disconnect STA and stop SAP
 *
 * @hdd_ctx: Pointer to hdd context
 *
 * Disable channels provided by user and disconnect STA if it is
 * connected to any AP, stop SAP and send deauthentication request
 * to STAs connected to SAP.
 *
 * Return: None
 */
static void disconnect_sta_and_stop_sap(struct hdd_context *hdd_ctx)
{
	struct hdd_adapter *adapter, *next = NULL;
	QDF_STATUS status;
	uint8_t ap_ch;

	if (!hdd_ctx)
		return;

	hdd_check_and_disconnect_sta_on_invalid_channel(hdd_ctx);

	status = hdd_get_front_adapter(hdd_ctx, &adapter);
	while (adapter && (status == QDF_STATUS_SUCCESS)) {
		if (!hdd_validate_adapter(adapter) &&
		    adapter->device_mode == QDF_SAP_MODE) {
			ap_ch = wlan_reg_freq_to_chan(
				hdd_ctx->pdev,
				adapter->session.ap.operating_chan_freq);
			if (check_disable_channels(hdd_ctx, ap_ch))
				wlan_hdd_stop_sap(adapter);
		}

		status = hdd_get_next_adapter(hdd_ctx, adapter, &next);
		adapter = next;
	}
}

/**
 * hdd_parse_disable_chan_cmd() - Parse the channel list received
 * in command.
 * @adapter: pointer to hdd adapter
 * @ptr: Pointer to the command string
 *
 * This function parses the channel list received in the command.
 * command should be a string having format
 * SET_DISABLE_CHANNEL_LIST <num of channels>
 * <channels separated by spaces>.
 * If the command comes multiple times than this function will compare
 * the channels received in the command with the channles cached in the
 * first command, if the channel list matches with the cached channles,
 * it returns success otherwise returns failure.
 *
 * Return: 0 on success, Error code on failure
 */

static int hdd_parse_disable_chan_cmd(struct hdd_adapter *adapter, uint8_t *ptr)
{
	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	uint8_t *param;
	int j, i, temp_int, ret = 0, num_channels;
	uint32_t parsed_channels[NUM_CHANNELS];
	bool is_command_repeated = false;

	if (!hdd_ctx) {
		hdd_err("HDD Context is NULL");
		return -EINVAL;
	}

	param = strnchr(ptr, strlen(ptr), ' ');
	/*no argument after the command*/
	if (!param)
		return -EINVAL;

	/*no space after the command*/
	else if (SPACE_ASCII_VALUE != *param)
		return -EINVAL;

	param++;

	/*removing empty spaces*/
	while ((SPACE_ASCII_VALUE  == *param) && ('\0' !=  *param))
		param++;

	/*no argument followed by spaces*/
	if ('\0' == *param)
		return -EINVAL;

	/*getting the first argument ie the number of channels*/
	if (sscanf(param, "%d ", &temp_int) != 1) {
		hdd_err("Cannot get number of channels from input");
		return -EINVAL;
	}

	if (temp_int < 0 || temp_int > NUM_CHANNELS) {
		hdd_err("Invalid Number of channel received");
		return -EINVAL;
	}

	hdd_debug("Number of channel to disable are: %d", temp_int);

	if (!temp_int) {
		/*
		 * Restore and Free the cache channels when the command is
		 * received with num channels as 0
		 */
		wlan_hdd_restore_channels(hdd_ctx, false);
		return 0;
	}

	qdf_mutex_acquire(&hdd_ctx->cache_channel_lock);

	if (!hdd_ctx->original_channels) {
		if (hdd_alloc_chan_cache(hdd_ctx, temp_int)) {
			ret = -ENOMEM;
			goto mem_alloc_failed;
		}
	} else if (hdd_ctx->original_channels->num_channels != temp_int) {
		hdd_err("Invalid Number of channels");
		ret = -EINVAL;
		is_command_repeated = true;
		goto parse_failed;
	} else {
		is_command_repeated = true;
	}
	num_channels = temp_int;
	for (j = 0; j < num_channels; j++) {
		/*
		 * param pointing to the beginning of first space
		 * after number of channels
		 */
		param = strpbrk(param, " ");
		/*no channel list after the number of channels argument*/
		if (!param) {
			hdd_err("Invalid No of channel provided in the list");
			ret = -EINVAL;
			goto parse_failed;
		}

		param++;

		/*removing empty space*/
		while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
			param++;

		if ('\0' == *param) {
			hdd_err("No channel is provided in the list");
			ret = -EINVAL;
			goto parse_failed;
		}

		if (sscanf(param, "%d ", &temp_int) != 1) {
			hdd_err("Cannot read channel number");
			ret = -EINVAL;
			goto parse_failed;
		}

		if (!IS_CHANNEL_VALID(temp_int)) {
			hdd_err("Invalid channel number received");
			ret = -EINVAL;
			goto parse_failed;
		}

		hdd_debug("channel[%d] = %d", j, temp_int);
		parsed_channels[j] = temp_int;
	}

	/*extra arguments check*/
	param = strpbrk(param, " ");
	if (param) {
		while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
			param++;

		if ('\0' !=  *param) {
			hdd_err("Invalid argument received");
			ret = -EINVAL;
			goto parse_failed;
		}
	}

	/*
	 * If command is received first time, cache the channels to
	 * be disabled else compare the channels received in the
	 * command with the cached channels, if channel list matches
	 * return success otherewise return failure.
	 */
	if (!is_command_repeated) {
		for (j = 0; j < num_channels; j++)
			hdd_ctx->original_channels->
					channel_info[j].channel_num =
							parsed_channels[j];

		/* Cache the channel list in regulatory also */
		ucfg_reg_cache_channel_state(hdd_ctx->pdev, parsed_channels,
					     num_channels);
	} else {
		for (i = 0; i < num_channels; i++) {
			for (j = 0; j < num_channels; j++)
				if (hdd_ctx->original_channels->
					channel_info[i].channel_num ==
							parsed_channels[j])
					break;
			if (j == num_channels) {
				ret = -EINVAL;
				goto parse_failed;
			}
		}
		ret = 0;
	}
mem_alloc_failed:

	qdf_mutex_release(&hdd_ctx->cache_channel_lock);
	/* Disable the channels received in command SET_DISABLE_CHANNEL_LIST */
	if (!is_command_repeated && hdd_ctx->original_channels) {
		ret = wlan_hdd_disable_channels(hdd_ctx);
		if (ret)
			return ret;
		disconnect_sta_and_stop_sap(hdd_ctx);
	}

	hdd_exit();

	return ret;

parse_failed:
	if (!is_command_repeated)
		wlan_hdd_free_cache_channels(hdd_ctx);

	qdf_mutex_release(&hdd_ctx->cache_channel_lock);
	hdd_exit();

	return ret;
}

static int drv_cmd_set_disable_chan_list(struct hdd_adapter *adapter,
					 struct hdd_context *hdd_ctx,
					 uint8_t *command,
					 uint8_t command_len,
					 struct hdd_priv_data *priv_data)
{
	return hdd_parse_disable_chan_cmd(adapter, command);
}

/**
 * hdd_get_disable_ch_list() - get disable channel list
 * @hdd_ctx: hdd context
 * @buf: buffer to hold disable channel list
 * @buf_len: buffer length
 *
 * Return: length of data copied to buf
 */
static int hdd_get_disable_ch_list(struct hdd_context *hdd_ctx, uint8_t *buf,
				   uint32_t buf_len)
{
	struct hdd_cache_channel_info *ch_list;
	unsigned char i, num_ch;
	int len = 0;

	qdf_mutex_acquire(&hdd_ctx->cache_channel_lock);
	if (hdd_ctx->original_channels &&
	    hdd_ctx->original_channels->num_channels &&
	    hdd_ctx->original_channels->channel_info) {
		num_ch = hdd_ctx->original_channels->num_channels;

		len = scnprintf(buf, buf_len, "%s %hhu",
				"GET_DISABLE_CHANNEL_LIST", num_ch);
		ch_list = hdd_ctx->original_channels->channel_info;
		for (i = 0; (i < num_ch) && (len < buf_len - 1); i++) {
			len += scnprintf(buf + len, buf_len - len,
					 " %d", ch_list[i].channel_num);
		}
	}
	qdf_mutex_release(&hdd_ctx->cache_channel_lock);

	return len;
}

static int drv_cmd_get_disable_chan_list(struct hdd_adapter *adapter,
					 struct hdd_context *hdd_ctx,
					 uint8_t *command,
					 uint8_t command_len,
					 struct hdd_priv_data *priv_data)
{
	char extra[512] = {0};
	int max_len, copied_length;

	hdd_debug("Received Command to get disable Channels list");

	max_len = QDF_MIN(priv_data->total_len, sizeof(extra));
	copied_length = hdd_get_disable_ch_list(hdd_ctx, extra, max_len);
	if (copied_length == 0) {
		hdd_err("disable channel list is not yet programmed");
		return -EINVAL;
	}

	if (copy_to_user(priv_data->buf, &extra, copied_length + 1)) {
		hdd_err("failed to copy data to user buffer");
		return -EFAULT;
	}

	hdd_debug("data:%s", extra);
	return 0;
}
#else

static int drv_cmd_set_disable_chan_list(struct hdd_adapter *adapter,
					 struct hdd_context *hdd_ctx,
					 uint8_t *command,
					 uint8_t command_len,
					 struct hdd_priv_data *priv_data)
{
	return 0;
}

void wlan_hdd_free_cache_channels(struct hdd_context *hdd_ctx)
{
}

static int drv_cmd_get_disable_chan_list(struct hdd_adapter *adapter,
					 struct hdd_context *hdd_ctx,
					 uint8_t *command,
					 uint8_t command_len,
					 struct hdd_priv_data *priv_data)
{
	return 0;
}
#endif

#ifdef FEATURE_ANI_LEVEL_REQUEST
static int drv_cmd_get_ani_level(struct hdd_adapter *adapter,
				 struct hdd_context *hdd_ctx,
				 uint8_t *command,
				 uint8_t command_len,
				 struct hdd_priv_data *priv_data)
{
	char *extra;
	int copied_length = 0, j, temp_int, ret = 0;
	uint8_t *param, num_freqs, num_recv_channels;
	uint32_t parsed_freqs[MAX_NUM_FREQS_FOR_ANI_LEVEL];
	struct wmi_host_ani_level_event ani[MAX_NUM_FREQS_FOR_ANI_LEVEL];
	size_t user_size = priv_data->total_len;

	hdd_debug("Received Command to get ANI level");

	param = strnchr(command, strlen(command), ' ');

	/* No argument after the command */
	if (!param)
		return -EINVAL;

	/* No space after the command */
	else if (SPACE_ASCII_VALUE != *param)
		return -EINVAL;

	param++;

	/* Removing empty spaces*/
	while ((SPACE_ASCII_VALUE  == *param) && ('\0' !=  *param))
		param++;

	/*no argument followed by spaces */
	if ('\0' == *param)
		return -EINVAL;

	/* Getting the first argument ie the number of channels */
	if (sscanf(param, "%d ", &temp_int) != 1) {
		hdd_err("Cannot get number of freq from input");
		return -EINVAL;
	}

	if (temp_int < 0 || temp_int > MAX_NUM_FREQS_FOR_ANI_LEVEL) {
		hdd_err("Invalid Number of channel received");
		return -EINVAL;
	}

	hdd_debug("Number of freq to fetch ANI level are: %d", temp_int);

	if (!temp_int)
		return 0;

	num_freqs = temp_int;

	for (j = 0; j < num_freqs; j++) {
		/*
		 * Param pointing to the beginning of first space
		 * after number of channels.
		 */
		param = strpbrk(param, " ");
		/*no channel list after the number of channels argument*/
		if (!param) {
			hdd_err("Invalid No of freq provided in the list");
			ret = -EINVAL;
			goto parse_failed;
		}

		param++;

		/* Removing empty space */
		while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
			param++;

		if ('\0' == *param) {
			hdd_err("No freq is provided in the list");
			ret = -EINVAL;
			goto parse_failed;
		}

		if (sscanf(param, "%d ", &temp_int) != 1) {
			hdd_err("Cannot read freq number");
			ret = -EINVAL;
			goto parse_failed;
		}

		hdd_debug("channel_freq[%d] = %d", j, temp_int);
		parsed_freqs[j] = temp_int;
	}

	/* Extra arguments check */
	param = strpbrk(param, " ");
	if (param) {
		while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
			param++;

		if ('\0' !=  *param) {
			hdd_err("Invalid argument received");
			ret = -EINVAL;
			goto parse_failed;
		}
	}

	qdf_mem_zero(ani, sizeof(ani));
	hdd_debug("num_freq: %d", num_freqs);
	if (QDF_IS_STATUS_ERROR(wlan_hdd_get_ani_level(adapter, ani,
						       parsed_freqs,
						       num_freqs))) {
		hdd_err("Unable to retrieve ani level");
		return -EINVAL;
	}

	extra = qdf_mem_malloc(user_size);
	if (!extra) {
		hdd_err("memory allocation failed");
		ret = -ENOMEM;
		goto parse_failed;
	}

	/*
	 * Find the number of channels that are populated. If freq is not
	 * filled then stop count there
	 */
	for (num_recv_channels = 0;
	     (num_recv_channels < num_freqs &&
	     ani[num_recv_channels].chan_freq); num_recv_channels++)
		;

	for (j = 0; j < num_recv_channels; j++) {
		/* Sanity check for ANI level validity */
		if (ani[j].ani_level > MAX_ANI_LEVEL)
			continue;

		copied_length += scnprintf(extra + copied_length,
					   user_size - copied_length, "%d:%d\n",
					   ani[j].chan_freq, ani[j].ani_level);
	}

	if (copied_length == 0) {
		hdd_err("ANI level not fetched");
		ret = -EINVAL;
		goto free;
	}

	hdd_debug("data: %s", extra);

	if (copy_to_user(priv_data->buf, extra, copied_length + 1)) {
		hdd_err("failed to copy data to user buffer");
		ret = -EFAULT;
		goto free;
	}

free:
	qdf_mem_free(extra);

parse_failed:
	return ret;
}

#else
static int drv_cmd_get_ani_level(struct hdd_adapter *adapter,
				 struct hdd_context *hdd_ctx,
				 uint8_t *command,
				 uint8_t command_len,
				 struct hdd_priv_data *priv_data)
{
	return 0;
}
#endif
/*
 * The following table contains all supported WLAN HDD
 * IOCTL driver commands and the handler for each of them.
 */
static const struct hdd_drv_cmd hdd_drv_cmds[] = {
	{"P2P_DEV_ADDR",              drv_cmd_p2p_dev_addr, false},
	{"P2P_SET_NOA",               drv_cmd_p2p_set_noa, true},
	{"P2P_SET_PS",                drv_cmd_p2p_set_ps, true},
	{"SETBAND",                   drv_cmd_set_band, true},
	{"SETWMMPS",                  drv_cmd_set_wmmps, true},
	{"COUNTRY",                   drv_cmd_country, true},
	{"SETCOUNTRYREV",             drv_cmd_country, true},
	{"GETCOUNTRYREV",             drv_cmd_get_country, false},
	{"SETSUSPENDMODE",            drv_cmd_set_suspend_mode, true},
	{"SET_AP_WPS_P2P_IE",         drv_cmd_dummy, false},
	{"SETROAMTRIGGER",            drv_cmd_set_roam_trigger, true},
	{"GETROAMTRIGGER",            drv_cmd_get_roam_trigger, false},
	{"SETROAMSCANPERIOD",         drv_cmd_set_roam_scan_period, true},
	{"GETROAMSCANPERIOD",         drv_cmd_get_roam_scan_period, false},
	{"SETROAMSCANREFRESHPERIOD",  drv_cmd_set_roam_scan_refresh_period,
	 true},
	{"GETROAMSCANREFRESHPERIOD",  drv_cmd_get_roam_scan_refresh_period,
	 false},
	{"SETROAMMODE",               drv_cmd_set_roam_mode, true},
	{"GETROAMMODE",               drv_cmd_get_roam_mode, false},
	{"SETROAMDELTA",              drv_cmd_set_roam_delta, true},
	{"GETROAMDELTA",              drv_cmd_get_roam_delta, false},
	{"GETBAND",                   drv_cmd_get_band, false},
	{"SETROAMSCANCHANNELS",       drv_cmd_set_roam_scan_channels, true},
	{"GETROAMSCANCHANNELS",       drv_cmd_get_roam_scan_channels, false},
	{"GETCCXMODE",                drv_cmd_get_ccx_mode, false},
	{"GETOKCMODE",                drv_cmd_get_okc_mode, false},
	{"GETFASTROAM",               drv_cmd_get_fast_roam, false},
	{"GETFASTTRANSITION",         drv_cmd_get_fast_transition, false},
	{"SETROAMSCANCHANNELMINTIME", drv_cmd_set_roam_scan_channel_min_time,
	 true},
	{"SENDACTIONFRAME",           drv_cmd_send_action_frame, true},
	{"GETROAMSCANCHANNELMINTIME", drv_cmd_get_roam_scan_channel_min_time,
	 false},
	{"SETSCANCHANNELTIME",        drv_cmd_set_scan_channel_time, true},
	{"GETSCANCHANNELTIME",        drv_cmd_get_scan_channel_time, false},
	{"SETSCANHOMETIME",           drv_cmd_set_scan_home_time, true},
	{"GETSCANHOMETIME",           drv_cmd_get_scan_home_time, false},
	{"SETROAMINTRABAND",          drv_cmd_set_roam_intra_band, true},
	{"GETROAMINTRABAND",          drv_cmd_get_roam_intra_band, false},
	{"SETSCANNPROBES",            drv_cmd_set_scan_n_probes, true},
	{"GETSCANNPROBES",            drv_cmd_get_scan_n_probes, false},
	{"SETSCANHOMEAWAYTIME",       drv_cmd_set_scan_home_away_time, true},
	{"GETSCANHOMEAWAYTIME",       drv_cmd_get_scan_home_away_time, false},
	{"REASSOC",                   drv_cmd_reassoc, true},
	{"SETWESMODE",                drv_cmd_set_wes_mode, true},
	{"GETWESMODE",                drv_cmd_get_wes_mode, false},
	{"SETOPPORTUNISTICRSSIDIFF",  drv_cmd_set_opportunistic_rssi_diff,
	 true},
	{"GETOPPORTUNISTICRSSIDIFF",  drv_cmd_get_opportunistic_rssi_diff,
	 false},
	{"SETROAMRESCANRSSIDIFF",     drv_cmd_set_roam_rescan_rssi_diff, true},
	{"GETROAMRESCANRSSIDIFF",     drv_cmd_get_roam_rescan_rssi_diff, false},
	{"SETFASTROAM",               drv_cmd_set_fast_roam, true},
	{"SETFASTTRANSITION",         drv_cmd_set_fast_transition, true},
	{"FASTREASSOC",               drv_cmd_fast_reassoc, true},
	{"SETROAMSCANCONTROL",        drv_cmd_set_roam_scan_control, true},
	{"SETOKCMODE",                drv_cmd_set_okc_mode, true},
	{"GETROAMSCANCONTROL",        drv_cmd_get_roam_scan_control, false},
	{"BTCOEXMODE",                drv_cmd_bt_coex_mode, true},
	{"SCAN-ACTIVE",               drv_cmd_scan_active, false},
	{"SCAN-PASSIVE",              drv_cmd_scan_passive, false},
	{"CONCSETDWELLTIME",          drv_cmd_conc_set_dwell_time, true},
	{"GETDWELLTIME",              drv_cmd_get_dwell_time, false},
	{"SETDWELLTIME",              drv_cmd_set_dwell_time, true},
	{"MIRACAST",                  drv_cmd_miracast, true},
	{"SETIBSSBEACONOUIDATA",      drv_cmd_set_ibss_beacon_oui_data, true},
#ifdef FEATURE_WLAN_RMC
	{"SETRMCENABLE",              drv_cmd_set_rmc_enable, true},
	{"SETRMCACTIONPERIOD",        drv_cmd_set_rmc_action_period, true},
	{"SETRMCTXRATE",              drv_cmd_set_rmc_tx_rate, true},
#endif
	{"GETIBSSPEERINFOALL",        drv_cmd_get_ibss_peer_info_all, false},
	{"GETIBSSPEERINFO",           drv_cmd_get_ibss_peer_info, true},
	{"SETIBSSTXFAILEVENT",        drv_cmd_set_ibss_tx_fail_event, true},
#ifdef FEATURE_WLAN_ESE
	{"SETCCXROAMSCANCHANNELS",    drv_cmd_set_ccx_roam_scan_channels, true},
	{"GETTSMSTATS",               drv_cmd_get_tsm_stats, true},
	{"SETCCKMIE",                 drv_cmd_set_cckm_ie, true},
	{"CCXBEACONREQ",	      drv_cmd_ccx_beacon_req, true},
	{"CCXPLMREQ",                 drv_cmd_ccx_plm_req, true},
	{"SETCCXMODE",                drv_cmd_set_ccx_mode, true},
#endif /* FEATURE_WLAN_ESE */
	{"SETMCRATE",                 drv_cmd_set_mc_rate, true},
	{"MAXTXPOWER",                drv_cmd_max_tx_power, true},
	{"SETDFSSCANMODE",            drv_cmd_set_dfs_scan_mode, true},
	{"GETDFSSCANMODE",            drv_cmd_get_dfs_scan_mode, false},
	{"GETLINKSTATUS",             drv_cmd_get_link_status, false},
#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
	{"ENABLEEXTWOW",              drv_cmd_enable_ext_wow, true},
	{"SETAPP1PARAMS",             drv_cmd_set_app1_params, true},
	{"SETAPP2PARAMS",             drv_cmd_set_app2_params, true},
#endif
#ifdef FEATURE_WLAN_TDLS
	{"TDLSSECONDARYCHANNELOFFSET", drv_cmd_tdls_secondary_channel_offset,
	 true},
	{"TDLSOFFCHANNELMODE",        drv_cmd_tdls_off_channel_mode, true},
	{"TDLSOFFCHANNEL",            drv_cmd_tdls_off_channel, true},
	{"TDLSSCAN",                  drv_cmd_tdls_scan, true},
#endif
	{"RSSI",                      drv_cmd_get_rssi, false},
	{"LINKSPEED",                 drv_cmd_get_linkspeed, false},
#ifdef WLAN_FEATURE_PACKET_FILTERING
	{"RXFILTER-REMOVE",           drv_cmd_rx_filter_remove, true},
	{"RXFILTER-ADD",              drv_cmd_rx_filter_add, true},
#endif
	{"SET_FCC_CHANNEL",           drv_cmd_set_fcc_channel, true},
	{"CHANNEL_SWITCH",            drv_cmd_set_channel_switch, true},
	{"SETANTENNAMODE",            drv_cmd_set_antenna_mode, true},
	{"GETANTENNAMODE",            drv_cmd_get_antenna_mode, false},
	{"SET_DISABLE_CHANNEL_LIST",  drv_cmd_set_disable_chan_list, true},
	{"GET_DISABLE_CHANNEL_LIST",  drv_cmd_get_disable_chan_list, false},
	{"GET_ANI_LEVEL",             drv_cmd_get_ani_level, false},
	{"STOP",                      drv_cmd_dummy, false},
	/* Deprecated commands */
	{"RXFILTER-START",            drv_cmd_dummy, false},
	{"RXFILTER-STOP",             drv_cmd_dummy, false},
	{"BTCOEXSCAN-START",          drv_cmd_dummy, false},
	{"BTCOEXSCAN-STOP",           drv_cmd_dummy, false},
};

/**
 * hdd_drv_cmd_process() - chooses and runs the proper
 *                                handler based on the input command
 * @adapter:	Pointer to the hdd adapter
 * @cmd:	Pointer to the driver command
 * @priv_data:	Pointer to the data associated with the command
 *
 * This function parses the input hdd driver command and runs
 * the proper handler
 *
 * Return: 0 for success non-zero for failure
 */
static int hdd_drv_cmd_process(struct hdd_adapter *adapter,
			       uint8_t *cmd,
			       struct hdd_priv_data *priv_data)
{
	struct hdd_context *hdd_ctx;
	int i;
	const int cmd_num_total = ARRAY_SIZE(hdd_drv_cmds);
	uint8_t *cmd_i = NULL;
	hdd_drv_cmd_handler_t handler = NULL;
	int len = 0, cmd_len = 0;
	uint8_t *ptr;
	bool args;

	if (!adapter || !cmd || !priv_data) {
		hdd_err("at least 1 param is NULL");
		return -EINVAL;
	}

	/* Calculate length of the first word */
	ptr = strchrnul(cmd, ' ');
	cmd_len = ptr - cmd;

	hdd_ctx = WLAN_HDD_GET_CTX(adapter);

	for (i = 0; i < cmd_num_total; i++) {

		cmd_i = (uint8_t *)hdd_drv_cmds[i].cmd;
		handler = hdd_drv_cmds[i].handler;
		len = strlen(cmd_i);
		args = hdd_drv_cmds[i].args;

		if (!handler) {
			hdd_err("no. %d handler is NULL", i);
			return -EINVAL;
		}

		if (len == cmd_len && strncasecmp(cmd, cmd_i, len) == 0) {
			if (args && drv_cmd_validate(cmd, len))
				return -EINVAL;

			return handler(adapter, hdd_ctx,
				       cmd, len, priv_data);
		}
	}

	return drv_cmd_invalid(adapter, hdd_ctx, cmd, len, priv_data);
}

/**
 * hdd_driver_command() - top level wlan hdd driver command handler
 * @adapter:	Pointer to the hdd adapter
 * @priv_data:	Pointer to the raw command data
 *
 * This function is the top level wlan hdd driver command handler. It
 * handles the command with the help of hdd_drv_cmd_process()
 *
 * Return: 0 for success non-zero for failure
 */
static int hdd_driver_command(struct hdd_adapter *adapter,
			      struct hdd_priv_data *priv_data)
{
	uint8_t *command = NULL;
	int ret = 0;
	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);

	hdd_enter();

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

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

	if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
		hdd_err("Driver module is closed; command can not be processed");
		return -EINVAL;
	}

	/*
	 * Note that valid pointers are provided by caller
	 */

	/* copy to local struct to avoid numerous changes to legacy code */
	if (priv_data->total_len <= 0 ||
	    priv_data->total_len > WLAN_PRIV_DATA_MAX_LEN) {
		hdd_warn("Invalid priv_data.total_len: %d!!!",
			  priv_data->total_len);
		ret = -EINVAL;
		goto exit;
	}

	/* Allocate +1 for '\0' */
	command = qdf_mem_malloc(priv_data->total_len + 1);
	if (!command) {
		hdd_err("failed to allocate memory");
		ret = -ENOMEM;
		goto exit;
	}

	if (copy_from_user(command, priv_data->buf, priv_data->total_len)) {
		ret = -EFAULT;
		goto exit;
	}

	/* Make sure the command is NUL-terminated */
	command[priv_data->total_len] = '\0';

	hdd_debug("%s: %s", adapter->dev->name, command);
	ret = hdd_drv_cmd_process(adapter, command, priv_data);

exit:
	if (command)
		qdf_mem_free(command);
	hdd_exit();
	return ret;
}

#ifdef CONFIG_COMPAT
static int hdd_driver_compat_ioctl(struct hdd_adapter *adapter, struct ifreq *ifr)
{
	struct {
		compat_uptr_t buf;
		int used_len;
		int total_len;
	} compat_priv_data;
	struct hdd_priv_data priv_data;
	int ret = 0;

	/*
	 * Note that adapter and ifr have already been verified by caller,
	 * and HDD context has also been validated
	 */
	if (copy_from_user(&compat_priv_data, ifr->ifr_data,
			   sizeof(compat_priv_data))) {
		ret = -EFAULT;
		goto exit;
	}
	priv_data.buf = compat_ptr(compat_priv_data.buf);
	priv_data.used_len = compat_priv_data.used_len;
	priv_data.total_len = compat_priv_data.total_len;
	ret = hdd_driver_command(adapter, &priv_data);
exit:
	return ret;
}
#else /* CONFIG_COMPAT */
static int hdd_driver_compat_ioctl(struct hdd_adapter *adapter, struct ifreq *ifr)
{
	/* will never be invoked */
	return 0;
}
#endif /* CONFIG_COMPAT */

static int hdd_driver_ioctl(struct hdd_adapter *adapter, struct ifreq *ifr)
{
	struct hdd_priv_data priv_data;
	int ret = 0;

	/*
	 * Note that adapter and ifr have already been verified by caller,
	 * and HDD context has also been validated
	 */
	if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data)))
		ret = -EFAULT;
	else
		ret = hdd_driver_command(adapter, &priv_data);

	return ret;
}

/**
 * __hdd_ioctl() - ioctl handler for wlan network interfaces
 * @dev: device upon which the ioctl was received
 * @ifr: ioctl request information
 * @cmd: ioctl command
 *
 * This function does initial processing of wlan device ioctls.
 * Currently two flavors of ioctls are supported.  The primary ioctl
 * that is supported is the (SIOCDEVPRIVATE + 1) ioctl which is used
 * for Android "DRIVER" commands.  The other ioctl that is
 * conditionally supported is the SIOCIOCTLTX99 ioctl which is used
 * for FTM on some platforms.  This function simply verifies that the
 * driver is in a sane state, and that the ioctl is one of the
 * supported flavors, in which case flavor-specific handlers are
 * dispatched.
 *
 * Return: 0 on success, non-zero on error
 */
static int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
	struct hdd_context *hdd_ctx;
	int ret;

	hdd_enter_dev(dev);

	if (dev != adapter->dev) {
		hdd_err("HDD adapter/dev inconsistency");
		ret = -ENODEV;
		goto exit;
	}

	if ((!ifr) || (!ifr->ifr_data)) {
		hdd_err("invalid data cmd: %d", cmd);
		ret = -EINVAL;
		goto exit;
	}
#if  defined(QCA_WIFI_FTM) && defined(LINUX_QCMBR)
	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
		if (SIOCIOCTLTX99 == cmd) {
			ret = wlan_hdd_qcmbr_unified_ioctl(adapter, ifr);
			goto exit;
		}
	}
#endif

	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	ret = wlan_hdd_validate_context(hdd_ctx);
	if (ret)
		goto exit;

	switch (cmd) {
	case (SIOCDEVPRIVATE + 1):
		if (in_compat_syscall())
			ret = hdd_driver_compat_ioctl(adapter, ifr);
		else
			ret = hdd_driver_ioctl(adapter, ifr);
		break;
	default:
		hdd_warn("unknown ioctl %d", cmd);
		ret = -EINVAL;
		break;
	}
exit:
	hdd_exit();
	return ret;
}

/**
 * hdd_ioctl() - ioctl handler (wrapper) for wlan network interfaces
 * @net_dev: device upon which the ioctl was received
 * @ifr: ioctl request information
 * @cmd: ioctl command
 *
 * This function acts as an SSR-protecting wrapper to __hdd_ioctl()
 * which is where the ioctls are really handled.
 *
 * Return: 0 on success, non-zero on error
 */
int hdd_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd)
{
	struct osif_vdev_sync *vdev_sync;
	int errno;

	errno = osif_vdev_sync_op_start(net_dev, &vdev_sync);
	if (errno)
		return errno;

	errno = __hdd_ioctl(net_dev, ifr, cmd);

	osif_vdev_sync_op_stop(vdev_sync);

	return errno;
}

