/*
 * Copyright (c) 2012-2020 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"
#include "qdf_func_tracker.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_FULL_MAC_FMT" %d %d ",
				QDF_FULL_MAC_REF(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_check_and_fill_freq() - to validate chan and convert into freq
 * @in_chan: input as channel number or freq to be checked
 * @freq: frequency for input in_chan (output parameter)
 *
 * This function checks input "in_chan" is channel number, if yes then fills
 * appropriate frequency into "freq" out param. If the "in_param" is greater
 * than WNI_CFG_CURRENT_CHANNEL_STAMAX then checks for valid frequencies.
 *
 * Return: true if "in_chan" is valid channel/frequency; false otherwise
 */
static bool hdd_check_and_fill_freq(uint32_t in_chan, qdf_freq_t *freq)
{
	if (in_chan <= WNI_CFG_CURRENT_CHANNEL_STAMAX)
		*freq = wlan_chan_to_freq(in_chan);
	else if (WLAN_REG_IS_24GHZ_CH_FREQ(in_chan) ||
		 WLAN_REG_IS_5GHZ_CH_FREQ(in_chan) ||
		 WLAN_REG_IS_6GHZ_CHAN_FREQ(in_chan))
		*freq = in_chan;
	else
		return false;

	return true;
}

/**
 * _hdd_parse_bssid_and_chan() - helper function to parse bssid and channel
 * @data:            input data
 * @target_ap_bssid: pointer to bssid (output parameter)
 * @freq:         pointer to freq (output parameter)
 *
 * Return: 0 if parsing is successful; -EINVAL otherwise
 */
static int _hdd_parse_bssid_and_chan(const uint8_t **data,
				     uint8_t *bssid,
				     qdf_freq_t *freq)
{
	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/freq 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)
		goto error;
	else if (!hdd_check_and_fill_freq(temp_int, freq))
		goto error;

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

/**
 * hdd_parse_send_action_frame_v1_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 | frequency><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,
				    qdf_freq_t *freq, 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, freq))
		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
 * @freq: Pointer to the Target AP frequency
 *
 * This function parses the reasoc command data passed in the format
 * REASSOC<space><bssid><space><channel/frequency>
 *
 * Return: 0 for success non-zero for failure
 */
static int hdd_parse_reassoc_command_v1_data(const uint8_t *command,
					     uint8_t *bssid,
					     qdf_freq_t *freq)
{
	const uint8_t *in_ptr = command;

	if (_hdd_parse_bssid_and_chan(&in_ptr, bssid, freq))
		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/FREQ
 *
 * Where "xx:xx:xx:xx:xx:xx" is the Hex-ASCII representation of the
 * BSSID and CH/FREQ is the ASCII representation of the channel/frequency.
 * For example
 *
 *    REASSOC 00:0a:0b:11:22:33 48
 *    REASSOC 00:0a:0b:11:22:33 2412
 *
 * Return: 0 for success non-zero for failure
 */
static int hdd_parse_reassoc_v1(struct hdd_adapter *adapter, const char *command)
{
	qdf_freq_t freq = 0;
	tSirMacAddr bssid;
	int ret;

	ret = hdd_parse_reassoc_command_v1_data(command, bssid, &freq);
	if (ret)
		hdd_err("Failed to parse reassoc command data");
	else
		ret = hdd_reassoc(adapter, bssid, freq, 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;
	qdf_freq_t freq = 0;
	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 {
		/*
		 * In Reassoc command, user can send channel number or frequency
		 * along with BSSID. If params.channel param of REASSOC command
		 * is less than WNI_CFG_CURRENT_CHANNEL_STAMAX, then host
		 * consider this as channel number else frequency.
		 */
		if (!hdd_check_and_fill_freq(params.channel, &freq))
			return -EINVAL;

		ret = hdd_reassoc(adapter, bssid, freq, 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/FREQ
	 * 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
 * @freq:	Frequency 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 qdf_freq_t freq, const uint8_t dwell_time,
		    const int payload_len, const uint8_t *payload)
{
	struct ieee80211_channel chan;
	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 (payload_len < sizeof(tSirMacVendorSpecificFrameHdr)) {
		hdd_warn("Invalid payload length: %d", payload_len);
		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);
	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 = freq;
	/* 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)) {
			/*
			 * if the freq number is different from operating
			 * freq then no need to send action frame
			 */
			if (freq) {
				if (freq != sta_ctx->conn_info.chan_freq) {
					hdd_warn("freq(%u) is different from operating freq(%u)",
						 freq,
						 sta_ctx->conn_info.chan_freq);
					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 frequency,
				 * delayed transmission of action frame is ok.
				 */
				chan.center_freq = sta_ctx->conn_info.chan_freq;
			}
		}
	}
	if (chan.center_freq == 0) {
		hdd_nofl_err("Invalid freq : %d", freq);
		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)
{
	qdf_freq_t freq = 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, &freq,
						  &dwell_time, &payload,
						  &payload_len);
	if (ret) {
		hdd_nofl_err("Failed to parse send action frame data");
	} else {
		ret = hdd_sendactionframe(adapter, bssid, freq,
					  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;
	qdf_freq_t freq = 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;
	}

	if (!hdd_check_and_fill_freq(params->channel, &freq)) {
		hdd_err("Invalid channel: %d", params->channel);
		return -EINVAL;
	}

	ret = hdd_sendactionframe(adapter, bssid, freq, 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 ((j != 0) && (*num_channels == j))
				return 0;
			else
				goto cnt_mismatch;
		}

		/* 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 ((j != 0) && (*num_channels == j))
				return 0;
			else
				goto cnt_mismatch;
		}

		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;

cnt_mismatch:
	hdd_debug("Mismatch in ch cnt: %d and num of ch: %d", *num_channels, j);
	*num_channels = 0;
	return -EINVAL;

}

/**
 * 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_FMT,
			  QDF_MAC_ADDR_REF(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 "QDF_MAC_ADDR_FMT" %.8s %u %.16s %u",
		  params.vdev_id,
		  QDF_MAC_ADDR_REF(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, "%02x:%02x:%02x:%02x:%02x:%02x",
			&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(QDF_MAC_ADDR_FMT" %.16s %u %u %u %u %u %u %u %u %u %u %u %u %u",
		  QDF_MAC_ADDR_REF(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 2G MAX", 19) == 0) {
		ucfg_scan_cfg_get_active_2g_dwelltime(psoc, &val);
		*len = scnprintf(extra, n, "GETDWELLTIME 2G 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_rl("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_rl("argument passed for SETDWELLTIME PASSIVE MAX is incorrect");
			return -EFAULT;
		}
		ucfg_scan_cfg_set_passive_dwelltime(psoc, val);
	} else if (strncmp(command, "SETDWELLTIME 2G MAX", 19) == 0) {
		if (drv_cmd_validate(command, 19))
			return -EINVAL;

		value = value + 20;
		temp = kstrtou32(value, 10, &val);
		if (temp || !cfg_in_range(CFG_ACTIVE_MAX_2G_CHANNEL_TIME,
					  val)) {
			hdd_err_rl("argument passed for SETDWELLTIME 2G MAX is incorrect");
			return -EFAULT;
		}
		ucfg_scan_cfg_set_active_2g_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_rl("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 = "QDF_MAC_ADDR_FMT", dev_mode %s(%d)",
		  rate_update.mcastDataRate24GHz,
		  QDF_MAC_ADDR_REF(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;
	uint32_t band_bitmap;

	/*
	 * 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;
	}

	band_bitmap = hdd_reg_legacy_setband_to_reg_wifi_band_bitmap(band);

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

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);
}

#ifdef WLAN_FEATURE_ROAM_OFFLOAD
static bool is_roam_ch_from_fw_supported(struct hdd_context *hdd_ctx)
{
	return hdd_ctx->roam_ch_from_fw_supported;
}

struct roam_ch_priv {
	struct roam_scan_ch_resp roam_ch;
};

void hdd_get_roam_scan_ch_cb(hdd_handle_t hdd_handle,
			     struct roam_scan_ch_resp *roam_ch,
			     void *context)
{
	struct osif_request *request;
	struct roam_ch_priv *priv;
	uint8_t *event = NULL, i = 0;
	uint32_t  *freq = NULL, len;
	struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);

	hdd_debug("roam scan ch list event received : vdev_id:%d command resp: %d",
		  roam_ch->vdev_id, roam_ch->command_resp);
	/**
	 * If command response is set in the response message, then it is
	 * getroamscanchannels command response else this event is asyncronous
	 * event raised by firmware.
	 */
	if (!roam_ch->command_resp) {
		len = roam_ch->num_channels * sizeof(roam_ch->chan_list[0]);
		if (!len) {
			hdd_err("Invalid len");
			return;
		}
		event = (uint8_t *)qdf_mem_malloc(len);
		if (!event) {
			hdd_err("Failed to alloc event response buf vdev_id: %d",
				roam_ch->vdev_id);
			return;
		}
		freq = (uint32_t *)event;
		for (i = 0; i < roam_ch->num_channels &&
		     i < WNI_CFG_VALID_CHANNEL_LIST_LEN; i++) {
			freq[i] = roam_ch->chan_list[i];
		}

		hdd_send_roam_scan_ch_list_event(hdd_ctx, roam_ch->vdev_id,
						 len, event);
		qdf_mem_free(event);
		return;
	}

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

	priv->roam_ch.num_channels = roam_ch->num_channels;
	for (i = 0; i < priv->roam_ch.num_channels &&
	     i < WNI_CFG_VALID_CHANNEL_LIST_LEN; i++)
		priv->roam_ch.chan_list[i] = roam_ch->chan_list[i];

	osif_request_complete(request);
	osif_request_put(request);
}

static uint32_t
hdd_get_roam_chan_from_fw(struct hdd_adapter *adapter, uint32_t *chan_list,
			  uint8_t *num_channels)
{
	QDF_STATUS status = QDF_STATUS_E_INVAL;
	struct hdd_context *hdd_ctx;
	int ret, i;
	void *cookie;
	struct osif_request *request;
	struct roam_ch_priv *priv;
	struct roam_scan_ch_resp *p_roam_ch;
	static const struct osif_request_params params = {
		.priv_size = sizeof(*priv) +
			     sizeof(priv->roam_ch.chan_list[0]) *
			     WNI_CFG_VALID_CHANNEL_LIST_LEN,
		.timeout_ms = WLAN_WAIT_TIME_STATS,
	};

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

	priv = osif_request_priv(request);
	p_roam_ch = &priv->roam_ch;
	/** channel list starts after response structure*/
	priv->roam_ch.chan_list = (uint32_t *)(p_roam_ch + 1);
	cookie = osif_request_cookie(request);
	status = sme_get_roam_scan_ch(hdd_ctx->mac_handle,
				      adapter->vdev_id, cookie);

	if (QDF_IS_STATUS_ERROR(status)) {
		hdd_err("Unable to retrieve roam channels");
		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 raom channels");
		goto cleanup;
	}

	priv = osif_request_priv(request);
	*num_channels = priv->roam_ch.num_channels;
	for (i = 0; i < *num_channels; i++)
		chan_list[i] = priv->roam_ch.chan_list[i];

cleanup:
	osif_request_put(request);

	return ret;
}

int
hdd_get_roam_scan_freq(struct hdd_adapter *adapter, mac_handle_t mac_handle,
		       uint32_t *chan_list, uint8_t *num_channels)
{
	int ret = 0;

	if (!adapter || !mac_handle || !chan_list || !num_channels) {
		hdd_err("failed to get roam scan channel, invalid input");
		return -EFAULT;
	}

	if (is_roam_ch_from_fw_supported(adapter->hdd_ctx)) {
		ret = hdd_get_roam_chan_from_fw(adapter, chan_list,
						num_channels);
		if (ret != QDF_STATUS_SUCCESS) {
			hdd_err("failed to get roam scan channel list from FW");
			return -EFAULT;
		}

		return ret;
	}

	if (sme_get_roam_scan_channel_list(mac_handle, chan_list,
					   num_channels, adapter->vdev_id) !=
					   QDF_STATUS_SUCCESS) {
		hdd_err("failed to get roam scan channel list");
		return -EFAULT;
	}

	return ret;
}
#endif

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;

	ret = hdd_get_roam_scan_freq(adapter, hdd_ctx->mac_handle, freq_list,
				     &num_channels);
	if (ret != QDF_STATUS_SUCCESS)
		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] = {0};
	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;
	qdf_freq_t freq = 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,
						&freq);
	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)) {
			hdd_wma_send_fastreassoc_cmd(
				adapter, bssid, sta_ctx->conn_info.chan_freq);
		} 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 freq number is a valid freq number */
	if (freq && QDF_STATUS_SUCCESS !=
		wlan_hdd_validate_operation_channel(adapter, freq)) {
		hdd_err("Invalid freq [%d]", freq);
		return -EINVAL;
	}

	if (roaming_offload_enabled(hdd_ctx)) {
		hdd_wma_send_fastreassoc_cmd(adapter, bssid, freq);
		goto exit;
	}
	/* Proceed with reassoc */
	req.ch_freq = freq;
	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_FMT " bssId: " QDF_MAC_ADDR_FMT,
			  adapter->device_mode, tx_power,
			  QDF_MAC_ADDR_REF(selfmac.bytes),
			  QDF_MAC_ADDR_REF(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_FMT,
				    action ? "setting" : "clearing",
				    QDF_MAC_ADDR_REF(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_debug("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);
}

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
 * @reason: Disconnect reason code as per @enum eSirMacReasonCodes
 *
 * 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,
					enum eSirMacReasonCodes reason)
{
	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, reason);

	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,
					    eSIR_MAC_OPER_CHANNEL_BAND_CHANGE);
	}

	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

#ifdef FUNC_CALL_MAP
static int drv_cmd_get_function_call_map(struct hdd_adapter *adapter,
					 struct hdd_context *hdd_ctx,
					 uint8_t *command,
					 uint8_t command_len,
					 struct hdd_priv_data *priv_data)
{
	char *cc_buf = qdf_mem_malloc(QDF_FUNCTION_CALL_MAP_BUF_LEN);
	uint8_t *param;
	int temp_int;

	param = strnchr(command, strlen(command), ' ');
	/*no argument after the command*/
	if (NULL == 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 */
	if (sscanf(param, "%d ", &temp_int) != 1) {
		hdd_err("No option given");
		return -EINVAL;
	}

	if (temp_int < 0 || temp_int > 1) {
		hdd_err("Invalid option given");
		return -EINVAL;
	}

	/* Read the buffer */
	if (temp_int) {
	/*
	 * These logs are required as these indicates the start and end of the
	 * dump for the auto script to parse
	 */
		hdd_info("Function call map dump start");
		qdf_get_func_call_map(cc_buf);
		qdf_trace_hex_dump(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO,
				   cc_buf, QDF_FUNCTION_CALL_MAP_BUF_LEN);
		hdd_info("Function call map dump end");
	} else {
		qdf_clear_func_call_map();
		hdd_info("Function call map clear");
	}
	qdf_mem_free(cc_buf);

	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},
#ifdef FUNC_CALL_MAP
	{"GET_FUNCTION_CALL_MAP",     drv_cmd_get_function_call_map, true},
#endif
	{"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;
}

